From 40f4a0b03747545fc3978f7daa3f527814547ce4 Mon Sep 17 00:00:00 2001 From: Forairaaaaa Date: Thu, 7 Dec 2023 11:23:25 +0800 Subject: [PATCH 01/10] adding app keyboard --- main/apps/app_keyboard/app_keyboard.cpp | 52 ++++++ main/apps/app_keyboard/app_keyboard.h | 49 ++++++ main/apps/app_keyboard/assets/keyboard_big.h | 149 ++++++++++++++++++ .../apps/app_keyboard/assets/keyboard_small.h | 117 ++++++++++++++ main/apps/apps.h | 2 +- main/cardputer.cpp | 8 +- 6 files changed, 373 insertions(+), 4 deletions(-) create mode 100644 main/apps/app_keyboard/app_keyboard.cpp create mode 100644 main/apps/app_keyboard/app_keyboard.h create mode 100644 main/apps/app_keyboard/assets/keyboard_big.h create mode 100644 main/apps/app_keyboard/assets/keyboard_small.h diff --git a/main/apps/app_keyboard/app_keyboard.cpp b/main/apps/app_keyboard/app_keyboard.cpp new file mode 100644 index 0000000..1d21d7e --- /dev/null +++ b/main/apps/app_keyboard/app_keyboard.cpp @@ -0,0 +1,52 @@ +/** + * @file app_keyboard.cpp + * @author Forairaaaaa + * @brief + * @version 0.1 + * @date 2023-12-07 + * + * @copyright Copyright (c) 2023 + * + */ +#include "app_keyboard.h" +#include "spdlog/spdlog.h" +#include "../utils/wifi_common_test/wifi_common_test.h" +#include "../utils/theme/theme_define.h" + + +using namespace MOONCAKE::APPS; + + +void AppKeyboard::onCreate() +{ + spdlog::info("{} onCreate", getAppName()); + + // Get hal + _data.hal = mcAppGetDatabase()->Get("HAL")->value(); +} + + +void AppKeyboard::onResume() +{ + ANIM_APP_OPEN(); + + + _data.hal->canvas()->fillScreen(THEME_COLOR_BG); + _data.hal->canvas()->setFont(FONT_REPL); + _data.hal->canvas()->setTextColor(TFT_ORANGE, THEME_COLOR_BG); + _data.hal->canvas()->setTextSize(1); + _data.hal->canvas_update(); + + +} + + +void AppKeyboard::onRunning() +{ + if (_data.hal->homeButton()->pressed()) + { + _data.hal->playNextSound(); + spdlog::info("quit app {}", getAppName()); + destroyApp(); + } +} diff --git a/main/apps/app_keyboard/app_keyboard.h b/main/apps/app_keyboard/app_keyboard.h new file mode 100644 index 0000000..ae286df --- /dev/null +++ b/main/apps/app_keyboard/app_keyboard.h @@ -0,0 +1,49 @@ +/** + * @file app_keyboard.h + * @author Forairaaaaa + * @brief + * @version 0.1 + * @date 2023-12-07 + * + * @copyright Copyright (c) 2023 + * + */ +#pragma once +#include +#include "../../hal/hal.h" +#include "../utils/theme/theme_define.h" +#include "../utils/anim/anim_define.h" +#include "../utils/icon/icon_define.h" + +#include "assets/keyboard_big.h" +#include "assets/keyboard_small.h" + + +namespace MOONCAKE +{ + namespace APPS + { + class AppKeyboard : public APP_BASE + { + private: + struct Data_t + { + HAL::Hal* hal = nullptr; + }; + Data_t _data; + + public: + void onCreate() override; + void onResume() override; + void onRunning() override; + }; + + class AppKeyboard_Packer : public APP_PACKER_BASE + { + std::string getAppName() override { return "KEYBOARD"; } + void* getAppIcon() override { return (void*)(new AppIcon_t(image_data_keyboard_big, image_data_keyboard_small)); } + void* newApp() override { return new AppKeyboard; } + void deleteApp(void *app) override { delete (AppKeyboard*)app; } + }; + } +} diff --git a/main/apps/app_keyboard/assets/keyboard_big.h b/main/apps/app_keyboard/assets/keyboard_big.h new file mode 100644 index 0000000..b9360e7 --- /dev/null +++ b/main/apps/app_keyboard/assets/keyboard_big.h @@ -0,0 +1,149 @@ + +/******************************************************************************* +* generated by lcd-image-converter rev.030b30d from 2019-03-17 01:38:34 +0500 +* image +* filename: unsaved +* name: keyboard_big +* +* preset name: Color R5G6B5 +* data block size: 16 bit(s), uint16_t +* RLE compression enabled: no +* conversion type: Color, not_used not_used +* split to rows: yes +* bits per pixel: 16 +* +* preprocess: +* main scan direction: top_to_bottom +* line scan direction: forward +* inverse: no +*******************************************************************************/ + +/* + typedef struct { + const uint16_t *data; + uint16_t width; + uint16_t height; + uint8_t dataSize; + } tImage; +*/ +#include + + + +static const uint16_t image_data_keyboard_big[3136] = { + // ████████████████████████████████████████████████████████ + // ████████████████████████████████████████████████████████ + // ████████████████████████████████████████████████████████ + // █████████▓▒▒▒▒▒▒▒▒▓▓████████████████████████████████████ + // ███████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▓██████████████████████████████████ + // █████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓████████████████████████████████ + // ████▓▒▒▒▒▓▓███████▓▒▒▒▒▒▓███████████████████████████████ + // ███▒▒▒▒▓▓███████████▓▒▒▒▒▓██████████████████████████████ + // ███▒▒▒▓███▓▒▒▒▒▒▒▓▓███▓▒▒▒██████████▒▒██████████████████ + // ███▓▒▓██▓▒▒▒▒▒▒▒▒▒▒▒███▓▒▓█████████▒∙∙░█████████████████ + // ███████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓█████████████░∙∙∙█████████████████ + // ██████▓▒▒▒▒▓▓███▓▒▒▒▒▒█████████████░∙∙∙█████████████████ + // ██████▓▒▒▒████████▓▒▒▒█████████████∙∙∙∙█████████████████ + // ███████▓▓██▓░░░░▒███▓▓███████▒∙∙∙∙∙∙∙∙░█████████████████ + // ██████████▒░░░░░░░▓█████████░∙∙∙∙∙∙∙∙∙▓█████████████████ + // ██████████░░░░░░░░░████████▒∙∙∙∙∙∙∙∙∙▒██████████████████ + // ██████████░░░▒▒░░░▒████████░∙∙∙░░░░▒████████████████████ + // ███████████▒▓███▓▓█████████∙∙∙∙█████████████████████████ + // ███████████████████████████∙∙∙░█████████████████████████ + // ███████████████████████████∙∙∙░█████████████████████████ + // ████████▓▒▒░░░░░░░░░░░░░░░░∙∙∙∙▒░░░░░░░░░░░░░░░▒▒▓██████ + // ██████▓∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙░▓████ + // █████▓∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙████ + // █████░∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙▒███ + // █████∙∙∙∙▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒∙∙∙░███ + // █████∙∙∙░████████████████████████████████████████∙∙∙░███ + // █████∙∙∙░██▓▒▒▒▒▒▒▒███░∙▒██▓∙░▓██░∙▒██▓∙░███░∙▓██∙∙∙░███ + // █████∙∙∙░█▓▒▒▒▒▒▒▒▒▒█▓∙∙∙██∙∙∙░█▒∙∙∙██∙∙∙▒█▒∙∙∙██∙∙∙░███ + // █████∙∙∙░██▒▒▒▒▒▒▒▒▒█▓∙∙∙██░∙∙░█▓∙∙∙██∙∙∙▒█▒∙∙∙██∙∙∙░███ + // █████∙∙∙░██▓▒▒▒▒▒▒▒███▒░▓██▓░░███▒░▓██▓░▒███▒░▓██∙∙∙░███ + // █████∙∙∙░████████████████████████████████████████∙∙∙░███ + // █████∙∙∙░████████▓▓████▓████▓▓████▓████▓▓████████∙∙∙░███ + // █████∙∙∙░██▒▒▒██▒∙∙▒█▓∙∙∙██▒∙∙▒█▓∙∙░██░∙∙▓██▒▒▓██∙∙∙░███ + // █████∙∙∙░█▓▒▒▒▓█∙∙∙░█▒∙∙∙▓█∙∙∙░█▒∙∙∙▓█∙∙∙░█▓▒▒▒██∙∙∙░███ + // █████∙∙∙░██▒▒▒██▒∙∙▒█▓∙∙∙██░∙∙▒█▓∙∙∙██░∙∙▓█▓▒▒▒██∙∙∙░███ + // █████∙∙∙░███▓████▓▓████▓████▓▓███▓▓████▓▓██▓▒▒▒██∙∙∙░███ + // █████∙∙∙░██████████████████████████████████▓▒▒▒██∙∙∙░███ + // █████∙∙∙░██▓▓▓███▓▓███▒░▓██▓░░███▓▓▓▓▓▓▓▓▓▓▒▒▒▒██∙∙∙░███ + // █████∙∙∙░██▒▒▒██▓▒▒▓█▓∙∙∙██∙∙∙▒█▓▒▒▒▒▒▒▒▒▒▒▒▒▒▓██∙∙∙░███ + // █████∙∙∙░██▒▒▒██▓▒▒▓█▓∙∙∙▓█∙∙∙░█▓▒▒▒▒▒▒▒▒▒▒▒▒▓███∙∙∙░███ + // █████∙∙∙░██▓▓▓███▓▓███░∙▒██▓∙░▓██▓▒▒▒▒▒▒▒▒▒▓▓████∙∙∙░███ + // █████∙∙∙░████████████████████████████████████████∙∙∙░███ + // █████∙∙∙░████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓████▓▓███▓▓███∙∙∙░███ + // █████∙∙∙░██▓▓▓██▒∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙░██░∙∙▓█▓∙∙∙██∙∙∙░███ + // █████∙∙∙░██▓▓▓██░∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙██∙∙∙░█▒∙∙∙██∙∙∙░███ + // █████∙∙∙░██▓▓▓██▓∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙░██░∙∙▓█▓∙∙░██∙∙∙░███ + // █████∙∙∙░████████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████▓█████▓███∙∙∙░███ + // █████∙∙∙∙████████████████████████████████████████∙∙∙░███ + // █████▒∙∙∙∙░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░∙∙∙∙▒███ + // ██████∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙████ + // ██████▓∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙█████ + // ████████▒∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙▒██████ + // ████████████████████████████████████████████████████████ + // ████████████████████████████████████████████████████████ + // ████████████████████████████████████████████████████████ + // ████████████████████████████████████████████████████████ + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3de7, 0x3dcf, 0x3dbf, 0x3ebf, 0x3ebf, 0x3ebf, 0x3dc7, 0x3ddf, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3de7, 0x3eaf, 0xff5e, 0x9f16, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0xbf2e, 0x1f7f, 0x3dd7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x1e9f, 0xbf2e, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0xff5e, 0x3dcf, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3dd7, 0xdf4e, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f0e, 0x7f0e, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f0e, 0x1f87, 0x3de7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3dc7, 0x9f1e, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x9f26, 0x1f7f, 0x3dbf, 0x3de7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ddf, 0x3eaf, 0xff5e, 0x7f0e, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0xdf56, 0x3de7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3dd7, 0x9f16, 0x7f06, 0x7f06, 0x7f06, 0x9f1e, 0x1e97, 0x3de7, 0x3ce7, 0x3ce7, 0x3de7, 0xfdce, 0xddc6, 0xfdd6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ddf, 0xff76, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0xff66, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3eaf, 0x7f06, 0x7f06, 0x7f06, 0xff5e, 0x3ddf, 0x3ce7, 0x1ddf, 0x3e8e, 0x3f3d, 0x9f04, 0x7f04, 0x7f04, 0x7f04, 0xbf0c, 0x9f4d, 0x9ea6, 0x3de7, 0x3ce7, 0x3dc7, 0x9f26, 0x7f06, 0x7f06, 0x9f16, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xb294, 0xcf7b, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3de7, 0xdf4e, 0x7f0e, 0x1f87, 0x3ce7, 0x3de7, 0x3f86, 0xbf0c, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x1f2d, 0xbeb6, 0x3ce7, 0x3dd7, 0xdf56, 0x7f0e, 0x1e97, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xef7b, 0x0000, 0x0000, 0xe739, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ddf, 0x7f4d, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x9f04, 0x3f86, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x8a52, 0x0000, 0x0000, 0x2000, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xff75, 0x7f04, 0x7f04, 0x7f04, 0x9f04, 0x9f4d, 0x7e9e, 0xfdce, 0x1dd7, 0xdebe, 0x3f86, 0x1f2d, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0xddbe, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x0842, 0x0000, 0x0000, 0x0000, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xff75, 0x7f04, 0x7f04, 0xff1c, 0xdebe, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3de7, 0x3e8e, 0x9f0c, 0x7f04, 0x9f04, 0xfdc6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x9ad6, 0x8210, 0x0000, 0x0000, 0x8210, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ddf, 0xff75, 0xff6d, 0x1ddf, 0x3ce7, 0xf58c, 0xf03a, 0xf132, 0x1133, 0xd032, 0x7053, 0x7ace, 0x3ce7, 0xdebe, 0xbf5d, 0x7e9e, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xb294, 0x6529, 0x2000, 0x0000, 0x4108, 0x0000, 0x0000, 0x0000, 0x0000, 0x494a, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xd163, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0xf132, 0x97ad, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xaa52, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x96b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x1233, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x1043, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x9294, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4108, 0x9294, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xf03a, 0x3333, 0x1233, 0x7053, 0x537c, 0xf03a, 0x3333, 0x3333, 0x537c, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x2842, 0x0000, 0x0000, 0x0000, 0xc739, 0x8a52, 0x694a, 0x8a52, 0xef7b, 0x79ce, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0x9484, 0xf8bd, 0x3ce7, 0x3ce7, 0x3ce7, 0x569d, 0x369d, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x6529, 0x0000, 0x0000, 0x0421, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x2421, 0x0000, 0x0000, 0xc739, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4529, 0x0000, 0x0000, 0xe739, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x1ce7, 0x14a5, 0x8e73, 0x2c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x2c63, 0x2c63, 0x2c63, 0x2c63, 0x2c63, 0x2c63, 0x0c63, 0x6108, 0x0000, 0x0000, 0x8210, 0x2c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0xeb5a, 0x0c63, 0x8e73, 0x518c, 0xd7bd, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xb6b5, 0xe318, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa631, 0x38c6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x59ce, 0x6108, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe318, 0xfbde, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x2c63, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3084, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xa210, 0x0000, 0x0000, 0x6108, 0x14a5, 0xb6b5, 0xd7bd, 0xf7bd, 0xf7bd, 0x18c6, 0x18c6, 0x18c6, 0x18c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x18c6, 0x18c6, 0x18c6, 0x18c6, 0x18c6, 0x18c6, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0xd7bd, 0xb294, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x0842, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3ce7, 0x74f3, 0x8ef8, 0x6df8, 0x4df8, 0x2df8, 0x2df8, 0x8ef8, 0xd0f9, 0xfaed, 0x3ce7, 0x3ce7, 0xeb5a, 0x0421, 0x3084, 0x3ce7, 0x3ce7, 0x96b5, 0x4529, 0xa631, 0x38c6, 0x3ce7, 0x1ce7, 0xaa52, 0xe318, 0x3084, 0x3ce7, 0x3ce7, 0x14a5, 0x0421, 0xe739, 0xbad6, 0x3ce7, 0xdbde, 0x2842, 0x2421, 0xd39c, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x99ed, 0x0cf8, 0x0cf8, 0x0cf8, 0x0cf8, 0x0cf8, 0x0cf8, 0x0cf8, 0x0cf8, 0xf1f9, 0x3ce7, 0xf39c, 0x0000, 0x0000, 0x0000, 0x79ce, 0x3ce7, 0x2421, 0x0000, 0x0000, 0xeb5a, 0x3ce7, 0x718c, 0x0000, 0x0000, 0x0000, 0x9ad6, 0x3ce7, 0xa210, 0x0000, 0x0000, 0xae73, 0x3ce7, 0xef7b, 0x0000, 0x0000, 0x4108, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0xfaed, 0x0cf8, 0x0cf8, 0x0cf8, 0x0cf8, 0x0cf8, 0x0cf8, 0x0cf8, 0x0cf8, 0x51fa, 0x3ce7, 0x34a5, 0x0000, 0x0000, 0x2000, 0x9ad6, 0x3ce7, 0xa631, 0x0000, 0x0000, 0x2c63, 0x3ce7, 0xf39c, 0x0000, 0x0000, 0x4108, 0xdbde, 0x3ce7, 0x2421, 0x0000, 0x0000, 0x8e73, 0x3ce7, 0x3084, 0x0000, 0x0000, 0xa210, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3ce7, 0x56f4, 0x11fa, 0x11fa, 0x11fa, 0x11fa, 0x11fa, 0x11fa, 0xb2f2, 0x7bee, 0x3ce7, 0x3ce7, 0x1084, 0x494a, 0x14a5, 0x3ce7, 0x3ce7, 0x38c6, 0x694a, 0xaa52, 0x9ad6, 0x3ce7, 0x3ce7, 0xef7b, 0x2842, 0x14a5, 0x3ce7, 0x3ce7, 0xd7bd, 0x694a, 0x4d6b, 0xfbde, 0x3ce7, 0x1ce7, 0x6d6b, 0x2842, 0x96b5, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3ce7, 0x3bdf, 0x17bf, 0x3bdf, 0x3ce7, 0x3ce7, 0x3ce7, 0x96b5, 0x18c6, 0x3ce7, 0x3ce7, 0x3ce7, 0xdbde, 0x75ad, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x96b5, 0x18c6, 0x3ce7, 0x3ce7, 0x3ce7, 0x9ad6, 0x55ad, 0x1ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x96b5, 0x59ce, 0x3ce7, 0x3ce7, 0x3ce7, 0xbde6, 0xfde5, 0x3ce7, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3bdf, 0x894e, 0x6636, 0x894e, 0x3bdf, 0x3ce7, 0xae73, 0x0000, 0x0000, 0x9294, 0x3ce7, 0x59ce, 0xa210, 0x0000, 0x2421, 0x1ce7, 0x3ce7, 0x6d6b, 0x0000, 0x0000, 0xb294, 0x3ce7, 0x38c6, 0x6108, 0x0000, 0xa631, 0x3ce7, 0x3ce7, 0xaa52, 0x0000, 0x0000, 0x55ad, 0x3ce7, 0x1de6, 0xdfc9, 0x9fc9, 0x7ed3, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0xf6b6, 0x6636, 0x6636, 0x6636, 0xf6b6, 0x3ce7, 0x2421, 0x0000, 0x0000, 0xe739, 0x3ce7, 0x3084, 0x0000, 0x0000, 0x0000, 0x18c6, 0x3ce7, 0xc318, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x1084, 0x0000, 0x0000, 0x0000, 0x59ce, 0x3ce7, 0x6108, 0x0000, 0x0000, 0x0c63, 0x3ce7, 0x5edc, 0x9fc9, 0x9fc9, 0xbfc9, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3bdf, 0x6846, 0x6636, 0x6846, 0x3bdf, 0x3ce7, 0x8e73, 0x0000, 0x0000, 0x518c, 0x3ce7, 0x59ce, 0x6108, 0x0000, 0x2421, 0x1ce7, 0x3ce7, 0xeb5a, 0x0000, 0x0000, 0x518c, 0x3ce7, 0x18c6, 0x4108, 0x0000, 0x4529, 0x3ce7, 0x3ce7, 0x694a, 0x0000, 0x0000, 0x34a5, 0x3ce7, 0x3edc, 0x9fc9, 0x9fc9, 0x9fc9, 0xfde6, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3ce7, 0x3bdf, 0xf6b6, 0x3bdf, 0x3ce7, 0x3ce7, 0x3ce7, 0x75ad, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x9ad6, 0xf39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x96b5, 0xf7bd, 0x3ce7, 0x3ce7, 0x3ce7, 0x59ce, 0x14a5, 0xfbde, 0x3ce7, 0x3ce7, 0x1ce7, 0x34a5, 0xf7bd, 0x3ce7, 0x3ce7, 0x3edc, 0x9fc9, 0x9fc9, 0x9fc9, 0xfce6, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x7ed3, 0x9fc9, 0x9fc9, 0x9fc9, 0x1ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3ce7, 0xfd96, 0xbe56, 0xfd9e, 0x3ce7, 0x3ce7, 0xdaee, 0xcff4, 0xf0f4, 0xfbee, 0x3ce7, 0x3ce7, 0x518c, 0xaa52, 0x75ad, 0x3ce7, 0x3ce7, 0x59ce, 0x0c63, 0x0c63, 0xdbde, 0x3ce7, 0x3ce7, 0xfedc, 0xded3, 0x7ed3, 0x5fd3, 0x5fd3, 0x5fd3, 0x7fd3, 0x7ed3, 0x7ed3, 0x1fd3, 0xbfc9, 0x9fc9, 0x9fc9, 0x1fca, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x1dc7, 0x7f06, 0x7f06, 0x7f06, 0x1dbf, 0x3ce7, 0x6dfc, 0x26fb, 0x26fb, 0xaff4, 0x3ce7, 0x55ad, 0x0000, 0x0000, 0x4108, 0x9ad6, 0x3ce7, 0x8631, 0x0000, 0x0000, 0x4d6b, 0x3ce7, 0x5ddd, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x5edc, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x1daf, 0x7f06, 0x7f06, 0x7f06, 0xfdae, 0x3ce7, 0xeafb, 0x26fb, 0x26fb, 0x6dfc, 0x3ce7, 0xd39c, 0x0000, 0x0000, 0x0000, 0x18c6, 0x3ce7, 0x4529, 0x0000, 0x0000, 0x694a, 0x3ce7, 0xfedc, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x3fd3, 0x1ce7, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3ce7, 0xde66, 0x9f26, 0xbe66, 0x3ce7, 0x3ce7, 0x37ee, 0x0bfc, 0x0bfc, 0x78ee, 0x3ce7, 0x1ce7, 0x8a52, 0xe318, 0xae73, 0x3ce7, 0x3ce7, 0x34a5, 0x2421, 0xc739, 0x18c6, 0x3ce7, 0xfce6, 0x3fd3, 0x3fca, 0x3fca, 0x3fca, 0x3fca, 0x3fca, 0x3fca, 0x3fca, 0x3fca, 0x3fca, 0xbfd2, 0xdedc, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3ce7, 0x39ef, 0xf3ee, 0x39ef, 0x3ce7, 0x3ce7, 0x3ce7, 0xb6b5, 0xb294, 0xb294, 0xb294, 0xb294, 0xb294, 0xb294, 0xb294, 0xb294, 0xb294, 0xb294, 0xb294, 0xb294, 0xb294, 0xb294, 0xb294, 0xb294, 0xf39c, 0xfbde, 0x3ce7, 0x3ce7, 0x1ce7, 0x14a5, 0xf7bd, 0x3ce7, 0x3ce7, 0x3ce7, 0x18c6, 0xf39c, 0xdbde, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3aef, 0x62fe, 0x60fe, 0x62fe, 0x3aef, 0x3ce7, 0x518c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3ce7, 0x494a, 0x0000, 0x0000, 0xf39c, 0x3ce7, 0xb6b5, 0x0000, 0x0000, 0x8631, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0xf4ee, 0x60fe, 0x60fe, 0x60fe, 0xf4ee, 0x3ce7, 0x8a52, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2000, 0x3ce7, 0x3ce7, 0x6108, 0x0000, 0x0000, 0x0c63, 0x3ce7, 0x3084, 0x0000, 0x0000, 0x0000, 0xdbde, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3aef, 0x63fe, 0x60fe, 0x84fe, 0x3aef, 0x3ce7, 0xf39c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xaa52, 0x3ce7, 0x3ce7, 0xaa52, 0x0000, 0x4108, 0x34a5, 0x3ce7, 0xf7bd, 0x6108, 0x0000, 0x0842, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2842, 0x3ce7, 0x3ce7, 0x3be7, 0x17ef, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x38c6, 0x14a5, 0xf39c, 0xf39c, 0xf39c, 0xf39c, 0xf39c, 0xf39c, 0xf39c, 0xf39c, 0xf39c, 0xf39c, 0xf39c, 0xf39c, 0xf39c, 0xf39c, 0x14a5, 0xd7bd, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xf7bd, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0xdbde, 0xd7bd, 0x3ce7, 0x3ce7, 0x3ce7, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x4108, 0x0000, 0x0000, 0x2421, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0x0000, 0x0000, 0x0000, 0x8a52, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x6d6b, 0x0000, 0x0000, 0x0000, 0x2421, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x2842, 0x0842, 0xc318, 0x0000, 0x0000, 0x0000, 0xae73, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x1ce7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4108, 0x1ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xffff, 0x14a5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x79ce, 0xbef7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xffff, 0xffff, 0xfbde, 0x6d6b, 0x6108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0xc318, 0x718c, 0x7def, 0xffff, 0xbef7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7 +}; +// const tImage keyboard_big = { image_data_keyboard_big, 56, 56, +// 16 }; + diff --git a/main/apps/app_keyboard/assets/keyboard_small.h b/main/apps/app_keyboard/assets/keyboard_small.h new file mode 100644 index 0000000..95c9552 --- /dev/null +++ b/main/apps/app_keyboard/assets/keyboard_small.h @@ -0,0 +1,117 @@ + +/******************************************************************************* +* generated by lcd-image-converter rev.030b30d from 2019-03-17 01:38:34 +0500 +* image +* filename: unsaved +* name: keyboard_small +* +* preset name: Color R5G6B5 +* data block size: 16 bit(s), uint16_t +* RLE compression enabled: no +* conversion type: Color, not_used not_used +* split to rows: yes +* bits per pixel: 16 +* +* preprocess: +* main scan direction: top_to_bottom +* line scan direction: forward +* inverse: no +*******************************************************************************/ + +/* + typedef struct { + const uint16_t *data; + uint16_t width; + uint16_t height; + uint8_t dataSize; + } tImage; +*/ +#include + + + +static const uint16_t image_data_keyboard_small[1600] = { + // ████████████████████████████████████████ + // ██████▓▓▓▓▓▓▓▓██████████████████████████ + // ████▓▒▒▒▒▒▒▒▒▒▒▓████████████████████████ + // ██▓▒▒▒▓▓▓▓▓▓▓▒▒▒▓███████████████████████ + // █▓▒▒▒▓████████▓▒▒▓██████████████████████ + // █▓▒▓██▓▒▒▒▒▒▓██▓▒▒▓███████▒▒████████████ + // ██▓█▓▒▒▒▒▒▒▒▒▒▓██▓███████▒∙∙▓███████████ + // ████▒▒▒▒▓▓▓▓▒▒▒▓█████████░∙∙▓███████████ + // ████▒▒▓██████▒▒▓██████▓▓▓∙∙∙▓███████████ + // ██████▓▒░░░▒▓█▓█████▒∙∙∙∙∙∙░████████████ + // ██████▓░░░░░░██████▓∙∙∙∙∙∙∙▓████████████ + // ██████▓▒▒▒▒▒▒██████░∙∙░▒▒▒██████████████ + // ███████▓███▓███████░∙∙▓█████████████████ + // ███████████████████░∙∙▓█████████████████ + // ████▓▒░░░░░░░░░░░░░∙∙∙░░░░░░░░░░░░░▒▓███ + // ███▓∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙░██ + // ███░∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙▓█ + // ██▓∙∙∙▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒∙∙▒█ + // ██▓∙∙░█▓▓▓▓▓▓██▓▒▓██▒▓██▒▓██▒▓██▒▓█▓∙∙▒█ + // ██▓∙∙░█▒▒▒▒▒▒▒█░∙░█░∙░█▒∙∙█▒∙∙▓▓∙∙▓▓∙∙▒█ + // ██▓∙∙░█▒▒▒▒▒▒▒█░∙░█▒∙░█▒∙∙█▒∙∙▓▓∙∙▓▓∙∙▒█ + // ██▓∙∙░██▓▓▓▓▓███▓▓██▓▓██▓▓██▓▓██▓▓█▓∙∙▒█ + // ██▓∙∙░██████▓███▓███▓███▓███▓██████▓∙∙▒█ + // ██▓∙∙░█▓▒▓█░∙▒█▒∙░█▒∙░█▓∙∙█▒∙∙▓█▒▒█▓∙∙▒█ + // ██▓∙∙░█▒▒▓█░∙░█░∙∙█░∙░█▒∙∙█▒∙∙▓▓▒▒█▓∙∙▒█ + // ██▓∙∙░██▓██▓▒██▓▒▓██▒▓██▒▓██▒▓█▓▒▒█▓∙∙▒█ + // ██▓∙∙░█████████████████████████▓▒▒█▓∙∙▒█ + // ██▓∙∙░█▓▓▓█▓▓▓█▒∙▒█▒∙▒██▓▒▒▒▒▒▒▒▒▒█▓∙∙▒█ + // ██▓∙∙░█▓▒▓█▓▒▓█░∙∙█░∙∙█▓▒▒▒▒▒▒▒▒▒▓█▓∙∙▒█ + // ██▓∙∙░█▓▓███▓██▓░▒█▓░▒██▓▓▓▓▓▓▓▓▓██▓∙∙▒█ + // ██▓∙∙░██████▓▓▓▓▓▓▓▓▓▓▓▓▓███▓██████▓∙∙▒█ + // ██▓∙∙░██▓██▒∙∙∙∙∙∙∙∙∙∙∙∙∙░█▓∙░▓▓∙░█▓∙∙▒█ + // ██▓∙∙░█▓▓██░∙∙∙∙∙∙∙∙∙∙∙∙∙∙█▒∙∙▓▓∙∙▓▓∙∙▒█ + // ██▓∙∙░█████▓░░░░░░░░░░░░░▒█▓▒▒██▒▒█▓∙∙▒█ + // ██▓∙∙░█████████████████████████████▓∙∙▒█ + // ███░∙∙∙░░░░░░░░░░░░░░░░░░░░░░░░░░░░∙∙∙▒█ + // ███▓∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙░██ + // ████▓░∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙▓███ + // ████████████████████████████████████████ + // ████████████████████████████████████████ + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ddf, 0x3dd7, 0x3dd7, 0x3dd7, 0x3ddf, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x1eaf, 0xdf5e, 0x9f26, 0x9f26, 0x9f26, 0x9f26, 0x9f26, 0xbf3e, 0xfe86, 0x3dd7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3cdf, 0x1ea7, 0xbf36, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f06, 0x7f16, 0xfe7e, 0x3dcf, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3dd7, 0xde6e, 0x7f16, 0x7f06, 0x7f06, 0x9f2e, 0xdf5e, 0xde76, 0xde7e, 0xde76, 0xde6e, 0xbf46, 0x7f0e, 0x7f06, 0x7f06, 0xbf3e, 0x1eaf, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ddf, 0xbf4e, 0x7f06, 0x7f06, 0x9f16, 0xfe86, 0x3dcf, 0x3ddf, 0x3ddf, 0xfdce, 0x1dd7, 0x3de7, 0x3dd7, 0x1dbf, 0xdf56, 0x7f06, 0x7f06, 0x9f26, 0x1daf, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3dcf, 0x9f2e, 0x7f06, 0xbf46, 0x3dcf, 0xfdd6, 0x5e96, 0x3f3d, 0x9f04, 0x7f04, 0x7f04, 0xdf14, 0xdf65, 0xddbe, 0x3ddf, 0xfe86, 0x9f16, 0x7f0e, 0xfe86, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0xcf7b, 0x9294, 0xfbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x1ea7, 0xfe86, 0x3dcf, 0x7ea6, 0x3f35, 0x9f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0x7f04, 0xbf14, 0xde6d, 0xfdce, 0x1ea7, 0xfe86, 0x3dd7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xef7b, 0x0000, 0x8210, 0x38c6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0xbdb6, 0xff24, 0x7f04, 0x7f04, 0x3f35, 0x3e8e, 0x9dae, 0x7ea6, 0xdf65, 0xbf14, 0x7f04, 0x9f04, 0xde6d, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x0c63, 0x0000, 0x0000, 0xf7bd, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0xbdb6, 0xff24, 0xdf1c, 0x1e86, 0xdbd6, 0x7ace, 0x7ac6, 0x7ace, 0xbbd6, 0xbdbe, 0x3f3d, 0xbf14, 0xfe75, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x9ad6, 0x18c6, 0x18c6, 0xb6b5, 0x4529, 0x0000, 0x6108, 0x38c6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xbdb6, 0xbdb6, 0x5ac6, 0x546c, 0x1133, 0x1233, 0x1133, 0x924b, 0x97a5, 0xfcce, 0x9ea6, 0x1dd7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x9294, 0x8631, 0x2000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe739, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x378d, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x5243, 0x9ace, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x75ad, 0x6108, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc318, 0x55ad, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x779d, 0x7343, 0xb34b, 0x737c, 0xd25b, 0x9343, 0x346c, 0xdbd6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xeb5a, 0x0000, 0x0000, 0x494a, 0x4d6b, 0x4d6b, 0x518c, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x19be, 0xbbd6, 0x3ce7, 0x3ce7, 0x39c6, 0xbbd6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x494a, 0x0000, 0xa210, 0x38c6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x494a, 0x0000, 0xe318, 0x59ce, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x1ce7, 0x38c6, 0x1084, 0xcb5a, 0x8a52, 0x8a52, 0x8a52, 0x8a52, 0x8a52, 0x8a52, 0x8a52, 0xaa52, 0xaa52, 0xaa52, 0xaa52, 0x8a52, 0xa210, 0x0000, 0x4108, 0x494a, 0x8a52, 0x8a52, 0x8a52, 0x8a52, 0x8a52, 0x8a52, 0x8a52, 0x8a52, 0x8a52, 0x8a52, 0x694a, 0xeb5a, 0xcf7b, 0x96b5, 0xfbde, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0xf39c, 0xe318, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6108, 0x0c63, 0x1ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x9ad6, 0xe739, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2000, 0x14a5, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x4108, 0x0000, 0x8631, 0xb6b5, 0x18c6, 0x38c6, 0x38c6, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x59ce, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x38c6, 0x18c6, 0x518c, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x3ce7, 0xb9ed, 0xf5f3, 0xd5f3, 0xb4f3, 0xd5f3, 0x36f4, 0x3aee, 0x3ce7, 0x18c6, 0x518c, 0xf7bd, 0x3ce7, 0x9ad6, 0x518c, 0x96b5, 0x1ce7, 0xdbde, 0x9294, 0x75ad, 0x3ce7, 0xbad6, 0x718c, 0xf39c, 0x1ce7, 0x1ce7, 0xb294, 0x14a5, 0x1ce7, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x9bee, 0x70f9, 0x0df8, 0x0cf8, 0x0cf8, 0x0cf8, 0x2df8, 0x31fa, 0xfbde, 0xeb5a, 0x2000, 0xa631, 0xfbde, 0xcb5a, 0x2000, 0xc739, 0x9ad6, 0x3084, 0x4108, 0xa210, 0xdbde, 0x518c, 0x6108, 0xe318, 0xb6b5, 0xf39c, 0x4108, 0xa210, 0x38c6, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0xbbee, 0xb0f9, 0x4df8, 0x4df8, 0x4df8, 0x4df8, 0x6df8, 0x92f2, 0xfbde, 0x0c63, 0x6108, 0xe739, 0xfbde, 0x4d6b, 0x6108, 0x0842, 0x9ad6, 0x718c, 0x8210, 0xe318, 0xfbde, 0x9294, 0xa210, 0x2421, 0xb6b5, 0x34a5, 0x8210, 0xe318, 0x38c6, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x3ce7, 0xfaed, 0xb7ec, 0x97ec, 0x97ec, 0x97ec, 0xd7ec, 0x7bee, 0x3ce7, 0x79ce, 0xf39c, 0x59ce, 0x3ce7, 0xdbde, 0xd39c, 0xf7bd, 0x3ce7, 0xfbde, 0x14a5, 0xf7bd, 0x3ce7, 0xdbde, 0x14a5, 0x96b5, 0x3ce7, 0x3ce7, 0x34a5, 0x96b5, 0x1ce7, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x3ce7, 0x3ce7, 0x18c7, 0x3ce7, 0x3ce7, 0xfbde, 0x18c6, 0x1ce7, 0x3ce7, 0x1ce7, 0xf7bd, 0xfbde, 0x3ce7, 0x3ce7, 0xf7bd, 0xbad6, 0x3ce7, 0x1ce7, 0x38c6, 0xdbde, 0x3ce7, 0x3ce7, 0x18c6, 0x9ad6, 0x3ce7, 0x3ce7, 0xbde6, 0xbde6, 0x3ce7, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x3bdf, 0x8c66, 0x6636, 0xd18e, 0x3ce7, 0xcb5a, 0x0000, 0x6d6b, 0x1ce7, 0x4d6b, 0x0000, 0xe739, 0x1ce7, 0xae73, 0x0000, 0x2842, 0xbad6, 0xf39c, 0x2000, 0x2421, 0x1ce7, 0xb294, 0x6108, 0xe318, 0x18c6, 0x1de6, 0xdfc9, 0x7fd2, 0x9de6, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x3ad7, 0x8a56, 0x6636, 0xb086, 0x3ce7, 0xe739, 0x0000, 0x8a52, 0xdbde, 0xaa52, 0x0000, 0x8631, 0xdbde, 0xcb5a, 0x0000, 0xa631, 0x9ad6, 0x3084, 0x0000, 0x8210, 0xdbde, 0x518c, 0x4108, 0xa210, 0xb6b5, 0xbedc, 0x9fc9, 0xbfc9, 0x3de6, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x3ce7, 0x18c7, 0xf4a6, 0x1ad7, 0x3ce7, 0x38c6, 0xb294, 0x79ce, 0x3ce7, 0x59ce, 0x718c, 0x18c6, 0x3ce7, 0x9ad6, 0xb294, 0xd7bd, 0x1ce7, 0xbad6, 0xb294, 0xb6b5, 0x3ce7, 0xbad6, 0xb294, 0x55ad, 0x1ce7, 0xbedc, 0x9fc9, 0x9fc9, 0x1de6, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x3ce7, 0x3cdf, 0x3dcf, 0x3ce7, 0x3ce7, 0x1ce7, 0xdaee, 0x1ce7, 0x3ce7, 0xfbde, 0x79ce, 0xfbde, 0x3ce7, 0x1ce7, 0x9ad6, 0xdbde, 0x3ce7, 0x3ce7, 0xbde6, 0x9de6, 0x9de6, 0x9de6, 0x9de6, 0x9de6, 0x9de6, 0xbed3, 0x9fc9, 0xbfc9, 0x3de6, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x3cdf, 0xde66, 0x9f2e, 0xfe8e, 0x3ce7, 0x52f5, 0x0bfc, 0x93f5, 0x1ce7, 0x3084, 0x6529, 0x8e73, 0x1ce7, 0x718c, 0x8631, 0x4d6b, 0xdbde, 0xbddd, 0xffd2, 0x9fd2, 0x7fd2, 0x7fd2, 0x7fd2, 0x9fd2, 0x7fd2, 0xbfc9, 0x9fc9, 0x7fd2, 0x9de6, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x1dcf, 0x9f1e, 0x7f06, 0xbe56, 0x3cdf, 0xeafb, 0x26fb, 0x2cfc, 0xdbde, 0x694a, 0x0000, 0x0421, 0xbad6, 0x494a, 0x0000, 0x4529, 0x79ce, 0x7edc, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0x9fc9, 0xdfc9, 0xdedc, 0x1ce7, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x3ce7, 0xfe8e, 0xbe4e, 0x1daf, 0x3ce7, 0x16ee, 0x8ef4, 0x37ee, 0x3ce7, 0x34a5, 0x2842, 0xd39c, 0x3ce7, 0xd7bd, 0x494a, 0x718c, 0x1ce7, 0x7de6, 0x7ed3, 0x1fd3, 0x1fd3, 0x1fd3, 0x1fd3, 0x1fd3, 0x1fd3, 0x5fd3, 0x9ddd, 0x3ce7, 0x3ce7, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x3ce7, 0x3be7, 0x18ef, 0x3ce7, 0x3ce7, 0x1ce7, 0x38c6, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0xf7bd, 0x18c6, 0xfbde, 0x3ce7, 0x3ce7, 0x59ce, 0xbad6, 0x3ce7, 0x3ce7, 0x9ad6, 0x9ad6, 0x3ce7, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x3be7, 0xa9f6, 0x63fe, 0xd0f6, 0x3ce7, 0x3084, 0xe318, 0xc318, 0xc318, 0xc318, 0xc318, 0xc318, 0xc318, 0xc318, 0xc318, 0xc318, 0xc318, 0xc318, 0xc318, 0x8a52, 0x3ce7, 0x34a5, 0x2421, 0xa631, 0x59ce, 0x38c6, 0x0421, 0xa631, 0x79ce, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x19ef, 0x84fe, 0x60fe, 0xabf6, 0x3be7, 0x694a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6108, 0x3ce7, 0x1084, 0x2000, 0x8210, 0x55ad, 0xf39c, 0x0000, 0x2000, 0xd7bd, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0xeb5a, 0x3ce7, 0xf1f6, 0xccf6, 0x16ef, 0x3ce7, 0x96b5, 0xcb5a, 0x694a, 0x694a, 0x694a, 0x694a, 0x694a, 0x694a, 0x694a, 0x694a, 0x694a, 0x694a, 0x694a, 0xaa52, 0x9294, 0x3ce7, 0x18c6, 0x4d6b, 0xef7b, 0xbad6, 0xbad6, 0x6d6b, 0xcf7b, 0xdbde, 0xf7bd, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0x18c6, 0x2000, 0x0000, 0x494a, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0xdbde, 0xdbde, 0xdbde, 0xdbde, 0xdbde, 0xdbde, 0xdbde, 0xdbde, 0xdbde, 0xdbde, 0xdbde, 0xfbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x1ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x1ce7, 0x1ce7, 0x3ce7, 0x96b5, 0x0000, 0x0000, 0x4d6b, 0x3ce7, + 0x3ce7, 0x3ce7, 0xbad6, 0x0842, 0x0000, 0x2000, 0x6529, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xc739, 0xa631, 0x8210, 0x0000, 0x0000, 0xb294, 0x3ce7, + 0x3ce7, 0x3ce7, 0x5def, 0x14a5, 0x6108, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xcb5a, 0x5def, 0x3ce7, + 0x3ce7, 0x3ce7, 0x5def, 0xbef7, 0x18c6, 0x694a, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x2421, 0xf39c, 0x7def, 0x9ef7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7 +}; +// const tImage keyboard_small = { image_data_keyboard_small, 40, 40, +// 16 }; + diff --git a/main/apps/apps.h b/main/apps/apps.h index 3d5f8b4..421d5b3 100644 --- a/main/apps/apps.h +++ b/main/apps/apps.h @@ -17,4 +17,4 @@ #include "app_repl/app_repl.h" #include "app_set_wifi/app_set_wifi.h" #include "app_timer/app_timer.h" - +#include "app_keyboard/app_keyboard.h" diff --git a/main/cardputer.cpp b/main/cardputer.cpp index 16cde9d..8c7de71 100644 --- a/main/cardputer.cpp +++ b/main/cardputer.cpp @@ -32,7 +32,7 @@ void _data_base_setup_callback(SIMPLEKV::SimpleKV& db) // #define ON_HAL_TEST // #define ON_APP_TEST 1 -// #define ON_APP_TEST_WITH_LAUNCHER 1 +#define ON_APP_TEST_WITH_LAUNCHER 1 extern "C" void app_main(void) { // Init hal @@ -85,8 +85,10 @@ extern "C" void app_main(void) // mooncake.installApp(new APPS::AppChat_Packer); // mooncake.installApp(new APPS::AppRecord_Packer); // mooncake.installApp(new APPS::AppWifiScan_Packer); - mooncake.installApp(new APPS::AppSetWiFi_Packer); - mooncake.installApp(new APPS::AppIR_Packer); + // mooncake.installApp(new APPS::AppSetWiFi_Packer); + // mooncake.installApp(new APPS::AppIR_Packer); + mooncake.installApp(new APPS::AppKeyboard_Packer); + // Create launcher mooncake.createApp(launcher); From 6b8cfb582a7fdc6ae3d25500deff30da788400e3 Mon Sep 17 00:00:00 2001 From: Forairaaaaa Date: Thu, 7 Dec 2023 13:30:22 +0800 Subject: [PATCH 02/10] update keyboard --- main/cardputer.cpp | 2 +- main/hal/keyboard/keyboard.cpp | 6 + main/hal/keyboard/keyboard.h | 70 +++++- main/hal/keyboard/keymap.h | 409 +++++++++++++++++++++++++++++++++ 4 files changed, 479 insertions(+), 8 deletions(-) create mode 100644 main/hal/keyboard/keymap.h diff --git a/main/cardputer.cpp b/main/cardputer.cpp index 8c7de71..dd9b149 100644 --- a/main/cardputer.cpp +++ b/main/cardputer.cpp @@ -32,7 +32,7 @@ void _data_base_setup_callback(SIMPLEKV::SimpleKV& db) // #define ON_HAL_TEST // #define ON_APP_TEST 1 -#define ON_APP_TEST_WITH_LAUNCHER 1 +// #define ON_APP_TEST_WITH_LAUNCHER 1 extern "C" void app_main(void) { // Init hal diff --git a/main/hal/keyboard/keyboard.cpp b/main/hal/keyboard/keyboard.cpp index 5897f7b..21b161e 100644 --- a/main/hal/keyboard/keyboard.cpp +++ b/main/hal/keyboard/keyboard.cpp @@ -279,9 +279,15 @@ void Keyboard::updateKeysState() for (auto& i : _key_values_without_special_keys) { if (_keys_state_buffer.ctrl || _keys_state_buffer.shift || _is_caps_locked) + { _keys_state_buffer.values.push_back(*getKeyValue(i).value_second); + _keys_state_buffer.hidKey.push_back(getKeyValue(i).value_num_second); + } else + { _keys_state_buffer.values.push_back(*getKeyValue(i).value_first); + _keys_state_buffer.hidKey.push_back(getKeyValue(i).value_num_first); + } } } diff --git a/main/hal/keyboard/keyboard.h b/main/hal/keyboard/keyboard.h index 284d38c..398b319 100644 --- a/main/hal/keyboard/keyboard.h +++ b/main/hal/keyboard/keyboard.h @@ -11,6 +11,8 @@ #pragma once #include #include +#include "keymap.h" + namespace KEYBOARD { @@ -45,16 +47,68 @@ namespace KEYBOARD struct KeyValue_t { const char* value_first; + const int value_num_first; const char* value_second; + const int value_num_second; }; - const KeyValue_t _key_value_map[4][14] = - { - {{"`", "~"}, {"1", "!"}, {"2", "@"}, {"3", "#"}, {"4", "$"}, {"5", "%"}, {"6", "^"}, {"7", "&"}, {"8", "*"}, {"9", "("}, {"0", ")"}, {"-", "_"}, {"=", "+"}, {"del", "del"}}, - {{"tab", "tab"}, {"q", "Q"}, {"w", "W"}, {"e", "E"}, {"r", "R"}, {"t", "T"}, {"y", "Y"}, {"u", "U"}, {"i", "I"}, {"o", "O"}, {"p", "P"}, {"[", "{"}, {"]", "}"}, {"\\", "|"}}, - {{"fn", "fn"}, {"shift", "shift"}, {"a", "A"}, {"s", "S"}, {"d", "D"}, {"f", "F"}, {"g", "G"}, {"h", "H"}, {"j", "J"}, {"k", "K"}, {"l", "L"}, {";", ":"}, {"'", "\""}, {"enter", "enter"}}, - {{"ctrl", "ctrl"}, {"opt", "opt"}, {"alt", "alt"}, {"z", "Z"}, {"x", "X"}, {"c", "C"}, {"v", "V"}, {"b", "B"}, {"n", "N"}, {"m", "M"}, {",", "<"}, {".", ">"}, {"/", "?"}, {"space", "space"}} - }; + const KeyValue_t _key_value_map[4][14] = { + {{"`", KEY_GRAVE, "~", KEY_GRAVE}, + {"1", KEY_1, "!", KEY_1}, + {"2", KEY_2, "@", KEY_2}, + {"3", KEY_3, "#", KEY_3}, + {"4", KEY_4, "$", KEY_4}, + {"5", KEY_5, "%", KEY_5}, + {"6", KEY_6, "^", KEY_6}, + {"7", KEY_7, "&", KEY_7}, + {"8", KEY_8, "*", KEY_KPASTERISK}, + {"9", KEY_9, "(", KEY_KPLEFTPAREN}, + {"0", KEY_0, ")", KEY_KPRIGHTPAREN}, + {"-", KEY_MINUS, "_", KEY_KPMINUS}, + {"=", KEY_EQUAL, "+", KEY_KPPLUS}, + {"del", KEY_BACKSPACE, "del", KEY_BACKSPACE}}, + {{"tab", KEY_TAB, "tab", KEY_TAB}, + {"q", KEY_Q, "Q", KEY_Q}, + {"w", KEY_W, "W", KEY_W}, + {"e", KEY_E, "E", KEY_E}, + {"r", KEY_R, "R", KEY_R}, + {"t", KEY_T, "T", KEY_T}, + {"y", KEY_Y, "Y", KEY_Y}, + {"u", KEY_U, "U", KEY_U}, + {"i", KEY_I, "I", KEY_I}, + {"o", KEY_O, "O", KEY_O}, + {"p", KEY_P, "P", KEY_P}, + {"[", KEY_LEFTBRACE, "{", KEY_LEFTBRACE}, + {"]", KEY_RIGHTBRACE, "}", KEY_RIGHTBRACE}, + {"\\", KEY_BACKSLASH, "|", KEY_BACKSLASH}}, + {{"fn", 0, "fn", 0}, + {"shift", 0, "shift", 0}, + {"a", KEY_A, "A", KEY_A}, + {"s", KEY_S, "S", KEY_S}, + {"d", KEY_D, "D", KEY_D}, + {"f", KEY_F, "F", KEY_F}, + {"g", KEY_G, "G", KEY_G}, + {"h", KEY_H, "H", KEY_H}, + {"j", KEY_J, "J", KEY_J}, + {"k", KEY_K, "K", KEY_K}, + {"l", KEY_L, "L", KEY_L}, + {";", KEY_SEMICOLON, ":", KEY_SEMICOLON}, + {"'", KEY_APOSTROPHE, "\"", KEY_APOSTROPHE}, + {"enter", KEY_ENTER, "enter", KEY_ENTER}}, + {{"ctrl", KEY_LEFTCTRL, "ctrl", KEY_LEFTCTRL}, + {"opt", 0, "opt", 0}, + {"alt", KEY_LEFTALT, "alt", KEY_LEFTALT}, + {"z", KEY_Z, "Z", KEY_Z}, + {"x", KEY_X, "X", KEY_X}, + {"c", KEY_C, "C", KEY_C}, + {"v", KEY_V, "V", KEY_V}, + {"b", KEY_B, "B", KEY_B}, + {"n", KEY_N, "N", KEY_N}, + {"m", KEY_M, "M", KEY_M}, + {",", KEY_COMMA, "<", KEY_COMMA}, + {".", KEY_DOT, ">", KEY_DOT}, + {"/", KEY_KPSLASH, "?", KEY_KPSLASH}, + {"space", KEY_SPACE, "space", KEY_SPACE}}}; class Keyboard { @@ -73,6 +127,7 @@ namespace KEYBOARD bool space = false; std::vector values; + std::vector hidKey; void reset() { @@ -87,6 +142,7 @@ namespace KEYBOARD space = false; values.clear(); + hidKey.clear(); } }; diff --git a/main/hal/keyboard/keymap.h b/main/hal/keyboard/keymap.h new file mode 100644 index 0000000..379efe0 --- /dev/null +++ b/main/hal/keyboard/keymap.h @@ -0,0 +1,409 @@ +/** + * This file is part of esp32s3-keyboard. + * + * Copyright (C) 2020-2021 Yuquan He + * (Institute of Computing Technology, Chinese Academy of Sciences) + * + * esp32s3-keyboard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * esp32s3-keyboard is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with esp32s3-keyboard. If not, see . + */ + +/** + * USB HID format: 8 bytes + * Byte 0: Keyboard modifier bits (SHIFT, ALT, CTRL etc) + * Byte 1: reserved + * Byte 2-7: Up to six keyboard usage indexes representing the keys that are + * currently "pressed". Order is not important, a key is either + * pressed (present in the buffer) or not pressed. + */ + +#ifndef MY_KEYMAP_H +#define MY_KEYMAP_H + +#include + +/** + * Modifier masks - used for the first byte in the HID report. + * NOTE: The second byte in the report is reserved, 0x00 + */ +#define KEY_MOD_LCTRL 0x01 +#define KEY_MOD_LSHIFT 0x02 +#define KEY_MOD_LALT 0x04 +#define KEY_MOD_LMETA 0x08 +#define KEY_MOD_RCTRL 0x10 +#define KEY_MOD_RSHIFT 0x20 +#define KEY_MOD_RALT 0x40 +#define KEY_MOD_RMETA 0x80 + +/** + * Scan codes - last N slots in the HID report (usually 6). + * 0x00 if no key pressed. + * + * If more than N keys are pressed, the HID reports + * KEY_ERR_OVF in all slots to indicate this condition. + */ + +#define KEY_NONE 0x00 // No key pressed +#define KEY_ERR_OVF \ + 0x01 // Keyboard Error Roll Over - used for all slots if too many keys are + // pressed ("Phantom key") +// 0x02 // Keyboard POST Fail +// 0x03 // Keyboard Error Undefined +#define KEY_A 0x04 // Keyboard a and A +#define KEY_B 0x05 // Keyboard b and B +#define KEY_C 0x06 // Keyboard c and C +#define KEY_D 0x07 // Keyboard d and D +#define KEY_E 0x08 // Keyboard e and E +#define KEY_F 0x09 // Keyboard f and F +#define KEY_G 0x0a // Keyboard g and G +#define KEY_H 0x0b // Keyboard h and H +#define KEY_I 0x0c // Keyboard i and I +#define KEY_J 0x0d // Keyboard j and J +#define KEY_K 0x0e // Keyboard k and K +#define KEY_L 0x0f // Keyboard l and L +#define KEY_M 0x10 // Keyboard m and M +#define KEY_N 0x11 // Keyboard n and N +#define KEY_O 0x12 // Keyboard o and O +#define KEY_P 0x13 // Keyboard p and P +#define KEY_Q 0x14 // Keyboard q and Q +#define KEY_R 0x15 // Keyboard r and R +#define KEY_S 0x16 // Keyboard s and S +#define KEY_T 0x17 // Keyboard t and T +#define KEY_U 0x18 // Keyboard u and U +#define KEY_V 0x19 // Keyboard v and V +#define KEY_W 0x1a // Keyboard w and W +#define KEY_X 0x1b // Keyboard x and X +#define KEY_Y 0x1c // Keyboard y and Y +#define KEY_Z 0x1d // Keyboard z and Z + +#define KEY_1 0x1e // Keyboard 1 and ! +#define KEY_2 0x1f // Keyboard 2 and @ +#define KEY_3 0x20 // Keyboard 3 and # +#define KEY_4 0x21 // Keyboard 4 and $ +#define KEY_5 0x22 // Keyboard 5 and % +#define KEY_6 0x23 // Keyboard 6 and ^ +#define KEY_7 0x24 // Keyboard 7 and & +#define KEY_8 0x25 // Keyboard 8 and * +#define KEY_9 0x26 // Keyboard 9 and ( +#define KEY_0 0x27 // Keyboard 0 and ) + +#define KEY_ENTER 0x28 // Keyboard Return (ENTER) +#define KEY_ESC 0x29 // Keyboard ESCAPE +#define KEY_BACKSPACE 0x2a // Keyboard DELETE (Backspace) +#define KEY_TAB 0x2b // Keyboard Tab +#define KEY_SPACE 0x2c // Keyboard Spacebar +#define KEY_MINUS 0x2d // Keyboard - and _ +#define KEY_EQUAL 0x2e // Keyboard = and + +#define KEY_LEFTBRACE 0x2f // Keyboard [ and { +#define KEY_RIGHTBRACE 0x30 // Keyboard ] and } +#define KEY_BACKSLASH 0x31 // Keyboard \ and | +#define KEY_HASHTILDE 0x32 // Keyboard Non-US # and ~ +#define KEY_SEMICOLON 0x33 // Keyboard ; and : +#define KEY_APOSTROPHE 0x34 // Keyboard ' and " +#define KEY_GRAVE 0x35 // Keyboard ` and ~ +#define KEY_COMMA 0x36 // Keyboard , and < +#define KEY_DOT 0x37 // Keyboard . and > +#define KEY_SLASH 0x38 // Keyboard / and ? +#define KEY_CAPSLOCK 0x39 // Keyboard Caps Lock + +#define KEY_F1 0x3a // Keyboard F1 +#define KEY_F2 0x3b // Keyboard F2 +#define KEY_F3 0x3c // Keyboard F3 +#define KEY_F4 0x3d // Keyboard F4 +#define KEY_F5 0x3e // Keyboard F5 +#define KEY_F6 0x3f // Keyboard F6 +#define KEY_F7 0x40 // Keyboard F7 +#define KEY_F8 0x41 // Keyboard F8 +#define KEY_F9 0x42 // Keyboard F9 +#define KEY_F10 0x43 // Keyboard F10 +#define KEY_F11 0x44 // Keyboard F11 +#define KEY_F12 0x45 // Keyboard F12 + +#define KEY_PRTSC 0x46 // Keyboard Print Screen +#define KEY_SCROLLLOCK 0x47 // Keyboard Scroll Lock +#define KEY_PAUSE 0x48 // Keyboard Pause +#define KEY_INSERT 0x49 // Keyboard Insert +#define KEY_HOME 0x4a // Keyboard Home +#define KEY_PAGEUP 0x4b // Keyboard Page Up +// #define KEY_DELETE 0x4c // Keyboard Delete Forward +#define KEY_DELETE 0xD4 // Keyboard Delete Forward +#define KEY_END 0x4d // Keyboard End +#define KEY_PAGEDOWN 0x4e // Keyboard Page Down +#define KEY_RIGHT 0x4f // Keyboard Right Arrow +#define KEY_LEFT 0x50 // Keyboard Left Arrow +#define KEY_DOWN 0x51 // Keyboard Down Arrow +#define KEY_UP 0x52 // Keyboard Up Arrow + +#define KEY_NUMLOCK 0x53 // Keyboard Num Lock and Clear +#define KEY_KPSLASH 0x54 // Keypad / +#define KEY_KPASTERISK 0x55 // Keypad * +#define KEY_KPMINUS 0x56 // Keypad - +#define KEY_KPPLUS 0x57 // Keypad + +#define KEY_KPENTER 0x58 // Keypad ENTER +#define KEY_KP1 0x59 // Keypad 1 and End +#define KEY_KP2 0x5a // Keypad 2 and Down Arrow +#define KEY_KP3 0x5b // Keypad 3 and PageDn +#define KEY_KP4 0x5c // Keypad 4 and Left Arrow +#define KEY_KP5 0x5d // Keypad 5 +#define KEY_KP6 0x5e // Keypad 6 and Right Arrow +#define KEY_KP7 0x5f // Keypad 7 and Home +#define KEY_KP8 0x60 // Keypad 8 and Up Arrow +#define KEY_KP9 0x61 // Keypad 9 and Page Up +#define KEY_KP0 0x62 // Keypad 0 and Insert +#define KEY_KPDOT 0x63 // Keypad . and Delete + +#define KEY_102ND 0x64 // Keyboard Non-US \ and | +#define KEY_COMPOSE 0x65 // Keyboard Application +#define KEY_POWER 0x66 // Keyboard Power +#define KEY_KPEQUAL 0x67 // Keypad = + +#define KEY_F13 0x68 // Keyboard F13 +#define KEY_F14 0x69 // Keyboard F14 +#define KEY_F15 0x6a // Keyboard F15 +#define KEY_F16 0x6b // Keyboard F16 +#define KEY_F17 0x6c // Keyboard F17 +#define KEY_F18 0x6d // Keyboard F18 +#define KEY_F19 0x6e // Keyboard F19 +#define KEY_F20 0x6f // Keyboard F20 +#define KEY_F21 0x70 // Keyboard F21 +#define KEY_F22 0x71 // Keyboard F22 +#define KEY_F23 0x72 // Keyboard F23 +#define KEY_F24 0x73 // Keyboard F24 + +#define KEY_OPEN 0x74 // Keyboard Execute +#define KEY_HELP 0x75 // Keyboard Help +#define KEY_PROPS 0x76 // Keyboard Menu +#define KEY_FRONT 0x77 // Keyboard Select +#define KEY_STOP 0x78 // Keyboard Stop +#define KEY_AGAIN 0x79 // Keyboard Again +#define KEY_UNDO 0x7a // Keyboard Undo +#define KEY_CUT 0x7b // Keyboard Cut +#define KEY_COPY 0x7c // Keyboard Copy +#define KEY_PASTE 0x7d // Keyboard Paste +#define KEY_FIND 0x7e // Keyboard Find +#define KEY_MUTE 0x7f // Keyboard Mute +#define KEY_VOLUMEUP 0x80 // Keyboard Volume Up +#define KEY_VOLUMEDOWN 0x81 // Keyboard Volume Down +// 0x82 Keyboard Locking Caps Lock +// 0x83 Keyboard Locking Num Lock +// 0x84 Keyboard Locking Scroll Lock +#define KEY_KPCOMMA 0x85 // Keypad Comma +// 0x86 Keypad Equal Sign +#define KEY_RO 0x87 // Keyboard International1 +#define KEY_KATAKANAHIRAGANA 0x88 // Keyboard International2 +#define KEY_YEN 0x89 // Keyboard International3 +#define KEY_HENKAN 0x8a // Keyboard International4 +#define KEY_MUHENKAN 0x8b // Keyboard International5 +#define KEY_KPJPCOMMA 0x8c // Keyboard International6 +// 0x8d Keyboard International7 +// 0x8e Keyboard International8 +// 0x8f Keyboard International9 +#define KEY_HANGEUL 0x90 // Keyboard LANG1 +#define KEY_HANJA 0x91 // Keyboard LANG2 +#define KEY_KATAKANA 0x92 // Keyboard LANG3 +#define KEY_HIRAGANA 0x93 // Keyboard LANG4 +#define KEY_ZENKAKUHANKAKU 0x94 // Keyboard LANG5 +// 0x95 Keyboard LANG6 +// 0x96 Keyboard LANG7 +// 0x97 Keyboard LANG8 +// 0x98 Keyboard LANG9 +// 0x99 Keyboard Alternate Erase +// 0x9a Keyboard SysReq/Attention +// 0x9b Keyboard Cancel +// 0x9c Keyboard Clear +// 0x9d Keyboard Prior +// 0x9e Keyboard Return +// 0x9f Keyboard Separator +// 0xa0 Keyboard Out +// 0xa1 Keyboard Oper +// 0xa2 Keyboard Clear/Again +// 0xa3 Keyboard CrSel/Props +// 0xa4 Keyboard ExSel + +// 0xb0 Keypad 00 +// 0xb1 Keypad 000 +// 0xb2 Thousands Separator +// 0xb3 Decimal Separator +// 0xb4 Currency Unit +// 0xb5 Currency Sub-unit +#define KEY_KPLEFTPAREN 0xb6 // Keypad ( +#define KEY_KPRIGHTPAREN 0xb7 // Keypad ) +// 0xb8 Keypad { +// 0xb9 Keypad } +// 0xba Keypad Tab +#define KEY_KPBACKSPACE 0xbb // Keypad Backspace +// 0xbc Keypad A +// 0xbd Keypad B +// 0xbe Keypad C +// 0xbf Keypad D +// 0xc0 Keypad E +// 0xc1 Keypad F +// 0xc2 Keypad XOR +// 0xc3 Keypad ^ +// 0xc4 Keypad % +// 0xc5 Keypad < +// 0xc6 Keypad > +// 0xc7 Keypad & +// 0xc8 Keypad && +// 0xc9 Keypad | +// 0xca Keypad || +// 0xcb Keypad : +// 0xcc Keypad # +// 0xcd Keypad Space +// 0xce Keypad @ +// 0xcf Keypad ! +// 0xd0 Keypad Memory Store +// 0xd1 Keypad Memory Recall +// 0xd2 Keypad Memory Clear +// 0xd3 Keypad Memory Add +// 0xd4 Keypad Memory Subtract +// 0xd5 Keypad Memory Multiply +// 0xd6 Keypad Memory Divide +// 0xd7 Keypad +/- +// 0xd8 Keypad Clear +// 0xd9 Keypad Clear Entry +// 0xda Keypad Binary +// 0xdb Keypad Octal +// 0xdc Keypad Decimal +// 0xdd Keypad Hexadecimal + +#define KEY_LEFTCTRL 0xe0 // Keyboard Left Control +#define KEY_LEFTSHIFT 0xe1 // Keyboard Left Shift +#define KEY_LEFTALT 0xe2 // Keyboard Left Alt +#define KEY_LEFTMETA 0xe3 // Keyboard Left GUI +#define KEY_RIGHTCTRL 0xe4 // Keyboard Right Control +#define KEY_RIGHTSHIFT 0xe5 // Keyboard Right Shift +#define KEY_RIGHTALT 0xe6 // Keyboard Right Alt +#define KEY_RIGHTMETA 0xe7 // Keyboard Right GUI + +#define KEY_MEDIA_PLAYPAUSE 0xe8 +#define KEY_MEDIA_STOPCD 0xe9 +#define KEY_MEDIA_PREVIOUSSONG 0xea +#define KEY_MEDIA_NEXTSONG 0xeb +#define KEY_MEDIA_EJECTCD 0xec +#define KEY_MEDIA_VOLUMEUP 0xed +#define KEY_MEDIA_VOLUMEDOWN 0xee +#define KEY_MEDIA_MUTE 0xef +#define KEY_MEDIA_WWW 0xf0 +#define KEY_MEDIA_BACK 0xf1 +#define KEY_MEDIA_FORWARD 0xf2 +#define KEY_MEDIA_STOP 0xf3 +#define KEY_MEDIA_FIND 0xf4 +#define KEY_MEDIA_SCROLLUP 0xf5 +#define KEY_MEDIA_SCROLLDOWN 0xf6 +#define KEY_MEDIA_EDIT 0xf7 +#define KEY_MEDIA_SLEEP 0xf8 +#define KEY_MEDIA_COFFEE 0xf9 +#define KEY_MEDIA_REFRESH 0xfa +#define KEY_MEDIA_CALC 0xfb + +enum { + // Generic Control + KEY_CONSUMER_CONTROL = 0x0001, + + // Power Control + KEY_CONSUMER_POWER = 0x0030, + KEY_CONSUMER_RESET = 0x0031, + KEY_CONSUMER_SLEEP = 0x0032, + + // Screen Brightness + KEY_CONSUMER_BRIGHTNESS_INCREMENT = 0x006F, + KEY_CONSUMER_BRIGHTNESS_DECREMENT = 0x0070, + + // These HID usages operate only on mobile systems (battery powered) and + // require Windows 8 (build 8302 or greater). + KEY_CONSUMER_WIRELESS_RADIO_CONTROLS = 0x000C, + KEY_CONSUMER_WIRELESS_RADIO_BUTTONS = 0x00C6, + KEY_CONSUMER_WIRELESS_RADIO_LED = 0x00C7, + KEY_CONSUMER_WIRELESS_RADIO_SLIDER_SWITCH = 0x00C8, + + // Media Control + KEY_CONSUMER_PLAY_PAUSE = 0x00CD, + KEY_CONSUMER_SCAN_NEXT = 0x00B5, + KEY_CONSUMER_SCAN_PREVIOUS = 0x00B6, + KEY_CONSUMER_STOP = 0x00B7, + KEY_CONSUMER_VOLUME = 0x00E0, + KEY_CONSUMER_MUTE = 0x00E2, + KEY_CONSUMER_BASS = 0x00E3, + KEY_CONSUMER_TREBLE = 0x00E4, + KEY_CONSUMER_BASS_BOOST = 0x00E5, + KEY_CONSUMER_VOLUME_INCREMENT = 0x00E9, + KEY_CONSUMER_VOLUME_DECREMENT = 0x00EA, + KEY_CONSUMER_BASS_INCREMENT = 0x0152, + KEY_CONSUMER_BASS_DECREMENT = 0x0153, + KEY_CONSUMER_TREBLE_INCREMENT = 0x0154, + KEY_CONSUMER_TREBLE_DECREMENT = 0x0155, + + // Application Launcher + KEY_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION = 0x0183, + KEY_CONSUMER_AL_EMAIL_READER = 0x018A, + KEY_CONSUMER_AL_CALCULATOR = 0x0192, + KEY_CONSUMER_AL_LOCAL_BROWSER = 0x0194, + + // Browser/Explorer Specific + KEY_CONSUMER_AC_SEARCH = 0x0221, + KEY_CONSUMER_AC_HOME = 0x0223, + KEY_CONSUMER_AC_BACK = 0x0224, + KEY_CONSUMER_AC_FORWARD = 0x0225, + KEY_CONSUMER_AC_STOP = 0x0226, + KEY_CONSUMER_AC_REFRESH = 0x0227, + KEY_CONSUMER_AC_BOOKMARKS = 0x022A, + + // Mouse Horizontal scroll + KEY_CONSUMER_AC_PAN = 0x0238, +}; + +/** + * keytable structure + */ +typedef struct { + uint8_t scan1, scan2; // scan code + uint8_t ascii; // ASCII code + uint8_t hidcode; // HID code for keyboard page +} keytable_t; + +/** + * FN functions + */ +typedef enum { + FN_NOP = 0, + FN_FNLOCK, + FN_BACKLIGHT, +} fn_function_t; + +/** + * FN keytable structure + */ +typedef struct { + uint8_t scan1, scan2; // scan code + uint16_t hidcode; // HID code for consumer page + fn_function_t fncode; // fn function type +} fn_keytable_t; + +/** + * search the USB HID key based on scan code + * @param scan1 scan code 1 + * @param scan2 scan code 2 + * @return -1 if not found + */ +int search_hid_key(unsigned scan1, unsigned scan2); + +/** + * search the FN function based on scan code + * @param scan1 scan code 1 + * @param scan2 scan code 2 + * @return NULL if not found + */ +fn_keytable_t* search_fn(unsigned scan1, unsigned scan2); + +#endif From 68eb4f3d85f463509145fd0d57cc7d58c8f74510 Mon Sep 17 00:00:00 2001 From: Forairaaaaa Date: Thu, 7 Dec 2023 17:52:49 +0800 Subject: [PATCH 03/10] adding ble keyboard wrap [todo] 1.back and enter not working 2.quit --- main/apps/app_keyboard/app_keyboard.cpp | 10 + .../ble_keyboard_wrap/ble_keyboard_wrap.cpp | 336 +++++++ .../ble_keyboard_wrap/ble_keyboard_wrap.h | 15 + .../utils/ble_keyboard_wrap/esp_hid_gap.c | 831 ++++++++++++++++++ .../utils/ble_keyboard_wrap/esp_hid_gap.h | 87 ++ main/cardputer.cpp | 2 +- main/hal/keyboard/keyboard.cpp | 9 + main/hal/keyboard/keyboard.h | 7 +- sdkconfig | 513 ++++++++++- sdkconfig.old | 312 ++++++- 10 files changed, 2100 insertions(+), 22 deletions(-) create mode 100644 main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.cpp create mode 100644 main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.h create mode 100755 main/apps/utils/ble_keyboard_wrap/esp_hid_gap.c create mode 100755 main/apps/utils/ble_keyboard_wrap/esp_hid_gap.h diff --git a/main/apps/app_keyboard/app_keyboard.cpp b/main/apps/app_keyboard/app_keyboard.cpp index 1d21d7e..b57483d 100644 --- a/main/apps/app_keyboard/app_keyboard.cpp +++ b/main/apps/app_keyboard/app_keyboard.cpp @@ -12,6 +12,7 @@ #include "spdlog/spdlog.h" #include "../utils/wifi_common_test/wifi_common_test.h" #include "../utils/theme/theme_define.h" +#include "../utils/ble_keyboard_wrap/ble_keyboard_wrap.h" using namespace MOONCAKE::APPS; @@ -38,6 +39,15 @@ void AppKeyboard::onResume() _data.hal->canvas_update(); + // Start ble keyboard + ble_keyboard_wrap_init(_data.hal->keyboard()); + + + // _data.hal->canvas()->deleteSprite(); + // while (1) + // { + // delay(1000); + // } } diff --git a/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.cpp b/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.cpp new file mode 100644 index 0000000..00773bb --- /dev/null +++ b/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.cpp @@ -0,0 +1,336 @@ +/** + * @file ble_keyboard_wrap.cpp + * @author Forairaaaaa + * @brief Ref: https://github.com/Gitshaoxiang/M5Cardputer-BLE-HID-Keyboard + * @version 0.1 + * @date 2023-12-07 + * + * @copyright Copyright (c) 2023 + * + */ + +/* This example code is in the Public Domain (or CC0 licensed, at your option.) + Unless required by applicable law or agreed to in writing, this software is + distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + */ + +#include +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "esp_event.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "esp_bt.h" +#include "esp_bt_defs.h" + +#include "esp_gap_ble_api.h" +#include "esp_gatts_api.h" +#include "esp_gatt_defs.h" + +#include "esp_bt_main.h" +#include "esp_bt_device.h" + +#include "esp_hidd.h" +#include "esp_hid_gap.h" + +// #include +// #include "Keyboard.h" + +// Keyboard_Class Keyboard = Keyboard_Class(); + +#include "ble_keyboard_wrap.h" +KEYBOARD::Keyboard* _keyboard = nullptr; + + +static const char *TAG = "HID_DEV_DEMO"; + +typedef struct { + xTaskHandle task_hdl; + esp_hidd_dev_t *hid_dev; + uint8_t protocol_mode; + uint8_t *buffer; +} local_param_t; + +static local_param_t s_ble_hid_param = {0}; + +const unsigned char hidReportMap[] = { + + 0x05, 0x01, // Usage Pg (Generic Desktop) + 0x09, 0x06, // Usage (Keyboard) + 0xA1, 0x01, // Collection: (Application) + 0x85, 0x01, // Report Id (1) + // + 0x05, 0x07, // Usage Pg (Key Codes) + 0x19, 0xE0, // Usage Min (224) + 0x29, 0xE7, // Usage Max (231) + 0x15, 0x00, // Log Min (0) + 0x25, 0x01, // Log Max (1) + // + // Modifier byte + 0x75, 0x01, // Report Size (1) + 0x95, 0x08, // Report Count (8) + 0x81, 0x02, // Input: (Data, Variable, Absolute) + // + // Reserved byte + 0x95, 0x01, // Report Count (1) + 0x75, 0x08, // Report Size (8) + 0x81, 0x01, // Input: (Constant) + // + // LED report + 0x95, 0x05, // Report Count (5) + 0x75, 0x01, // Report Size (1) + 0x05, 0x08, // Usage Pg (LEDs) + 0x19, 0x01, // Usage Min (1) + 0x29, 0x05, // Usage Max (5) + 0x91, 0x02, // Output: (Data, Variable, Absolute) + // + // LED report padding + 0x95, 0x01, // Report Count (1) + 0x75, 0x03, // Report Size (3) + 0x91, 0x01, // Output: (Constant) + // + // Key arrays (6 bytes) + 0x95, 0x06, // Report Count (6) + 0x75, 0x08, // Report Size (8) + 0x15, 0x00, // Log Min (0) + 0x25, 0xF1, // Log Max (241) + 0x05, 0x07, // Usage Pg (Key Codes) + 0x19, 0x00, // Usage Min (0) + 0x29, 0xf1, // Usage Max (241) + 0x81, 0x00, // Input: (Data, Array) + // + 0xC0, // End Collection +}; + +static esp_hid_raw_report_map_t ble_report_maps[] = { + {.data = hidReportMap, .len = sizeof(hidReportMap)}}; + +static esp_hid_device_config_t ble_hid_config = { + .vendor_id = 0x16C0, + .product_id = 0x05DF, + .version = 0x0100, + .device_name = "M5-Keyboard", + .manufacturer_name = "Espressif", + .serial_number = "1234567890", + .report_maps = ble_report_maps, + .report_maps_len = 1}; + +#define HID_RPT_ID_CC_IN 3 // Consumer Control input report ID +#define HID_CC_IN_RPT_LEN 2 // Consumer Control input report Len +void esp_hidd_send_consumer_value(uint8_t key_cmd, bool key_pressed) { + uint8_t buffer[HID_CC_IN_RPT_LEN] = {0, 0}; + + esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 0, HID_RPT_ID_CC_IN, buffer, + HID_CC_IN_RPT_LEN); + return; +} + +void ble_hid_demo_task(void *pvParameters) { + static bool send_volum_up = false; + ESP_LOGI(TAG, "ble_hid_demo_task start"); + + // uint8_t buffer1[8] = {0, 0, 0x17, 0, 0, 0, 0, 0}; + uint8_t buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + while (1) { + _keyboard->updateKeyList(); + _keyboard->updateKeysState(); + if (_keyboard->isChanged()) { + uint8_t modifier = 0; + if (_keyboard->isPressed()) { + memset(buffer, 0, 8); + auto status = _keyboard->keysState(); + + int count = 0; + for (auto i : status.hidKey) { + if (count < 6) { + buffer[2 + count] = i; + count++; + } + } + + if (status.ctrl) { + ESP_LOGI(TAG, "CONTROL"); + modifier |= 0x01; + } + + if (status.shift) { + ESP_LOGI(TAG, "SHIFT"); + modifier |= 0x02; + } + + if (status.alt) { + ESP_LOGI(TAG, "ALT"); + modifier |= 0x03; + } + + buffer[0] = modifier; + + ESP_LOG_BUFFER_HEX(TAG, buffer, 8); + + esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 0, 1, buffer, + 8); + } else { + memset(buffer, 0, 8); + esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 0, 1, buffer, + 8); + } + } + vTaskDelay(50 / portTICK_PERIOD_MS); + } +} + +void ble_hid_task_start_up(void) { + xTaskCreate(ble_hid_demo_task, "ble_hid_demo_task", 10 * 1024, NULL, + configMAX_PRIORITIES - 3, &s_ble_hid_param.task_hdl); +} + +void ble_hid_task_shut_down(void) { + if (s_ble_hid_param.task_hdl) { + vTaskDelete(s_ble_hid_param.task_hdl); + s_ble_hid_param.task_hdl = NULL; + } +} + +static void ble_hidd_event_callback(void *handler_args, esp_event_base_t base, + int32_t id, void *event_data) { + esp_hidd_event_t event = (esp_hidd_event_t)id; + esp_hidd_event_data_t *param = (esp_hidd_event_data_t *)event_data; + static const char *TAG = "HID_DEV_BLE"; + + switch (event) { + case ESP_HIDD_START_EVENT: { + ESP_LOGI(TAG, "START"); + esp_hid_ble_gap_adv_start(); + break; + } + case ESP_HIDD_CONNECT_EVENT: { + ESP_LOGI(TAG, "CONNECT"); + ble_hid_task_start_up(); // todo: this should be on auth_complete + // (in GAP) + // M5.Display.clear(); + // M5.Display.fillRect(10, M5.Display.height() / 2 - 15, + // M5.Display.width() - 20, 30, GREEN); + + // M5.Display.drawString("CONNECTED!", M5.Display.width() / 2, + // M5.Display.height() / 2); + + break; + } + case ESP_HIDD_PROTOCOL_MODE_EVENT: { + ESP_LOGI(TAG, "PROTOCOL MODE[%u]: %s", + param->protocol_mode.map_index, + param->protocol_mode.protocol_mode ? "REPORT" : "BOOT"); + break; + } + case ESP_HIDD_CONTROL_EVENT: { + ESP_LOGI(TAG, "CONTROL[%u]: %sSUSPEND", param->control.map_index, + param->control.control ? "EXIT_" : ""); + break; + } + case ESP_HIDD_OUTPUT_EVENT: { + ESP_LOGI(TAG, "OUTPUT[%u]: %8s ID: %2u, Len: %d, Data:", + param->output.map_index, + esp_hid_usage_str(param->output.usage), + param->output.report_id, param->output.length); + ESP_LOG_BUFFER_HEX(TAG, param->output.data, param->output.length); + break; + } + case ESP_HIDD_FEATURE_EVENT: { + ESP_LOGI(TAG, "FEATURE[%u]: %8s ID: %2u, Len: %d, Data:", + param->feature.map_index, + esp_hid_usage_str(param->feature.usage), + param->feature.report_id, param->feature.length); + ESP_LOG_BUFFER_HEX(TAG, param->feature.data, param->feature.length); + break; + } + case ESP_HIDD_DISCONNECT_EVENT: { + ESP_LOGI(TAG, "DISCONNECT: %s", + esp_hid_disconnect_reason_str( + esp_hidd_dev_transport_get(param->disconnect.dev), + param->disconnect.reason)); + ble_hid_task_shut_down(); + esp_hid_ble_gap_adv_start(); + // M5.Display.clear(); + + // M5.Display.fillRect(10, M5.Display.height() / 2 - 15, + // M5.Display.width() - 20, 30, RED); + + // M5.Display.drawString("DISCONNECT", M5.Display.width() / 2, + // M5.Display.height() / 2); + + break; + } + case ESP_HIDD_STOP_EVENT: { + ESP_LOGI(TAG, "STOP"); + break; + } + default: + break; + } + return; +} + +void ble_keyboard_wrap_init(KEYBOARD::Keyboard* keyboard) { + + // Copy pointer + _keyboard = keyboard; + + + esp_err_t ret; +#if HID_DEV_MODE == HIDD_IDLE_MODE + ESP_LOGE(TAG, "Please turn on BT HID device or BLE!"); + return; +#endif + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || + ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + // auto cfg = M5.config(); + + // M5.begin(); + + // M5.Display.begin(); + + // M5.begin(cfg); + // M5.Display.setRotation(1); + // M5.Display.setTextColor(BLACK); + // M5.Display.setTextDatum(middle_center); + // M5.Display.setTextFont(&fonts::FreeSerifBoldItalic12pt7b); + // M5.Display.setTextSize(1); + + // M5.Display.fillRect(10, M5.Display.height() / 2 - 15, + // M5.Display.width() - 20, 30, BLUE); + // M5.Display.drawString("BLE KEYBOARD", M5.Display.width() / 2, + // M5.Display.height() / 2); + + // Keyboard.begin(); + + ESP_LOGI(TAG, "setting hid gap, mode:%d", HID_DEV_MODE); + ret = esp_hid_gap_init(HID_DEV_MODE); + ESP_ERROR_CHECK(ret); + + ret = esp_hid_ble_gap_adv_init(ESP_HID_APPEARANCE_GENERIC, + ble_hid_config.device_name); + ESP_ERROR_CHECK(ret); + + if ((ret = esp_ble_gatts_register_callback(esp_hidd_gatts_event_handler)) != + ESP_OK) { + ESP_LOGE(TAG, "GATTS register callback failed: %d", ret); + return; + } + ESP_LOGI(TAG, "setting ble device"); + ESP_ERROR_CHECK(esp_hidd_dev_init(&ble_hid_config, ESP_HID_TRANSPORT_BLE, + ble_hidd_event_callback, + &s_ble_hid_param.hid_dev)); +} diff --git a/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.h b/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.h new file mode 100644 index 0000000..f340b6d --- /dev/null +++ b/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.h @@ -0,0 +1,15 @@ +/** + * @file ble_keyboard_wrap.h + * @author Forairaaaaa + * @brief Ref: https://github.com/Gitshaoxiang/M5Cardputer-BLE-HID-Keyboard + * @version 0.1 + * @date 2023-12-07 + * + * @copyright Copyright (c) 2023 + * + */ +#pragma once +#include "../../../hal/keyboard/keyboard.h" + + +void ble_keyboard_wrap_init(KEYBOARD::Keyboard* keyboard); diff --git a/main/apps/utils/ble_keyboard_wrap/esp_hid_gap.c b/main/apps/utils/ble_keyboard_wrap/esp_hid_gap.c new file mode 100755 index 0000000..12606f4 --- /dev/null +++ b/main/apps/utils/ble_keyboard_wrap/esp_hid_gap.c @@ -0,0 +1,831 @@ +// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" + +#include "esp_hid_gap.h" + +static const char *TAG = "ESP_HID_GAP"; + +// uncomment to print all devices that were seen during a scan +#define GAP_DBG_PRINTF(...) //printf(__VA_ARGS__) +//static const char * gap_bt_prop_type_names[5] = {"","BDNAME","COD","RSSI","EIR"}; + +static esp_hid_scan_result_t *bt_scan_results = NULL; +static size_t num_bt_scan_results = 0; + +static esp_hid_scan_result_t *ble_scan_results = NULL; +static size_t num_ble_scan_results = 0; + +static xSemaphoreHandle bt_hidh_cb_semaphore = NULL; +#define WAIT_BT_CB() xSemaphoreTake(bt_hidh_cb_semaphore, portMAX_DELAY) +#define SEND_BT_CB() xSemaphoreGive(bt_hidh_cb_semaphore) + +static xSemaphoreHandle ble_hidh_cb_semaphore = NULL; +#define WAIT_BLE_CB() xSemaphoreTake(ble_hidh_cb_semaphore, portMAX_DELAY) +#define SEND_BLE_CB() xSemaphoreGive(ble_hidh_cb_semaphore) + +#define SIZEOF_ARRAY(a) (sizeof(a)/sizeof(*a)) + +static const char *ble_gap_evt_names[] = { "ADV_DATA_SET_COMPLETE", "SCAN_RSP_DATA_SET_COMPLETE", "SCAN_PARAM_SET_COMPLETE", "SCAN_RESULT", "ADV_DATA_RAW_SET_COMPLETE", "SCAN_RSP_DATA_RAW_SET_COMPLETE", "ADV_START_COMPLETE", "SCAN_START_COMPLETE", "AUTH_CMPL", "KEY", "SEC_REQ", "PASSKEY_NOTIF", "PASSKEY_REQ", "OOB_REQ", "LOCAL_IR", "LOCAL_ER", "NC_REQ", "ADV_STOP_COMPLETE", "SCAN_STOP_COMPLETE", "SET_STATIC_RAND_ADDR", "UPDATE_CONN_PARAMS", "SET_PKT_LENGTH_COMPLETE", "SET_LOCAL_PRIVACY_COMPLETE", "REMOVE_BOND_DEV_COMPLETE", "CLEAR_BOND_DEV_COMPLETE", "GET_BOND_DEV_COMPLETE", "READ_RSSI_COMPLETE", "UPDATE_WHITELIST_COMPLETE"}; +static const char *bt_gap_evt_names[] = { "DISC_RES", "DISC_STATE_CHANGED", "RMT_SRVCS", "RMT_SRVC_REC", "AUTH_CMPL", "PIN_REQ", "CFM_REQ", "KEY_NOTIF", "KEY_REQ", "READ_RSSI_DELTA"}; +static const char *ble_addr_type_names[] = {"PUBLIC", "RANDOM", "RPA_PUBLIC", "RPA_RANDOM"}; + +const char *ble_addr_type_str(esp_ble_addr_type_t ble_addr_type) +{ + if (ble_addr_type > BLE_ADDR_TYPE_RPA_RANDOM) { + return "UNKNOWN"; + } + return ble_addr_type_names[ble_addr_type]; +} + +const char *ble_gap_evt_str(uint8_t event) +{ + if (event >= SIZEOF_ARRAY(ble_gap_evt_names)) { + return "UNKNOWN"; + } + return ble_gap_evt_names[event]; +} + +const char *bt_gap_evt_str(uint8_t event) +{ + if (event >= SIZEOF_ARRAY(bt_gap_evt_names)) { + return "UNKNOWN"; + } + return bt_gap_evt_names[event]; +} + +#if CONFIG_BT_BLE_ENABLED +const char *esp_ble_key_type_str(esp_ble_key_type_t key_type) +{ + const char *key_str = NULL; + switch (key_type) { + case ESP_LE_KEY_NONE: + key_str = "ESP_LE_KEY_NONE"; + break; + case ESP_LE_KEY_PENC: + key_str = "ESP_LE_KEY_PENC"; + break; + case ESP_LE_KEY_PID: + key_str = "ESP_LE_KEY_PID"; + break; + case ESP_LE_KEY_PCSRK: + key_str = "ESP_LE_KEY_PCSRK"; + break; + case ESP_LE_KEY_PLK: + key_str = "ESP_LE_KEY_PLK"; + break; + case ESP_LE_KEY_LLK: + key_str = "ESP_LE_KEY_LLK"; + break; + case ESP_LE_KEY_LENC: + key_str = "ESP_LE_KEY_LENC"; + break; + case ESP_LE_KEY_LID: + key_str = "ESP_LE_KEY_LID"; + break; + case ESP_LE_KEY_LCSRK: + key_str = "ESP_LE_KEY_LCSRK"; + break; + default: + key_str = "INVALID BLE KEY TYPE"; + break; + + } + return key_str; +} +#endif /* CONFIG_BT_BLE_ENABLED */ + +void esp_hid_scan_results_free(esp_hid_scan_result_t *results) +{ + esp_hid_scan_result_t *r = NULL; + while (results) { + r = results; + results = results->next; + if (r->name != NULL) { + free((char *)r->name); + } + free(r); + } +} + +#if (CONFIG_BT_HID_DEVICE_ENABLED || CONFIG_BT_BLE_ENABLED) +static esp_hid_scan_result_t *find_scan_result(esp_bd_addr_t bda, esp_hid_scan_result_t *results) +{ + esp_hid_scan_result_t *r = results; + while (r) { + if (memcmp(bda, r->bda, sizeof(esp_bd_addr_t)) == 0) { + return r; + } + r = r->next; + } + return NULL; +} +#endif /* (CONFIG_BT_HID_DEVICE_ENABLED || CONFIG_BT_BLE_ENABLED) */ + +#if CONFIG_BT_HID_DEVICE_ENABLED +static void add_bt_scan_result(esp_bd_addr_t bda, esp_bt_cod_t *cod, esp_bt_uuid_t *uuid, uint8_t *name, uint8_t name_len, int rssi) +{ + esp_hid_scan_result_t *r = find_scan_result(bda, bt_scan_results); + if (r) { + //Some info may come later + if (r->name == NULL && name && name_len) { + char *name_s = (char *)malloc(name_len + 1); + if (name_s == NULL) { + ESP_LOGE(TAG, "Malloc result name failed!"); + return; + } + memcpy(name_s, name, name_len); + name_s[name_len] = 0; + r->name = (const char *)name_s; + } + if (r->bt.uuid.len == 0 && uuid->len) { + memcpy(&r->bt.uuid, uuid, sizeof(esp_bt_uuid_t)); + } + if (rssi != 0) { + r->rssi = rssi; + } + return; + } + + r = (esp_hid_scan_result_t *)malloc(sizeof(esp_hid_scan_result_t)); + if (r == NULL) { + ESP_LOGE(TAG, "Malloc bt_hidh_scan_result_t failed!"); + return; + } + r->transport = ESP_HID_TRANSPORT_BT; + memcpy(r->bda, bda, sizeof(esp_bd_addr_t)); + memcpy(&r->bt.cod, cod, sizeof(esp_bt_cod_t)); + memcpy(&r->bt.uuid, uuid, sizeof(esp_bt_uuid_t)); + r->usage = esp_hid_usage_from_cod((uint32_t)cod); + r->rssi = rssi; + r->name = NULL; + if (name_len && name) { + char *name_s = (char *)malloc(name_len + 1); + if (name_s == NULL) { + free(r); + ESP_LOGE(TAG, "Malloc result name failed!"); + return; + } + memcpy(name_s, name, name_len); + name_s[name_len] = 0; + r->name = (const char *)name_s; + } + r->next = bt_scan_results; + bt_scan_results = r; + num_bt_scan_results++; +} +#endif + +#if CONFIG_BT_BLE_ENABLED +static void add_ble_scan_result(esp_bd_addr_t bda, esp_ble_addr_type_t addr_type, uint16_t appearance, uint8_t *name, uint8_t name_len, int rssi) +{ + if (find_scan_result(bda, ble_scan_results)) { + ESP_LOGW(TAG, "Result already exists!"); + return; + } + esp_hid_scan_result_t *r = (esp_hid_scan_result_t *)malloc(sizeof(esp_hid_scan_result_t)); + if (r == NULL) { + ESP_LOGE(TAG, "Malloc ble_hidh_scan_result_t failed!"); + return; + } + r->transport = ESP_HID_TRANSPORT_BLE; + memcpy(r->bda, bda, sizeof(esp_bd_addr_t)); + r->ble.appearance = appearance; + r->ble.addr_type = addr_type; + r->usage = esp_hid_usage_from_appearance(appearance); + r->rssi = rssi; + r->name = NULL; + if (name_len && name) { + char *name_s = (char *)malloc(name_len + 1); + if (name_s == NULL) { + free(r); + ESP_LOGE(TAG, "Malloc result name failed!"); + return; + } + memcpy(name_s, name, name_len); + name_s[name_len] = 0; + r->name = (const char *)name_s; + } + r->next = ble_scan_results; + ble_scan_results = r; + num_ble_scan_results++; +} +#endif /* CONFIG_BT_BLE_ENABLED */ + +void print_uuid(esp_bt_uuid_t *uuid) +{ + if (uuid->len == ESP_UUID_LEN_16) { + GAP_DBG_PRINTF("UUID16: 0x%04x", uuid->uuid.uuid16); + } else if (uuid->len == ESP_UUID_LEN_32) { + GAP_DBG_PRINTF("UUID32: 0x%08x", uuid->uuid.uuid32); + } else if (uuid->len == ESP_UUID_LEN_128) { + GAP_DBG_PRINTF("UUID128: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x", uuid->uuid.uuid128[0], + uuid->uuid.uuid128[1], uuid->uuid.uuid128[2], uuid->uuid.uuid128[3], + uuid->uuid.uuid128[4], uuid->uuid.uuid128[5], uuid->uuid.uuid128[6], + uuid->uuid.uuid128[7], uuid->uuid.uuid128[8], uuid->uuid.uuid128[9], + uuid->uuid.uuid128[10], uuid->uuid.uuid128[11], uuid->uuid.uuid128[12], + uuid->uuid.uuid128[13], uuid->uuid.uuid128[14], uuid->uuid.uuid128[15]); + } +} + +#if CONFIG_BT_HID_DEVICE_ENABLED +static void handle_bt_device_result(struct disc_res_param *disc_res) +{ + GAP_DBG_PRINTF("BT : " ESP_BD_ADDR_STR, ESP_BD_ADDR_HEX(disc_res->bda)); + uint32_t codv = 0; + esp_bt_cod_t *cod = (esp_bt_cod_t *)&codv; + int8_t rssi = 0; + uint8_t *name = NULL; + uint8_t name_len = 0; + esp_bt_uuid_t uuid; + + uuid.len = ESP_UUID_LEN_16; + uuid.uuid.uuid16 = 0; + + for (int i = 0; i < disc_res->num_prop; i++) { + esp_bt_gap_dev_prop_t *prop = &disc_res->prop[i]; + if (prop->type != ESP_BT_GAP_DEV_PROP_EIR) { + GAP_DBG_PRINTF(", %s: ", gap_bt_prop_type_names[prop->type]); + } + if (prop->type == ESP_BT_GAP_DEV_PROP_BDNAME) { + name = (uint8_t *)prop->val; + name_len = strlen((const char *)name); + GAP_DBG_PRINTF("%s", (const char *)name); + } else if (prop->type == ESP_BT_GAP_DEV_PROP_RSSI) { + rssi = *((int8_t *)prop->val); + GAP_DBG_PRINTF("%d", rssi); + } else if (prop->type == ESP_BT_GAP_DEV_PROP_COD) { + memcpy(&codv, prop->val, sizeof(uint32_t)); + GAP_DBG_PRINTF("major: %s, minor: %d, service: 0x%03x", esp_hid_cod_major_str(cod->major), cod->minor, cod->service); + } else if (prop->type == ESP_BT_GAP_DEV_PROP_EIR) { + uint8_t len = 0; + uint8_t *data = 0; + + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_16BITS_UUID, &len); + if (data == NULL) { + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_INCMPL_16BITS_UUID, &len); + } + if (data && len == ESP_UUID_LEN_16) { + uuid.len = ESP_UUID_LEN_16; + uuid.uuid.uuid16 = data[0] + (data[1] << 8); + GAP_DBG_PRINTF(", "); print_uuid(&uuid); + continue; + } + + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_32BITS_UUID, &len); + if (data == NULL) { + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_INCMPL_32BITS_UUID, &len); + } + if (data && len == ESP_UUID_LEN_32) { + uuid.len = len; + memcpy(&uuid.uuid.uuid32, data, sizeof(uint32_t)); + GAP_DBG_PRINTF(", "); print_uuid(&uuid); + continue; + } + + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_128BITS_UUID, &len); + if (data == NULL) { + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_INCMPL_128BITS_UUID, &len); + } + if (data && len == ESP_UUID_LEN_128) { + uuid.len = len; + memcpy(uuid.uuid.uuid128, (uint8_t *)data, len); + GAP_DBG_PRINTF(", "); print_uuid(&uuid); + continue; + } + + //try to find a name + if (name == NULL) { + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &len); + if (data == NULL) { + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &len); + } + if (data && len) { + name = data; + name_len = len; + GAP_DBG_PRINTF(", NAME: "); + for (int x = 0; x < len; x++) { + GAP_DBG_PRINTF("%c", (char)data[x]); + } + } + } + } + } + GAP_DBG_PRINTF("\n"); + + if (cod->major == ESP_BT_COD_MAJOR_DEV_PERIPHERAL || (find_scan_result(disc_res->bda, bt_scan_results) != NULL)) { + add_bt_scan_result(disc_res->bda, cod, &uuid, name, name_len, rssi); + } +} +#endif + +#if CONFIG_BT_BLE_ENABLED +static void handle_ble_device_result(struct ble_scan_result_evt_param *scan_rst) +{ + + uint16_t uuid = 0; + uint16_t appearance = 0; + char name[64] = {0}; + + uint8_t uuid_len = 0; + uint8_t *uuid_d = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_16SRV_CMPL, &uuid_len); + if (uuid_d != NULL && uuid_len) { + uuid = uuid_d[0] + (uuid_d[1] << 8); + } + + uint8_t appearance_len = 0; + uint8_t *appearance_d = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_APPEARANCE, &appearance_len); + if (appearance_d != NULL && appearance_len) { + appearance = appearance_d[0] + (appearance_d[1] << 8); + } + + uint8_t adv_name_len = 0; + uint8_t *adv_name = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + + if (adv_name == NULL) { + adv_name = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_NAME_SHORT, &adv_name_len); + } + + if (adv_name != NULL && adv_name_len) { + memcpy(name, adv_name, adv_name_len); + name[adv_name_len] = 0; + } + + GAP_DBG_PRINTF("BLE: " ESP_BD_ADDR_STR ", ", ESP_BD_ADDR_HEX(scan_rst->bda)); + GAP_DBG_PRINTF("RSSI: %d, ", scan_rst->rssi); + GAP_DBG_PRINTF("UUID: 0x%04x, ", uuid); + GAP_DBG_PRINTF("APPEARANCE: 0x%04x, ", appearance); + GAP_DBG_PRINTF("ADDR_TYPE: '%s'", ble_addr_type_str(scan_rst->ble_addr_type)); + if (adv_name_len) { + GAP_DBG_PRINTF(", NAME: '%s'", name); + } + GAP_DBG_PRINTF("\n"); + + if (uuid == ESP_GATT_UUID_HID_SVC) { + add_ble_scan_result(scan_rst->bda, scan_rst->ble_addr_type, appearance, adv_name, adv_name_len, scan_rst->rssi); + } +} +#endif /* CONFIG_BT_BLE_ENABLED */ + +#if CONFIG_BT_HID_DEVICE_ENABLED +/* + * BT GAP + * */ + +static void bt_gap_event_handler(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) +{ + switch (event) { + case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: { + ESP_LOGV(TAG, "BT GAP DISC_STATE %s", (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) ? "START" : "STOP"); + if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) { + SEND_BT_CB(); + } + break; + } + case ESP_BT_GAP_DISC_RES_EVT: { + handle_bt_device_result(¶m->disc_res); + break; + } + case ESP_BT_GAP_KEY_NOTIF_EVT: + ESP_LOGI(TAG, "BT GAP KEY_NOTIF passkey:%d", param->key_notif.passkey); + break; + case ESP_BT_GAP_MODE_CHG_EVT: + ESP_LOGI(TAG, "BT GAP MODE_CHG_EVT mode:%d", param->mode_chg.mode); + break; + default: + ESP_LOGV(TAG, "BT GAP EVENT %s", bt_gap_evt_str(event)); + break; + } +} + +static esp_err_t init_bt_gap(void) +{ + esp_err_t ret; +#if (CONFIG_BT_SSP_ENABLED) + /* Set default parameters for Secure Simple Pairing */ + esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; + esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_NONE; + esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); +#endif + /* + * Set default parameters for Legacy Pairing + * Use fixed pin code + */ + esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED; + esp_bt_pin_code_t pin_code; + pin_code[0] = '1'; + pin_code[1] = '2'; + pin_code[2] = '3'; + pin_code[3] = '4'; + esp_bt_gap_set_pin(pin_type, 4, pin_code); + + if ((ret = esp_bt_gap_register_callback(bt_gap_event_handler)) != ESP_OK) { + ESP_LOGE(TAG, "esp_bt_gap_register_callback failed: %d", ret); + return ret; + } + + // Allow BT devices to connect back to us + if ((ret = esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_NON_DISCOVERABLE)) != ESP_OK) { + ESP_LOGE(TAG, "esp_bt_gap_set_scan_mode failed: %d", ret); + return ret; + } + return ret; +} + +static esp_err_t start_bt_scan(uint32_t seconds) +{ + esp_err_t ret = ESP_OK; + if ((ret = esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, (int)(seconds / 1.28), 0)) != ESP_OK) { + ESP_LOGE(TAG, "esp_bt_gap_start_discovery failed: %d", ret); + return ret; + } + return ret; +} +#endif + +#if CONFIG_BT_BLE_ENABLED +/* + * BLE GAP + * */ + +static void ble_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) +{ + switch (event) { + /* + * SCAN + * */ + case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { + ESP_LOGV(TAG, "BLE GAP EVENT SCAN_PARAM_SET_COMPLETE"); + SEND_BLE_CB(); + break; + } + case ESP_GAP_BLE_SCAN_RESULT_EVT: { + esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; + switch (scan_result->scan_rst.search_evt) { + case ESP_GAP_SEARCH_INQ_RES_EVT: { + handle_ble_device_result(&scan_result->scan_rst); + break; + } + case ESP_GAP_SEARCH_INQ_CMPL_EVT: + ESP_LOGV(TAG, "BLE GAP EVENT SCAN DONE: %d", scan_result->scan_rst.num_resps); + SEND_BLE_CB(); + break; + default: + break; + } + break; + } + case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: { + ESP_LOGV(TAG, "BLE GAP EVENT SCAN CANCELED"); + break; + } + + /* + * ADVERTISEMENT + * */ + case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: + ESP_LOGV(TAG, "BLE GAP ADV_DATA_SET_COMPLETE"); + break; + + case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: + ESP_LOGV(TAG, "BLE GAP ADV_START_COMPLETE"); + break; + + /* + * AUTHENTICATION + * */ + case ESP_GAP_BLE_AUTH_CMPL_EVT: + if (!param->ble_security.auth_cmpl.success) { + ESP_LOGE(TAG, "BLE GAP AUTH ERROR: 0x%x", param->ble_security.auth_cmpl.fail_reason); + } else { + ESP_LOGI(TAG, "BLE GAP AUTH SUCCESS"); + } + break; + + case ESP_GAP_BLE_KEY_EVT: //shows the ble key info share with peer device to the user. + ESP_LOGI(TAG, "BLE GAP KEY type = %s", esp_ble_key_type_str(param->ble_security.ble_key.key_type)); + break; + + case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: // ESP_IO_CAP_OUT + // The app will receive this evt when the IO has Output capability and the peer device IO has Input capability. + // Show the passkey number to the user to input it in the peer device. + ESP_LOGI(TAG, "BLE GAP PASSKEY_NOTIF passkey:%d", param->ble_security.key_notif.passkey); + break; + + case ESP_GAP_BLE_NC_REQ_EVT: // ESP_IO_CAP_IO + // The app will receive this event when the IO has DisplayYesNO capability and the peer device IO also has DisplayYesNo capability. + // show the passkey number to the user to confirm it with the number displayed by peer device. + ESP_LOGI(TAG, "BLE GAP NC_REQ passkey:%d", param->ble_security.key_notif.passkey); + esp_ble_confirm_reply(param->ble_security.key_notif.bd_addr, true); + break; + + case ESP_GAP_BLE_PASSKEY_REQ_EVT: // ESP_IO_CAP_IN + // The app will receive this evt when the IO has Input capability and the peer device IO has Output capability. + // See the passkey number on the peer device and send it back. + ESP_LOGI(TAG, "BLE GAP PASSKEY_REQ"); + //esp_ble_passkey_reply(param->ble_security.ble_req.bd_addr, true, 1234); + break; + + case ESP_GAP_BLE_SEC_REQ_EVT: + ESP_LOGI(TAG, "BLE GAP SEC_REQ"); + // Send the positive(true) security response to the peer device to accept the security request. + // If not accept the security request, should send the security response with negative(false) accept value. + esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true); + break; + + default: + ESP_LOGV(TAG, "BLE GAP EVENT %s", ble_gap_evt_str(event)); + break; + } +} + +static esp_err_t init_ble_gap(void) +{ + esp_err_t ret; + + if ((ret = esp_ble_gap_register_callback(ble_gap_event_handler)) != ESP_OK) { + ESP_LOGE(TAG, "esp_ble_gap_register_callback failed: %d", ret); + return ret; + } + return ret; +} + +static esp_ble_scan_params_t hid_scan_params = { + .scan_type = BLE_SCAN_TYPE_ACTIVE, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, + .scan_interval = 0x50, + .scan_window = 0x30, + .scan_duplicate = BLE_SCAN_DUPLICATE_ENABLE, +}; + +static esp_err_t start_ble_scan(uint32_t seconds) +{ + esp_err_t ret = ESP_OK; + if ((ret = esp_ble_gap_set_scan_params(&hid_scan_params)) != ESP_OK) { + ESP_LOGE(TAG, "esp_ble_gap_set_scan_params failed: %d", ret); + return ret; + } + WAIT_BLE_CB(); + + if ((ret = esp_ble_gap_start_scanning(seconds)) != ESP_OK) { + ESP_LOGE(TAG, "esp_ble_gap_start_scanning failed: %d", ret); + return ret; + } + return ret; +} + +esp_err_t esp_hid_ble_gap_adv_init(uint16_t appearance, const char *device_name) +{ + + esp_err_t ret; + + const uint8_t hidd_service_uuid128[] = { + 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x12, 0x18, 0x00, 0x00, + }; + + esp_ble_adv_data_t ble_adv_data = { + .set_scan_rsp = false, + .include_name = true, + .include_txpower = true, + .min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec + .max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec + .appearance = appearance, + .manufacturer_len = 0, + .p_manufacturer_data = NULL, + .service_data_len = 0, + .p_service_data = NULL, + .service_uuid_len = sizeof(hidd_service_uuid128), + .p_service_uuid = (uint8_t *)hidd_service_uuid128, + .flag = 0x6, + }; + + esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND; + //esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT;//you have to enter the key on the host + //esp_ble_io_cap_t iocap = ESP_IO_CAP_IN;//you have to enter the key on the device + esp_ble_io_cap_t iocap = ESP_IO_CAP_IO;//you have to agree that key matches on both + //esp_ble_io_cap_t iocap = ESP_IO_CAP_NONE;//device is not capable of input or output, unsecure + uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK; + uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK; + uint8_t key_size = 16; //the key size should be 7~16 bytes + uint32_t passkey = 1234;//ESP_IO_CAP_OUT + + if ((ret = esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, 1)) != ESP_OK) { + ESP_LOGE(TAG, "GAP set_security_param AUTHEN_REQ_MODE failed: %d", ret); + return ret; + } + + if ((ret = esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, 1)) != ESP_OK) { + ESP_LOGE(TAG, "GAP set_security_param IOCAP_MODE failed: %d", ret); + return ret; + } + + if ((ret = esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, 1)) != ESP_OK) { + ESP_LOGE(TAG, "GAP set_security_param SET_INIT_KEY failed: %d", ret); + return ret; + } + + if ((ret = esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, 1)) != ESP_OK) { + ESP_LOGE(TAG, "GAP set_security_param SET_RSP_KEY failed: %d", ret); + return ret; + } + + if ((ret = esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, 1)) != ESP_OK) { + ESP_LOGE(TAG, "GAP set_security_param MAX_KEY_SIZE failed: %d", ret); + return ret; + } + + if ((ret = esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t))) != ESP_OK) { + ESP_LOGE(TAG, "GAP set_security_param SET_STATIC_PASSKEY failed: %d", ret); + return ret; + } + + if ((ret = esp_ble_gap_set_device_name(device_name)) != ESP_OK) { + ESP_LOGE(TAG, "GAP set_device_name failed: %d", ret); + return ret; + } + + if ((ret = esp_ble_gap_config_adv_data(&ble_adv_data)) != ESP_OK) { + ESP_LOGE(TAG, "GAP config_adv_data failed: %d", ret); + return ret; + } + + return ret; +} + +esp_err_t esp_hid_ble_gap_adv_start(void) +{ + static esp_ble_adv_params_t hidd_adv_params = { + .adv_int_min = 0x20, + .adv_int_max = 0x30, + .adv_type = ADV_TYPE_IND, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .channel_map = ADV_CHNL_ALL, + .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, + }; + return esp_ble_gap_start_advertising(&hidd_adv_params); +} +#endif /* CONFIG_BT_BLE_ENABLED */ + +/* + * CONTROLLER INIT + * */ + +static esp_err_t init_low_level(uint8_t mode) +{ + esp_err_t ret; + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); +#if CONFIG_IDF_TARGET_ESP32 + bt_cfg.mode = mode; +#endif +#if CONFIG_BT_HID_DEVICE_ENABLED + if (mode & ESP_BT_MODE_CLASSIC_BT) { + bt_cfg.bt_max_acl_conn = 3; + bt_cfg.bt_max_sync_conn = 3; + } else +#endif + { + ret = esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT); + if (ret) { + ESP_LOGE(TAG, "esp_bt_controller_mem_release failed: %d", ret); + return ret; + } + } + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(TAG, "esp_bt_controller_init failed: %d", ret); + return ret; + } + + ret = esp_bt_controller_enable(mode); + if (ret) { + ESP_LOGE(TAG, "esp_bt_controller_enable failed: %d", ret); + return ret; + } + + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(TAG, "esp_bluedroid_init failed: %d", ret); + return ret; + } + + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(TAG, "esp_bluedroid_enable failed: %d", ret); + return ret; + } +#if CONFIG_BT_HID_DEVICE_ENABLED + if (mode & ESP_BT_MODE_CLASSIC_BT) { + ret = init_bt_gap(); + if (ret) { + return ret; + } + } +#endif +#if CONFIG_BT_BLE_ENABLED + if (mode & ESP_BT_MODE_BLE) { + ret = init_ble_gap(); + if (ret) { + return ret; + } + } +#endif /* CONFIG_BT_BLE_ENABLED */ + return ret; +} + +esp_err_t esp_hid_gap_init(uint8_t mode) +{ + esp_err_t ret; + if (!mode || mode > ESP_BT_MODE_BTDM) { + ESP_LOGE(TAG, "Invalid mode given!"); + return ESP_FAIL; + } + + if (bt_hidh_cb_semaphore != NULL) { + ESP_LOGE(TAG, "Already initialised"); + return ESP_FAIL; + } + + bt_hidh_cb_semaphore = xSemaphoreCreateBinary(); + if (bt_hidh_cb_semaphore == NULL) { + ESP_LOGE(TAG, "xSemaphoreCreateMutex failed!"); + return ESP_FAIL; + } + + ble_hidh_cb_semaphore = xSemaphoreCreateBinary(); + if (ble_hidh_cb_semaphore == NULL) { + ESP_LOGE(TAG, "xSemaphoreCreateMutex failed!"); + vSemaphoreDelete(bt_hidh_cb_semaphore); + bt_hidh_cb_semaphore = NULL; + return ESP_FAIL; + } + + ret = init_low_level(mode); + if (ret != ESP_OK) { + vSemaphoreDelete(bt_hidh_cb_semaphore); + bt_hidh_cb_semaphore = NULL; + vSemaphoreDelete(ble_hidh_cb_semaphore); + ble_hidh_cb_semaphore = NULL; + return ret; + } + + return ESP_OK; +} + +esp_err_t esp_hid_scan(uint32_t seconds, size_t *num_results, esp_hid_scan_result_t **results) +{ + if (num_bt_scan_results || bt_scan_results || num_ble_scan_results || ble_scan_results) { + ESP_LOGE(TAG, "There are old scan results. Free them first!"); + return ESP_FAIL; + } + +#if CONFIG_BT_BLE_ENABLED + if (start_ble_scan(seconds) == ESP_OK) { + WAIT_BLE_CB(); + } else { + return ESP_FAIL; + } +#endif /* CONFIG_BT_BLE_ENABLED */ + +#if CONFIG_BT_HID_DEVICE_ENABLED + if (start_bt_scan(seconds) == ESP_OK) { + WAIT_BT_CB(); + } else { + return ESP_FAIL; + } +#endif + + *num_results = num_bt_scan_results + num_ble_scan_results; + *results = bt_scan_results; + if (num_bt_scan_results) { + while (bt_scan_results->next != NULL) { + bt_scan_results = bt_scan_results->next; + } + bt_scan_results->next = ble_scan_results; + } else { + *results = ble_scan_results; + } + + num_bt_scan_results = 0; + bt_scan_results = NULL; + num_ble_scan_results = 0; + ble_scan_results = NULL; + return ESP_OK; +} diff --git a/main/apps/utils/ble_keyboard_wrap/esp_hid_gap.h b/main/apps/utils/ble_keyboard_wrap/esp_hid_gap.h new file mode 100755 index 0000000..524fbc4 --- /dev/null +++ b/main/apps/utils/ble_keyboard_wrap/esp_hid_gap.h @@ -0,0 +1,87 @@ +// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _ESP_HID_GAP_H_ +#define _ESP_HID_GAP_H_ + +#define HIDD_IDLE_MODE 0x00 +#define HIDD_BLE_MODE 0x01 +#define HIDD_BT_MODE 0x02 +#define HIDD_BTDM_MODE 0x03 + +#if CONFIG_BT_HID_DEVICE_ENABLED +#if CONFIG_BT_BLE_ENABLED +#define HID_DEV_MODE HIDD_BTDM_MODE +#else +#define HID_DEV_MODE HIDD_BT_MODE +#endif +#elif CONFIG_BT_BLE_ENABLED +#define HID_DEV_MODE HIDD_BLE_MODE +#else +#define HID_DEV_MODE HIDD_IDLE_MODE +#endif + +#include "esp_err.h" +#include "esp_log.h" + +#include "esp_bt.h" +#include "esp_bt_defs.h" +#include "esp_bt_main.h" +#include "esp_gap_bt_api.h" +#include "esp_hid_common.h" +#if CONFIG_BT_BLE_ENABLED +#include "esp_gattc_api.h" +#include "esp_gatt_defs.h" +#include "esp_gap_ble_api.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct esp_hidh_scan_result_s { + struct esp_hidh_scan_result_s *next; + + esp_bd_addr_t bda; + const char *name; + int8_t rssi; + esp_hid_usage_t usage; + esp_hid_transport_t transport; //BT, BLE or USB + union { + struct { + esp_bt_cod_t cod; + esp_bt_uuid_t uuid; + } bt; + struct { + esp_ble_addr_type_t addr_type; + uint16_t appearance; + } ble; + }; +} esp_hid_scan_result_t; + +esp_err_t esp_hid_gap_init(uint8_t mode); +esp_err_t esp_hid_scan(uint32_t seconds, size_t *num_results, esp_hid_scan_result_t **results); +void esp_hid_scan_results_free(esp_hid_scan_result_t *results); + +esp_err_t esp_hid_ble_gap_adv_init(uint16_t appearance, const char *device_name); +esp_err_t esp_hid_ble_gap_adv_start(void); + +void print_uuid(esp_bt_uuid_t *uuid); +const char *ble_addr_type_str(esp_ble_addr_type_t ble_addr_type); + +#ifdef __cplusplus +} +#endif + +#endif /* _ESP_HIDH_GAP_H_ */ diff --git a/main/cardputer.cpp b/main/cardputer.cpp index dd9b149..8c7de71 100644 --- a/main/cardputer.cpp +++ b/main/cardputer.cpp @@ -32,7 +32,7 @@ void _data_base_setup_callback(SIMPLEKV::SimpleKV& db) // #define ON_HAL_TEST // #define ON_APP_TEST 1 -// #define ON_APP_TEST_WITH_LAUNCHER 1 +#define ON_APP_TEST_WITH_LAUNCHER 1 extern "C" void app_main(void) { // Init hal diff --git a/main/hal/keyboard/keyboard.cpp b/main/hal/keyboard/keyboard.cpp index 21b161e..2914082 100644 --- a/main/hal/keyboard/keyboard.cpp +++ b/main/hal/keyboard/keyboard.cpp @@ -292,3 +292,12 @@ void Keyboard::updateKeysState() } +bool Keyboard::isChanged() +{ + if (_last_key_size != _key_list_buffer.size()) + { + _last_key_size = _key_list_buffer.size(); + return true; + } + return false; +} diff --git a/main/hal/keyboard/keyboard.h b/main/hal/keyboard/keyboard.h index 398b319..81a7a53 100644 --- a/main/hal/keyboard/keyboard.h +++ b/main/hal/keyboard/keyboard.h @@ -154,6 +154,7 @@ namespace KEYBOARD KeysState _keys_state_buffer; bool _is_caps_locked; + uint8_t _last_key_size; void _set_output(const std::vector& pinList, uint8_t output); @@ -162,7 +163,8 @@ namespace KEYBOARD public: Keyboard() : - _is_caps_locked(false) + _is_caps_locked(false), + _last_key_size(0) {} void init(); @@ -183,5 +185,8 @@ namespace KEYBOARD inline bool capslocked(void) { return _is_caps_locked; } inline void setCapsLocked(bool isLocked) { _is_caps_locked = isLocked; } + + bool isChanged(); + inline uint8_t isPressed() { return _key_list_buffer.size(); } }; } diff --git a/sdkconfig b/sdkconfig index 1c4dbd8..0ee0c7d 100644 --- a/sdkconfig +++ b/sdkconfig @@ -189,9 +189,308 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # # Bluetooth # -# CONFIG_BT_ENABLED is not set +CONFIG_BT_ENABLED=y +CONFIG_BT_SOC_SUPPORT_5_0=y + +# +# Bluetooth controller +# +CONFIG_BT_CTRL_MODE_EFF=1 +CONFIG_BT_CTRL_BLE_MAX_ACT=6 +CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=6 +CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0 +CONFIG_BT_CTRL_PINNED_TO_CORE_0=y +# CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set +CONFIG_BT_CTRL_PINNED_TO_CORE=0 +CONFIG_BT_CTRL_HCI_MODE_VHCI=y +# CONFIG_BT_CTRL_HCI_MODE_UART_H4 is not set +CONFIG_BT_CTRL_HCI_TL=1 +CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30 +CONFIG_BT_BLE_CCA_MODE_NONE=y +# CONFIG_BT_BLE_CCA_MODE_HW is not set +# CONFIG_BT_BLE_CCA_MODE_SW is not set +CONFIG_BT_BLE_CCA_MODE=0 +CONFIG_BT_CTRL_HW_CCA_VAL=20 +CONFIG_BT_CTRL_HW_CCA_EFF=0 +CONFIG_BT_CTRL_CE_LENGTH_TYPE_ORIG=y +# CONFIG_BT_CTRL_CE_LENGTH_TYPE_CE is not set +# CONFIG_BT_CTRL_CE_LENGTH_TYPE_SD is not set +CONFIG_BT_CTRL_CE_LENGTH_TYPE_EFF=0 +CONFIG_BT_CTRL_TX_ANTENNA_INDEX_0=y +# CONFIG_BT_CTRL_TX_ANTENNA_INDEX_1 is not set +CONFIG_BT_CTRL_TX_ANTENNA_INDEX_EFF=0 +CONFIG_BT_CTRL_RX_ANTENNA_INDEX_0=y +# CONFIG_BT_CTRL_RX_ANTENNA_INDEX_1 is not set +CONFIG_BT_CTRL_RX_ANTENNA_INDEX_EFF=0 +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N24 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N21 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N18 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N15 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N12 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N9 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N6 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N3 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N0 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P3 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P6 is not set +CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P9=y +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P12 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P15 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P18 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P21 is not set +CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=11 +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_BT_CTRL_BLE_SCAN_DUPL=y +CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DEVICE=y +# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA is not set +# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE is not set +CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0 +CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BT_CTRL_DUPL_SCAN_CACHE_REFRESH_PERIOD=0 +# CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN is not set +# CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EN is not set +CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS=y +CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF=0 + +# +# MODEM SLEEP Options +# +# CONFIG_BT_CTRL_MODEM_SLEEP is not set +# end of MODEM SLEEP Options + +CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 +CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 +CONFIG_BT_CTRL_HCI_TL_EFF=1 +# CONFIG_BT_CTRL_AGC_RECORRECT_EN is not set +# CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# end of Bluetooth controller + +CONFIG_BT_BLUEDROID_ENABLED=y +# CONFIG_BT_NIMBLE_ENABLED is not set +# CONFIG_BT_CONTROLLER_ONLY is not set + +# +# Bluedroid Options +# +CONFIG_BT_BTC_TASK_STACK_SIZE=3072 +CONFIG_BT_BLUEDROID_PINNED_TO_CORE_0=y +# CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1 is not set +CONFIG_BT_BLUEDROID_PINNED_TO_CORE=0 +CONFIG_BT_BTU_TASK_STACK_SIZE=4096 +# CONFIG_BT_BLUEDROID_MEM_DEBUG is not set +CONFIG_BT_BLE_ENABLED=y +CONFIG_BT_GATTS_ENABLE=y +# CONFIG_BT_GATTS_PPCP_CHAR_GAP is not set +# CONFIG_BT_BLE_BLUFI_ENABLE is not set +CONFIG_BT_GATT_MAX_SR_PROFILES=8 +CONFIG_BT_GATT_MAX_SR_ATTRIBUTES=100 +# CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL is not set +CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_AUTO=y +CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MODE=0 +# CONFIG_BT_GATTS_ROBUST_CACHING_ENABLED is not set +# CONFIG_BT_GATTS_DEVICE_NAME_WRITABLE is not set +# CONFIG_BT_GATTS_APPEARANCE_WRITABLE is not set +CONFIG_BT_GATTC_ENABLE=y +CONFIG_BT_GATTC_MAX_CACHE_CHAR=40 +# CONFIG_BT_GATTC_CACHE_NVS_FLASH is not set +CONFIG_BT_GATTC_CONNECT_RETRY_COUNT=3 +CONFIG_BT_BLE_SMP_ENABLE=y +# CONFIG_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set +# CONFIG_BT_STACK_NO_LOG is not set + +# +# BT DEBUG LOG LEVEL +# +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_HCI_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_HCI_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BTM_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BTM_TRACE_LEVEL=2 +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_L2CAP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL=2 +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_SDP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_SDP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_GAP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_GAP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BNEP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BNEP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_PAN_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_PAN_TRACE_LEVEL=2 +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_A2D_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_A2D_TRACE_LEVEL=2 +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_AVDT_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_AVDT_TRACE_LEVEL=2 +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_AVCT_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_AVCT_TRACE_LEVEL=2 +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_AVRC_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_AVRC_TRACE_LEVEL=2 +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_MCA_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_MCA_TRACE_LEVEL=2 +# CONFIG_BT_LOG_HID_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_HID_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_HID_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_HID_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_HID_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_HID_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_HID_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_HID_TRACE_LEVEL=2 +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_APPL_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_APPL_TRACE_LEVEL=2 +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_GATT_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_GATT_TRACE_LEVEL=2 +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_SMP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_SMP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BTIF_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BTIF_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BTC_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BTC_TRACE_LEVEL=2 +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_OSI_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_OSI_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BLUFI_TRACE_LEVEL=2 +# end of BT DEBUG LOG LEVEL + +CONFIG_BT_ACL_CONNECTIONS=4 +CONFIG_BT_MULTI_CONNECTION_ENBALE=y +# CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST is not set +# CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY is not set +# CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set +CONFIG_BT_SMP_ENABLE=y +# CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set +CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 +CONFIG_BT_MAX_DEVICE_NAME_LEN=32 +CONFIG_BT_BLE_RPA_TIMEOUT=900 +CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y +CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y +# CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL is not set +# end of Bluedroid Options # end of Bluetooth +# CONFIG_BLE_MESH is not set + # # CoAP Configuration # @@ -336,7 +635,6 @@ CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y # CONFIG_ESP32S3_RTC_CLK_SRC_INT_8MD256 is not set CONFIG_ESP32S3_RTC_CLK_CAL_CYCLES=1024 CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY=2000 -# CONFIG_ESP32S3_NO_BLOBS is not set # CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM is not set # CONFIG_ESP32S3_USE_FIXED_STATIC_RAM_SIZE is not set # end of ESP32S3-Specific @@ -517,7 +815,7 @@ CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=6000 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=8000 CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y # CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set # CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set @@ -559,6 +857,7 @@ CONFIG_ESP_TIMER_IMPL_SYSTIMER=y # Wi-Fi # CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set @@ -1262,7 +1561,9 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_WIFI_PROV_BLE_BONDING is not set # CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set # end of Wi-Fi Provisioning Manager # @@ -1279,6 +1580,17 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # CONFIG_WPA_DPP_SUPPORT is not set # end of Supplicant +# +# CMake Utilities +# +# CONFIG_CU_RELINKER_ENABLE is not set +# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set +CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y +# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set +# CONFIG_CU_GCC_LTO_ENABLE is not set +# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set +# end of CMake Utilities + # # ESP-NOW Configuration # @@ -1345,17 +1657,6 @@ CONFIG_ESPNOW_DEBUG_CONSOLE_UART_NUM_0=y CONFIG_ESPNOW_DEBUG_CONSOLE_UART_NUM=0 # end of ESP-NOW Debug Configuration # end of ESP-NOW Configuration - -# -# CMake Utilities -# -# CONFIG_CU_RELINKER_ENABLE is not set -# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set -CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y -# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set -# CONFIG_CU_GCC_LTO_ENABLE is not set -# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set -# end of CMake Utilities # end of Component config # @@ -1405,6 +1706,187 @@ CONFIG_STACK_CHECK_NONE=y # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_BLUEDROID_ENABLED=y +# CONFIG_NIMBLE_ENABLED is not set +CONFIG_BTC_TASK_STACK_SIZE=3072 +CONFIG_BLUEDROID_PINNED_TO_CORE_0=y +# CONFIG_BLUEDROID_PINNED_TO_CORE_1 is not set +CONFIG_BLUEDROID_PINNED_TO_CORE=0 +CONFIG_BTU_TASK_STACK_SIZE=4096 +# CONFIG_BLUEDROID_MEM_DEBUG is not set +CONFIG_GATTS_ENABLE=y +# CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL is not set +CONFIG_GATTS_SEND_SERVICE_CHANGE_AUTO=y +CONFIG_GATTS_SEND_SERVICE_CHANGE_MODE=0 +CONFIG_GATTC_ENABLE=y +# CONFIG_GATTC_CACHE_NVS_FLASH is not set +CONFIG_BLE_SMP_ENABLE=y +# CONFIG_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set +# CONFIG_HCI_TRACE_LEVEL_NONE is not set +# CONFIG_HCI_TRACE_LEVEL_ERROR is not set +CONFIG_HCI_TRACE_LEVEL_WARNING=y +# CONFIG_HCI_TRACE_LEVEL_API is not set +# CONFIG_HCI_TRACE_LEVEL_EVENT is not set +# CONFIG_HCI_TRACE_LEVEL_DEBUG is not set +# CONFIG_HCI_TRACE_LEVEL_VERBOSE is not set +CONFIG_HCI_INITIAL_TRACE_LEVEL=2 +# CONFIG_BTM_TRACE_LEVEL_NONE is not set +# CONFIG_BTM_TRACE_LEVEL_ERROR is not set +CONFIG_BTM_TRACE_LEVEL_WARNING=y +# CONFIG_BTM_TRACE_LEVEL_API is not set +# CONFIG_BTM_TRACE_LEVEL_EVENT is not set +# CONFIG_BTM_TRACE_LEVEL_DEBUG is not set +# CONFIG_BTM_TRACE_LEVEL_VERBOSE is not set +CONFIG_BTM_INITIAL_TRACE_LEVEL=2 +# CONFIG_L2CAP_TRACE_LEVEL_NONE is not set +# CONFIG_L2CAP_TRACE_LEVEL_ERROR is not set +CONFIG_L2CAP_TRACE_LEVEL_WARNING=y +# CONFIG_L2CAP_TRACE_LEVEL_API is not set +# CONFIG_L2CAP_TRACE_LEVEL_EVENT is not set +# CONFIG_L2CAP_TRACE_LEVEL_DEBUG is not set +# CONFIG_L2CAP_TRACE_LEVEL_VERBOSE is not set +CONFIG_L2CAP_INITIAL_TRACE_LEVEL=2 +# CONFIG_RFCOMM_TRACE_LEVEL_NONE is not set +# CONFIG_RFCOMM_TRACE_LEVEL_ERROR is not set +CONFIG_RFCOMM_TRACE_LEVEL_WARNING=y +# CONFIG_RFCOMM_TRACE_LEVEL_API is not set +# CONFIG_RFCOMM_TRACE_LEVEL_EVENT is not set +# CONFIG_RFCOMM_TRACE_LEVEL_DEBUG is not set +# CONFIG_RFCOMM_TRACE_LEVEL_VERBOSE is not set +CONFIG_RFCOMM_INITIAL_TRACE_LEVEL=2 +# CONFIG_SDP_TRACE_LEVEL_NONE is not set +# CONFIG_SDP_TRACE_LEVEL_ERROR is not set +CONFIG_SDP_TRACE_LEVEL_WARNING=y +# CONFIG_SDP_TRACE_LEVEL_API is not set +# CONFIG_SDP_TRACE_LEVEL_EVENT is not set +# CONFIG_SDP_TRACE_LEVEL_DEBUG is not set +# CONFIG_SDP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BTH_LOG_SDP_INITIAL_TRACE_LEVEL=2 +# CONFIG_GAP_TRACE_LEVEL_NONE is not set +# CONFIG_GAP_TRACE_LEVEL_ERROR is not set +CONFIG_GAP_TRACE_LEVEL_WARNING=y +# CONFIG_GAP_TRACE_LEVEL_API is not set +# CONFIG_GAP_TRACE_LEVEL_EVENT is not set +# CONFIG_GAP_TRACE_LEVEL_DEBUG is not set +# CONFIG_GAP_TRACE_LEVEL_VERBOSE is not set +CONFIG_GAP_INITIAL_TRACE_LEVEL=2 +CONFIG_BNEP_INITIAL_TRACE_LEVEL=2 +# CONFIG_PAN_TRACE_LEVEL_NONE is not set +# CONFIG_PAN_TRACE_LEVEL_ERROR is not set +CONFIG_PAN_TRACE_LEVEL_WARNING=y +# CONFIG_PAN_TRACE_LEVEL_API is not set +# CONFIG_PAN_TRACE_LEVEL_EVENT is not set +# CONFIG_PAN_TRACE_LEVEL_DEBUG is not set +# CONFIG_PAN_TRACE_LEVEL_VERBOSE is not set +CONFIG_PAN_INITIAL_TRACE_LEVEL=2 +# CONFIG_A2D_TRACE_LEVEL_NONE is not set +# CONFIG_A2D_TRACE_LEVEL_ERROR is not set +CONFIG_A2D_TRACE_LEVEL_WARNING=y +# CONFIG_A2D_TRACE_LEVEL_API is not set +# CONFIG_A2D_TRACE_LEVEL_EVENT is not set +# CONFIG_A2D_TRACE_LEVEL_DEBUG is not set +# CONFIG_A2D_TRACE_LEVEL_VERBOSE is not set +CONFIG_A2D_INITIAL_TRACE_LEVEL=2 +# CONFIG_AVDT_TRACE_LEVEL_NONE is not set +# CONFIG_AVDT_TRACE_LEVEL_ERROR is not set +CONFIG_AVDT_TRACE_LEVEL_WARNING=y +# CONFIG_AVDT_TRACE_LEVEL_API is not set +# CONFIG_AVDT_TRACE_LEVEL_EVENT is not set +# CONFIG_AVDT_TRACE_LEVEL_DEBUG is not set +# CONFIG_AVDT_TRACE_LEVEL_VERBOSE is not set +CONFIG_AVDT_INITIAL_TRACE_LEVEL=2 +# CONFIG_AVCT_TRACE_LEVEL_NONE is not set +# CONFIG_AVCT_TRACE_LEVEL_ERROR is not set +CONFIG_AVCT_TRACE_LEVEL_WARNING=y +# CONFIG_AVCT_TRACE_LEVEL_API is not set +# CONFIG_AVCT_TRACE_LEVEL_EVENT is not set +# CONFIG_AVCT_TRACE_LEVEL_DEBUG is not set +# CONFIG_AVCT_TRACE_LEVEL_VERBOSE is not set +CONFIG_AVCT_INITIAL_TRACE_LEVEL=2 +# CONFIG_AVRC_TRACE_LEVEL_NONE is not set +# CONFIG_AVRC_TRACE_LEVEL_ERROR is not set +CONFIG_AVRC_TRACE_LEVEL_WARNING=y +# CONFIG_AVRC_TRACE_LEVEL_API is not set +# CONFIG_AVRC_TRACE_LEVEL_EVENT is not set +# CONFIG_AVRC_TRACE_LEVEL_DEBUG is not set +# CONFIG_AVRC_TRACE_LEVEL_VERBOSE is not set +CONFIG_AVRC_INITIAL_TRACE_LEVEL=2 +# CONFIG_MCA_TRACE_LEVEL_NONE is not set +# CONFIG_MCA_TRACE_LEVEL_ERROR is not set +CONFIG_MCA_TRACE_LEVEL_WARNING=y +# CONFIG_MCA_TRACE_LEVEL_API is not set +# CONFIG_MCA_TRACE_LEVEL_EVENT is not set +# CONFIG_MCA_TRACE_LEVEL_DEBUG is not set +# CONFIG_MCA_TRACE_LEVEL_VERBOSE is not set +CONFIG_MCA_INITIAL_TRACE_LEVEL=2 +# CONFIG_HID_TRACE_LEVEL_NONE is not set +# CONFIG_HID_TRACE_LEVEL_ERROR is not set +CONFIG_HID_TRACE_LEVEL_WARNING=y +# CONFIG_HID_TRACE_LEVEL_API is not set +# CONFIG_HID_TRACE_LEVEL_EVENT is not set +# CONFIG_HID_TRACE_LEVEL_DEBUG is not set +# CONFIG_HID_TRACE_LEVEL_VERBOSE is not set +CONFIG_HID_INITIAL_TRACE_LEVEL=2 +# CONFIG_APPL_TRACE_LEVEL_NONE is not set +# CONFIG_APPL_TRACE_LEVEL_ERROR is not set +CONFIG_APPL_TRACE_LEVEL_WARNING=y +# CONFIG_APPL_TRACE_LEVEL_API is not set +# CONFIG_APPL_TRACE_LEVEL_EVENT is not set +# CONFIG_APPL_TRACE_LEVEL_DEBUG is not set +# CONFIG_APPL_TRACE_LEVEL_VERBOSE is not set +CONFIG_APPL_INITIAL_TRACE_LEVEL=2 +# CONFIG_GATT_TRACE_LEVEL_NONE is not set +# CONFIG_GATT_TRACE_LEVEL_ERROR is not set +CONFIG_GATT_TRACE_LEVEL_WARNING=y +# CONFIG_GATT_TRACE_LEVEL_API is not set +# CONFIG_GATT_TRACE_LEVEL_EVENT is not set +# CONFIG_GATT_TRACE_LEVEL_DEBUG is not set +# CONFIG_GATT_TRACE_LEVEL_VERBOSE is not set +CONFIG_GATT_INITIAL_TRACE_LEVEL=2 +# CONFIG_SMP_TRACE_LEVEL_NONE is not set +# CONFIG_SMP_TRACE_LEVEL_ERROR is not set +CONFIG_SMP_TRACE_LEVEL_WARNING=y +# CONFIG_SMP_TRACE_LEVEL_API is not set +# CONFIG_SMP_TRACE_LEVEL_EVENT is not set +# CONFIG_SMP_TRACE_LEVEL_DEBUG is not set +# CONFIG_SMP_TRACE_LEVEL_VERBOSE is not set +CONFIG_SMP_INITIAL_TRACE_LEVEL=2 +# CONFIG_BTIF_TRACE_LEVEL_NONE is not set +# CONFIG_BTIF_TRACE_LEVEL_ERROR is not set +CONFIG_BTIF_TRACE_LEVEL_WARNING=y +# CONFIG_BTIF_TRACE_LEVEL_API is not set +# CONFIG_BTIF_TRACE_LEVEL_EVENT is not set +# CONFIG_BTIF_TRACE_LEVEL_DEBUG is not set +# CONFIG_BTIF_TRACE_LEVEL_VERBOSE is not set +CONFIG_BTIF_INITIAL_TRACE_LEVEL=2 +# CONFIG_BTC_TRACE_LEVEL_NONE is not set +# CONFIG_BTC_TRACE_LEVEL_ERROR is not set +CONFIG_BTC_TRACE_LEVEL_WARNING=y +# CONFIG_BTC_TRACE_LEVEL_API is not set +# CONFIG_BTC_TRACE_LEVEL_EVENT is not set +# CONFIG_BTC_TRACE_LEVEL_DEBUG is not set +# CONFIG_BTC_TRACE_LEVEL_VERBOSE is not set +CONFIG_BTC_INITIAL_TRACE_LEVEL=2 +# CONFIG_OSI_TRACE_LEVEL_NONE is not set +# CONFIG_OSI_TRACE_LEVEL_ERROR is not set +CONFIG_OSI_TRACE_LEVEL_WARNING=y +# CONFIG_OSI_TRACE_LEVEL_API is not set +# CONFIG_OSI_TRACE_LEVEL_EVENT is not set +# CONFIG_OSI_TRACE_LEVEL_DEBUG is not set +# CONFIG_OSI_TRACE_LEVEL_VERBOSE is not set +CONFIG_OSI_INITIAL_TRACE_LEVEL=2 +# CONFIG_BLUFI_TRACE_LEVEL_NONE is not set +# CONFIG_BLUFI_TRACE_LEVEL_ERROR is not set +CONFIG_BLUFI_TRACE_LEVEL_WARNING=y +# CONFIG_BLUFI_TRACE_LEVEL_API is not set +# CONFIG_BLUFI_TRACE_LEVEL_EVENT is not set +# CONFIG_BLUFI_TRACE_LEVEL_DEBUG is not set +# CONFIG_BLUFI_TRACE_LEVEL_VERBOSE is not set +CONFIG_BLUFI_INITIAL_TRACE_LEVEL=2 +# CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK is not set +CONFIG_SMP_ENABLE=y +# CONFIG_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY is not set +CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT=30 CONFIG_ADC2_DISABLE_DAC=y # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y @@ -1425,7 +1907,7 @@ CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_MAIN_TASK_STACK_SIZE=6000 +CONFIG_MAIN_TASK_STACK_SIZE=8000 CONFIG_CONSOLE_UART_DEFAULT=y # CONFIG_CONSOLE_UART_CUSTOM is not set # CONFIG_ESP_CONSOLE_UART_NONE is not set @@ -1438,6 +1920,7 @@ CONFIG_INT_WDT_CHECK_CPU1=y # CONFIG_TASK_WDT is not set # CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_SW_COEXIST_ENABLE=y # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y diff --git a/sdkconfig.old b/sdkconfig.old index 787c187..0f1099c 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -156,7 +156,8 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set CONFIG_COMPILER_HIDE_PATHS_MACROS=y -# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +CONFIG_COMPILER_CXX_EXCEPTIONS=y +CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0 # CONFIG_COMPILER_CXX_RTTI is not set CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set @@ -188,9 +189,308 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # # Bluetooth # -# CONFIG_BT_ENABLED is not set +CONFIG_BT_ENABLED=y +CONFIG_BT_SOC_SUPPORT_5_0=y + +# +# Bluetooth controller +# +CONFIG_BT_CTRL_MODE_EFF=1 +CONFIG_BT_CTRL_BLE_MAX_ACT=6 +CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=6 +CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0 +CONFIG_BT_CTRL_PINNED_TO_CORE_0=y +# CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set +CONFIG_BT_CTRL_PINNED_TO_CORE=0 +CONFIG_BT_CTRL_HCI_MODE_VHCI=y +# CONFIG_BT_CTRL_HCI_MODE_UART_H4 is not set +CONFIG_BT_CTRL_HCI_TL=1 +CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30 +CONFIG_BT_BLE_CCA_MODE_NONE=y +# CONFIG_BT_BLE_CCA_MODE_HW is not set +# CONFIG_BT_BLE_CCA_MODE_SW is not set +CONFIG_BT_BLE_CCA_MODE=0 +CONFIG_BT_CTRL_HW_CCA_VAL=20 +CONFIG_BT_CTRL_HW_CCA_EFF=0 +CONFIG_BT_CTRL_CE_LENGTH_TYPE_ORIG=y +# CONFIG_BT_CTRL_CE_LENGTH_TYPE_CE is not set +# CONFIG_BT_CTRL_CE_LENGTH_TYPE_SD is not set +CONFIG_BT_CTRL_CE_LENGTH_TYPE_EFF=0 +CONFIG_BT_CTRL_TX_ANTENNA_INDEX_0=y +# CONFIG_BT_CTRL_TX_ANTENNA_INDEX_1 is not set +CONFIG_BT_CTRL_TX_ANTENNA_INDEX_EFF=0 +CONFIG_BT_CTRL_RX_ANTENNA_INDEX_0=y +# CONFIG_BT_CTRL_RX_ANTENNA_INDEX_1 is not set +CONFIG_BT_CTRL_RX_ANTENNA_INDEX_EFF=0 +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N24 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N21 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N18 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N15 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N12 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N9 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N6 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N3 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N0 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P3 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P6 is not set +CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P9=y +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P12 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P15 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P18 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P21 is not set +CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=11 +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_BT_CTRL_BLE_SCAN_DUPL=y +CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DEVICE=y +# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA is not set +# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE is not set +CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0 +CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BT_CTRL_DUPL_SCAN_CACHE_REFRESH_PERIOD=0 +# CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN is not set +# CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EN is not set +CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS=y +CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF=0 + +# +# MODEM SLEEP Options +# +# CONFIG_BT_CTRL_MODEM_SLEEP is not set +# end of MODEM SLEEP Options + +CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 +CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 +CONFIG_BT_CTRL_HCI_TL_EFF=1 +# CONFIG_BT_CTRL_AGC_RECORRECT_EN is not set +# CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# end of Bluetooth controller + +CONFIG_BT_BLUEDROID_ENABLED=y +# CONFIG_BT_NIMBLE_ENABLED is not set +# CONFIG_BT_CONTROLLER_ONLY is not set + +# +# Bluedroid Options +# +CONFIG_BT_BTC_TASK_STACK_SIZE=3072 +CONFIG_BT_BLUEDROID_PINNED_TO_CORE_0=y +# CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1 is not set +CONFIG_BT_BLUEDROID_PINNED_TO_CORE=0 +CONFIG_BT_BTU_TASK_STACK_SIZE=4096 +# CONFIG_BT_BLUEDROID_MEM_DEBUG is not set +CONFIG_BT_BLE_ENABLED=y +CONFIG_BT_GATTS_ENABLE=y +# CONFIG_BT_GATTS_PPCP_CHAR_GAP is not set +# CONFIG_BT_BLE_BLUFI_ENABLE is not set +CONFIG_BT_GATT_MAX_SR_PROFILES=8 +CONFIG_BT_GATT_MAX_SR_ATTRIBUTES=100 +# CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL is not set +CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_AUTO=y +CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MODE=0 +# CONFIG_BT_GATTS_ROBUST_CACHING_ENABLED is not set +# CONFIG_BT_GATTS_DEVICE_NAME_WRITABLE is not set +# CONFIG_BT_GATTS_APPEARANCE_WRITABLE is not set +CONFIG_BT_GATTC_ENABLE=y +CONFIG_BT_GATTC_MAX_CACHE_CHAR=40 +# CONFIG_BT_GATTC_CACHE_NVS_FLASH is not set +CONFIG_BT_GATTC_CONNECT_RETRY_COUNT=3 +CONFIG_BT_BLE_SMP_ENABLE=y +# CONFIG_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set +# CONFIG_BT_STACK_NO_LOG is not set + +# +# BT DEBUG LOG LEVEL +# +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_HCI_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_HCI_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BTM_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BTM_TRACE_LEVEL=2 +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_L2CAP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL=2 +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_SDP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_SDP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_GAP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_GAP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BNEP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BNEP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_PAN_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_PAN_TRACE_LEVEL=2 +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_A2D_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_A2D_TRACE_LEVEL=2 +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_AVDT_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_AVDT_TRACE_LEVEL=2 +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_AVCT_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_AVCT_TRACE_LEVEL=2 +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_AVRC_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_AVRC_TRACE_LEVEL=2 +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_MCA_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_MCA_TRACE_LEVEL=2 +# CONFIG_BT_LOG_HID_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_HID_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_HID_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_HID_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_HID_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_HID_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_HID_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_HID_TRACE_LEVEL=2 +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_APPL_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_APPL_TRACE_LEVEL=2 +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_GATT_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_GATT_TRACE_LEVEL=2 +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_SMP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_SMP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BTIF_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BTIF_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BTC_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BTC_TRACE_LEVEL=2 +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_OSI_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_OSI_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BLUFI_TRACE_LEVEL=2 +# end of BT DEBUG LOG LEVEL + +CONFIG_BT_ACL_CONNECTIONS=4 +CONFIG_BT_MULTI_CONNECTION_ENBALE=y +# CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST is not set +# CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY is not set +# CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set +CONFIG_BT_SMP_ENABLE=y +# CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set +CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 +CONFIG_BT_MAX_DEVICE_NAME_LEN=32 +CONFIG_BT_BLE_RPA_TIMEOUT=900 +CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y +CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y +# CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL is not set +# end of Bluedroid Options # end of Bluetooth +# CONFIG_BLE_MESH is not set + # # CoAP Configuration # @@ -335,7 +635,6 @@ CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y # CONFIG_ESP32S3_RTC_CLK_SRC_INT_8MD256 is not set CONFIG_ESP32S3_RTC_CLK_CAL_CYCLES=1024 CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY=2000 -# CONFIG_ESP32S3_NO_BLOBS is not set # CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM is not set # CONFIG_ESP32S3_USE_FIXED_STATIC_RAM_SIZE is not set # end of ESP32S3-Specific @@ -515,8 +814,8 @@ CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y # end of Memory protection CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=6000 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4000 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=4000 CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y # CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set # CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set @@ -558,6 +857,7 @@ CONFIG_ESP_TIMER_IMPL_SYSTIMER=y # Wi-Fi # CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set @@ -1261,7 +1561,9 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_WIFI_PROV_BLE_BONDING is not set # CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set # end of Wi-Fi Provisioning Manager # From 8ea2efe8eca6d7702fb55f8a8421c41fe628e757 Mon Sep 17 00:00:00 2001 From: Forairaaaaa Date: Fri, 8 Dec 2023 16:37:34 +0800 Subject: [PATCH 04/10] adding ble keyboard, add silence reboot, fix (maybe) stack overflow crush(menuconfig doesn't work) --- main/apps/app_keyboard/app_keyboard.cpp | 129 +++++++++-- main/apps/app_keyboard/app_keyboard.h | 5 + .../launcher/views/boot_anim/boot_anim.cpp | 4 + .../ble_keyboard_wrap/ble_keyboard_wrap.cpp | 216 +++++++++++------- .../ble_keyboard_wrap/ble_keyboard_wrap.h | 11 + main/cardputer.cpp | 3 +- sdkconfig | 28 +-- sdkconfig.old | 28 +-- 8 files changed, 297 insertions(+), 127 deletions(-) diff --git a/main/apps/app_keyboard/app_keyboard.cpp b/main/apps/app_keyboard/app_keyboard.cpp index b57483d..ba2727a 100644 --- a/main/apps/app_keyboard/app_keyboard.cpp +++ b/main/apps/app_keyboard/app_keyboard.cpp @@ -31,23 +31,19 @@ void AppKeyboard::onResume() { ANIM_APP_OPEN(); + { + _data.hal->canvas()->fillScreen(THEME_COLOR_BG); + _data.hal->canvas()->setFont(FONT_REPL); + _data.hal->canvas()->setTextColor(TFT_ORANGE, THEME_COLOR_BG); + _data.hal->canvas()->setTextSize(1); + _data.hal->canvas_update(); - _data.hal->canvas()->fillScreen(THEME_COLOR_BG); - _data.hal->canvas()->setFont(FONT_REPL); - _data.hal->canvas()->setTextColor(TFT_ORANGE, THEME_COLOR_BG); - _data.hal->canvas()->setTextSize(1); - _data.hal->canvas_update(); + // Start ble keyboard + spdlog::info("remain before: {}", uxTaskGetStackHighWaterMark(NULL)); + } - // Start ble keyboard ble_keyboard_wrap_init(_data.hal->keyboard()); - - - // _data.hal->canvas()->deleteSprite(); - // while (1) - // { - // delay(1000); - // } } @@ -59,4 +55,111 @@ void AppKeyboard::onRunning() spdlog::info("quit app {}", getAppName()); destroyApp(); } + + _update_infos(); + _update_kb_input(); +} + + +void AppKeyboard::onDestroy() +{ + spdlog::info("{} onDestroy", getAppName()); + // ble_keyboard_wrap_deinit(); + + delay(200); + esp_restart(); + delay(10000); +} + + +void AppKeyboard::_update_infos() +{ + if (millis() - _data.update_infos_time_count > 500) + { + // spdlog::info("remain: {}", uxTaskGetStackHighWaterMark(NULL)); + + _data.hal->canvas()->fillScreen(THEME_COLOR_BG); + + _data.hal->canvas()->setCursor(0, 0); + _data.hal->canvas()->setTextColor(TFT_ORANGE, THEME_COLOR_BG); + _data.hal->canvas()->printf("[BLE Keyboard]\n"); + _data.hal->canvas()->printf("> Name: %s\n", ble_keyboard_wrap_get_device_name()); + + // State + _data.hal->canvas()->printf("> State: "); + _data.hal->canvas()->setTextColor( + ble_keyboard_wrap_get_current_state() == ble_kb_wrap_state_connected ? TFT_GREENYELLOW : TFT_ORANGE, + THEME_COLOR_BG + ); + _data.hal->canvas()->printf( + "%s\n", + ble_keyboard_wrap_get_current_state() == ble_kb_wrap_state_connected ? "Connected" : "Wait connect.." + ); + + _data.hal->canvas_update(); + _data.update_infos_time_count = millis(); + } +} + + +static uint8_t _input_buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + +void AppKeyboard::_update_kb_input() +{ + // spdlog::info("remain: {}", uxTaskGetStackHighWaterMark(NULL)); + + if (ble_keyboard_wrap_get_current_state() != ble_kb_wrap_state_connected) + return; + + if (millis() - _data.update_kb_time_count > 10) + { + if (_data.hal->keyboard()->isChanged()) + { + uint8_t modifier = 0; + if (_data.hal->keyboard()->isPressed()) + { + memset(_input_buffer, 0, 8); + auto status = _data.hal->keyboard()->keysState(); + + int count = 0; + for (auto i : status.hidKey) + { + if (count < 6) + { + _input_buffer[2 + count] = i; + count++; + } + } + + if (status.ctrl) + { + // ESP_LOGI(TAG, "CONTROL"); + modifier |= 0x01; + } + + if (status.shift) { + // ESP_LOGI(TAG, "SHIFT"); + modifier |= 0x02; + } + + if (status.alt) + { + // ESP_LOGI(TAG, "ALT"); + modifier |= 0x03; + } + + _input_buffer[0] = modifier; + + // ESP_LOG_BUFFER_HEX(TAG, buffer, 8); + ble_keyboard_wrap_update_input(_input_buffer); + } + else + { + memset(_input_buffer, 0, 8); + ble_keyboard_wrap_update_input(_input_buffer); + } + } + + _data.update_kb_time_count = millis(); + } } diff --git a/main/apps/app_keyboard/app_keyboard.h b/main/apps/app_keyboard/app_keyboard.h index ae286df..1737d78 100644 --- a/main/apps/app_keyboard/app_keyboard.h +++ b/main/apps/app_keyboard/app_keyboard.h @@ -29,13 +29,18 @@ namespace MOONCAKE struct Data_t { HAL::Hal* hal = nullptr; + uint32_t update_infos_time_count = 0; + uint32_t update_kb_time_count = 0; }; Data_t _data; + void _update_infos(); + void _update_kb_input(); public: void onCreate() override; void onResume() override; void onRunning() override; + void onDestroy() override; }; class AppKeyboard_Packer : public APP_PACKER_BASE diff --git a/main/apps/launcher/views/boot_anim/boot_anim.cpp b/main/apps/launcher/views/boot_anim/boot_anim.cpp index fd41622..7ff7775 100644 --- a/main/apps/launcher/views/boot_anim/boot_anim.cpp +++ b/main/apps/launcher/views/boot_anim/boot_anim.cpp @@ -19,6 +19,10 @@ void Launcher::_boot_anim() { spdlog::info("start boot anim"); + // If software restart + if (esp_reset_reason() != ESP_RST_POWERON) + return; + // Show logo _data.hal->display()->pushImage(0, 0, 240, 135, image_data_logo); _port_wait_enter(); diff --git a/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.cpp b/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.cpp index 00773bb..8be7ec7 100644 --- a/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.cpp +++ b/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.cpp @@ -46,7 +46,8 @@ // Keyboard_Class Keyboard = Keyboard_Class(); #include "ble_keyboard_wrap.h" -KEYBOARD::Keyboard* _keyboard = nullptr; +static KEYBOARD::Keyboard* _keyboard = nullptr; +static BleKbWrapState_t _keyboard_current_state = ble_kb_wrap_state_wait_connect; static const char *TAG = "HID_DEV_DEMO"; @@ -132,70 +133,85 @@ void esp_hidd_send_consumer_value(uint8_t key_cmd, bool key_pressed) { return; } -void ble_hid_demo_task(void *pvParameters) { - static bool send_volum_up = false; - ESP_LOGI(TAG, "ble_hid_demo_task start"); - - // uint8_t buffer1[8] = {0, 0, 0x17, 0, 0, 0, 0, 0}; - uint8_t buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - while (1) { - _keyboard->updateKeyList(); - _keyboard->updateKeysState(); - if (_keyboard->isChanged()) { - uint8_t modifier = 0; - if (_keyboard->isPressed()) { - memset(buffer, 0, 8); - auto status = _keyboard->keysState(); - - int count = 0; - for (auto i : status.hidKey) { - if (count < 6) { - buffer[2 + count] = i; - count++; - } - } - - if (status.ctrl) { - ESP_LOGI(TAG, "CONTROL"); - modifier |= 0x01; - } - - if (status.shift) { - ESP_LOGI(TAG, "SHIFT"); - modifier |= 0x02; - } - - if (status.alt) { - ESP_LOGI(TAG, "ALT"); - modifier |= 0x03; - } - - buffer[0] = modifier; - - ESP_LOG_BUFFER_HEX(TAG, buffer, 8); - - esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 0, 1, buffer, - 8); - } else { - memset(buffer, 0, 8); - esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 0, 1, buffer, - 8); - } - } - vTaskDelay(50 / portTICK_PERIOD_MS); - } -} +// void ble_hid_demo_task(void *pvParameters) { +// // static bool send_volum_up = false; +// ESP_LOGI(TAG, "ble_hid_demo_task start"); + +// // uint8_t buffer1[8] = {0, 0, 0x17, 0, 0, 0, 0, 0}; +// uint8_t buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +// while (1) { +// // _keyboard->updateKeyList(); +// // _keyboard->updateKeysState(); +// if (_keyboard->isChanged()) { +// uint8_t modifier = 0; +// if (_keyboard->isPressed()) { +// memset(buffer, 0, 8); +// auto status = _keyboard->keysState(); + +// int count = 0; +// for (auto i : status.hidKey) { +// if (count < 6) { +// buffer[2 + count] = i; +// count++; +// } +// } + +// if (status.ctrl) { +// ESP_LOGI(TAG, "CONTROL"); +// modifier |= 0x01; +// } + +// if (status.shift) { +// ESP_LOGI(TAG, "SHIFT"); +// modifier |= 0x02; +// } + +// if (status.alt) { +// ESP_LOGI(TAG, "ALT"); +// modifier |= 0x03; +// } + +// buffer[0] = modifier; + +// ESP_LOG_BUFFER_HEX(TAG, buffer, 8); + +// esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 0, 1, buffer, +// 8); +// } else { +// memset(buffer, 0, 8); +// esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 0, 1, buffer, +// 8); +// } +// } +// vTaskDelay(50 / portTICK_PERIOD_MS); +// } +// } + + +// static StaticTask_t _xTaskBuffer; +// static StackType_t* _ble_hid_update_task_stack = nullptr; void ble_hid_task_start_up(void) { - xTaskCreate(ble_hid_demo_task, "ble_hid_demo_task", 10 * 1024, NULL, - configMAX_PRIORITIES - 3, &s_ble_hid_param.task_hdl); + // xTaskCreate(ble_hid_demo_task, "ble_hid_update", 2000, NULL, + // configMAX_PRIORITIES - 3, &s_ble_hid_param.task_hdl); + + // // Dynamic + // _ble_hid_update_task_stack = new StackType_t[4000]; + // s_ble_hid_param.task_hdl = xTaskCreateStatic(ble_hid_demo_task, "ble_hid_update", 4000, NULL, + // configMAX_PRIORITIES - 3, _ble_hid_update_task_stack, &_xTaskBuffer); + + _keyboard_current_state = ble_kb_wrap_state_connected; } void ble_hid_task_shut_down(void) { - if (s_ble_hid_param.task_hdl) { - vTaskDelete(s_ble_hid_param.task_hdl); - s_ble_hid_param.task_hdl = NULL; - } + // if (s_ble_hid_param.task_hdl) { + // vTaskDelete(s_ble_hid_param.task_hdl); + // s_ble_hid_param.task_hdl = NULL; + + // // delete[] _ble_hid_update_task_stack; + // } + + _keyboard_current_state = ble_kb_wrap_state_wait_connect; } static void ble_hidd_event_callback(void *handler_args, esp_event_base_t base, @@ -204,16 +220,20 @@ static void ble_hidd_event_callback(void *handler_args, esp_event_base_t base, esp_hidd_event_data_t *param = (esp_hidd_event_data_t *)event_data; static const char *TAG = "HID_DEV_BLE"; + // printf("stack remain: %d\n", (unsigned int)uxTaskGetStackHighWaterMark(NULL)); + switch (event) { case ESP_HIDD_START_EVENT: { - ESP_LOGI(TAG, "START"); + // ESP_LOGI(TAG, "START"); esp_hid_ble_gap_adv_start(); break; } case ESP_HIDD_CONNECT_EVENT: { - ESP_LOGI(TAG, "CONNECT"); - ble_hid_task_start_up(); // todo: this should be on auth_complete - // (in GAP) + // ESP_LOGI(TAG, "CONNECT"); + // ble_hid_task_start_up(); // todo: this should be on auth_complete + // // (in GAP) + _keyboard_current_state = ble_kb_wrap_state_connected; + // M5.Display.clear(); // M5.Display.fillRect(10, M5.Display.height() / 2 - 15, // M5.Display.width() - 20, 30, GREEN); @@ -224,39 +244,41 @@ static void ble_hidd_event_callback(void *handler_args, esp_event_base_t base, break; } case ESP_HIDD_PROTOCOL_MODE_EVENT: { - ESP_LOGI(TAG, "PROTOCOL MODE[%u]: %s", - param->protocol_mode.map_index, - param->protocol_mode.protocol_mode ? "REPORT" : "BOOT"); + // ESP_LOGI(TAG, "PROTOCOL MODE[%u]: %s", + // param->protocol_mode.map_index, + // param->protocol_mode.protocol_mode ? "REPORT" : "BOOT"); break; } case ESP_HIDD_CONTROL_EVENT: { - ESP_LOGI(TAG, "CONTROL[%u]: %sSUSPEND", param->control.map_index, - param->control.control ? "EXIT_" : ""); + // ESP_LOGI(TAG, "CONTROL[%u]: %sSUSPEND", param->control.map_index, + // param->control.control ? "EXIT_" : ""); break; } case ESP_HIDD_OUTPUT_EVENT: { - ESP_LOGI(TAG, "OUTPUT[%u]: %8s ID: %2u, Len: %d, Data:", - param->output.map_index, - esp_hid_usage_str(param->output.usage), - param->output.report_id, param->output.length); - ESP_LOG_BUFFER_HEX(TAG, param->output.data, param->output.length); + // ESP_LOGI(TAG, "OUTPUT[%u]: %8s ID: %2u, Len: %d, Data:", + // param->output.map_index, + // esp_hid_usage_str(param->output.usage), + // param->output.report_id, param->output.length); + // ESP_LOG_BUFFER_HEX(TAG, param->output.data, param->output.length); break; } case ESP_HIDD_FEATURE_EVENT: { - ESP_LOGI(TAG, "FEATURE[%u]: %8s ID: %2u, Len: %d, Data:", - param->feature.map_index, - esp_hid_usage_str(param->feature.usage), - param->feature.report_id, param->feature.length); - ESP_LOG_BUFFER_HEX(TAG, param->feature.data, param->feature.length); + // ESP_LOGI(TAG, "FEATURE[%u]: %8s ID: %2u, Len: %d, Data:", + // param->feature.map_index, + // esp_hid_usage_str(param->feature.usage), + // param->feature.report_id, param->feature.length); + // ESP_LOG_BUFFER_HEX(TAG, param->feature.data, param->feature.length); break; } case ESP_HIDD_DISCONNECT_EVENT: { - ESP_LOGI(TAG, "DISCONNECT: %s", - esp_hid_disconnect_reason_str( - esp_hidd_dev_transport_get(param->disconnect.dev), - param->disconnect.reason)); - ble_hid_task_shut_down(); + // ESP_LOGI(TAG, "DISCONNECT: %s", + // esp_hid_disconnect_reason_str( + // esp_hidd_dev_transport_get(param->disconnect.dev), + // param->disconnect.reason)); + // ble_hid_task_shut_down(); esp_hid_ble_gap_adv_start(); + _keyboard_current_state = ble_kb_wrap_state_wait_connect; + // M5.Display.clear(); // M5.Display.fillRect(10, M5.Display.height() / 2 - 15, @@ -268,7 +290,7 @@ static void ble_hidd_event_callback(void *handler_args, esp_event_base_t base, break; } case ESP_HIDD_STOP_EVENT: { - ESP_LOGI(TAG, "STOP"); + // ESP_LOGI(TAG, "STOP"); break; } default: @@ -334,3 +356,27 @@ void ble_keyboard_wrap_init(KEYBOARD::Keyboard* keyboard) { ble_hidd_event_callback, &s_ble_hid_param.hid_dev)); } + + +void ble_keyboard_wrap_deinit() +{ + esp_hidd_dev_deinit(s_ble_hid_param.hid_dev); +} + + +void ble_keyboard_wrap_update_input(uint8_t* input) +{ + esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 0, 1, input, 8); +} + + +BleKbWrapState_t ble_keyboard_wrap_get_current_state() +{ + return _keyboard_current_state; +} + + +const char* ble_keyboard_wrap_get_device_name() +{ + return ble_hid_config.device_name; +} diff --git a/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.h b/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.h index f340b6d..55c5782 100644 --- a/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.h +++ b/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.h @@ -12,4 +12,15 @@ #include "../../../hal/keyboard/keyboard.h" +enum BleKbWrapState_t +{ + ble_kb_wrap_state_wait_connect = 0, + ble_kb_wrap_state_connected, +}; + + void ble_keyboard_wrap_init(KEYBOARD::Keyboard* keyboard); +void ble_keyboard_wrap_deinit(); +void ble_keyboard_wrap_update_input(uint8_t* input); +BleKbWrapState_t ble_keyboard_wrap_get_current_state(); +const char* ble_keyboard_wrap_get_device_name(); diff --git a/main/cardputer.cpp b/main/cardputer.cpp index 8c7de71..a7b0464 100644 --- a/main/cardputer.cpp +++ b/main/cardputer.cpp @@ -32,7 +32,7 @@ void _data_base_setup_callback(SIMPLEKV::SimpleKV& db) // #define ON_HAL_TEST // #define ON_APP_TEST 1 -#define ON_APP_TEST_WITH_LAUNCHER 1 +// #define ON_APP_TEST_WITH_LAUNCHER 1 extern "C" void app_main(void) { // Init hal @@ -116,6 +116,7 @@ extern "C" void app_main(void) mooncake.installApp(new APPS::AppREPL_Packer); mooncake.installApp(new APPS::AppSetWiFi_Packer); mooncake.installApp(new APPS::AppTimer_Packer); + mooncake.installApp(new APPS::AppKeyboard_Packer); // Create launcher mooncake.createApp(launcher); diff --git a/sdkconfig b/sdkconfig index 0ee0c7d..b305f6f 100644 --- a/sdkconfig +++ b/sdkconfig @@ -476,7 +476,7 @@ CONFIG_BT_LOG_BLUFI_TRACE_LEVEL=2 CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_MULTI_CONNECTION_ENBALE=y # CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST is not set -# CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY is not set +CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=y # CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set CONFIG_BT_SMP_ENABLE=y # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set @@ -815,7 +815,7 @@ CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=8000 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=9000 CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y # CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set # CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set @@ -1580,17 +1580,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # CONFIG_WPA_DPP_SUPPORT is not set # end of Supplicant -# -# CMake Utilities -# -# CONFIG_CU_RELINKER_ENABLE is not set -# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set -CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y -# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set -# CONFIG_CU_GCC_LTO_ENABLE is not set -# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set -# end of CMake Utilities - # # ESP-NOW Configuration # @@ -1657,6 +1646,17 @@ CONFIG_ESPNOW_DEBUG_CONSOLE_UART_NUM_0=y CONFIG_ESPNOW_DEBUG_CONSOLE_UART_NUM=0 # end of ESP-NOW Debug Configuration # end of ESP-NOW Configuration + +# +# CMake Utilities +# +# CONFIG_CU_RELINKER_ENABLE is not set +# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set +CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y +# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set +# CONFIG_CU_GCC_LTO_ENABLE is not set +# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set +# end of CMake Utilities # end of Component config # @@ -1907,7 +1907,7 @@ CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_MAIN_TASK_STACK_SIZE=8000 +CONFIG_MAIN_TASK_STACK_SIZE=9000 CONFIG_CONSOLE_UART_DEFAULT=y # CONFIG_CONSOLE_UART_CUSTOM is not set # CONFIG_ESP_CONSOLE_UART_NONE is not set diff --git a/sdkconfig.old b/sdkconfig.old index 0f1099c..4475c73 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -476,7 +476,7 @@ CONFIG_BT_LOG_BLUFI_TRACE_LEVEL=2 CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_MULTI_CONNECTION_ENBALE=y # CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST is not set -# CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY is not set +CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=y # CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set CONFIG_BT_SMP_ENABLE=y # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set @@ -814,8 +814,8 @@ CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y # end of Memory protection CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4000 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=4000 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=9000 CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y # CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set # CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set @@ -1580,17 +1580,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # CONFIG_WPA_DPP_SUPPORT is not set # end of Supplicant -# -# CMake Utilities -# -# CONFIG_CU_RELINKER_ENABLE is not set -# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set -CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y -# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set -# CONFIG_CU_GCC_LTO_ENABLE is not set -# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set -# end of CMake Utilities - # # ESP-NOW Configuration # @@ -1657,6 +1646,17 @@ CONFIG_ESPNOW_DEBUG_CONSOLE_UART_NUM_0=y CONFIG_ESPNOW_DEBUG_CONSOLE_UART_NUM=0 # end of ESP-NOW Debug Configuration # end of ESP-NOW Configuration + +# +# CMake Utilities +# +# CONFIG_CU_RELINKER_ENABLE is not set +# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set +CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y +# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set +# CONFIG_CU_GCC_LTO_ENABLE is not set +# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set +# end of CMake Utilities # end of Component config # From 7963d811026f89e0240d9a1e3b69c6033a88924b Mon Sep 17 00:00:00 2001 From: Forairaaaaa Date: Fri, 8 Dec 2023 16:53:12 +0800 Subject: [PATCH 05/10] fix keys: del, enter, backspace, space --- main/apps/app_keyboard/app_keyboard.cpp | 2 ++ main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.h | 3 ++- main/hal/keyboard/keyboard.cpp | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/main/apps/app_keyboard/app_keyboard.cpp b/main/apps/app_keyboard/app_keyboard.cpp index ba2727a..98db3b9 100644 --- a/main/apps/app_keyboard/app_keyboard.cpp +++ b/main/apps/app_keyboard/app_keyboard.cpp @@ -121,6 +121,8 @@ void AppKeyboard::_update_kb_input() memset(_input_buffer, 0, 8); auto status = _data.hal->keyboard()->keysState(); + + int count = 0; for (auto i : status.hidKey) { diff --git a/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.h b/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.h index 55c5782..6c20f8f 100644 --- a/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.h +++ b/main/apps/utils/ble_keyboard_wrap/ble_keyboard_wrap.h @@ -18,7 +18,8 @@ enum BleKbWrapState_t ble_kb_wrap_state_connected, }; - +// Stack overflow crush can not fix, menuconfig not working +// https://github.com/espressif/esp-idf/issues/9720 void ble_keyboard_wrap_init(KEYBOARD::Keyboard* keyboard); void ble_keyboard_wrap_deinit(); void ble_keyboard_wrap_update_input(uint8_t* input); diff --git a/main/hal/keyboard/keyboard.cpp b/main/hal/keyboard/keyboard.cpp index 2914082..505b599 100644 --- a/main/hal/keyboard/keyboard.cpp +++ b/main/hal/keyboard/keyboard.cpp @@ -257,18 +257,21 @@ void Keyboard::updateKeysState() if (strcmp(getKeyValue(i).value_first, "del") == 0) { _keys_state_buffer.del = true; + _keys_state_buffer.hidKey.push_back(KEY_BACKSPACE); continue; } if (strcmp(getKeyValue(i).value_first, "enter") == 0) { _keys_state_buffer.enter = true; + _keys_state_buffer.hidKey.push_back(KEY_ENTER); continue; } if (strcmp(getKeyValue(i).value_first, "space") == 0) { _keys_state_buffer.space = true; + _keys_state_buffer.hidKey.push_back(KEY_SPACE); continue; } From 81d064600a740c4d58a7fb08ddf40349534dc8dc Mon Sep 17 00:00:00 2001 From: Forairaaaaa Date: Fri, 8 Dec 2023 17:53:46 +0800 Subject: [PATCH 06/10] fix cap lock --- main/apps/app_keyboard/app_keyboard.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/main/apps/app_keyboard/app_keyboard.cpp b/main/apps/app_keyboard/app_keyboard.cpp index 98db3b9..86fb9c7 100644 --- a/main/apps/app_keyboard/app_keyboard.cpp +++ b/main/apps/app_keyboard/app_keyboard.cpp @@ -121,10 +121,8 @@ void AppKeyboard::_update_kb_input() memset(_input_buffer, 0, 8); auto status = _data.hal->keyboard()->keysState(); - - int count = 0; - for (auto i : status.hidKey) + for (auto& i : status.hidKey) { if (count < 6) { @@ -139,7 +137,7 @@ void AppKeyboard::_update_kb_input() modifier |= 0x01; } - if (status.shift) { + if (status.shift || _data.hal->keyboard()->capslocked()) { // ESP_LOGI(TAG, "SHIFT"); modifier |= 0x02; } From f77d85d11a518be99ef78b0897bd826742898ff9 Mon Sep 17 00:00:00 2001 From: Forairaaaaa Date: Mon, 11 Dec 2023 11:35:16 +0800 Subject: [PATCH 07/10] sort --- .../spdlog/include/spdlog/fmt/bundled/core.h | 2 + .../include/spdlog/fmt/bundled/format.h | 2 + dependencies.lock | 4 +- main/apps/app_keyboard/app_keyboard.cpp | 108 ++-------------- main/apps/app_keyboard/app_keyboard.h | 5 +- .../ble_keyboard/ble_keyboarad.cpp | 117 ++++++++++++++++++ sdkconfig | 28 ++--- sdkconfig.old | 83 ++++++++++++- 8 files changed, 231 insertions(+), 118 deletions(-) create mode 100644 main/apps/app_keyboard/ble_keyboard/ble_keyboarad.cpp diff --git a/components/mooncake/src/spdlog/include/spdlog/fmt/bundled/core.h b/components/mooncake/src/spdlog/include/spdlog/fmt/bundled/core.h index f6a37af..48f8204 100644 --- a/components/mooncake/src/spdlog/include/spdlog/fmt/bundled/core.h +++ b/components/mooncake/src/spdlog/include/spdlog/fmt/bundled/core.h @@ -1201,6 +1201,8 @@ template FMT_CONSTEXPR FMT_INLINE void init_named_args(std::nullptr_t, int, int, const Args&...) {} +#undef B1 + template constexpr auto count() -> size_t { return B ? 1 : 0; } template constexpr auto count() -> size_t { return (B1 ? 1 : 0) + count(); diff --git a/components/mooncake/src/spdlog/include/spdlog/fmt/bundled/format.h b/components/mooncake/src/spdlog/include/spdlog/fmt/bundled/format.h index 7c607db..63a4bfd 100644 --- a/components/mooncake/src/spdlog/include/spdlog/fmt/bundled/format.h +++ b/components/mooncake/src/spdlog/include/spdlog/fmt/bundled/format.h @@ -1435,6 +1435,8 @@ template struct basic_fp { using fp = basic_fp; +#undef F + // Normalizes the value converted from double and multiplied by (1 << SHIFT). template FMT_CONSTEXPR basic_fp normalize(basic_fp value) { diff --git a/dependencies.lock b/dependencies.lock index 12cb664..b350173 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -1,10 +1,10 @@ dependencies: espressif/cmake_utilities: - component_hash: c3f351bed6fdb3d91bee6076740cb13d22e2c7bfcdd78969a65b46943885bbd4 + component_hash: 351350613ceafba240b761b4ea991e0f231ac7a9f59a9ee901f751bddc0bb18f source: service_url: https://api.components.espressif.com/ type: service - version: 0.5.2 + version: 0.5.3 espressif/esp-now: component_hash: 7355037518944af5d0ea20fe48aa0a8cf82081599b6fbd83f086ee8b39df87c1 source: diff --git a/main/apps/app_keyboard/app_keyboard.cpp b/main/apps/app_keyboard/app_keyboard.cpp index 86fb9c7..8819497 100644 --- a/main/apps/app_keyboard/app_keyboard.cpp +++ b/main/apps/app_keyboard/app_keyboard.cpp @@ -12,12 +12,14 @@ #include "spdlog/spdlog.h" #include "../utils/wifi_common_test/wifi_common_test.h" #include "../utils/theme/theme_define.h" -#include "../utils/ble_keyboard_wrap/ble_keyboard_wrap.h" using namespace MOONCAKE::APPS; +#define TEST_USE_BLE + + void AppKeyboard::onCreate() { spdlog::info("{} onCreate", getAppName()); @@ -38,12 +40,13 @@ void AppKeyboard::onResume() _data.hal->canvas()->setTextSize(1); _data.hal->canvas_update(); - // Start ble keyboard spdlog::info("remain before: {}", uxTaskGetStackHighWaterMark(NULL)); } - ble_keyboard_wrap_init(_data.hal->keyboard()); + #ifdef TEST_USE_BLE + _ble_kb_init(); + #endif } @@ -56,8 +59,10 @@ void AppKeyboard::onRunning() destroyApp(); } - _update_infos(); - _update_kb_input(); + #ifdef TEST_USE_BLE + _ble_kb_update_infos(); + _ble_kb_update_kb_input(); + #endif } @@ -70,96 +75,3 @@ void AppKeyboard::onDestroy() esp_restart(); delay(10000); } - - -void AppKeyboard::_update_infos() -{ - if (millis() - _data.update_infos_time_count > 500) - { - // spdlog::info("remain: {}", uxTaskGetStackHighWaterMark(NULL)); - - _data.hal->canvas()->fillScreen(THEME_COLOR_BG); - - _data.hal->canvas()->setCursor(0, 0); - _data.hal->canvas()->setTextColor(TFT_ORANGE, THEME_COLOR_BG); - _data.hal->canvas()->printf("[BLE Keyboard]\n"); - _data.hal->canvas()->printf("> Name: %s\n", ble_keyboard_wrap_get_device_name()); - - // State - _data.hal->canvas()->printf("> State: "); - _data.hal->canvas()->setTextColor( - ble_keyboard_wrap_get_current_state() == ble_kb_wrap_state_connected ? TFT_GREENYELLOW : TFT_ORANGE, - THEME_COLOR_BG - ); - _data.hal->canvas()->printf( - "%s\n", - ble_keyboard_wrap_get_current_state() == ble_kb_wrap_state_connected ? "Connected" : "Wait connect.." - ); - - _data.hal->canvas_update(); - _data.update_infos_time_count = millis(); - } -} - - -static uint8_t _input_buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - -void AppKeyboard::_update_kb_input() -{ - // spdlog::info("remain: {}", uxTaskGetStackHighWaterMark(NULL)); - - if (ble_keyboard_wrap_get_current_state() != ble_kb_wrap_state_connected) - return; - - if (millis() - _data.update_kb_time_count > 10) - { - if (_data.hal->keyboard()->isChanged()) - { - uint8_t modifier = 0; - if (_data.hal->keyboard()->isPressed()) - { - memset(_input_buffer, 0, 8); - auto status = _data.hal->keyboard()->keysState(); - - int count = 0; - for (auto& i : status.hidKey) - { - if (count < 6) - { - _input_buffer[2 + count] = i; - count++; - } - } - - if (status.ctrl) - { - // ESP_LOGI(TAG, "CONTROL"); - modifier |= 0x01; - } - - if (status.shift || _data.hal->keyboard()->capslocked()) { - // ESP_LOGI(TAG, "SHIFT"); - modifier |= 0x02; - } - - if (status.alt) - { - // ESP_LOGI(TAG, "ALT"); - modifier |= 0x03; - } - - _input_buffer[0] = modifier; - - // ESP_LOG_BUFFER_HEX(TAG, buffer, 8); - ble_keyboard_wrap_update_input(_input_buffer); - } - else - { - memset(_input_buffer, 0, 8); - ble_keyboard_wrap_update_input(_input_buffer); - } - } - - _data.update_kb_time_count = millis(); - } -} diff --git a/main/apps/app_keyboard/app_keyboard.h b/main/apps/app_keyboard/app_keyboard.h index 1737d78..891e86a 100644 --- a/main/apps/app_keyboard/app_keyboard.h +++ b/main/apps/app_keyboard/app_keyboard.h @@ -33,8 +33,9 @@ namespace MOONCAKE uint32_t update_kb_time_count = 0; }; Data_t _data; - void _update_infos(); - void _update_kb_input(); + void _ble_kb_init(); + void _ble_kb_update_infos(); + void _ble_kb_update_kb_input(); public: void onCreate() override; diff --git a/main/apps/app_keyboard/ble_keyboard/ble_keyboarad.cpp b/main/apps/app_keyboard/ble_keyboard/ble_keyboarad.cpp new file mode 100644 index 0000000..36e9dc7 --- /dev/null +++ b/main/apps/app_keyboard/ble_keyboard/ble_keyboarad.cpp @@ -0,0 +1,117 @@ +/** + * @file ble_keyboarad.cpp + * @author Forairaaaaa + * @brief + * @version 0.1 + * @date 2023-12-11 + * + * @copyright Copyright (c) 2023 + * + */ +#include "../app_keyboard.h" +#include "spdlog/spdlog.h" +#include "../../utils/wifi_common_test/wifi_common_test.h" +#include "../../utils/theme/theme_define.h" +#include "../../utils/ble_keyboard_wrap/ble_keyboard_wrap.h" + + +using namespace MOONCAKE::APPS; + + +void AppKeyboard::_ble_kb_init() +{ + ble_keyboard_wrap_init(_data.hal->keyboard()); +} + + +void AppKeyboard::_ble_kb_update_infos() +{ + if (millis() - _data.update_infos_time_count > 500) + { + // spdlog::info("remain: {}", uxTaskGetStackHighWaterMark(NULL)); + + _data.hal->canvas()->fillScreen(THEME_COLOR_BG); + + _data.hal->canvas()->setCursor(0, 0); + _data.hal->canvas()->setTextColor(TFT_ORANGE, THEME_COLOR_BG); + _data.hal->canvas()->printf("[BLE Keyboard]\n"); + _data.hal->canvas()->printf("> Name: %s\n", ble_keyboard_wrap_get_device_name()); + + // State + _data.hal->canvas()->printf("> State: "); + _data.hal->canvas()->setTextColor( + ble_keyboard_wrap_get_current_state() == ble_kb_wrap_state_connected ? TFT_GREENYELLOW : TFT_ORANGE, + THEME_COLOR_BG + ); + _data.hal->canvas()->printf( + "%s\n", + ble_keyboard_wrap_get_current_state() == ble_kb_wrap_state_connected ? "Connected" : "Wait connect.." + ); + + _data.hal->canvas_update(); + _data.update_infos_time_count = millis(); + } +} + + +static uint8_t _input_buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + +void AppKeyboard::_ble_kb_update_kb_input() +{ + // spdlog::info("remain: {}", uxTaskGetStackHighWaterMark(NULL)); + + if (ble_keyboard_wrap_get_current_state() != ble_kb_wrap_state_connected) + return; + + if (millis() - _data.update_kb_time_count > 10) + { + if (_data.hal->keyboard()->isChanged()) + { + uint8_t modifier = 0; + if (_data.hal->keyboard()->isPressed()) + { + memset(_input_buffer, 0, 8); + auto status = _data.hal->keyboard()->keysState(); + + int count = 0; + for (auto& i : status.hidKey) + { + if (count < 6) + { + _input_buffer[2 + count] = i; + count++; + } + } + + if (status.ctrl) + { + // ESP_LOGI(TAG, "CONTROL"); + modifier |= 0x01; + } + + if (status.shift || _data.hal->keyboard()->capslocked()) { + // ESP_LOGI(TAG, "SHIFT"); + modifier |= 0x02; + } + + if (status.alt) + { + // ESP_LOGI(TAG, "ALT"); + modifier |= 0x03; + } + + _input_buffer[0] = modifier; + + // ESP_LOG_BUFFER_HEX(TAG, buffer, 8); + ble_keyboard_wrap_update_input(_input_buffer); + } + else + { + memset(_input_buffer, 0, 8); + ble_keyboard_wrap_update_input(_input_buffer); + } + } + + _data.update_kb_time_count = millis(); + } +} diff --git a/sdkconfig b/sdkconfig index b305f6f..39627db 100644 --- a/sdkconfig +++ b/sdkconfig @@ -815,7 +815,7 @@ CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=9000 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=8000 CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y # CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set # CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set @@ -1071,7 +1071,7 @@ CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# CONFIG_LWIP_SO_RCVBUF is not set +CONFIG_LWIP_SO_RCVBUF=y # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP4_FRAG=y CONFIG_LWIP_IP6_FRAG=y @@ -1580,6 +1580,17 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # CONFIG_WPA_DPP_SUPPORT is not set # end of Supplicant +# +# CMake Utilities +# +# CONFIG_CU_RELINKER_ENABLE is not set +# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set +CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y +# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set +# CONFIG_CU_GCC_LTO_ENABLE is not set +# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set +# end of CMake Utilities + # # ESP-NOW Configuration # @@ -1646,17 +1657,6 @@ CONFIG_ESPNOW_DEBUG_CONSOLE_UART_NUM_0=y CONFIG_ESPNOW_DEBUG_CONSOLE_UART_NUM=0 # end of ESP-NOW Debug Configuration # end of ESP-NOW Configuration - -# -# CMake Utilities -# -# CONFIG_CU_RELINKER_ENABLE is not set -# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set -CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y -# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set -# CONFIG_CU_GCC_LTO_ENABLE is not set -# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set -# end of CMake Utilities # end of Component config # @@ -1907,7 +1907,7 @@ CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_MAIN_TASK_STACK_SIZE=9000 +CONFIG_MAIN_TASK_STACK_SIZE=8000 CONFIG_CONSOLE_UART_DEFAULT=y # CONFIG_CONSOLE_UART_CUSTOM is not set # CONFIG_ESP_CONSOLE_UART_NONE is not set diff --git a/sdkconfig.old b/sdkconfig.old index 4475c73..bfa59ff 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -143,6 +143,85 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table +# +# Arduino Configuration +# +CONFIG_ARDUINO_VARIANT="esp32s3" +CONFIG_ENABLE_ARDUINO_DEPENDS=y +# CONFIG_AUTOSTART_ARDUINO is not set +# CONFIG_ARDUINO_RUN_CORE0 is not set +CONFIG_ARDUINO_RUN_CORE1=y +# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_RUNNING_CORE=1 +CONFIG_ARDUINO_LOOP_STACK_SIZE=1000 +# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set +CONFIG_ARDUINO_EVENT_RUN_CORE1=y +# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set +CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y +CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=1000 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 +CONFIG_ARDUINO_UDP_RUN_CORE0=y +# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set +# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_UDP_RUNNING_CORE=0 +CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# CONFIG_ARDUINO_ISR_IRAM is not set +# CONFIG_DISABLE_HAL_LOCKS is not set + +# +# Debug Log Configuration +# +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 +# CONFIG_ARDUHAL_LOG_COLORS is not set +# CONFIG_ARDUHAL_ESP_LOG is not set +# end of Debug Log Configuration + +CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y +# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set +CONFIG_ARDUHAL_PARTITION_SCHEME="default" +CONFIG_ARDUINO_SELECTIVE_COMPILATION=y +# CONFIG_ARDUINO_SELECTIVE_ArduinoOTA is not set +# CONFIG_ARDUINO_SELECTIVE_AsyncUDP is not set +# CONFIG_ARDUINO_SELECTIVE_AzureIoT is not set +# CONFIG_ARDUINO_SELECTIVE_BLE is not set +# CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set +# CONFIG_ARDUINO_SELECTIVE_DNSServer is not set +# CONFIG_ARDUINO_SELECTIVE_EEPROM is not set +# CONFIG_ARDUINO_SELECTIVE_ESP32 is not set +# CONFIG_ARDUINO_SELECTIVE_ESPmDNS is not set +# CONFIG_ARDUINO_SELECTIVE_FFat is not set +# CONFIG_ARDUINO_SELECTIVE_FS is not set +CONFIG_ARDUINO_SELECTIVE_HTTPClient=y +# CONFIG_ARDUINO_SELECTIVE_LITTLEFS is not set +# CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set +# CONFIG_ARDUINO_SELECTIVE_Preferences is not set +# CONFIG_ARDUINO_SELECTIVE_SD is not set +# CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set +# CONFIG_ARDUINO_SELECTIVE_SimpleBLE is not set +# CONFIG_ARDUINO_SELECTIVE_SPI is not set +# CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set +# CONFIG_ARDUINO_SELECTIVE_Ticker is not set +# CONFIG_ARDUINO_SELECTIVE_Update is not set +# CONFIG_ARDUINO_SELECTIVE_WebServer is not set +CONFIG_ARDUINO_SELECTIVE_WiFi=y +CONFIG_ARDUINO_SELECTIVE_WiFiClientSecure=y +# CONFIG_ARDUINO_SELECTIVE_WiFiProv is not set +# CONFIG_ARDUINO_SELECTIVE_Wire is not set +# end of Arduino Configuration + # # Compiler options # @@ -815,7 +894,7 @@ CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=9000 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=8000 CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y # CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set # CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set @@ -1071,7 +1150,7 @@ CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# CONFIG_LWIP_SO_RCVBUF is not set +CONFIG_LWIP_SO_RCVBUF=y # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP4_FRAG=y CONFIG_LWIP_IP6_FRAG=y From 38bf0a6291caf2506337749a418ca9d1a72b9136 Mon Sep 17 00:00:00 2001 From: Forairaaaaa Date: Mon, 11 Dec 2023 12:05:03 +0800 Subject: [PATCH 08/10] try add wrap --- CMakeLists.txt | 2 + dependencies.lock | 8 +- main/Kconfig.projbuild | 26 ++ .../hid_device/tusb_config.h | 114 +++++++++ .../hid_device/usb_descriptors.c | 160 +++++++++++++ .../hid_device/usb_descriptors.h | 45 ++++ .../utils/usb_keyboard_wrap/tinyusb_hid.c | 132 ++++++++++ .../utils/usb_keyboard_wrap/tinyusb_hid.h | 226 ++++++++++++++++++ .../usb_keyboard_wrap/usb_keyboard_wrap.c | 205 ++++++++++++++++ .../usb_keyboard_wrap/usb_keyboard_wrap.h | 24 ++ main/idf_component.yml | 8 + sdkconfig | 17 ++ sdkconfig.old | 90 ++----- 13 files changed, 980 insertions(+), 77 deletions(-) create mode 100644 main/Kconfig.projbuild create mode 100644 main/apps/utils/usb_keyboard_wrap/hid_device/tusb_config.h create mode 100644 main/apps/utils/usb_keyboard_wrap/hid_device/usb_descriptors.c create mode 100644 main/apps/utils/usb_keyboard_wrap/hid_device/usb_descriptors.h create mode 100644 main/apps/utils/usb_keyboard_wrap/tinyusb_hid.c create mode 100644 main/apps/utils/usb_keyboard_wrap/tinyusb_hid.h create mode 100644 main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.c create mode 100644 main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f7010b..24dca7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,8 @@ cmake_minimum_required(VERSION 3.16) # add_definitions(-DMC_USE_CUSTOM_CONF) # add_definitions(-DNO_BOOT_PLAY_SHIT) +include_directories(./main/apps/utils/usb_keyboard_wrap/hid_device) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(cardputer) diff --git a/dependencies.lock b/dependencies.lock index b350173..fefc899 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -16,6 +16,12 @@ dependencies: source: type: idf version: 4.4.6 -manifest_hash: 4152ab7064ca9cbbd8d1d8f29a55ce717a41aec30188ca3c34b7db8227f03084 + leeebo/tinyusb_src: + component_hash: 117cb2432654d6f194e0a9a47f87e5f3143312c8b4897601d7b3b9651757734f + source: + service_url: https://api.components.espressif.com/ + type: service + version: 0.15.0~7 +manifest_hash: b6597783385c4b38496cd80e4e82d7c706daa89f68f0c09c37f36971218c34c5 target: esp32s3 version: 1.0.0 diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild new file mode 100644 index 0000000..3c447cf --- /dev/null +++ b/main/Kconfig.projbuild @@ -0,0 +1,26 @@ +menu "USB HID Device Example" + + choice HID_SUBCLASS + prompt "HID Device" + default SUBCLASS_MOUSE + + config SUBCLASS_MOUSE + bool "Mouse" + config SUBCLASS_KEYBOARD + bool "Keyboard" + endchoice + + config TUSB_VID + hex "USB Device VID" + default 0x303A + config TUSB_PID + hex "USB Device PID" + default 0x8000 + config TUSB_MANUFACTURER + string "USB Device Manufacture" + default "Espressif" + config TUSB_PRODUCT + string "Product Name" + default "HID Demo" + +endmenu \ No newline at end of file diff --git a/main/apps/utils/usb_keyboard_wrap/hid_device/tusb_config.h b/main/apps/utils/usb_keyboard_wrap/hid_device/tusb_config.h new file mode 100644 index 0000000..27183fb --- /dev/null +++ b/main/apps/utils/usb_keyboard_wrap/hid_device/tusb_config.h @@ -0,0 +1,114 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_TUD_RHPORT +#define BOARD_TUD_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUD_MAX_SPEED +#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// Common Configuration +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU +#error CFG_TUSB_MCU must be defined +#endif + +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_FREERTOS +#endif + +// Espressif IDF requires "freertos/" prefix in include path +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#define CFG_TUSB_OS_INC_PATH freertos/ +#endif + +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +// Enable Device stack +#define CFG_TUD_ENABLED 1 + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// +// The number of video control interfaces +#define CFG_TUD_HID 1 +#define CFG_TUD_HID_EP_BUFSIZE 64 + +#define USB_VID CONFIG_TUSB_VID +#define USB_PID CONFIG_TUSB_PID +#define USB_MANUFACTURER CONFIG_TUSB_MANUFACTURER +#define USB_PRODUCT CONFIG_TUSB_PRODUCT + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_CONFIG_H_ */ \ No newline at end of file diff --git a/main/apps/utils/usb_keyboard_wrap/hid_device/usb_descriptors.c b/main/apps/utils/usb_keyboard_wrap/hid_device/usb_descriptors.c new file mode 100644 index 0000000..40237e5 --- /dev/null +++ b/main/apps/utils/usb_keyboard_wrap/hid_device/usb_descriptors.c @@ -0,0 +1,160 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "tusb.h" +#include "usb_descriptors.h" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] VIDEO | AUDIO | MIDI | HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#ifndef USB_PID +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ + _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VIDEO, 5) | _PID_MAP(VENDOR, 6) ) +#endif + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + // Use Interface Association Descriptor (IAD) for Video + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = USB_VID, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +uint8_t const desc_hid_report[] = { + TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID_KEYBOARD)), + TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(REPORT_ID_MOUSE)) +}; + +uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) +{ + (void) instance; + return desc_hid_report; +} + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const *tud_descriptor_device_cb(void) +{ + return (uint8_t const *) &desc_device; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN * CFG_TUD_HID) + +uint8_t const desc_fs_configuration[] = { + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 100), + // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval + TUD_HID_DESCRIPTOR(ITF_NUM_HID, 4, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), (0x80 | EPNUM_HID_DATA), CFG_TUD_HID_EP_BUFSIZE, 10) +}; + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const *tud_descriptor_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + + return desc_fs_configuration; +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// array of pointer to string descriptors +char const *string_desc_arr [] = { + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + USB_MANUFACTURER, // 1: Manufacturer + USB_PRODUCT, // 2: Product + "123456", // 3: Serials, should use chip ID + "HID", // 4: HID Interface +}; + +static uint16_t _desc_str[32]; + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) +{ + (void) langid; + + uint8_t chr_count; + + if (index == 0) { + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + } else { + // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. + // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors + + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { + return NULL; + } + + const char *str = string_desc_arr[index]; + + // Cap at max char + chr_count = (uint8_t) strlen(str); + if (chr_count > 31) { + chr_count = 31; + } + + // Convert ASCII string into UTF-16 + for (uint8_t i = 0; i < chr_count; i++) { + _desc_str[1 + i] = str[i]; + } + } + + // first byte is length (including header), second byte is string type + _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); + + return _desc_str; +} \ No newline at end of file diff --git a/main/apps/utils/usb_keyboard_wrap/hid_device/usb_descriptors.h b/main/apps/utils/usb_keyboard_wrap/hid_device/usb_descriptors.h new file mode 100644 index 0000000..2912604 --- /dev/null +++ b/main/apps/utils/usb_keyboard_wrap/hid_device/usb_descriptors.h @@ -0,0 +1,45 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Jerzy Kasenbreg + * Copyright (c) 2021 Koji KITAYAMA + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _USB_DESCRIPTORS_H_ +#define _USB_DESCRIPTORS_H_ + +enum { + REPORT_ID_KEYBOARD = 1, + REPORT_ID_MOUSE +}; + +enum { + ITF_NUM_HID = 0, + ITF_NUM_TOTAL +}; + +enum { + EPNUM_DEFAULT = 0, + EPNUM_HID_DATA, +}; + +#endif \ No newline at end of file diff --git a/main/apps/utils/usb_keyboard_wrap/tinyusb_hid.c b/main/apps/utils/usb_keyboard_wrap/tinyusb_hid.c new file mode 100644 index 0000000..a1e5201 --- /dev/null +++ b/main/apps/utils/usb_keyboard_wrap/tinyusb_hid.c @@ -0,0 +1,132 @@ +/* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "esp_err.h" +#include "esp_log.h" +#include "tinyusb_hid.h" +#include "usb_descriptors.h" +#include "device/usbd.h" + +static const char *TAG = "tinyusb_hid.h"; +static bool s_keyboard_pressed = false; + +void tinyusb_hid_mouse_move_report(int8_t x, int8_t y, int8_t vertical, int8_t horizontal) +{ + ESP_LOGD(TAG, "x=%d, y=%d, vertical=%d, horizontal=%d", x, y, vertical, horizontal); + + // Remote wakeup + if (tud_suspended()) { + // Wake up host if we are in suspend mode + // and REMOTE_WAKEUP feature is enabled by host + tud_remote_wakeup(); + } else { + // Send the 1st of report chain, the rest will be sent by tud_hid_report_complete_cb() + // skip if hid is not ready yet + if (!tud_hid_ready()) { + ESP_LOGW(TAG, "tinyusb not ready %s %d", __func__, __LINE__); + return; + } + + tud_hid_mouse_report(REPORT_ID_MOUSE, 0x00, x, y, vertical, horizontal); + + } +} + +void tinyusb_hid_mouse_button_report(uint8_t buttons_map) +{ + ESP_LOGD(TAG, "buttons_map = %u", buttons_map); + + // Remote wakeup + if (tud_suspended()) { + // Wake up host if we are in suspend mode + // and REMOTE_WAKEUP feature is enabled by host + tud_remote_wakeup(); + } else { + // Send the 1st of report chain, the rest will be sent by tud_hid_report_complete_cb() + // skip if hid is not ready yet + if (!tud_hid_ready()) { + ESP_LOGW(TAG, "tinyusb not ready %s %d", __func__, __LINE__); + return; + } + + tud_hid_mouse_report(REPORT_ID_MOUSE, buttons_map, 0, 0, 0, 0); + + } +} + +void tinyusb_hid_keyboard_report(uint8_t keycode[]) +{ + ESP_LOGD(TAG, "keycode = %u %u %u %u %u %u", keycode[0], keycode[1], keycode[2], keycode[3], keycode[4], keycode[5]); + + // Remote wakeup + if (tud_suspended()) { + // Wake up host if we are in suspend mode + // and REMOTE_WAKEUP feature is enabled by host + tud_remote_wakeup(); + } else { + // Send the 1st of report chain, the rest will be sent by tud_hid_report_complete_cb() + // skip if hid is not ready yet + if (!tud_hid_ready()) { + ESP_LOGW(TAG, "tinyusb not ready %s %d", __func__, __LINE__); + return; + } + + uint8_t _keycode[6] = { 0 }; + _keycode[0] = keycode[0]; + _keycode[1] = keycode[1]; + _keycode[2] = keycode[2]; + _keycode[3] = keycode[3]; + _keycode[4] = keycode[4]; + _keycode[5] = keycode[5]; + + tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, _keycode); + s_keyboard_pressed = true; + } +} + +/************************************************** TinyUSB callbacks ***********************************************/ +// Invoked when sent REPORT successfully to host +// Application can use this to send the next report +// Note: For composite reports, report[0] is report ID +void tud_hid_report_complete_cb(uint8_t itf, uint8_t const *report, uint16_t len) +{ + (void) itf; + (void) len; + uint8_t report_id = report[0]; + + if (report_id == REPORT_ID_KEYBOARD && s_keyboard_pressed) { + tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL); + s_keyboard_pressed = false; + } +} + +// Invoked when received GET_REPORT control request +// Application must fill buffer report's content and return its length. +// Return zero will cause the stack to STALL request +uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) +{ + // TODO not Implemented + (void) itf; + (void) report_id; + (void) report_type; + (void) buffer; + (void) reqlen; + + return 0; +} + +// Invoked when received SET_REPORT control request or +// received data on OUT endpoint ( Report ID = 0, Type = 0 ) +void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) +{ + // TODO set LED based on CAPLOCK, NUMLOCK etc... + (void) itf; + (void) report_id; + (void) report_type; + (void) buffer; + (void) bufsize; +} \ No newline at end of file diff --git a/main/apps/utils/usb_keyboard_wrap/tinyusb_hid.h b/main/apps/utils/usb_keyboard_wrap/tinyusb_hid.h new file mode 100644 index 0000000..1abc9ba --- /dev/null +++ b/main/apps/utils/usb_keyboard_wrap/tinyusb_hid.h @@ -0,0 +1,226 @@ +/* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "tusb.h" + +/** + * @brief Report delta movement of mouse. + * + * @param x Current delta x movement of the mouse + * @param y Current delta y movement on the mouse + * @param vertical Current delta wheel movement on the mouse + * @param horizontal using AC Pan + */ +void tinyusb_hid_mouse_move_report(int8_t x, int8_t y, int8_t vertical, int8_t horizontal); + +/** + * @brief Report button click in the mouse, using bitmap here. + * eg. MOUSE_BUTTON_LEFT | MOUSE_BUTTON_RIGHT, if click left and right button at same time. + * + * @param buttons hid mouse button bit mask + */ +void tinyusb_hid_mouse_button_report(uint8_t buttons_map); + +/** + * @brief Report key press in the keyboard, using array here, contains six keys at most. + * + * @param keycode hid keyboard code array + */ +void tinyusb_hid_keyboard_report(uint8_t keycode[]); + +//--------------------------------------------------------------------+ +// HID MOUSE BUTTON BIT MASK +//--------------------------------------------------------------------+ +// MOUSE_BUTTON_LEFT = TU_BIT(0), ///< Left button +// MOUSE_BUTTON_RIGHT = TU_BIT(1), ///< Right button +// MOUSE_BUTTON_MIDDLE = TU_BIT(2), ///< Middle button +// MOUSE_BUTTON_BACKWARD = TU_BIT(3), ///< Backward button, +// MOUSE_BUTTON_FORWARD = TU_BIT(4), ///< Forward button, + +//--------------------------------------------------------------------+ +// HID KEYCODE +//--------------------------------------------------------------------+ +// #define HID_KEY_NONE 0x00 +// #define HID_KEY_A 0x04 +// #define HID_KEY_B 0x05 +// #define HID_KEY_C 0x06 +// #define HID_KEY_D 0x07 +// #define HID_KEY_E 0x08 +// #define HID_KEY_F 0x09 +// #define HID_KEY_G 0x0A +// #define HID_KEY_H 0x0B +// #define HID_KEY_I 0x0C +// #define HID_KEY_J 0x0D +// #define HID_KEY_K 0x0E +// #define HID_KEY_L 0x0F +// #define HID_KEY_M 0x10 +// #define HID_KEY_N 0x11 +// #define HID_KEY_O 0x12 +// #define HID_KEY_P 0x13 +// #define HID_KEY_Q 0x14 +// #define HID_KEY_R 0x15 +// #define HID_KEY_S 0x16 +// #define HID_KEY_T 0x17 +// #define HID_KEY_U 0x18 +// #define HID_KEY_V 0x19 +// #define HID_KEY_W 0x1A +// #define HID_KEY_X 0x1B +// #define HID_KEY_Y 0x1C +// #define HID_KEY_Z 0x1D +// #define HID_KEY_1 0x1E +// #define HID_KEY_2 0x1F +// #define HID_KEY_3 0x20 +// #define HID_KEY_4 0x21 +// #define HID_KEY_5 0x22 +// #define HID_KEY_6 0x23 +// #define HID_KEY_7 0x24 +// #define HID_KEY_8 0x25 +// #define HID_KEY_9 0x26 +// #define HID_KEY_0 0x27 +// #define HID_KEY_ENTER 0x28 +// #define HID_KEY_ESCAPE 0x29 +// #define HID_KEY_BACKSPACE 0x2A +// #define HID_KEY_TAB 0x2B +// #define HID_KEY_SPACE 0x2C +// #define HID_KEY_MINUS 0x2D +// #define HID_KEY_EQUAL 0x2E +// #define HID_KEY_BRACKET_LEFT 0x2F +// #define HID_KEY_BRACKET_RIGHT 0x30 +// #define HID_KEY_BACKSLASH 0x31 +// #define HID_KEY_EUROPE_1 0x32 +// #define HID_KEY_SEMICOLON 0x33 +// #define HID_KEY_APOSTROPHE 0x34 +// #define HID_KEY_GRAVE 0x35 +// #define HID_KEY_COMMA 0x36 +// #define HID_KEY_PERIOD 0x37 +// #define HID_KEY_SLASH 0x38 +// #define HID_KEY_CAPS_LOCK 0x39 +// #define HID_KEY_F1 0x3A +// #define HID_KEY_F2 0x3B +// #define HID_KEY_F3 0x3C +// #define HID_KEY_F4 0x3D +// #define HID_KEY_F5 0x3E +// #define HID_KEY_F6 0x3F +// #define HID_KEY_F7 0x40 +// #define HID_KEY_F8 0x41 +// #define HID_KEY_F9 0x42 +// #define HID_KEY_F10 0x43 +// #define HID_KEY_F11 0x44 +// #define HID_KEY_F12 0x45 +// #define HID_KEY_PRINT_SCREEN 0x46 +// #define HID_KEY_SCROLL_LOCK 0x47 +// #define HID_KEY_PAUSE 0x48 +// #define HID_KEY_INSERT 0x49 +// #define HID_KEY_HOME 0x4A +// #define HID_KEY_PAGE_UP 0x4B +// #define HID_KEY_DELETE 0x4C +// #define HID_KEY_END 0x4D +// #define HID_KEY_PAGE_DOWN 0x4E +// #define HID_KEY_ARROW_RIGHT 0x4F +// #define HID_KEY_ARROW_LEFT 0x50 +// #define HID_KEY_ARROW_DOWN 0x51 +// #define HID_KEY_ARROW_UP 0x52 +// #define HID_KEY_NUM_LOCK 0x53 +// #define HID_KEY_KEYPAD_DIVIDE 0x54 +// #define HID_KEY_KEYPAD_MULTIPLY 0x55 +// #define HID_KEY_KEYPAD_SUBTRACT 0x56 +// #define HID_KEY_KEYPAD_ADD 0x57 +// #define HID_KEY_KEYPAD_ENTER 0x58 +// #define HID_KEY_KEYPAD_1 0x59 +// #define HID_KEY_KEYPAD_2 0x5A +// #define HID_KEY_KEYPAD_3 0x5B +// #define HID_KEY_KEYPAD_4 0x5C +// #define HID_KEY_KEYPAD_5 0x5D +// #define HID_KEY_KEYPAD_6 0x5E +// #define HID_KEY_KEYPAD_7 0x5F +// #define HID_KEY_KEYPAD_8 0x60 +// #define HID_KEY_KEYPAD_9 0x61 +// #define HID_KEY_KEYPAD_0 0x62 +// #define HID_KEY_KEYPAD_DECIMAL 0x63 +// #define HID_KEY_EUROPE_2 0x64 +// #define HID_KEY_APPLICATION 0x65 +// #define HID_KEY_POWER 0x66 +// #define HID_KEY_KEYPAD_EQUAL 0x67 +// #define HID_KEY_F13 0x68 +// #define HID_KEY_F14 0x69 +// #define HID_KEY_F15 0x6A +// #define HID_KEY_F16 0x6B +// #define HID_KEY_F17 0x6C +// #define HID_KEY_F18 0x6D +// #define HID_KEY_F19 0x6E +// #define HID_KEY_F20 0x6F +// #define HID_KEY_F21 0x70 +// #define HID_KEY_F22 0x71 +// #define HID_KEY_F23 0x72 +// #define HID_KEY_F24 0x73 +// #define HID_KEY_EXECUTE 0x74 +// #define HID_KEY_HELP 0x75 +// #define HID_KEY_MENU 0x76 +// #define HID_KEY_SELECT 0x77 +// #define HID_KEY_STOP 0x78 +// #define HID_KEY_AGAIN 0x79 +// #define HID_KEY_UNDO 0x7A +// #define HID_KEY_CUT 0x7B +// #define HID_KEY_COPY 0x7C +// #define HID_KEY_PASTE 0x7D +// #define HID_KEY_FIND 0x7E +// #define HID_KEY_MUTE 0x7F +// #define HID_KEY_VOLUME_UP 0x80 +// #define HID_KEY_VOLUME_DOWN 0x81 +// #define HID_KEY_LOCKING_CAPS_LOCK 0x82 +// #define HID_KEY_LOCKING_NUM_LOCK 0x83 +// #define HID_KEY_LOCKING_SCROLL_LOCK 0x84 +// #define HID_KEY_KEYPAD_COMMA 0x85 +// #define HID_KEY_KEYPAD_EQUAL_SIGN 0x86 +// #define HID_KEY_KANJI1 0x87 +// #define HID_KEY_KANJI2 0x88 +// #define HID_KEY_KANJI3 0x89 +// #define HID_KEY_KANJI4 0x8A +// #define HID_KEY_KANJI5 0x8B +// #define HID_KEY_KANJI6 0x8C +// #define HID_KEY_KANJI7 0x8D +// #define HID_KEY_KANJI8 0x8E +// #define HID_KEY_KANJI9 0x8F +// #define HID_KEY_LANG1 0x90 +// #define HID_KEY_LANG2 0x91 +// #define HID_KEY_LANG3 0x92 +// #define HID_KEY_LANG4 0x93 +// #define HID_KEY_LANG5 0x94 +// #define HID_KEY_LANG6 0x95 +// #define HID_KEY_LANG7 0x96 +// #define HID_KEY_LANG8 0x97 +// #define HID_KEY_LANG9 0x98 +// #define HID_KEY_ALTERNATE_ERASE 0x99 +// #define HID_KEY_SYSREQ_ATTENTION 0x9A +// #define HID_KEY_CANCEL 0x9B +// #define HID_KEY_CLEAR 0x9C +// #define HID_KEY_PRIOR 0x9D +// #define HID_KEY_RETURN 0x9E +// #define HID_KEY_SEPARATOR 0x9F +// #define HID_KEY_OUT 0xA0 +// #define HID_KEY_OPER 0xA1 +// #define HID_KEY_CLEAR_AGAIN 0xA2 +// #define HID_KEY_CRSEL_PROPS 0xA3 +// #define HID_KEY_EXSEL 0xA4 +// //RESERVED 0xA5-DF +// #define HID_KEY_CONTROL_LEFT 0xE0 +// #define HID_KEY_SHIFT_LEFT 0xE1 +// #define HID_KEY_ALT_LEFT 0xE2 +// #define HID_KEY_GUI_LEFT 0xE3 +// #define HID_KEY_CONTROL_RIGHT 0xE4 +// #define HID_KEY_SHIFT_RIGHT 0xE5 +// #define HID_KEY_ALT_RIGHT 0xE6 +// #define HID_KEY_GUI_RIGHT 0xE7 + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.c b/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.c new file mode 100644 index 0000000..87d9d1d --- /dev/null +++ b/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.c @@ -0,0 +1,205 @@ +/* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_log.h" +#include "sdkconfig.h" +// #include "iot_button.h" +#include "hal/usb_hal.h" +#include "esp_private/usb_phy.h" +#include "tinyusb_hid.h" + +#define TAG "HID Example" + +/* Button GPIO number */ +#define EXAMPLE_BUTTON_NUM 4 +#define EXAMPLE_BUTTON_UP 0 +#define EXAMPLE_BUTTON_DOWN 11 +#define EXAMPLE_BUTTON_LEFT 10 +#define EXAMPLE_BUTTON_RIGHT 14 + +/* Mouse offset when button click */ +#define EXAMPLE_MOUSE_OFFSET_X 8 +#define EXAMPLE_MOUSE_OFFSET_Y 8 + +// static int s_button_gpio[EXAMPLE_BUTTON_NUM] = {EXAMPLE_BUTTON_UP, EXAMPLE_BUTTON_DOWN, EXAMPLE_BUTTON_LEFT, EXAMPLE_BUTTON_RIGHT}; +// static button_handle_t s_button_handles[EXAMPLE_BUTTON_NUM] = {NULL}; + +// static int get_button_gpio(button_handle_t btn_hdl) +// { +// for (size_t i = 0; i < EXAMPLE_BUTTON_NUM; i++) { +// if (s_button_handles[i] == btn_hdl) { +// return s_button_gpio[i]; +// } +// } +// return -1; +// } + +#ifdef CONFIG_SUBCLASS_KEYBOARD +static void button_keyboard_cb(void *arg, void *arg2) +{ + // button_handle_t button_hdl = (button_handle_t)arg; + // int button_gpio = get_button_gpio(button_hdl); + // uint8_t _keycode[6] = { 0 }; + // switch (button_gpio) { + // case EXAMPLE_BUTTON_UP: + // _keycode[0] = HID_KEY_U; + // break; + + // case EXAMPLE_BUTTON_DOWN: + // _keycode[0] = HID_KEY_D; + // break; + + // case EXAMPLE_BUTTON_LEFT: + // _keycode[0] = HID_KEY_L; + // break; + + // case EXAMPLE_BUTTON_RIGHT: + // _keycode[0] = HID_KEY_R; + // break; + + // default: + // break; + // } + // tinyusb_hid_keyboard_report(_keycode); + // ESP_LOGI(TAG, "Keyboard %c", _keycode[0] - HID_KEY_A + 'a'); +} +#elif defined CONFIG_SUBCLASS_MOUSE +static void button_mouse_cb(void *arg, void *arg2) +{ + // button_handle_t button_hdl = (button_handle_t)arg; + // int button_gpio = get_button_gpio(button_hdl); + // int mouse_offset_x = 0, mouse_offset_y = 0; + // switch (button_gpio) { + // case EXAMPLE_BUTTON_UP: + // mouse_offset_y = -EXAMPLE_MOUSE_OFFSET_Y; + // break; + + // case EXAMPLE_BUTTON_DOWN: + // mouse_offset_y = EXAMPLE_MOUSE_OFFSET_Y; + // break; + + // case EXAMPLE_BUTTON_LEFT: + // mouse_offset_x = -EXAMPLE_MOUSE_OFFSET_X; + // break; + + // case EXAMPLE_BUTTON_RIGHT: + // mouse_offset_x = EXAMPLE_MOUSE_OFFSET_X; + // break; + + // default: + // break; + // } + // tinyusb_hid_mouse_move_report(mouse_offset_x, mouse_offset_y, 0, 0); + // ESP_LOGI(TAG, "Mouse x=%d y=%d", mouse_offset_x, mouse_offset_y); +} +#endif + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +static void tusb_device_task(void *arg) +{ + while (1) { + tud_task(); + } +} + + +// Invoked when device is mounted +void tud_mount_cb(void) +{ + ESP_LOGI(TAG, "USB Mount"); +} + +// Invoked when device is unmounted +void tud_umount_cb(void) +{ + ESP_LOGI(TAG, "USB Un-Mount"); +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allow us to perform remote wakeup +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) +{ + (void) remote_wakeup_en; + ESP_LOGI(TAG, "USB Suspend"); +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) +{ + ESP_LOGI(TAG, "USB Resume"); +} + +//--------------------------------------------------------------------+ +// USB PHY config +//--------------------------------------------------------------------+ +static void usb_phy_init(void) +{ + usb_phy_handle_t phy_hdl; + // Configure USB PHY + usb_phy_config_t phy_conf = { + .controller = USB_PHY_CTRL_OTG, + .otg_mode = USB_OTG_MODE_DEVICE, + }; + phy_conf.target = USB_PHY_TARGET_INT; + usb_new_phy(&phy_conf, &phy_hdl); +} + +void usb_kb_wrap_init(void) +{ + // switch esp usb phy to usb-otg + usb_phy_init(); + tud_init(BOARD_TUD_RHPORT); + xTaskCreate(tusb_device_task, "TinyUSB", 4096, NULL, 5, NULL); + + // /* buttons init, buttons used to simulate keyboard or mouse events */ + // button_config_t cfg = { + // .type = BUTTON_TYPE_GPIO, + // .gpio_button_config = { + // .active_level = 0, + // }, + // }; + + // for (size_t i = 0; i < EXAMPLE_BUTTON_NUM; i++) { + // cfg.gpio_button_config.gpio_num = s_button_gpio[i]; + // s_button_handles[i] = iot_button_create(&cfg); + // if (s_button_handles[i] == NULL) { + // ESP_LOGE(TAG, "Button io = %d created failed", s_button_gpio[i]); + // assert(0); + // } else { + // ESP_LOGI(TAG, "Button io = %d created", s_button_gpio[i]); + // } + // } + +#ifdef CONFIG_SUBCLASS_KEYBOARD + // button_cb_t button_cb = button_keyboard_cb; + // ESP_LOGI(TAG, "HID Keyboard demo: press button to simulate keyboard"); +#elif defined CONFIG_SUBCLASS_MOUSE + // button_cb_t button_cb = button_mouse_cb; + // ESP_LOGI(TAG, "HID Mouse demo: press button to simulate mouse"); +#endif + ESP_LOGI(TAG, "Wait Mount through USB interface"); + + // /* register button callback, send HID report when click button */ + // for (size_t i = 0; i < EXAMPLE_BUTTON_NUM; i++) { + // iot_button_register_cb(s_button_handles[i], BUTTON_SINGLE_CLICK, button_cb, NULL); + // } + + // while (1) { + // vTaskDelay(pdMS_TO_TICKS(1000)); + // } +} + + +void usb_kb_wrap_report(uint8_t* keycode) +{ + tinyusb_hid_keyboard_report(keycode); +} diff --git a/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.h b/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.h new file mode 100644 index 0000000..7058417 --- /dev/null +++ b/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.h @@ -0,0 +1,24 @@ +/** + * @file usb_keyboard_wrap.h + * @author Forairaaaaa + * @brief + * @version 0.1 + * @date 2023-12-11 + * + * @copyright Copyright (c) 2023 + * + */ +#pragma once +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void usb_kb_wrap_init(); +void usb_kb_wrap_report(uint8_t* keycode); + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/main/idf_component.yml b/main/idf_component.yml index f78b4eb..fa9f0ff 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -1,6 +1,14 @@ ## IDF Component Manager Manifest File dependencies: espressif/esp-now: "=*" + espressif/tinyusb: + version: ">=0.15.0~2" + rules: + - if: "idf_version >=5.0" + leeebo/tinyusb_src: + version: ">=0.15.0~6" + rules: + - if: "idf_version >=4.4,<5.0" ## Required IDF version idf: version: ">=4.1.0" diff --git a/sdkconfig b/sdkconfig index 39627db..970df93 100644 --- a/sdkconfig +++ b/sdkconfig @@ -143,6 +143,17 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table +# +# USB HID Device Example +# +# CONFIG_SUBCLASS_MOUSE is not set +CONFIG_SUBCLASS_KEYBOARD=y +CONFIG_TUSB_VID=0x303A +CONFIG_TUSB_PID=0x8000 +CONFIG_TUSB_MANUFACTURER="Espressif" +CONFIG_TUSB_PRODUCT="M5-Cardputer" +# end of USB HID Device Example + # # Compiler options # @@ -1657,6 +1668,12 @@ CONFIG_ESPNOW_DEBUG_CONSOLE_UART_NUM_0=y CONFIG_ESPNOW_DEBUG_CONSOLE_UART_NUM=0 # end of ESP-NOW Debug Configuration # end of ESP-NOW Configuration + +# +# TinyUSB soucre +# +# CONFIG_USING_SYNOPSYS_DWC2_DRIVER is not set +# end of TinyUSB soucre # end of Component config # diff --git a/sdkconfig.old b/sdkconfig.old index bfa59ff..716c14a 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -144,83 +144,15 @@ CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table # -# Arduino Configuration -# -CONFIG_ARDUINO_VARIANT="esp32s3" -CONFIG_ENABLE_ARDUINO_DEPENDS=y -# CONFIG_AUTOSTART_ARDUINO is not set -# CONFIG_ARDUINO_RUN_CORE0 is not set -CONFIG_ARDUINO_RUN_CORE1=y -# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_RUNNING_CORE=1 -CONFIG_ARDUINO_LOOP_STACK_SIZE=1000 -# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set -CONFIG_ARDUINO_EVENT_RUN_CORE1=y -# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set -CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y -CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=1000 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 -CONFIG_ARDUINO_UDP_RUN_CORE0=y -# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set -# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_UDP_RUNNING_CORE=0 -CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 -# CONFIG_ARDUINO_ISR_IRAM is not set -# CONFIG_DISABLE_HAL_LOCKS is not set - -# -# Debug Log Configuration +# USB HID Device Example # -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 -# CONFIG_ARDUHAL_LOG_COLORS is not set -# CONFIG_ARDUHAL_ESP_LOG is not set -# end of Debug Log Configuration - -CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y -# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set -CONFIG_ARDUHAL_PARTITION_SCHEME="default" -CONFIG_ARDUINO_SELECTIVE_COMPILATION=y -# CONFIG_ARDUINO_SELECTIVE_ArduinoOTA is not set -# CONFIG_ARDUINO_SELECTIVE_AsyncUDP is not set -# CONFIG_ARDUINO_SELECTIVE_AzureIoT is not set -# CONFIG_ARDUINO_SELECTIVE_BLE is not set -# CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set -# CONFIG_ARDUINO_SELECTIVE_DNSServer is not set -# CONFIG_ARDUINO_SELECTIVE_EEPROM is not set -# CONFIG_ARDUINO_SELECTIVE_ESP32 is not set -# CONFIG_ARDUINO_SELECTIVE_ESPmDNS is not set -# CONFIG_ARDUINO_SELECTIVE_FFat is not set -# CONFIG_ARDUINO_SELECTIVE_FS is not set -CONFIG_ARDUINO_SELECTIVE_HTTPClient=y -# CONFIG_ARDUINO_SELECTIVE_LITTLEFS is not set -# CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set -# CONFIG_ARDUINO_SELECTIVE_Preferences is not set -# CONFIG_ARDUINO_SELECTIVE_SD is not set -# CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set -# CONFIG_ARDUINO_SELECTIVE_SimpleBLE is not set -# CONFIG_ARDUINO_SELECTIVE_SPI is not set -# CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set -# CONFIG_ARDUINO_SELECTIVE_Ticker is not set -# CONFIG_ARDUINO_SELECTIVE_Update is not set -# CONFIG_ARDUINO_SELECTIVE_WebServer is not set -CONFIG_ARDUINO_SELECTIVE_WiFi=y -CONFIG_ARDUINO_SELECTIVE_WiFiClientSecure=y -# CONFIG_ARDUINO_SELECTIVE_WiFiProv is not set -# CONFIG_ARDUINO_SELECTIVE_Wire is not set -# end of Arduino Configuration +CONFIG_SUBCLASS_MOUSE=y +# CONFIG_SUBCLASS_KEYBOARD is not set +CONFIG_TUSB_VID=0x303A +CONFIG_TUSB_PID=0x8000 +CONFIG_TUSB_MANUFACTURER="Espressif" +CONFIG_TUSB_PRODUCT="HID Demo" +# end of USB HID Device Example # # Compiler options @@ -1736,6 +1668,12 @@ CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y # CONFIG_CU_GCC_LTO_ENABLE is not set # CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set # end of CMake Utilities + +# +# TinyUSB soucre +# +# CONFIG_USING_SYNOPSYS_DWC2_DRIVER is not set +# end of TinyUSB soucre # end of Component config # From 8977d21c68f601958957259dcdea6b652be35701 Mon Sep 17 00:00:00 2001 From: Forairaaaaa Date: Mon, 11 Dec 2023 15:27:31 +0800 Subject: [PATCH 09/10] usb kb test ok --- main/CMakeLists.txt | 7 + main/apps/app_keyboard/app_keyboard.cpp | 10 +- main/apps/app_keyboard/app_keyboard.h | 3 + .../usb_keyboard/usb_keyboard.cpp | 154 ++++++++++++++++++ .../usb_keyboard_wrap/usb_keyboard_wrap.c | 71 ++++---- .../usb_keyboard_wrap/usb_keyboard_wrap.h | 2 +- sdkconfig | 22 +-- 7 files changed, 225 insertions(+), 44 deletions(-) create mode 100644 main/apps/app_keyboard/usb_keyboard/usb_keyboard.cpp diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 7475b8d..5d68674 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -15,5 +15,12 @@ set(PIKA_PYTHON_INCS ./apps/app_repl/pikapython/pikascript-core/ ) + + idf_component_register(SRCS "cardputer.cpp" ${APPS_SRCS} ${HAL_SRCS} INCLUDE_DIRS "." "./hal" ${PIKA_PYTHON_INCS}) + + +idf_component_get_property(tusb_lib leeebo__tinyusb_src COMPONENT_LIB) +cmake_policy(SET CMP0079 NEW) +target_link_libraries(${tusb_lib} PRIVATE ${COMPONENT_LIB}) diff --git a/main/apps/app_keyboard/app_keyboard.cpp b/main/apps/app_keyboard/app_keyboard.cpp index 8819497..5d8fdcf 100644 --- a/main/apps/app_keyboard/app_keyboard.cpp +++ b/main/apps/app_keyboard/app_keyboard.cpp @@ -17,7 +17,8 @@ using namespace MOONCAKE::APPS; -#define TEST_USE_BLE +// #define TEST_USE_BLE +#define TEST_USE_USB void AppKeyboard::onCreate() @@ -47,6 +48,9 @@ void AppKeyboard::onResume() #ifdef TEST_USE_BLE _ble_kb_init(); #endif + #ifdef TEST_USE_USB + _usb_kb_init(); + #endif } @@ -63,6 +67,10 @@ void AppKeyboard::onRunning() _ble_kb_update_infos(); _ble_kb_update_kb_input(); #endif + #ifdef TEST_USE_USB + _usb_kb_update_infos(); + _usb_kb_update_kb_input(); + #endif } diff --git a/main/apps/app_keyboard/app_keyboard.h b/main/apps/app_keyboard/app_keyboard.h index 891e86a..233b001 100644 --- a/main/apps/app_keyboard/app_keyboard.h +++ b/main/apps/app_keyboard/app_keyboard.h @@ -36,6 +36,9 @@ namespace MOONCAKE void _ble_kb_init(); void _ble_kb_update_infos(); void _ble_kb_update_kb_input(); + void _usb_kb_init(); + void _usb_kb_update_infos(); + void _usb_kb_update_kb_input(); public: void onCreate() override; diff --git a/main/apps/app_keyboard/usb_keyboard/usb_keyboard.cpp b/main/apps/app_keyboard/usb_keyboard/usb_keyboard.cpp new file mode 100644 index 0000000..1b59690 --- /dev/null +++ b/main/apps/app_keyboard/usb_keyboard/usb_keyboard.cpp @@ -0,0 +1,154 @@ +/** + * @file usb_keyboard.cpp + * @author Forairaaaaa + * @brief + * @version 0.1 + * @date 2023-12-11 + * + * @copyright Copyright (c) 2023 + * + */ +#include "../app_keyboard.h" +#include "spdlog/spdlog.h" +#include "../../utils/wifi_common_test/wifi_common_test.h" +#include "../../utils/theme/theme_define.h" +#include "../../utils/usb_keyboard_wrap/usb_keyboard_wrap.h" + + +using namespace MOONCAKE::APPS; + +enum UsbKeyboardState_t +{ + _state_wait_connect = 0, + _state_mounted, +}; +static UsbKeyboardState_t _current_state = _state_wait_connect; +static bool _is_state_updated = true; + + +// Invoked when device is mounted +extern "C" void tud_mount_cb(void) +{ + _current_state = _state_mounted; + _is_state_updated = true; +} + +// Invoked when device is unmounted +extern "C" void tud_umount_cb(void) +{ + _current_state = _state_wait_connect; + _is_state_updated = true; +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allow us to perform remote wakeup +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +extern "C" void tud_suspend_cb(bool remote_wakeup_en) +{ + (void) remote_wakeup_en; +} + +// Invoked when usb bus is resumed +extern "C" void tud_resume_cb(void) +{ +} + + +void AppKeyboard::_usb_kb_init() +{ + usb_kb_wrap_init(); +} + + +void AppKeyboard::_usb_kb_update_infos() +{ + if (_is_state_updated) + { + _is_state_updated = false; + + _data.hal->canvas()->fillScreen(THEME_COLOR_BG); + + _data.hal->canvas()->setCursor(0, 0); + _data.hal->canvas()->setTextColor(TFT_ORANGE, THEME_COLOR_BG); + _data.hal->canvas()->printf("[USB Keyboard]\n"); + // _data.hal->canvas()->printf("> Name: %s\n", ble_keyboard_wrap_get_device_name()); + + // State + _data.hal->canvas()->printf("> State: "); + _data.hal->canvas()->setTextColor( + _current_state == _state_mounted ? TFT_GREENYELLOW : TFT_ORANGE, + THEME_COLOR_BG + ); + _data.hal->canvas()->printf( + "%s\n", + _current_state == _state_mounted ? "Mounted" : "Wait connect.." + ); + + _data.hal->canvas_update(); + } +} + + +static uint8_t _input_buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + +void AppKeyboard::_usb_kb_update_kb_input() +{ + if (_current_state != _state_mounted) + return; + + if (millis() - _data.update_kb_time_count > 10) + { + if (_data.hal->keyboard()->isChanged()) + { + uint8_t modifier = 0; + if (_data.hal->keyboard()->isPressed()) + { + memset(_input_buffer, 0, 8); + auto status = _data.hal->keyboard()->keysState(); + + int count = 0; + for (auto& i : status.hidKey) + { + if (count < 6) + { + _input_buffer[2 + count] = i; + count++; + } + } + + if (status.ctrl) + { + // ESP_LOGI(TAG, "CONTROL"); + // modifier |= 0x01; + modifier |= 0xE0; + } + + if (status.shift || _data.hal->keyboard()->capslocked()) { + // ESP_LOGI(TAG, "SHIFT"); + // modifier |= 0x02; + modifier |= 0xE1; + } + + if (status.alt) + { + // ESP_LOGI(TAG, "ALT"); + // modifier |= 0x03; + modifier |= 0xE2; + } + + _input_buffer[0] = modifier; + + // ESP_LOG_BUFFER_HEX(TAG, buffer, 8); + usb_kb_wrap_report(_input_buffer); + } + else + { + memset(_input_buffer, 0, 8); + usb_kb_wrap_report(_input_buffer); + } + } + + _data.update_kb_time_count = millis(); + } +} + diff --git a/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.c b/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.c index 87d9d1d..c637222 100644 --- a/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.c +++ b/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.c @@ -40,8 +40,8 @@ // } #ifdef CONFIG_SUBCLASS_KEYBOARD -static void button_keyboard_cb(void *arg, void *arg2) -{ +// static void button_keyboard_cb(void *arg, void *arg2) +// { // button_handle_t button_hdl = (button_handle_t)arg; // int button_gpio = get_button_gpio(button_hdl); // uint8_t _keycode[6] = { 0 }; @@ -55,11 +55,11 @@ static void button_keyboard_cb(void *arg, void *arg2) // break; // case EXAMPLE_BUTTON_LEFT: - // _keycode[0] = HID_KEY_L; + // _keycode[0] = HID_KEY_L; // break; // case EXAMPLE_BUTTON_RIGHT: - // _keycode[0] = HID_KEY_R; + // _keycode[0] = HID_KEY_R; // break; // default: @@ -67,10 +67,10 @@ static void button_keyboard_cb(void *arg, void *arg2) // } // tinyusb_hid_keyboard_report(_keycode); // ESP_LOGI(TAG, "Keyboard %c", _keycode[0] - HID_KEY_A + 'a'); -} +// } #elif defined CONFIG_SUBCLASS_MOUSE -static void button_mouse_cb(void *arg, void *arg2) -{ +// static void button_mouse_cb(void *arg, void *arg2) +// { // button_handle_t button_hdl = (button_handle_t)arg; // int button_gpio = get_button_gpio(button_hdl); // int mouse_offset_x = 0, mouse_offset_y = 0; @@ -96,7 +96,7 @@ static void button_mouse_cb(void *arg, void *arg2) // } // tinyusb_hid_mouse_move_report(mouse_offset_x, mouse_offset_y, 0, 0); // ESP_LOGI(TAG, "Mouse x=%d y=%d", mouse_offset_x, mouse_offset_y); -} +// } #endif //--------------------------------------------------------------------+ @@ -111,32 +111,32 @@ static void tusb_device_task(void *arg) } -// Invoked when device is mounted -void tud_mount_cb(void) -{ - ESP_LOGI(TAG, "USB Mount"); -} +// // Invoked when device is mounted +// void tud_mount_cb(void) +// { +// ESP_LOGI(TAG, "USB Mount"); +// } -// Invoked when device is unmounted -void tud_umount_cb(void) -{ - ESP_LOGI(TAG, "USB Un-Mount"); -} +// // Invoked when device is unmounted +// void tud_umount_cb(void) +// { +// ESP_LOGI(TAG, "USB Un-Mount"); +// } -// Invoked when usb bus is suspended -// remote_wakeup_en : if host allow us to perform remote wakeup -// Within 7ms, device must draw an average of current less than 2.5 mA from bus -void tud_suspend_cb(bool remote_wakeup_en) -{ - (void) remote_wakeup_en; - ESP_LOGI(TAG, "USB Suspend"); -} +// // Invoked when usb bus is suspended +// // remote_wakeup_en : if host allow us to perform remote wakeup +// // Within 7ms, device must draw an average of current less than 2.5 mA from bus +// void tud_suspend_cb(bool remote_wakeup_en) +// { +// (void) remote_wakeup_en; +// ESP_LOGI(TAG, "USB Suspend"); +// } -// Invoked when usb bus is resumed -void tud_resume_cb(void) -{ - ESP_LOGI(TAG, "USB Resume"); -} +// // Invoked when usb bus is resumed +// void tud_resume_cb(void) +// { +// ESP_LOGI(TAG, "USB Resume"); +// } //--------------------------------------------------------------------+ // USB PHY config @@ -153,12 +153,15 @@ static void usb_phy_init(void) usb_new_phy(&phy_conf, &phy_hdl); } +// static TaskHandle_t _task_handler; + void usb_kb_wrap_init(void) { // switch esp usb phy to usb-otg usb_phy_init(); tud_init(BOARD_TUD_RHPORT); xTaskCreate(tusb_device_task, "TinyUSB", 4096, NULL, 5, NULL); + // xTaskCreate(tusb_device_task, "TinyUSB", 4096, NULL, 5, &_task_handler); // /* buttons init, buttons used to simulate keyboard or mouse events */ // button_config_t cfg = { @@ -203,3 +206,9 @@ void usb_kb_wrap_report(uint8_t* keycode) { tinyusb_hid_keyboard_report(keycode); } + + +// void usb_kb_wrap_deinit() +// { +// vTaskDelete(_task_handler); +// } diff --git a/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.h b/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.h index 7058417..9178df3 100644 --- a/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.h +++ b/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.h @@ -21,4 +21,4 @@ void usb_kb_wrap_report(uint8_t* keycode); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/sdkconfig b/sdkconfig index 970df93..e956df3 100644 --- a/sdkconfig +++ b/sdkconfig @@ -1592,15 +1592,10 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # end of Supplicant # -# CMake Utilities +# TinyUSB soucre # -# CONFIG_CU_RELINKER_ENABLE is not set -# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set -CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y -# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set -# CONFIG_CU_GCC_LTO_ENABLE is not set -# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set -# end of CMake Utilities +# CONFIG_USING_SYNOPSYS_DWC2_DRIVER is not set +# end of TinyUSB soucre # # ESP-NOW Configuration @@ -1670,10 +1665,15 @@ CONFIG_ESPNOW_DEBUG_CONSOLE_UART_NUM=0 # end of ESP-NOW Configuration # -# TinyUSB soucre +# CMake Utilities # -# CONFIG_USING_SYNOPSYS_DWC2_DRIVER is not set -# end of TinyUSB soucre +# CONFIG_CU_RELINKER_ENABLE is not set +# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set +CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y +# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set +# CONFIG_CU_GCC_LTO_ENABLE is not set +# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set +# end of CMake Utilities # end of Component config # From 5885a09d5ff6c2d8a70160b714a07ed8cff0a920 Mon Sep 17 00:00:00 2001 From: Forairaaaaa Date: Mon, 11 Dec 2023 18:28:41 +0800 Subject: [PATCH 10/10] usb keyboard ok, add kb select menu --- main/apps/app_keyboard/app_keyboard.cpp | 48 ++++--- main/apps/app_keyboard/app_keyboard.h | 8 ++ .../ble_keyboard/ble_keyboarad.cpp | 1 - .../app_keyboard/select_menu/select_menu.cpp | 123 ++++++++++++++++++ .../usb_keyboard/usb_keyboard.cpp | 11 +- main/apps/launcher/views/boot_anim/logo.h | 46 +++---- .../usb_keyboard_wrap/usb_keyboard_wrap.h | 2 +- sdkconfig | 22 ++-- 8 files changed, 204 insertions(+), 57 deletions(-) create mode 100644 main/apps/app_keyboard/select_menu/select_menu.cpp diff --git a/main/apps/app_keyboard/app_keyboard.cpp b/main/apps/app_keyboard/app_keyboard.cpp index 5d8fdcf..128cae7 100644 --- a/main/apps/app_keyboard/app_keyboard.cpp +++ b/main/apps/app_keyboard/app_keyboard.cpp @@ -18,7 +18,7 @@ using namespace MOONCAKE::APPS; // #define TEST_USE_BLE -#define TEST_USE_USB +// #define TEST_USE_USB void AppKeyboard::onCreate() @@ -45,12 +45,19 @@ void AppKeyboard::onResume() spdlog::info("remain before: {}", uxTaskGetStackHighWaterMark(NULL)); } - #ifdef TEST_USE_BLE - _ble_kb_init(); - #endif - #ifdef TEST_USE_USB - _usb_kb_init(); - #endif + _select_kb_type(); + + // #ifdef TEST_USE_BLE + // _ble_kb_init(); + // #endif + // #ifdef TEST_USE_USB + // _usb_kb_init(); + // #endif + + if (_data.kb_type == kb_type_ble) + _ble_kb_init(); + else if (_data.kb_type == kb_type_usb) + _usb_kb_init(); } @@ -63,14 +70,25 @@ void AppKeyboard::onRunning() destroyApp(); } - #ifdef TEST_USE_BLE - _ble_kb_update_infos(); - _ble_kb_update_kb_input(); - #endif - #ifdef TEST_USE_USB - _usb_kb_update_infos(); - _usb_kb_update_kb_input(); - #endif + // #ifdef TEST_USE_BLE + // _ble_kb_update_infos(); + // _ble_kb_update_kb_input(); + // #endif + // #ifdef TEST_USE_USB + // _usb_kb_update_infos(); + // _usb_kb_update_kb_input(); + // #endif + + if (_data.kb_type == kb_type_ble) + { + _ble_kb_update_infos(); + _ble_kb_update_kb_input(); + } + else if (_data.kb_type == kb_type_usb) + { + _usb_kb_update_infos(); + _usb_kb_update_kb_input(); + } } diff --git a/main/apps/app_keyboard/app_keyboard.h b/main/apps/app_keyboard/app_keyboard.h index 233b001..18ba2e8 100644 --- a/main/apps/app_keyboard/app_keyboard.h +++ b/main/apps/app_keyboard/app_keyboard.h @@ -26,13 +26,21 @@ namespace MOONCAKE class AppKeyboard : public APP_BASE { private: + enum KeyboardType_t + { + kb_type_ble = 0, + kb_type_usb, + }; + struct Data_t { HAL::Hal* hal = nullptr; uint32_t update_infos_time_count = 0; uint32_t update_kb_time_count = 0; + KeyboardType_t kb_type = kb_type_ble; }; Data_t _data; + void _select_kb_type(); void _ble_kb_init(); void _ble_kb_update_infos(); void _ble_kb_update_kb_input(); diff --git a/main/apps/app_keyboard/ble_keyboard/ble_keyboarad.cpp b/main/apps/app_keyboard/ble_keyboard/ble_keyboarad.cpp index 36e9dc7..63e417c 100644 --- a/main/apps/app_keyboard/ble_keyboard/ble_keyboarad.cpp +++ b/main/apps/app_keyboard/ble_keyboard/ble_keyboarad.cpp @@ -10,7 +10,6 @@ */ #include "../app_keyboard.h" #include "spdlog/spdlog.h" -#include "../../utils/wifi_common_test/wifi_common_test.h" #include "../../utils/theme/theme_define.h" #include "../../utils/ble_keyboard_wrap/ble_keyboard_wrap.h" diff --git a/main/apps/app_keyboard/select_menu/select_menu.cpp b/main/apps/app_keyboard/select_menu/select_menu.cpp new file mode 100644 index 0000000..5b97fe7 --- /dev/null +++ b/main/apps/app_keyboard/select_menu/select_menu.cpp @@ -0,0 +1,123 @@ +/** + * @file select_menu.cpp + * @author Forairaaaaa + * @brief + * @version 0.1 + * @date 2023-12-11 + * + * @copyright Copyright (c) 2023 + * + */ +#include "../app_keyboard.h" +#include "spdlog/spdlog.h" +#include "../../utils/theme/theme_define.h" + + +using namespace MOONCAKE::APPS; + + +struct SelectItem_t +{ + std::string tag; + int x = 0; + int y = 0; + SelectItem_t(std::string tag, int x, int y) + { + this->tag = tag; + this->x = x; + this->y = y; + } +}; + + + +void AppKeyboard::_select_kb_type() +{ + int8_t selected = 0; + bool is_select_change = true; + std::vector item_list; + item_list.push_back(SelectItem_t("BLE Keyboard", 0, 32)); + item_list.push_back(SelectItem_t("USB Keyboard", 0, 56)); + + while (1) + { + // Update select + _data.hal->keyboard()->updateKeyList(); + _data.hal->keyboard()->updateKeysState(); + + if (_data.hal->keyboard()->isKeyPressing(55) || _data.hal->keyboard()->isKeyPressing(54)) + { + _data.hal->playKeyboardSound(); + + // Hold till release + while (_data.hal->keyboard()->isKeyPressing(55) || _data.hal->keyboard()->isKeyPressing(54)) + _data.hal->keyboard()->updateKeyList(); + + selected++; + if (selected >= item_list.size()) + selected = 0; + is_select_change = true; + + _data.hal->playNextSound(); + } + else if (_data.hal->keyboard()->isKeyPressing(53) || _data.hal->keyboard()->isKeyPressing(40)) + { + _data.hal->playKeyboardSound(); + + // Hold till release + while (_data.hal->keyboard()->isKeyPressing(53) || _data.hal->keyboard()->isKeyPressing(40)) + _data.hal->keyboard()->updateKeyList(); + + selected--; + if (selected < 0) + selected = item_list.size() - 1; + is_select_change = true; + + _data.hal->playNextSound(); + } + else if (_data.hal->keyboard()->isKeyPressing(42)) + { + _data.hal->playKeyboardSound(); + + // Hold till release + while (_data.hal->keyboard()->isKeyPressing(42)) + _data.hal->keyboard()->updateKeyList(); + + _data.hal->playNextSound(); + + // Quit + break; + } + + + // Render + if (is_select_change) + { + is_select_change = false; + + _data.hal->canvas()->fillScreen(THEME_COLOR_BG); + _data.hal->canvas()->setTextColor(TFT_ORANGE, THEME_COLOR_BG); + _data.hal->canvas()->setCursor(0, 0); + _data.hal->canvas()->print("[Select Type]"); + + for (int i = 0; i < item_list.size(); i++) + { + if (i == selected) + { + _data.hal->canvas()->fillSmoothCircle(item_list[i].x + 12, item_list[i].y + 8, 6, TFT_GREENYELLOW); + _data.hal->canvas()->setTextColor(TFT_GREENYELLOW, THEME_COLOR_BG); + } + else + _data.hal->canvas()->setTextColor(TFT_ORANGE, THEME_COLOR_BG); + + _data.hal->canvas()->setCursor(item_list[i].x + 26, item_list[i].y); + _data.hal->canvas()->print(item_list[i].tag.c_str()); + } + + _data.hal->canvas_update(); + } + } + + spdlog::info("selected {}", item_list[selected].tag); + _data.kb_type = static_cast(selected); +} diff --git a/main/apps/app_keyboard/usb_keyboard/usb_keyboard.cpp b/main/apps/app_keyboard/usb_keyboard/usb_keyboard.cpp index 1b59690..84a5794 100644 --- a/main/apps/app_keyboard/usb_keyboard/usb_keyboard.cpp +++ b/main/apps/app_keyboard/usb_keyboard/usb_keyboard.cpp @@ -10,7 +10,6 @@ */ #include "../app_keyboard.h" #include "spdlog/spdlog.h" -#include "../../utils/wifi_common_test/wifi_common_test.h" #include "../../utils/theme/theme_define.h" #include "../../utils/usb_keyboard_wrap/usb_keyboard_wrap.h" @@ -89,7 +88,7 @@ void AppKeyboard::_usb_kb_update_infos() } -static uint8_t _input_buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static uint8_t _input_buffer[6] = {0, 0, 0, 0, 0, 0}; void AppKeyboard::_usb_kb_update_kb_input() { @@ -103,15 +102,15 @@ void AppKeyboard::_usb_kb_update_kb_input() uint8_t modifier = 0; if (_data.hal->keyboard()->isPressed()) { - memset(_input_buffer, 0, 8); + memset(_input_buffer, 0, 6); auto status = _data.hal->keyboard()->keysState(); int count = 0; for (auto& i : status.hidKey) { - if (count < 6) + if (count < 5) { - _input_buffer[2 + count] = i; + _input_buffer[1 + count] = i; count++; } } @@ -143,7 +142,7 @@ void AppKeyboard::_usb_kb_update_kb_input() } else { - memset(_input_buffer, 0, 8); + memset(_input_buffer, 0, 6); usb_kb_wrap_report(_input_buffer); } } diff --git a/main/apps/launcher/views/boot_anim/logo.h b/main/apps/launcher/views/boot_anim/logo.h index a2b7cee..cd09746 100644 --- a/main/apps/launcher/views/boot_anim/logo.h +++ b/main/apps/launcher/views/boot_anim/logo.h @@ -3,7 +3,7 @@ * generated by lcd-image-converter rev.030b30d from 2019-03-17 01:38:34 +0500 * image * filename: unsaved -* name: logo_2 +* name: logo_3 * * preset name: Color R5G6B5 * data block size: 16 bit(s), uint16_t @@ -149,16 +149,16 @@ static const uint16_t image_data_logo[32400] = { // ████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ // ████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ // ████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ - // ████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▓▓▓█████▓▓▓██▓▓▓▓▓███████▓▓▓▓▓▓█████████ - // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▓▓█████▓▓██▓▓▓▓▓▓▓█████▓▓▓▓▓▓▓▓████████ - // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▓▓▓███▓▓▓█▓▓▓██▓▓▓█████▓▓▓██▓▓▓████████ - // ████████████████████████████████████████████████████████████████████████████████▓▓██████████████████▓▓███▓▓████████████████▓████████████▓▓▓▓▓█▓▓██████████████▓███████████████████████████████████████████▓▓███▓▓██▓▓▓███▓▓█████▓▓▓▓▓▓▓▓████████ - // ████████████████████████████████████████████████████████████████████████████████▓▓███▓▓▓▓▓██▓███▓▓██▓▓██▓▓██▓▓▓▓██▓▓██▓▓██▓▓▓▓██▓▓▓▓████▓█████▓▓▓██▓▓▓▓██▓▓▓▓▓▓▓▓█████████████████████████████████████████▓▓▓█▓▓▓██▓▓████▓▓██████▓▓▓▓▓▓█████████ - // ███████████████████████████████████████████████████████████████████████████████▓█▓▓██▓▓██▓▓█▓▓██▓███▓▓▓▓▓███▓▓█▓▓█▓▓██▓▓███▓███▓▓██▓████▓█████▓▓███▓██▓██▓▓███▓███████████████████████████████████████████▓▓▓█▓▓▓██▓▓████▓▓█████▓▓▓▓▓▓▓▓████████ - // ███████████████████████████████████████████████████████████████████████████████▓██▓██▓▓██▓▓██▓█▓▓███▓▓▓▓▓██▓▓██▓▓█▓▓▓▓▓████▓███▓███▓▓████▓▓▓██▓▓██████▓▓█▓▓███▓████████████████████████████████████████████▓▓▓▓▓███▓▓▓███▓▓█████▓▓▓███▓▓████████ - // ██████████████████████████████████████████████████████████████████████████████▓▓▓▓▓▓█▓▓██▓▓██▓█▓████▓▓▓▓▓▓█▓▓▓▓▓▓██▓▓▓▓████▓███▓███▓▓███████▓█▓▓███▓▓▓▓▓█▓▓███▓████████████████████████████████████████████▓▓▓▓▓███▓▓▓██▓▓▓█▓▓▓█▓▓▓██▓▓▓████████ - // ██████████████████████████████████████████████████████████████████████████████▓████▓█▓▓██▓▓███▓▓████▓▓██▓▓██▓▓█▓███▓▓▓█████▓███▓▓██▓████████▓█▓▓██▓▓██▓▓█▓▓███▓█████████████████████████████████████████████▓▓▓█████▓▓▓▓▓▓██▓▓▓█▓▓▓▓▓▓▓▓████████ - // █████████████████████████████████████████████████████████████████████████████▓▓████▓▓▓▓██▓▓███▓▓████▓▓███▓▓█▓▓▓▓████▓▓█████▓▓▓██▓▓▓▓████▓▓▓▓▓██▓▓▓█▓▓▓▓▓█▓▓███▓▓▓█▓█████████████████████████████████████████▓▓▓██████▓▓▓▓███▓▓▓███▓▓▓▓▓█████████ + // ████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▓▓▓█████▓▓▓██▓▓▓▓▓███████▓▓▓▓▓██████████ + // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▓▓█████▓▓██▓▓▓▓▓▓▓█████▓▓▓▓▓▓▓█████████ + // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▓▓▓███▓▓▓█▓▓▓██▓▓▓█████▓▓███▓▓▓████████ + // ████████████████████████████████████████████████████████████████████████████████▓▓██████████████████▓▓███▓▓████████████████▓████████████▓▓▓▓▓█▓▓██████████████▓███████████████████████████████████████████▓▓███▓▓██▓▓▓███▓▓█████▓▓███▓▓▓████████ + // ████████████████████████████████████████████████████████████████████████████████▓▓███▓▓▓▓▓██▓███▓▓██▓▓██▓▓██▓▓▓▓██▓▓██▓▓██▓▓▓▓██▓▓▓▓████▓█████▓▓▓██▓▓▓▓██▓▓▓▓▓▓▓▓█████████████████████████████████████████▓▓▓█▓▓▓██▓▓████▓▓█████▓▓▓▓▓▓▓▓████████ + // ███████████████████████████████████████████████████████████████████████████████▓█▓▓██▓▓██▓▓█▓▓██▓███▓▓▓▓▓███▓▓█▓▓█▓▓██▓▓███▓███▓▓██▓████▓█████▓▓███▓██▓██▓▓███▓███████████████████████████████████████████▓▓▓█▓▓▓██▓▓████▓▓██████▓▓▓▓▓▓▓████████ + // ███████████████████████████████████████████████████████████████████████████████▓██▓██▓▓██▓▓██▓█▓▓███▓▓▓▓▓██▓▓██▓▓█▓▓▓▓▓████▓███▓███▓▓████▓▓▓██▓▓██████▓▓█▓▓███▓████████████████████████████████████████████▓▓▓▓▓███▓▓▓███▓▓██████████▓▓▓████████ + // ██████████████████████████████████████████████████████████████████████████████▓▓▓▓▓▓█▓▓██▓▓██▓█▓████▓▓▓▓▓▓█▓▓▓▓▓▓██▓▓▓▓████▓███▓███▓▓███████▓█▓▓███▓▓▓▓▓█▓▓███▓████████████████████████████████████████████▓▓▓▓▓███▓▓▓██▓▓▓█▓▓▓█████▓▓▓█████████ + // ██████████████████████████████████████████████████████████████████████████████▓████▓█▓▓██▓▓███▓▓████▓▓██▓▓██▓▓█▓███▓▓▓█████▓███▓▓██▓████████▓█▓▓██▓▓██▓▓█▓▓███▓█████████████████████████████████████████████▓▓▓█████▓▓▓▓▓▓██▓▓▓█▓▓▓▓▓▓▓█████████ + // █████████████████████████████████████████████████████████████████████████████▓▓████▓▓▓▓██▓▓███▓▓████▓▓███▓▓█▓▓▓▓████▓▓█████▓▓▓██▓▓▓▓████▓▓▓▓▓██▓▓▓█▓▓▓▓▓█▓▓███▓▓▓█▓█████████████████████████████████████████▓▓▓██████▓▓▓▓███▓▓▓█▓▓▓▓▓███████████ // ██████████████████████████████████████████████████████████████████████████████████████████████▓███████████████████▓▓▓▓██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ // ████████████████████████████████████████████████████████████████████████████████████████████▓▓████████████████████▓▓▓███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ // ████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ @@ -283,17 +283,17 @@ static const uint16_t image_data_logo[32400] = { 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, - 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xdbde, 0xbad6, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xdbde, 0xbad6, 0xdbde, 0x3ce7, 0x3ce7, 0x1ce7, 0xbad6, 0xbad6, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xdbde, 0xbad6, 0xbad6, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, - 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xd7bd, 0xd39c, 0x14a5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x96b5, 0xd39c, 0xd7bd, 0x3ce7, 0x79ce, 0x34a5, 0xd39c, 0xd39c, 0x14a5, 0x18c6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xf7bd, 0x34a5, 0xd39c, 0xd39c, 0x14a5, 0xb6b5, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, - 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0xf39c, 0xd39c, 0x79ce, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0xf39c, 0xf39c, 0xbad6, 0x9ad6, 0x14a5, 0xd39c, 0x96b5, 0x96b5, 0xd39c, 0xd39c, 0x38c6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x18c6, 0xd39c, 0xd39c, 0x96b5, 0x96b5, 0xd39c, 0xd39c, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, - 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0xfbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x75ad, 0xd39c, 0x75ad, 0x3ce7, 0x3ce7, 0x3ce7, 0xd7bd, 0xd39c, 0x96b5, 0x3ce7, 0x75ad, 0xd39c, 0xb6b5, 0x3ce7, 0x3ce7, 0xf7bd, 0xd39c, 0x55ad, 0x1ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x96b5, 0xd39c, 0xb6b5, 0x3ce7, 0x3ce7, 0x18c6, 0xd39c, 0x34a5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, - 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x1ce7, 0xd39c, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x9ad6, 0x3ce7, 0x79ce, 0xd39c, 0xf7bd, 0xfbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x59ce, 0x55ad, 0x96b5, 0x55ad, 0x38c6, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x79ce, 0xd39c, 0x14a5, 0xdbde, 0x3ce7, 0xfbde, 0x34a5, 0xd39c, 0x79ce, 0xdbde, 0x34a5, 0xd39c, 0x59ce, 0x3ce7, 0x3ce7, 0xfbde, 0xd39c, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xf7bd, 0xd39c, 0x34a5, 0x59ce, 0x59ce, 0x75ad, 0xd39c, 0x96b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, - 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x79ce, 0xb6b5, 0xd39c, 0x1ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x55ad, 0x55ad, 0x55ad, 0x1ce7, 0x1ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0xb6b5, 0x59ce, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x9ad6, 0x79ce, 0xd39c, 0x96b5, 0x1ce7, 0x3ce7, 0x59ce, 0xd39c, 0xd39c, 0x96b5, 0xdbde, 0xbad6, 0xd39c, 0xb6b5, 0x3ce7, 0x3ce7, 0xd39c, 0x55ad, 0x1ce7, 0x3ce7, 0x96b5, 0xd39c, 0x96b5, 0x18c6, 0x3ce7, 0x1ce7, 0x96b5, 0x96b5, 0x34a5, 0x38c6, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0xd39c, 0x1ce7, 0x3ce7, 0x3ce7, 0xdbde, 0x79ce, 0x34a5, 0x34a5, 0x96b5, 0xdbde, 0x1ce7, 0xb6b5, 0x96b5, 0x34a5, 0xf7bd, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x55ad, 0x18c6, 0x96b5, 0xd39c, 0x96b5, 0x18c6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x55ad, 0xd39c, 0xd7bd, 0x3ce7, 0x38c6, 0xd39c, 0x55ad, 0x1ce7, 0xbad6, 0xd39c, 0xd39c, 0x79ce, 0x3ce7, 0x3ce7, 0xfbde, 0xd39c, 0xd39c, 0x9ad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xdbde, 0x75ad, 0xd39c, 0xd39c, 0xd39c, 0xd39c, 0x14a5, 0x9ad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, - 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x55ad, 0xbad6, 0x38c6, 0x18c6, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0xfbde, 0x3ce7, 0x96b5, 0x38c6, 0x3ce7, 0xf7bd, 0x18c6, 0x3ce7, 0xfbde, 0xd39c, 0xfbde, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0xb6b5, 0xd39c, 0x55ad, 0xfbde, 0x3ce7, 0xbad6, 0xd39c, 0xb6b5, 0x9ad6, 0xd39c, 0x55ad, 0x3ce7, 0x34a5, 0xd39c, 0x3ce7, 0x79ce, 0xd39c, 0x59ce, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0xf7bd, 0xf7bd, 0x3ce7, 0x1ce7, 0x34a5, 0x9ad6, 0x3ce7, 0x3ce7, 0xfbde, 0xd39c, 0x9ad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x1ce7, 0x59ce, 0x3ce7, 0x1ce7, 0xd39c, 0xbad6, 0x3ce7, 0x38c6, 0xd39c, 0xfbde, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x18c6, 0xd39c, 0x55ad, 0xbad6, 0x55ad, 0xd39c, 0x18c6, 0x3ce7, 0xbad6, 0xf39c, 0xd39c, 0x79ce, 0x3ce7, 0x3ce7, 0xfbde, 0xd39c, 0xd39c, 0x9ad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xb6b5, 0xd39c, 0xf39c, 0xb6b5, 0xd7bd, 0x34a5, 0xd39c, 0x55ad, 0x1ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, - 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x79ce, 0xb6b5, 0x3ce7, 0x1ce7, 0xd39c, 0x1ce7, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0xdbde, 0xd39c, 0x3ce7, 0x38c6, 0xf7bd, 0x3ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0xd39c, 0xd39c, 0xf7bd, 0x3ce7, 0x3ce7, 0xf7bd, 0xd39c, 0xbad6, 0x3ce7, 0xf7bd, 0xd39c, 0xdbde, 0x59ce, 0xd39c, 0x59ce, 0x96b5, 0xd39c, 0xfbde, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x38c6, 0xf7bd, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0xf7bd, 0x55ad, 0xf7bd, 0xfbde, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x96b5, 0x59ce, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0x14a5, 0xd39c, 0xf7bd, 0xd39c, 0x14a5, 0xfbde, 0x3ce7, 0x3ce7, 0x34a5, 0xd39c, 0x38c6, 0x3ce7, 0x3ce7, 0x9ad6, 0xd39c, 0xd39c, 0xfbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x1ce7, 0xf39c, 0xd39c, 0x38c6, 0x3ce7, 0x3ce7, 0x9ad6, 0xd39c, 0xd39c, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, - 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x55ad, 0x34a5, 0x96b5, 0x96b5, 0xd39c, 0x38c6, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x55ad, 0x79ce, 0x34a5, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x55ad, 0x55ad, 0xd39c, 0x59ce, 0x3ce7, 0x96b5, 0xd39c, 0xd39c, 0xd39c, 0xd39c, 0xd39c, 0x9ad6, 0x1ce7, 0xd39c, 0x34a5, 0xd39c, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x38c6, 0xf7bd, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x79ce, 0xd39c, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0xfbde, 0x55ad, 0x18c6, 0x38c6, 0x34a5, 0x59ce, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xb6b5, 0xd39c, 0xd39c, 0xd39c, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0xd7bd, 0xd39c, 0x55ad, 0x9ad6, 0x9ad6, 0x96b5, 0xd39c, 0x55ad, 0x1ce7, 0x59ce, 0x55ad, 0x38c6, 0x1ce7, 0x55ad, 0xd39c, 0xd7bd, 0x9ad6, 0x9ad6, 0x38c6, 0xd39c, 0xd39c, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, - 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0x34a5, 0x3ce7, 0x3ce7, 0x3ce7, 0xdbde, 0xd39c, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x79ce, 0xd39c, 0x55ad, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x9ad6, 0xfbde, 0xd39c, 0xd39c, 0xdbde, 0x79ce, 0xd39c, 0xb6b5, 0xbad6, 0x59ce, 0xdbde, 0x3ce7, 0x3ce7, 0xb6b5, 0xd39c, 0xd39c, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0xf7bd, 0xf7bd, 0x3ce7, 0x1ce7, 0x34a5, 0x9ad6, 0x3ce7, 0x3ce7, 0xfbde, 0xbad6, 0x3ce7, 0x3ce7, 0x1ce7, 0xd39c, 0xfbde, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x38c6, 0x96b5, 0x3ce7, 0x1ce7, 0x34a5, 0x59ce, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x9ad6, 0xd39c, 0xd39c, 0xd39c, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0x34a5, 0xd39c, 0xf39c, 0xf39c, 0xd39c, 0x34a5, 0x9ad6, 0x3ce7, 0x75ad, 0xd39c, 0x34a5, 0x3ce7, 0x18c6, 0xd39c, 0xd39c, 0xf39c, 0xf39c, 0xd39c, 0xd39c, 0xb6b5, 0x1ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, - 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x96b5, 0x59ce, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x96b5, 0x59ce, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0x59ce, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x9ad6, 0x3ce7, 0xbad6, 0xd39c, 0x34a5, 0x1ce7, 0x38c6, 0x55ad, 0xd39c, 0x55ad, 0x79ce, 0x3ce7, 0x3ce7, 0x9ad6, 0xd39c, 0x34a5, 0x1ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x18c6, 0x34a5, 0x55ad, 0x1ce7, 0x1ce7, 0x96b5, 0x55ad, 0x55ad, 0x18c6, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0xf7bd, 0x55ad, 0x96b5, 0x55ad, 0x59ce, 0x3ce7, 0xfbde, 0xd39c, 0x55ad, 0x59ce, 0x1ce7, 0x55ad, 0x55ad, 0x96b5, 0xd39c, 0x59ce, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x18c6, 0x34a5, 0x55ad, 0x1ce7, 0x34a5, 0x9ad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x55ad, 0x14a5, 0x75ad, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0xf7bd, 0x34a5, 0x14a5, 0xb6b5, 0x9ad6, 0x3ce7, 0x3ce7, 0x38c6, 0x34a5, 0x18c6, 0x3ce7, 0x3ce7, 0x79ce, 0xb6b5, 0x34a5, 0x34a5, 0x96b5, 0x59ce, 0x1ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xdbde, 0xbad6, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xdbde, 0xbad6, 0xdbde, 0x3ce7, 0x3ce7, 0x1ce7, 0xbad6, 0xbad6, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xdbde, 0xbad6, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xd7bd, 0xd39c, 0x14a5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x96b5, 0xd39c, 0xd7bd, 0x3ce7, 0x79ce, 0x34a5, 0xd39c, 0xd39c, 0x14a5, 0x18c6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x9ad6, 0x55ad, 0xd39c, 0xd39c, 0xd39c, 0x75ad, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0xf39c, 0xd39c, 0x79ce, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0xf39c, 0xf39c, 0xbad6, 0x9ad6, 0x14a5, 0xd39c, 0x96b5, 0x96b5, 0xd39c, 0xd39c, 0x38c6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xdbde, 0x34a5, 0xd39c, 0x34a5, 0xb6b5, 0x34a5, 0xd39c, 0x55ad, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0xfbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x75ad, 0xd39c, 0x75ad, 0x3ce7, 0x3ce7, 0x3ce7, 0xd7bd, 0xd39c, 0x96b5, 0x3ce7, 0x75ad, 0xd39c, 0xb6b5, 0x3ce7, 0x3ce7, 0xf7bd, 0xd39c, 0x55ad, 0x1ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x79ce, 0xd39c, 0xf39c, 0x1ce7, 0x3ce7, 0x1ce7, 0x14a5, 0xd39c, 0x38c6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x1ce7, 0xd39c, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x9ad6, 0x3ce7, 0x79ce, 0xd39c, 0xf7bd, 0xfbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x59ce, 0x55ad, 0x96b5, 0x55ad, 0x38c6, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x79ce, 0xd39c, 0x14a5, 0xdbde, 0x3ce7, 0xfbde, 0x34a5, 0xd39c, 0x79ce, 0xdbde, 0x34a5, 0xd39c, 0x59ce, 0x3ce7, 0x3ce7, 0xfbde, 0xd39c, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x79ce, 0xd39c, 0xf39c, 0xbad6, 0x3ce7, 0x9ad6, 0xf39c, 0xd39c, 0x96b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x79ce, 0xb6b5, 0xd39c, 0x1ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x55ad, 0x55ad, 0x55ad, 0x1ce7, 0x1ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0xb6b5, 0x59ce, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x9ad6, 0x79ce, 0xd39c, 0x96b5, 0x1ce7, 0x3ce7, 0x59ce, 0xd39c, 0xd39c, 0x96b5, 0xdbde, 0xbad6, 0xd39c, 0xb6b5, 0x3ce7, 0x3ce7, 0xd39c, 0x55ad, 0x1ce7, 0x3ce7, 0x96b5, 0xd39c, 0x96b5, 0x18c6, 0x3ce7, 0x1ce7, 0x96b5, 0x96b5, 0x34a5, 0x38c6, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0xd39c, 0x1ce7, 0x3ce7, 0x3ce7, 0xdbde, 0x79ce, 0x34a5, 0x34a5, 0x96b5, 0xdbde, 0x1ce7, 0xb6b5, 0x96b5, 0x34a5, 0xf7bd, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x55ad, 0x18c6, 0x96b5, 0xd39c, 0x96b5, 0x18c6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x55ad, 0xd39c, 0xd7bd, 0x3ce7, 0x38c6, 0xd39c, 0x55ad, 0x1ce7, 0xbad6, 0xd39c, 0xd39c, 0x79ce, 0x3ce7, 0x3ce7, 0xfbde, 0xd39c, 0xd39c, 0x9ad6, 0x3ce7, 0x3ce7, 0x3ce7, 0xdbde, 0x34a5, 0xd39c, 0xf39c, 0x14a5, 0xf39c, 0xd39c, 0xd39c, 0x75ad, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x55ad, 0xbad6, 0x38c6, 0x18c6, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0xfbde, 0x3ce7, 0x96b5, 0x38c6, 0x3ce7, 0xf7bd, 0x18c6, 0x3ce7, 0xfbde, 0xd39c, 0xfbde, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0xb6b5, 0xd39c, 0x55ad, 0xfbde, 0x3ce7, 0xbad6, 0xd39c, 0xb6b5, 0x9ad6, 0xd39c, 0x55ad, 0x3ce7, 0x34a5, 0xd39c, 0x3ce7, 0x79ce, 0xd39c, 0x59ce, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0xf7bd, 0xf7bd, 0x3ce7, 0x1ce7, 0x34a5, 0x9ad6, 0x3ce7, 0x3ce7, 0xfbde, 0xd39c, 0x9ad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x1ce7, 0x59ce, 0x3ce7, 0x1ce7, 0xd39c, 0xbad6, 0x3ce7, 0x38c6, 0xd39c, 0xfbde, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x18c6, 0xd39c, 0x55ad, 0xbad6, 0x55ad, 0xd39c, 0x18c6, 0x3ce7, 0xbad6, 0xf39c, 0xd39c, 0x79ce, 0x3ce7, 0x3ce7, 0xfbde, 0xd39c, 0xd39c, 0x9ad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x9ad6, 0x96b5, 0xf39c, 0xf39c, 0x96b5, 0x96b5, 0xd39c, 0x96b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x79ce, 0xb6b5, 0x3ce7, 0x1ce7, 0xd39c, 0x1ce7, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0xdbde, 0xd39c, 0x3ce7, 0x38c6, 0xf7bd, 0x3ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0xd39c, 0xd39c, 0xf7bd, 0x3ce7, 0x3ce7, 0xf7bd, 0xd39c, 0xbad6, 0x3ce7, 0xf7bd, 0xd39c, 0xdbde, 0x59ce, 0xd39c, 0x59ce, 0x96b5, 0xd39c, 0xfbde, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x38c6, 0xf7bd, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0xf7bd, 0x55ad, 0xf7bd, 0xfbde, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x96b5, 0x59ce, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0x14a5, 0xd39c, 0xf7bd, 0xd39c, 0x14a5, 0xfbde, 0x3ce7, 0x3ce7, 0x34a5, 0xd39c, 0x38c6, 0x3ce7, 0x3ce7, 0x9ad6, 0xd39c, 0xd39c, 0xfbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x1ce7, 0x55ad, 0xd39c, 0xf7bd, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x55ad, 0x34a5, 0x96b5, 0x96b5, 0xd39c, 0x38c6, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x55ad, 0x79ce, 0x34a5, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x55ad, 0x55ad, 0xd39c, 0x59ce, 0x3ce7, 0x96b5, 0xd39c, 0xd39c, 0xd39c, 0xd39c, 0xd39c, 0x9ad6, 0x1ce7, 0xd39c, 0x34a5, 0xd39c, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x38c6, 0xf7bd, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x79ce, 0xd39c, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0xfbde, 0x55ad, 0x18c6, 0x38c6, 0x34a5, 0x59ce, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xb6b5, 0xd39c, 0xd39c, 0xd39c, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0xd7bd, 0xd39c, 0x55ad, 0x9ad6, 0x9ad6, 0x96b5, 0xd39c, 0x55ad, 0x1ce7, 0x59ce, 0x55ad, 0x38c6, 0x3ce7, 0xbad6, 0x9ad6, 0x1ce7, 0x9ad6, 0xb6b5, 0xd39c, 0x14a5, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0x34a5, 0x3ce7, 0x3ce7, 0x3ce7, 0xdbde, 0xd39c, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x79ce, 0xd39c, 0x55ad, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x9ad6, 0xfbde, 0xd39c, 0xd39c, 0xdbde, 0x79ce, 0xd39c, 0xb6b5, 0xbad6, 0x59ce, 0xdbde, 0x3ce7, 0x3ce7, 0xb6b5, 0xd39c, 0xd39c, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0xf7bd, 0xf7bd, 0x3ce7, 0x1ce7, 0x34a5, 0x9ad6, 0x3ce7, 0x3ce7, 0xfbde, 0xbad6, 0x3ce7, 0x3ce7, 0x1ce7, 0xd39c, 0xfbde, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x38c6, 0x96b5, 0x3ce7, 0x1ce7, 0x34a5, 0x59ce, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0xdbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x9ad6, 0xd39c, 0xd39c, 0xd39c, 0xbad6, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0x34a5, 0xd39c, 0xf39c, 0xf39c, 0xd39c, 0x34a5, 0x9ad6, 0x3ce7, 0x75ad, 0xd39c, 0x34a5, 0x3ce7, 0x96b5, 0xf39c, 0xf39c, 0xf39c, 0xd39c, 0x14a5, 0x59ce, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x96b5, 0x59ce, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x96b5, 0x59ce, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0xd39c, 0x59ce, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x38c6, 0xd39c, 0x9ad6, 0x3ce7, 0xbad6, 0xd39c, 0x34a5, 0x1ce7, 0x38c6, 0x55ad, 0xd39c, 0x55ad, 0x79ce, 0x3ce7, 0x3ce7, 0x9ad6, 0xd39c, 0x34a5, 0x1ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x18c6, 0x34a5, 0x55ad, 0x1ce7, 0x1ce7, 0x96b5, 0x55ad, 0x55ad, 0x18c6, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0xf7bd, 0x55ad, 0x96b5, 0x55ad, 0x59ce, 0x3ce7, 0xfbde, 0xd39c, 0x55ad, 0x59ce, 0x1ce7, 0x55ad, 0x55ad, 0x96b5, 0xd39c, 0x59ce, 0x3ce7, 0x38c6, 0xb6b5, 0x3ce7, 0x3ce7, 0x3ce7, 0x18c6, 0x34a5, 0x55ad, 0x1ce7, 0x34a5, 0x9ad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x55ad, 0x14a5, 0x75ad, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0xf7bd, 0x34a5, 0x14a5, 0xb6b5, 0x9ad6, 0x3ce7, 0x3ce7, 0x38c6, 0x34a5, 0x18c6, 0x3ce7, 0x18c6, 0x75ad, 0x34a5, 0x34a5, 0xd7bd, 0x9ad6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xfbde, 0xd39c, 0xfbde, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x1ce7, 0x59ce, 0x38c6, 0xd39c, 0x59ce, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0xd39c, 0x55ad, 0x79ce, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0xbad6, 0xd39c, 0xd39c, 0x18c6, 0x1ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, @@ -302,6 +302,6 @@ static const uint16_t image_data_logo[32400] = { 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7 }; -// const tImage logo_2 = { image_data_logo_2, 240, 135, +// const tImage logo_3 = { image_data_logo_3, 240, 135, // 16 }; diff --git a/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.h b/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.h index 9178df3..c176005 100644 --- a/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.h +++ b/main/apps/utils/usb_keyboard_wrap/usb_keyboard_wrap.h @@ -1,7 +1,7 @@ /** * @file usb_keyboard_wrap.h * @author Forairaaaaa - * @brief + * @brief Ref: https://github.com/espressif/esp-iot-solution/tree/master/examples/usb/device/usb_hid_device * @version 0.1 * @date 2023-12-11 * diff --git a/sdkconfig b/sdkconfig index e956df3..6d8934e 100644 --- a/sdkconfig +++ b/sdkconfig @@ -1591,6 +1591,17 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # CONFIG_WPA_DPP_SUPPORT is not set # end of Supplicant +# +# CMake Utilities +# +# CONFIG_CU_RELINKER_ENABLE is not set +# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set +CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y +# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set +# CONFIG_CU_GCC_LTO_ENABLE is not set +# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set +# end of CMake Utilities + # # TinyUSB soucre # @@ -1663,17 +1674,6 @@ CONFIG_ESPNOW_DEBUG_CONSOLE_UART_NUM_0=y CONFIG_ESPNOW_DEBUG_CONSOLE_UART_NUM=0 # end of ESP-NOW Debug Configuration # end of ESP-NOW Configuration - -# -# CMake Utilities -# -# CONFIG_CU_RELINKER_ENABLE is not set -# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set -CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y -# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set -# CONFIG_CU_GCC_LTO_ENABLE is not set -# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set -# end of CMake Utilities # end of Component config #