From 112a9593e0e24397a5a7f3cc6cfc8ff87a84fa09 Mon Sep 17 00:00:00 2001 From: Philip Smart Date: Sat, 25 Jun 2022 10:55:24 +0100 Subject: [PATCH] Updates and compile and test verification --- .gitignore | 1 + sdkconfig | 264 ++++-- v1.2/CMakeLists.txt | 8 + v1.2/main/CMakeLists.txt | 4 + v1.2/main/Kconfig.projbuild | 416 ++++++++++ v1.2/main/MZKeyTable.h | 309 +++++++ v1.2/main/PS2KeyAdvanced.cpp | 1093 +++++++++++++++++++++++++ v1.2/main/PS2KeyAdvanced.h | 445 ++++++++++ v1.2/main/PS2KeyCode.h | 276 +++++++ v1.2/main/PS2KeyTable.h | 397 +++++++++ v1.2/main/component.mk | 8 + v1.2/main/font8x8_basic.h | 174 ++++ v1.2/main/main.cpp | 1254 ++++++++++++++++++++++++++++ v1.2/main/ssd1306.c | 229 ++++++ v1.2/main/ssd1306.h | 143 ++++ v1.2/main/ssd1306_i2c.c | 253 ++++++ v1.2/main/ssd1306_spi.c | 253 ++++++ v1.2/sdkconfig | 1493 ++++++++++++++++++++++++++++++++++ 18 files changed, 6968 insertions(+), 52 deletions(-) create mode 100644 v1.2/CMakeLists.txt create mode 100644 v1.2/main/CMakeLists.txt create mode 100644 v1.2/main/Kconfig.projbuild create mode 100644 v1.2/main/MZKeyTable.h create mode 100644 v1.2/main/PS2KeyAdvanced.cpp create mode 100644 v1.2/main/PS2KeyAdvanced.h create mode 100644 v1.2/main/PS2KeyCode.h create mode 100644 v1.2/main/PS2KeyTable.h create mode 100644 v1.2/main/component.mk create mode 100644 v1.2/main/font8x8_basic.h create mode 100644 v1.2/main/main.cpp create mode 100644 v1.2/main/ssd1306.c create mode 100644 v1.2/main/ssd1306.h create mode 100644 v1.2/main/ssd1306_i2c.c create mode 100644 v1.2/main/ssd1306_spi.c create mode 100644 v1.2/sdkconfig diff --git a/.gitignore b/.gitignore index d3e4eb7..ea1f474 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,4 @@ sdkconfigq components.x/ components/ main/main.cpp.bak2 +webfs/ diff --git a/sdkconfig b/sdkconfig index 8ae8532..34a35d2 100644 --- a/sdkconfig +++ b/sdkconfig @@ -40,10 +40,10 @@ CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 # CONFIG_ENABLE_ARDUINO_DEPENDS=y # CONFIG_AUTOSTART_ARDUINO is not set -CONFIG_ARDUINO_RUN_CORE0=y +# CONFIG_ARDUINO_RUN_CORE0 is not set # CONFIG_ARDUINO_RUN_CORE1 is not set -# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_RUNNING_CORE=0 +CONFIG_ARDUINO_RUN_NO_AFFINITY=y +CONFIG_ARDUINO_RUNNING_CORE=-1 CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 CONFIG_ARDUINO_EVENT_RUN_CORE0=y # CONFIG_ARDUINO_EVENT_RUN_CORE1 is not set @@ -77,7 +77,34 @@ CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y # 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 is not set +CONFIG_ARDUINO_SELECTIVE_COMPILATION=y +CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y +# 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=y +CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y +# CONFIG_ARDUINO_SELECTIVE_FFat is not set +CONFIG_ARDUINO_SELECTIVE_FS=y +CONFIG_ARDUINO_SELECTIVE_HTTPClient=y +CONFIG_ARDUINO_SELECTIVE_LITTLEFS=y +# CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set +CONFIG_ARDUINO_SELECTIVE_Preferences=y +# 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=y +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 # @@ -90,11 +117,11 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set # CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set # CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set -CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y +# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set # CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set # CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set -CONFIG_BOOTLOADER_LOG_LEVEL=3 +CONFIG_BOOTLOADER_LOG_LEVEL=2 # CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y # CONFIG_BOOTLOADER_FACTORY_RESET is not set @@ -176,9 +203,11 @@ CONFIG_PARTITION_TABLE_MD5=y # # SharpKey Configuration # -CONFIG_SHARPKEY=y -# CONFIG_MZ25KEY_MZ2500 is not set +# CONFIG_SHARPKEY is not set +CONFIG_MZ25KEY_MZ2500=y # CONFIG_MZ25KEY_MZ2800 is not set +CONFIG_DISABLE_FEATURE_SECURITY=y +# CONFIG_ENABLE_FEATURE_SECURITY is not set # # PS2 Keyboard @@ -308,9 +337,101 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # # Bluetooth # -# CONFIG_BT_ENABLED is not set +CONFIG_BT_ENABLED=y + +# +# Bluetooth controller +# +# CONFIG_BTDM_CTRL_MODE_BLE_ONLY is not set +# CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set +CONFIG_BTDM_CTRL_MODE_BTDM=y +CONFIG_BTDM_CTRL_BLE_MAX_CONN=5 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN=5 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN=0 +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI=y +# CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_PCM is not set +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_AUTO_LATENCY=y +CONFIG_BTDM_CTRL_AUTO_LATENCY_EFF=y +CONFIG_BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT=y +CONFIG_BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT_EFF=y +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=5 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=5 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y +# CONFIG_BTDM_CTRL_PINNED_TO_CORE_1 is not set +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y +# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set + +# +# MODEM SLEEP Options +# +# CONFIG_BTDM_CTRL_MODEM_SLEEP is not set +# end of MODEM SLEEP Options + +CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM=y +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 +CONFIG_BTDM_BLE_SCAN_DUPL=y +CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA is not set +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE is not set +CONFIG_BTDM_SCAN_DUPL_TYPE=0 +CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=10 +# CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set +CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_BTDM_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_CTRL_HLI=y +# 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_CLASSIC_ENABLED=y +# CONFIG_BT_A2DP_ENABLE is not set +# CONFIG_BT_SPP_ENABLED is not set +# CONFIG_BT_HFP_ENABLE is not set +CONFIG_BT_HID_ENABLED=y +CONFIG_BT_HID_HOST_ENABLED=y +# CONFIG_BT_HID_DEVICE_ENABLED is not set +CONFIG_BT_SSP_ENABLED=y +CONFIG_BT_BLE_ENABLED=y +# CONFIG_BT_GATTS_ENABLE is not set +CONFIG_BT_GATTC_ENABLE=y +# CONFIG_BT_GATTC_CACHE_NVS_FLASH is not set +CONFIG_BT_GATTC_CONNECT_RETRY_COUNT=7 +CONFIG_BT_BLE_SMP_ENABLE=y +# CONFIG_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set +CONFIG_BT_STACK_NO_LOG=y +CONFIG_BT_ACL_CONNECTIONS=5 +CONFIG_BT_MULTI_CONNECTION_ENBALE=y +# CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST 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 +CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=60 +# CONFIG_BT_BLE_RPA_SUPPORTED is not set +# end of Bluedroid Options # end of Bluetooth +# CONFIG_BLE_MESH is not set + # # CoAP Configuration # @@ -387,12 +508,11 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # CONFIG_EFUSE_CUSTOM_TABLE=y CONFIG_EFUSE_CUSTOM_TABLE_FILENAME="main/esp_efuse_custom_table.csv" -CONFIG_EFUSE_VIRTUAL=y -# CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH is not set -# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set -CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +# CONFIG_EFUSE_VIRTUAL is not set +CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE=y +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4 is not set # CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set -CONFIG_EFUSE_MAX_BLK_LEN=192 +CONFIG_EFUSE_MAX_BLK_LEN=256 # end of eFuse Bit Manager # @@ -450,7 +570,6 @@ CONFIG_ESP32_XTAL_FREQ_40=y # CONFIG_ESP32_XTAL_FREQ_AUTO is not set CONFIG_ESP32_XTAL_FREQ=40 # CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set -# CONFIG_ESP32_NO_BLOBS is not set # CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set # CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set @@ -483,10 +602,7 @@ CONFIG_ETH_RMII_CLK_IN_GPIO=0 CONFIG_ETH_DMA_BUFFER_SIZE=512 CONFIG_ETH_DMA_RX_BUFFER_NUM=10 CONFIG_ETH_DMA_TX_BUFFER_NUM=10 -CONFIG_ETH_USE_SPI_ETHERNET=y -# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set -# CONFIG_ETH_SPI_ETHERNET_W5500 is not set -# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set +# CONFIG_ETH_USE_SPI_ETHERNET is not set # CONFIG_ETH_USE_OPENETH is not set # end of Ethernet @@ -593,9 +709,9 @@ CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y # CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=10 -CONFIG_ESP_PHY_MAX_TX_POWER=10 -CONFIG_ESP_PHY_REDUCE_TX_POWER=y +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set # end of PHY # @@ -634,16 +750,15 @@ CONFIG_ESP_CONSOLE_MULTIPLE_UART=y CONFIG_ESP_CONSOLE_UART_NUM=0 CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 CONFIG_ESP_INT_WDT=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=1000 +CONFIG_ESP_INT_WDT_TIMEOUT_MS=5000 # CONFIG_ESP_INT_WDT_CHECK_CPU1 is not set CONFIG_ESP_TASK_WDT=y -# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_PANIC=y CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 # CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set # CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set # CONFIG_ESP_PANIC_HANDLER_IRAM is not set -# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y # end of ESP System Settings # @@ -663,13 +778,14 @@ CONFIG_ESP_TIMER_IMPL_TG0_LAC=y # Wi-Fi # CONFIG_ESP32_WIFI_ENABLED=y +# CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE is not set 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 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_CSI_ENABLED=y CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y @@ -681,7 +797,7 @@ CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 CONFIG_ESP32_WIFI_IRAM_OPT=y CONFIG_ESP32_WIFI_RX_IRAM_OPT=y -CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +# CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE is not set # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set # CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set # CONFIG_ESP_WIFI_GMAC_SUPPORT is not set @@ -949,10 +1065,10 @@ CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0=y # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x0 # CONFIG_LWIP_PPP_SUPPORT is not set CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 @@ -1024,8 +1140,8 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set # end of Certificate Bundle -# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set -# CONFIG_MBEDTLS_CMAC_C is not set +CONFIG_MBEDTLS_ECP_RESTARTABLE=y +CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_HARDWARE_MPI=y CONFIG_MBEDTLS_HARDWARE_SHA=y @@ -1142,10 +1258,9 @@ CONFIG_MDNS_MULTIPLE_INSTANCE=y # # ESP-MQTT Configurations # -CONFIG_MQTT_PROTOCOL_311=y -CONFIG_MQTT_TRANSPORT_SSL=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_PROTOCOL_311 is not set +# CONFIG_MQTT_TRANSPORT_SSL is not set +# CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set # CONFIG_MQTT_MSG_ID_INCREMENTAL is not set # CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set # CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set @@ -1175,7 +1290,7 @@ CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y # OpenSSL # # CONFIG_OPENSSL_DEBUG is not set -CONFIG_OPENSSL_ERROR_STACK=y +# CONFIG_OPENSSL_ERROR_STACK is not set # CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set CONFIG_OPENSSL_ASSERT_EXIT=y # end of OpenSSL @@ -1228,7 +1343,7 @@ CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y # end of Auto-detect flash chips -CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE is not set # end of SPI Flash driver # @@ -1321,6 +1436,7 @@ 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 # end of Wi-Fi Provisioning Manager # @@ -1366,11 +1482,11 @@ CONFIG_LITTLEFS_MTIME_USE_SECONDS=y CONFIG_TOOLPREFIX="xtensa-esp32-elf-" # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set -CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +CONFIG_LOG_BOOTLOADER_LEVEL_WARN=y +# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set # CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set # CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set -CONFIG_LOG_BOOTLOADER_LEVEL=3 +CONFIG_LOG_BOOTLOADER_LEVEL=2 # CONFIG_APP_ROLLBACK_ENABLE is not set # CONFIG_FLASH_ENCRYPTION_ENABLED is not set # CONFIG_FLASHMODE_QIO is not set @@ -1402,6 +1518,50 @@ 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_BTDM_CONTROLLER_MODE_BLE_ONLY is not set +# CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY is not set +CONFIG_BTDM_CONTROLLER_MODE_BTDM=y +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=5 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN=5 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN=0 +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=5 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=5 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 +CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y +# CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 is not set +# CONFIG_BTDM_CONTROLLER_MODEM_SLEEP is not set +CONFIG_BLE_SCAN_DUPLICATE=y +CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y +# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA is not set +# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set +CONFIG_SCAN_DUPLICATE_TYPE=0 +CONFIG_DUPLICATE_SCAN_CACHE_SIZE=10 +# CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM=100 +CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +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_CLASSIC_BT_ENABLED=y +# CONFIG_A2DP_ENABLE is not set +# CONFIG_HFP_ENABLE is not set +# CONFIG_GATTS_ENABLE is not set +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_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=60 CONFIG_ADC2_DISABLE_DAC=y # CONFIG_SPIRAM_SUPPORT is not set CONFIG_TRACEMEM_RESERVE_DRAM=0x0 @@ -1422,7 +1582,6 @@ CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y # CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set # CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set # CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set -# CONFIG_NO_BLOBS is not set # CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y @@ -1435,9 +1594,9 @@ CONFIG_ESP_SYSTEM_PD_FLASH=y CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=10 -CONFIG_ESP32_PHY_MAX_TX_POWER=10 -CONFIG_ESP32_REDUCE_PHY_TX_POWER=y +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set # CONFIG_ESP32S2_PANIC_PRINT_HALT is not set CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y # CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set @@ -1452,14 +1611,15 @@ CONFIG_CONSOLE_UART=y CONFIG_CONSOLE_UART_NUM=0 CONFIG_CONSOLE_UART_BAUDRATE=115200 CONFIG_INT_WDT=y -CONFIG_INT_WDT_TIMEOUT_MS=1000 +CONFIG_INT_WDT_TIMEOUT_MS=5000 # CONFIG_INT_WDT_CHECK_CPU1 is not set CONFIG_TASK_WDT=y -# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_PANIC=y CONFIG_TASK_WDT_TIMEOUT_S=5 # CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set # CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set CONFIG_TIMER_TASK_STACK_SIZE=3584 +# CONFIG_SW_COEXIST_ENABLE is not set # 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 @@ -1501,10 +1661,10 @@ CONFIG_TCP_OVERSIZE_MSS=y # CONFIG_TCP_OVERSIZE_DISABLE is not set CONFIG_UDP_RECVMBOX_SIZE=6 CONFIG_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_TCPIP_TASK_AFFINITY_CPU0=y # CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_TCPIP_TASK_AFFINITY=0x0 # CONFIG_PPP_SUPPORT is not set CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 diff --git a/v1.2/CMakeLists.txt b/v1.2/CMakeLists.txt new file mode 100644 index 0000000..f0aff97 --- /dev/null +++ b/v1.2/CMakeLists.txt @@ -0,0 +1,8 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(main) diff --git a/v1.2/main/CMakeLists.txt b/v1.2/main/CMakeLists.txt new file mode 100644 index 0000000..910363b --- /dev/null +++ b/v1.2/main/CMakeLists.txt @@ -0,0 +1,4 @@ +set(COMPONENT_SRCS main.cpp ssd1306.c ssd1306_i2c.c ssd1306_spi.c PS2KeyAdvanced.cpp) +set(COMPONENT_ADD_INCLUDEDIRS ".") + +register_component() diff --git a/v1.2/main/Kconfig.projbuild b/v1.2/main/Kconfig.projbuild new file mode 100644 index 0000000..c966472 --- /dev/null +++ b/v1.2/main/Kconfig.projbuild @@ -0,0 +1,416 @@ +menu "MZ25Key Configuration" + + menu "PS2 Keyboard" + + config PS2_HW_DATAPIN + int "GPIO pin number used for the PS/2 DATA line" + range 0 46 + default 14 + help + GPIO number (IOxx) used to connect with the PS/2 Keyboard DATA line. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C. + GPIOs 35-39 are input-only so cannot be used as outputs. + + config PS2_HW_CLKPIN + int "GPIO pin number used for the PS/2 CLK line" + range 0 46 + default 13 + help + GPIO number (IOxx) used to connect with the PS/2 Keyboard CLK line. + This pin must be interrupt capable. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C. + GPIOs 35-39 are input-only so cannot be used as outputs. + + choice KEYBOARD + prompt "Keyboard mapping" + default KEYMAP_WYSE_KB3926 + help + Choose the PS/2 Keyboard being used with the interface. This option selects the map defined in + PS2KeyTable.h which maps the PS/2 Keyboard scan codes to the standard PS2_KEY_* definitions used + in the map to MZ-2500/2800 keys. + + config KEYMAP_WYSE_KB3926 + bool "Wyse KB-3926" + help + The Wyse KB3296 PS/2 keyboard mapping. + + config KEYMAP_STANDARD + bool "Standard Definition" + help + A generic PS/2 keyboard mapping. + + endchoice + + endmenu + + menu "MZ-2500/2800 Interface" + choice "Model" + prompt "Machine Model" + default MODEL_MZ2500 + help + Choose the target machine on which the interface will be used. The MZ-2500 and MZ-2800 have the same keyboard hardware but the protocol differs and this option + will choose the correct protocol. + + config MODEL_MZ2500 + bool "Sharp MZ-2500" + help + The target machine is a Sharp MZ-2500. + + config MODEL_MZ2800 + bool "Sharp MZ-2800" + help + The target machine is a Sharp MZ-2800. + endchoice + + menu "4Bit Strobe Input" + + config MZ_KDB0 + int "KDB0 GPIO pin number" + range 0 46 + default 23 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 4bit bidirectional data bus Bit 0 with the ESP32. See schematic for actual used value. May change with revisions. + + config MZ_KDB1 + int "KDB1 GPIO pin number" + range 0 46 + default 25 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 4bit bidirectional data bus Bit 1 with the ESP32. See schematic for actual used value. May change with revisions. + + config MZ_KDB2 + int "KDB2 GPIO pin number" + range 0 46 + default 26 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 4bit bidirectional data bus Bit 2 with the ESP32. See schematic for actual used value. May change with revisions. + + config MZ_KDB3 + int "KDB3 GPIO pin number" + range 0 46 + default 27 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 4bit bidirectional data bus Bit 3 with the ESP32. See schematic for actual used value. May change with revisions. + endmenu + + menu "8Bit Scan Data Output" + config MZ_KDO0 + int "KDO0 GPIO pin number" + range 0 46 + default 14 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 0 to the 74HCT257 IC. See schematic for actual used value. May change with revisions. + + config MZ_KDO1 + int "KDO1 GPIO pin number" + range 0 46 + default 15 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 1 to the 74HCT257 IC. See schematic for actual used value. May change with revisions. + + config MZ_KDO2 + int "KDO2 GPIO pin number" + range 0 46 + default 16 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 2 to the 74HCT257 IC. See schematic for actual used value. May change with revisions. + + config MZ_KDO3 + int "KDO3 GPIO pin number" + range 0 46 + default 17 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 3 to the 74HCT257 IC. See schematic for actual used value. May change with revisions. + + config MZ_KDO4 + int "KDO4 GPIO pin number" + range 0 46 + default 18 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 4 to the 74HCT257 IC. See schematic for actual used value. May change with revisions. + + config MZ_KDO5 + int "KDO5 GPIO pin number" + range 0 46 + default 19 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 5 to the 74HCT257 IC. See schematic for actual used value. May change with revisions. + + config MZ_KDO6 + int "KDO6 GPIO pin number" + range 0 46 + default 21 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 6 to the 74HCT257 IC. See schematic for actual used value. May change with revisions. + + config MZ_KDO7 + int "KDO7 GPIO pin number" + range 0 46 + default 21 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 7 to the 74HCT257 IC. See schematic for actual used value. May change with revisions. + endmenu + + config MZ_RTSNI + int "RTSNi GPIO pin number" + range 0 46 + default 35 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 RTSN line with the ESP32. See schematic for actual used value. May change with revisions. + + config MZ_KDI4 + int "KDI4 GPIO pin number" + range 0 46 + default 13 + help + GPIO number (IOxx) used to connect the MZ-2500/2800 KDI4 line with the ESP32. See schematic for actual used value. May change with revisions. + + endmenu + + menu "WiFi" + + config MZ_WIFI_ENABLED + bool "Enable WiFi connectivity" + default false + help + Allow interface to act as an Access Point to allow external connectivity. Once connected the WiFi is intended to be used for making + key mapping changes. + This is an experimental feature and under development. + + config MZ_WIFI_EN_KEY + int "WiFi Enable GPIO pin number" + range 0 46 + default 34 + depends on MZ_WIFI_ENABLED + help + GPIO number (IOxx) used by the WiFi En switch to enable wifi connectivity. + + config MZ_SSID + string "Default SSID in Access Point Mode" + default "mz25key" + depends on MZ_WIFI_ENABLED + help + The SSID broadcast whilst the mz25key module advertises wireless connectivity. + + config MZ_DEFAULT_SSID_PWD + string "Default password for initial connection to Access Point Mode" + default "mz25key" + depends on MZ_WIFI_ENABLED + help + The initial password needed to connect and logon to access point. + + config MZ_WIFI_MAX_RETRIES + int "Maximum number of connection retries." + range 0 100 + default 10 + depends on MZ_WIFI_ENABLED + help + Number of retries allowed for making a wireless connection with a client. + + config MZ_WIFI_AP_CHANNEL + int "Channel of the Access Point." + range 0 13 + default 7 + depends on MZ_WIFI_ENABLED + help + Channel use by the Access Point, default is 7. + + config MZ_WIFI_SSID_HIDDEN + int "Broadcast SSID?" + range 0 1 + default 0 + depends on MZ_WIFI_ENABLED + help + Broadcast the SSID (0) or hide it (1). + + config MZ_WIFI_MAX_CONNECTIONS + int "Maximum sinultaneous connections." + range 0 20 + default 5 + depends on MZ_WIFI_ENABLED + help + Maximum number of simultaneous open connections supported. + + endmenu + + menu "Debug Options" + + menu "OLED" + + choice INTERFACE + prompt "OLED Interface Type" + default OLED_DISABLED + help + Select Interface. + config OLED_DISABLED + bool "Interface disabled" + help + No OLED present or to be disabled. + config I2C_INTERFACE + bool "I2C Interface" + help + I2C Interface. + config SPI_INTERFACE + bool "SPI Interface" + help + SPI Interface. + endchoice + + choice PANEL + prompt "OLED Panel Type" + depends on I2C_INTERFACE || SPI_INTERFACE + default SSD1306_128x64 + help + Select Panel Type. + config SSD1306_128x32 + bool "128x32 Panel" + help + Panel is 128x32. + config SSD1306_128x64 + bool "128x64 Panel" + help + Panel is 128x64. + endchoice + + config OFFSETX + int "GRAM X OFFSET" + range 0 99 + default 0 + help + When your TFT have offset(X), set it. + + config FLIP + bool "Flip upside down" + default false + help + Flip upside down. + + config SCL_GPIO + depends on I2C_INTERFACE + int "SCL GPIO number" + range 0 46 + default 22 if IDF_TARGET_ESP32 + default 12 if IDF_TARGET_ESP32S2 + default 9 if IDF_TARGET_ESP32C3 + default 15 if IDF_TARGET_HELTEC32 + help + GPIO number (IOxx) to I2C SCL. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C. + GPIOs 35-39 are input-only so cannot be used as outputs. + + config SDA_GPIO + depends on I2C_INTERFACE + int "SDA GPIO number" + range 0 46 + default 21 if IDF_TARGET_ESP32 + default 11 if IDF_TARGET_ESP32S2 + default 10 if IDF_TARGET_ESP32C3 + default 4 if IDF_TARGET_HELTEC32 + help + GPIO number (IOxx) to I2C SDA. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C. + GPIOs 35-39 are input-only so cannot be used as outputs. + + config RESET_GPIO + int "RESET GPIO number" + range -1 46 + default -1 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 + default 16 if IDF_TARGET_HELTEC32 + help + GPIO number (IOxx) to RESET. + When it is -1, RESET isn't performed. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to Reset. + GPIOs 35-39 are input-only so cannot be used as outputs. + + config MOSI_GPIO + depends on SPI_INTERFACE + int "MOSI GPIO number" + range 0 46 + default 23 if IDF_TARGET_ESP32 + default 35 if IDF_TARGET_ESP32S2 + default 0 if IDF_TARGET_ESP32C3 + help + GPIO number (IOxx) to SPI MOSI. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to DC. + On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs. + On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs. + + config SCLK_GPIO + depends on SPI_INTERFACE + int "SCLK GPIO number" + range 0 46 + default 18 if IDF_TARGET_ESP32 + default 36 if IDF_TARGET_ESP32S2 + default 1 if IDF_TARGET_ESP32C3 + help + GPIO number (IOxx) to SPI SCLK. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to DC. + On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs. + On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs. + + config CS_GPIO + depends on SPI_INTERFACE + int "CS GPIO number" + range 0 34 + default 5 if IDF_TARGET_ESP32 + default 34 if IDF_TARGET_ESP32S2 + default 10 if IDF_TARGET_ESP32C3 + help + GPIO number (IOxx) to SPI CS. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to CS. + GPIOs 35-39 are input-only so cannot be used as outputs. + + config DC_GPIO + depends on SPI_INTERFACE + int "DC GPIO number" + range 0 34 + default 2 + help + GPIO number (IOxx) to SPI DC. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to DC. + GPIOs 35-39 are input-only so cannot be used as outputs. + + endmenu + + config MZ_DEBUG_SERIAL + bool "Serial debug output" + default false + help + Enable debug output (non ESP logging) on the serial port. + + config MZ_DISABLE_KDB + bool "Disable input mode actuation of the KDB data bus" + default false + help + Disable the MZ Interface KDB input configuration step, useful feature for debugging. + + config MZ_DISABLE_KDO + bool "Disable output mode actuation of the KDO strobe row" + default false + help + Disable the MZ Interface KDO output configuration step, useful feature for debugging. + + config MZ_DISABLE_RTSNI + bool "Disable input mode actuation of the RTSNi signal" + default false + help + Disable the MZ Interface RTSNi input configuration step, useful feature for debugging. + + config MZ_DISABLE_KDI + bool "Disable input mode actuation of the KDI4 signal" + default false + help + Disable the MZ Interface KDI input configuration step, useful feature for debugging. + endmenu + + config PWRLED + int "GPIO pin number used for Power On and Status LED" + range 0 46 + default 25 + help + GPIO number (IOxx) used to control the Power On/Status LED. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C. + GPIOs 35-39 are input-only so cannot be used as outputs. + +endmenu + diff --git a/v1.2/main/MZKeyTable.h b/v1.2/main/MZKeyTable.h new file mode 100644 index 0000000..f81c030 --- /dev/null +++ b/v1.2/main/MZKeyTable.h @@ -0,0 +1,309 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Name: MZKeyTable.h +// Created: Jan 2022 +// Version: v1.0 +// Author(s): Philip Smart +// Description: The PS/2 Scan Code to MZ-2500/2800 Key Matrix mapping logic. +// This source file contains the definitions and tables to convert a PS/2 scan code +// into an MZ 14x8 matrix equivalent for the received key. The matrix is then read +// out to the MZ-2500/2800 as though it was a real keyboard. +// Credits: +// Copyright: (c) 2019-2022 Philip Smart +// +// History: Jan 2022 - Initial write. +// Feb 2022 - Added parameterisation to the mapping table such that keymaps +// are applied according to machine selected to cater for differences +// between the MZ2500/2000/80B. Also added release parameters which are +// needed when say SHIFT+Key on PS/2 is required whereas on the MZ +// only the mapped key. As SHIFT is an override and will be presented to +// the MZ, it needs to be deactivated before applying a mapped key then +// reactivated after completion. +// +// Notes: See Makefile to enable/disable conditional components +// +///////////////////////////////////////////////////////////////////////////////////////////////////////// +// This source file is free software: you can redistribute it and#or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef KEYTABLE_H +#define KEYTABLE_H + +// The initial mapping is made inside the PS2KeyAdvanced class from Scan Code Set 2 to ASCII +// for a selected keyboard. Special functions are detected and combined inside this module +// before mapping with the table below to MZ Scan Matrix. +// ie. PS/2 Scan Code -> ASCII + Flags -> MZ Scan Matrix +#include + +/////////////////////////// +// MZ-2500 Keyboard Map. // +/////////////////////////// +// +// Row D7 D6 D5 D4 D3 D2 D1 D0 +//---------------------------------------------------------------------------------- +// 0 F8 F7 F6 F5 F4 F3 F2 F1 +// 1 KP - KP + KP . KP , KP 9 KP 8 F1O F9 +// 2 KP 7 KP 6 KP 5 KP 4 KP 3 KP 2 KP 1 KP 0 +// 3 BREAK RIGHT LEFT DOWN UP RETURN SPACE TAB +// 4 G F E D C B A / ? +// 5 O N M L K J I H +// 6 W V U T S R Q P +// 7 , < . > _ YEN | ^ '¿ Z ¿ Y X ¿ +// 8 7 ' 6 & 5 % 4 $ 3 # 2 " 1 ! 0 +// 9 [ { @ ` - = ; + : * 9 ) 8 ( +// 10 KP / KP * ESC BACKSPACE INST/DEL CLR/HOME COPY ] } +// 11 CTRL KANA SHIFT LOCK GRAPH +// 12 KJ2 KJ1 +// 13 HELP ARGO +// +// Col 0 1 2 3 4 5 6 7 8 9 10 11 12 13 +// -------------------------------------------------------------------------------------------------------------------------------------- +// D0 F1 F9 KP 0 TAB / ? H P X 0 8 ( ] } GRAPH KJ1 ARGO +// D1 F2 F10 KP 1 SPACE A I Q Y 1 ! 9 ) COPY LOCK KJ2 HELP +// D2 F3 KP 8 KP 2 RETURN B J R Z 2 " : * CLR/HOME SHIFT +// D3 F4 KP 9 KP 3 UP C K S ^ '¿ 3 # ; + INST/DEL KANA +// D4 F5 KP , KP 4 DOWN D L T YEN | 4 $ - = BACKSPACE CTRL +// D5 F6 KP . KP 5 LEFT E M U _ 5 % @ ` ESC +// D6 F7 KP + KP 6 RIGHT F N V . > 6 & [ { KP * +// D7 F8 KP - KP 7 BREAK G O W , < 7 ' KP / +// +// + +#define MZ_ALL 0 +#define MZ_80B 1 +#define MZ_2000 2 +#define MZ_2500 3 +#define PSMZTBL_KEYPOS 0 +#define PSMZTBL_MACHINE 1 +#define PSMZTBL_SHIFTPOS 2 +#define PSMZTBL_FUNCPOS 3 +#define PSMZTBL_CTRLPOS 4 +#define PSMZTBL_ALTPOS 5 +#define PSMZTBL_ALTGRPOS 6 +#define PSMZTBL_GUIPOS 7 +#define PSMZTBL_MK_ROW1 8 +#define PSMZTBL_MK_KEY1 9 +#define PSMZTBL_MK_ROW2 10 +#define PSMZTBL_MK_KEY2 11 +#define PSMZTBL_MK_ROW3 12 +#define PSMZTBL_MK_KEY3 13 +#define PSMZTBL_BRK_ROW1 14 +#define PSMZTBL_BRK_KEY1 15 +#define PSMZTBL_BRK_ROW2 16 +#define PSMZTBL_BRK_KEY2 17 +#define PSMZTBL_MAXROWS 18 + +// Lookup table to matrix row/column co-ordinates. +// +// Given that the MZ-2500 can emulate 3 machines and each machine has it's own mapping, differences are tagged by machine name, ie. ALL, MZ80B, MZ2000, MZ2500 +// +// If a PS2 key is matched, then the Matrix is updated using MK_ROW to point into the array with MK_KEY being the column value, equivalent of strobe line and +// the required KEY bits to be set. Upto 3 matrix bits can be set (3 key presses on the MZ-2500 keyboard) per PS/2 key. Upto 2 matrix releases can be set per +// PS/2 key. A key release is used when a modifier may already have been pressed, ie. SHIFT and it needs to be released to set the required key into the matrix. +// A set bit = 1, reset bits = 0 but is inverted in the actual matrix (1 = inactive, 0 = active), this applies for releases two, if bit = 1 then that key will be released. +// The table is scanned for a match from top to bottom. The first match is used so order is important. Japanese characters are being added as I gleam more information. +// +#if defined(CONFIG_KEYMAP_WYSE_KB3926) || defined(CONFIG_KEYMAP_STANDARD) + // + // This mapping is for the UK Wyse KB-3926 PS/2 keyboard + // + const unsigned char PS2toMZ[][PSMZTBL_MAXROWS] = + { + // < Keys to be applied on match > < Keys to be reset on match > + // PS2 Code Machine Shift Function Ctrl ALT ALT-Gr GUI MK_ROW1 MK_KEY1 MK_ROW2 MK_KEY2 MK_ROW3 MK_KEY3 BRK_ROW1 BRK_KEY1 BRK_ROW2 BRK_KEY2 + PS2_KEY_F1, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // F1 + PS2_KEY_F2, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // F2 + PS2_KEY_F3, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x00, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // F3 + PS2_KEY_F4, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // F4 + PS2_KEY_F5, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x00, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // F5 + PS2_KEY_F6, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x00, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // F6 + PS2_KEY_F7, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x00, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // F7 + PS2_KEY_F8, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // F8 + PS2_KEY_F9, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // F9 + PS2_KEY_F10, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x01, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // F10 + PS2_KEY_F11, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0D, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // HELP + PS2_KEY_F12, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0A, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // COPY + PS2_KEY_TAB, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x03, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // TAB + PS2_KEY_0, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x09, 0x02, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Close Right Bracket ) + PS2_KEY_0, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x08, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0 + PS2_KEY_1, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x08, 0x02, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Exclamation + PS2_KEY_1, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x08, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 1 + PS2_KEY_2, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x08, 0x04, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Double quote. + PS2_KEY_2, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x08, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 2 + PS2_KEY_3, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x08, 0x08, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Pound Sign -> Hash + PS2_KEY_3, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 3 + PS2_KEY_4, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x08, 0x10, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Dollar + PS2_KEY_4, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x08, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 4 + PS2_KEY_5, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x08, 0x20, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Percent + PS2_KEY_5, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x08, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 5 + PS2_KEY_6, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x07, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0x0B, 0x04, 0xFF, 0xFF, // Kappa + PS2_KEY_6, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x08, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 6 + PS2_KEY_7, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x08, 0x40, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Ampersand + PS2_KEY_7, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x08, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 7 + PS2_KEY_8, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x09, 0x04, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Star + PS2_KEY_8, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x09, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 8 + PS2_KEY_9, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x09, 0x01, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Open Left Bracket ( + PS2_KEY_9, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x09, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 9 + PS2_KEY_A, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x04, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // a + PS2_KEY_A, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x04, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // A + PS2_KEY_B, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x04, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // b + PS2_KEY_B, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x04, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // B + PS2_KEY_C, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // c + PS2_KEY_C, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C + PS2_KEY_D, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x04, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // d + PS2_KEY_D, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x04, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // D + PS2_KEY_E, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x04, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // e + PS2_KEY_E, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x04, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // E + PS2_KEY_F, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x04, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // f + PS2_KEY_F, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x04, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // F + PS2_KEY_G, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x04, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // g + PS2_KEY_G, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x04, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // G + PS2_KEY_H, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x05, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // h + PS2_KEY_H, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x05, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // H + PS2_KEY_I, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x05, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // i + PS2_KEY_I, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x05, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // I + PS2_KEY_J, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // j + PS2_KEY_J, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // J + PS2_KEY_K, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x05, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // k + PS2_KEY_K, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x05, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // K + PS2_KEY_L, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x05, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // l + PS2_KEY_L, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x05, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // L + PS2_KEY_M, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x05, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // m + PS2_KEY_M, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x05, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // M + PS2_KEY_N, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x05, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // n + PS2_KEY_N, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x05, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // N + PS2_KEY_O, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x05, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // o + PS2_KEY_O, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x05, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // O + PS2_KEY_P, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x06, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // p + PS2_KEY_P, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x06, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // P + PS2_KEY_Q, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x06, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // q + PS2_KEY_Q, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x06, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Q + PS2_KEY_R, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x06, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // r + PS2_KEY_R, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x06, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // R + PS2_KEY_S, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x06, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // s + PS2_KEY_S, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x06, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // S + PS2_KEY_T, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x06, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // t + PS2_KEY_T, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x06, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // T + PS2_KEY_U, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x06, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // u + PS2_KEY_U, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x06, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // U + PS2_KEY_V, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x06, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // v + PS2_KEY_V, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x06, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // V + PS2_KEY_W, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x06, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // w + PS2_KEY_W, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x06, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // W + PS2_KEY_X, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x07, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // x + PS2_KEY_X, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x07, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // X + PS2_KEY_Y, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x07, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // y + PS2_KEY_Y, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x07, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Y + PS2_KEY_Z, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x07, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // z + PS2_KEY_Z, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x07, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Z + // PS2 Code Machine Shift Function Ctrl ALT ALT-Gr GUI MK_ROW1 MK_KEY1 MK_ROW2 MK_KEY2 MK_ROW3 MK_KEY3 BRK_ROW1 BRK_KEY1 BRK_ROW2 BRK_KEY2 + PS2_KEY_SPACE, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x03, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Space + PS2_KEY_COMMA, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x07, 0x80, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Less Than < + PS2_KEY_COMMA, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x07, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Comma , + PS2_KEY_SEMI, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x09, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x0B, 0x04, 0xFF, 0xFF, // Colon : + PS2_KEY_SEMI, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x09, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Semi-Colon ; + PS2_KEY_DOT, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x07, 0x40, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Greater Than > + PS2_KEY_DOT, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x07, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Full stop . + PS2_KEY_DIV, MZ_2000, 1, 0, 0, 0, 0, 0, 0x07, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0x0B, 0x04, 0xFF, 0xFF, // Question ? + PS2_KEY_DIV, MZ_80B, 1, 0, 0, 0, 0, 0, 0x07, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0x0B, 0x04, 0xFF, 0xFF, // Question ? + PS2_KEY_DIV, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x04, 0x01, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Question ? + PS2_KEY_DIV, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x04, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Divide / + PS2_KEY_MINUS, MZ_2000, 1, 0, 0, 0, 0, 0, 0x08, 0x01, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Upper bar + PS2_KEY_MINUS, MZ_80B, 1, 0, 0, 0, 0, 0, 0x08, 0x01, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Upper bar + PS2_KEY_MINUS, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x07, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0x0B, 0x04, 0xFF, 0xFF, // Underscore + PS2_KEY_MINUS, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x09, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_APOS, MZ_80B, 1, 0, 0, 0, 0, 0, 0x09, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0x0B, 0x04, 0xFF, 0xFF, // At @ + PS2_KEY_APOS, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x09, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0x0B, 0x04, 0xFF, 0xFF, // At @ + PS2_KEY_APOS, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x08, 0x80, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Single quote ' + PS2_KEY_OPEN_SQ, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x09, 0x40, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Open Left Brace { + PS2_KEY_OPEN_SQ, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x09, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Open Left Square Bracket [ + PS2_KEY_EQUAL, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x09, 0x08, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Plus + + PS2_KEY_EQUAL, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x09, 0x10, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Equal = + PS2_KEY_CAPS, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0B, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // LOCK + PS2_KEY_ENTER, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x03, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // ENTER/RETURN + PS2_KEY_CLOSE_SQ, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x0A, 0x01, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Close Right Brace } + PS2_KEY_CLOSE_SQ, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0A, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Close Right Square Bracket ] + PS2_KEY_BACK, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x07, 0x10, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // + PS2_KEY_BACK, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x07, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Back slash maps to Yen + PS2_KEY_BTICK, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x07, 0x10, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Pipe + PS2_KEY_BTICK, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x09, 0x20, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Back tick ` + PS2_KEY_HASH, MZ_2000, 1, 0, 0, 0, 0, 0, 0x07, 0x08, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Tilde + PS2_KEY_HASH, MZ_80B, 1, 0, 0, 0, 0, 0, 0x07, 0x08, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Tilde + PS2_KEY_HASH, MZ_ALL, 1, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Tilde has no mapping. + PS2_KEY_HASH, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Hash + PS2_KEY_BS, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0A, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Backspace + PS2_KEY_ESC, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0A, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // ESCape + PS2_KEY_SCROLL, MZ_ALL, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Not assigned. + PS2_KEY_INSERT, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0A, 0x08, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // INSERT + PS2_KEY_HOME, MZ_ALL, 1, 0, 0, 0, 0, 0, 0x0A, 0x04, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // CLR + PS2_KEY_HOME, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0A, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // HOME + PS2_KEY_PGUP, MZ_ALL, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Not assigned. + PS2_KEY_DELETE, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0A, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // DELETE + PS2_KEY_END, MZ_ALL, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Not assigned. + #if defined(CONFIG_MODEL_MZ2500) + PS2_KEY_PGDN, MZ_ALL, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Not mapped + #endif + #if defined(CONFIG_MODEL_MZ2800) + PS2_KEY_PGDN, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0C, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Japanese Key - Previous + #endif + PS2_KEY_UP_ARROW, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x03, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Up Arrow + PS2_KEY_L_ARROW, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x03, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Left Arrow + PS2_KEY_DN_ARROW, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x03, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Down Arrow + PS2_KEY_R_ARROW, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x03, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Right Arrow + PS2_KEY_NUM, MZ_ALL, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Not assigned. + + // Keypad. + PS2_KEY_KP0, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x02, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad 0 + PS2_KEY_KP1, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x02, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad 1 + PS2_KEY_KP2, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x02, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad 2 + PS2_KEY_KP3, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x02, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad 3 + PS2_KEY_KP4, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x02, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad 4 + PS2_KEY_KP5, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad 5 + PS2_KEY_KP6, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x02, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad 6 + PS2_KEY_KP7, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x02, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad 7 + PS2_KEY_KP8, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x01, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad 8 + PS2_KEY_KP9, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x01, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad 9 + PS2_KEY_KP_COMMA, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x01, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad Comma , + PS2_KEY_KP_DOT, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x01, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad Full stop . + PS2_KEY_KP_PLUS, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x01, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad Plus + + PS2_KEY_KP_MINUS, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad Minus - + PS2_KEY_KP_TIMES, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0A, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad Times * + PS2_KEY_KP_DIV, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0A, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad Divide / + PS2_KEY_KP_ENTER, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x03, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Keypad Ebter / + + // PS2 Code Machine Shift Function Ctrl ALT ALT-Gr GUI MK_ROW1 MK_KEY1 MK_ROW2 MK_KEY2 MK_ROW3 MK_KEY3 BRK_ROW1 BRK_KEY1 BRK_ROW2 BRK_KEY2 + + // Special keys. + PS2_KEY_PRTSCR, MZ_ALL, 0, 1, 0, 0, 0, 0, 0x0D, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // ARGO KEY + PS2_KEY_PAUSE, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x03, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // BREAK KEY + PS2_KEY_L_GUI, MZ_ALL, 0, 1, 0, 0, 0, 1, 0x0B, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // GRAPH KEY + PS2_KEY_L_ALT, MZ_ALL, 0, 1, 0, 1, 0, 0, 0x0C, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // KJ1 Sentence + PS2_KEY_R_ALT, MZ_ALL, 0, 1, 0, 0, 1, 0, 0x0C, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // KJ2 Transform + PS2_KEY_R_GUI, MZ_ALL, 0, 1, 0, 0, 0, 1, 0x0B, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // KANA KEY + PS2_KEY_MENU, MZ_ALL, 0, 1, 0, 0, 0, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Not assigned. + // Modifiers are last, only being selected if an earlier match isnt made. + PS2_KEY_L_SHIFT, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_R_SHIFT, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_L_CTRL, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0B, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + #if defined(CONFIG_MODEL_MZ2500) + PS2_KEY_R_CTRL, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0B, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Map to Control + #endif + #if defined(CONFIG_MODEL_MZ2800) + PS2_KEY_R_CTRL, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0C, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Japanese Key - Cancel + #endif + 0, MZ_ALL, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; +#endif + +#endif // KEYTABLE_H diff --git a/v1.2/main/PS2KeyAdvanced.cpp b/v1.2/main/PS2KeyAdvanced.cpp new file mode 100644 index 0000000..6f7784a --- /dev/null +++ b/v1.2/main/PS2KeyAdvanced.cpp @@ -0,0 +1,1093 @@ +/* Version V1.0.9 + PS2KeyAdvanced.cpp - PS2KeyAdvanced library + Copyright (c) 2007 Free Software Foundation. All right reserved. + Written by Paul Carpenter, PC Services + Created September 2014 + Updated January 2016 - Paul Carpenter - add tested on Due and tidy ups for V1.5 Library Management + January 2020 Fix typos, correct keyboard reset status improve library.properties + and additional platform handling and some documentation + March 2020 Add SAMD1 as recognised support as has been tested by user + Improve different architecture handling + November 2020 Add support for STM32 from user Hiabuto-de + Tested on STM32Duino-Framework and PlatformIO on STM32F103C8T6 and an IBM Model M + July 2021 Add workaround for ESP32 issue with Silicon (hardware) from user submissions + + IMPORTANT WARNING + + If using a DUE or similar board with 3V3 I/O you MUST put a level translator + like a Texas Instruments TXS0102 or FET circuit as the signals are + Bi-directional (signals transmitted from both ends on same wire). + + Failure to do so may damage your Arduino Due or similar board. + + Test History + September 2014 Uno and Mega 2560 September 2014 using Arduino V1.6.0 + January 2016 Uno, Mega 2560 and Due using Arduino 1.6.7 and Due Board + Manager V1.6.6 + + + Assumption - Only ONE keyboard added to one Arduino + - No stream support + + This is for a LATIN style keyboard using Scan code set 2. See various + websites on what different scan code sets use. Scan Code Set 2 is the + default scan code set for PS2 keyboards on power up. + + Fully featured PS2 keyboard library to provide + All keys as a keycode (A-Z and 0-9 as ASCII equivalents) + All function and movement keys supported even multi-lingual + Parity checking of data sent/received on receive request keyboard resend + Resends data when needed handles keyboard protocol for RESEND and ECHO + Functions for get and set of + Scancode set in use READ only + LED and LOCK control + ReadID + Reset keyboard + Send ECHO + Handles NUM, _CAPS and SCROLL lock keys to LEDs + Handles NUM/SCROLL internally + + Returns an uint16_t containing + Make/Break status + CAPS status + SHIFT, CTRL, ALT, ALT GR, GUI keys + Flag for function key not a displayable/printable character + 8 bit key code + + Code Ranges(bottom byte of uint16_t) see PS2KeyAdvanced.h for details + 0 invalid/error + 1-1F Functions (_CAPS, _SHIFT, _ALT, Enter, DEL... ) + 1A-1F Functions with ASCII control code + (DEL, BS, TAB, ESC, ENTER, SPACE) + 20-60 Printable characters noting + 0-9 = 0x30 to 0x39 as ASCII + A to Z = 0x41 to 0x5A as upper case ASCII type codes + 8B Extra European key + 61-A0 Function keys and other special keys (plus F2 and F1 less 8B) + 61-78 F1 to F24 + 79-8A Multimedia + 8C-8E ACPI power + 91-A0 and F2 and F1 - Special multilingual + A8-FF Keyboard communications commands (note F2 and F1 are special + codes for special multi-lingual keyboards) + + By using these ranges it is possible to perform detection of any key and do + easy translation to ASCII/UTF-8 avoiding keys that do not have a valid code. + + Top Byte is 8 bits denoting as follows with defines for bit code + + Define name bit description + PS2_BREAK 15 1 = Break key code + (MSB) 0 = Make Key code + PS2_SHIFT 14 1 = Shift key pressed as well (either side) + 0 = NO shift key + PS2_CTRL 13 1 = Ctrl key pressed as well (either side) + 0 = NO Ctrl key + PS2_CAPS 12 1 = Caps Lock ON + 0 = Caps lock OFF + PS2_ALT 11 1 = Left Alt key pressed as well + 0 = NO Left Alt key + PS2_ALT_GR 10 1 = Right Alt (Alt GR) key pressed as well + 0 = NO Right Alt key + PS2_GUI 9 1 = GUI key pressed as well (either) + 0 = NO GUI key + PS2_FUNCTION 8 1 = FUNCTION key non-printable character (plus space, tab, enter) + 0 = standard character key + + Error Codes + Most functions return 0 or 0xFFFF as error, other codes to note and + handle appropriately value in bottom byte + 0xAA keyboard has reset and passed power up tests + will happen if keyboard plugged in after code start + 0xFC Keyboard General error or power up fail + + It is responsibility of your programme to deal with converting special cases + like <_CTRL>+ sends a special code to something else. A better method + is to use PS2KeyMap library and add your own table to that library. If you + wish to do that make a NEW library called SOMETHING different NOT a variant + or revision of this one, as you are changing base functionality + + See PS2KeyCode.h for codes from the keyboard this library uses to decode. + (may disappear in updates do not rely on this file or definitions) + + See PS2KeyAvanced.h for returned definitions of Keys and accessible + definitions + + See PS2KeyMap.h for tables currently supported + + To get the key as ASCII/UTF-8 single byte character conversion requires use + of PS2KeyMap library AS WELL. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include +// Internal headers for library defines/codes/etc +#include "PS2KeyAdvanced.h" +#include "PS2KeyCode.h" +#include "PS2KeyTable.h" + + +// Private function declarations +void send_bit( void ); +void send_now( uint8_t ); +int16_t send_next( void ); +void ps2_reset( void ); +uint8_t decode_key( uint8_t ); +void pininput( uint8_t ); +void set_lock( ); + +/* Constant control functions to flags array + in translated key code value order */ +#if defined( PS2_REQUIRES_PROGMEM ) +const uint8_t PROGMEM control_flags[] = { +#else +const uint8_t control_flags[] = { +#endif + _SHIFT, _SHIFT, _CTRL, _CTRL, + _ALT, _ALT_GR, _GUI, _GUI + }; + +// Private Variables +volatile uint8_t _ps2mode; /* _ps2mode contains + _PS2_BUSY bit 7 = busy until all expected bytes RX/TX + _TX_MODE bit 6 = direction 1 = TX, 0 = RX (default) + _BREAK_KEY bit 5 = break code detected + _WAIT_RESPONSE bit 4 = expecting data response + _E0_MODE bit 3 = in E0 mode + _E1_MODE bit 2 = in E1 mode + _LAST_VALID bit 1 = last sent valid in case we receive resend + and not sent anything */ + +/* volatile RX buffers and variables accessed via interrupt functions */ +volatile uint16_t _rx_buffer[ _RX_BUFFER_SIZE ]; // buffer for data from keyboard +volatile uint8_t _head; // _head = last byte written +uint8_t _tail; // _tail = last byte read (not modified in IRQ ever) +volatile int8_t _bytes_expected; +volatile uint8_t _bitcount; // Main state variable and bit count for interrupts +volatile uint8_t _shiftdata; +volatile uint8_t _parity; + +/* TX variables */ +volatile uint8_t _tx_buff[ _TX_BUFFER_SIZE ]; // buffer for keyboard commands +volatile uint8_t _tx_head; // buffer write pointer +volatile uint8_t _tx_tail; // buffer read pointer +volatile uint8_t _last_sent; // last byte if resend requested +volatile uint8_t _now_send; // immediate byte to send +volatile uint8_t _response_count; // bytes expected in reply to next TX +volatile uint8_t _tx_ready; // TX status for type of send contains + /* _HANDSHAKE 0x80 = handshaking command (ECHO/RESEND) + _COMMAND 0x01 = other command processing */ + +/* Output key buffering */ +uint16_t _key_buffer[ _KEY_BUFF_SIZE ]; // Output Buffer for translated keys +uint8_t _key_head; // Output buffer WR pointer +uint8_t _key_tail; // Output buffer RD pointer +uint8_t _mode = 0; // Mode for output buffer contains + /* _NO_REPEATS 0x80 No repeat make codes for _CTRL, _ALT, _SHIFT, _GUI + _NO_BREAKS 0x08 No break codes */ + +// Arduino settings for pins and interrupts Needed to send data +uint8_t PS2_DataPin; +uint8_t PS2_IrqPin; + +// Key decoding variables +uint8_t PS2_led_lock = 0; // LED and Lock status +uint8_t PS2_lockstate[ 4 ]; // Save if had break on key for locks +uint8_t PS2_keystatus; // current CAPS etc status for top byte + + +/*------------------ Code starts here -------------------------*/ + +/* The ISR for the external interrupt + To receive 11 bits - start 8 data, ODD parity, stop + To send data calls send_bit( ) + Interrupt every falling incoming clock edge from keyboard */ +void ps2interrupt( void ) +{ +// Workaround for ESP32 SILICON error see extra/Porting.md +#ifdef PS2_ONLY_CHANGE_IRQ +if( digitalRead( PS2_IrqPin ) ) + return; +#endif +if( _ps2mode & _TX_MODE ) + send_bit( ); +else + { + static uint32_t prev_ms = 0; + uint32_t now_ms; + uint8_t val, ret; + + val = digitalRead( PS2_DataPin ); + /* timeout catch for glitches reset everything */ + now_ms = millis( ); + if( now_ms - prev_ms > 250 ) + { + _bitcount = 0; + _shiftdata = 0; + } + prev_ms = now_ms; + _bitcount++; // Now point to next bit + switch( _bitcount ) + { + case 1: // Start bit + _parity = 0; + _ps2mode |= _PS2_BUSY; // set busy + break; + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: // Data bits + _parity += val; // another one received ? + _shiftdata >>= 1; // right _SHIFT one place for next bit + _shiftdata |= ( val ) ? 0x80 : 0; // or in MSbit + break; + case 10: // Parity check + _parity &= 1; // Get LSB if 1 = odd number of 1's so parity bit should be 0 + if( _parity == val ) // Both same parity error + _parity = 0xFD; // To ensure at next bit count clear and discard + break; + case 11: // Stop bit lots of spare time now + if( _parity >= 0xFD ) // had parity error + { + send_now( PS2_KC_RESEND ); // request resend + _tx_ready |= _HANDSHAKE; + } + else // Good so save byte in _rx_buffer + { + // Check _SHIFTed data for commands and action + ret = decode_key( _shiftdata ); + if( ret & 0x2 ) // decrement expected bytes + _bytes_expected--; + if( _bytes_expected <= 0 || ret & 4 ) // Save value ?? + { + val = _head + 1; + if( val >= _RX_BUFFER_SIZE ) + val = 0; + if( val != _tail ) + { + // get last byte to save + _rx_buffer[ val ] = uint16_t( _shiftdata ); + // save extra details + _rx_buffer[ val ] |= uint16_t( _ps2mode ) << 8; + _head = val; + } + } + if( ret & 0x10 ) // Special command to send (ECHO/RESEND) + { + send_now( _now_send ); + _tx_ready |= _HANDSHAKE; + } + else + if( _bytes_expected <= 0 ) // Receive data finished + { + // Set mode and status for next receive byte + _ps2mode &= ~( _E0_MODE + _E1_MODE + _WAIT_RESPONSE + _BREAK_KEY ); + _bytes_expected = 0; + _ps2mode &= ~_PS2_BUSY; + send_next( ); // Check for more to send + } + } + _bitcount = 0; // end of byte + break; + default: // in case of weird error and end of byte reception re-sync + _bitcount = 0; + } + } +} + + +/* Decode value received to check for errors commands and responses + NOT keycode translate yet + returns bit Or'ing + 0x10 send command in _now_send (after any saves and decrements) + 0x08 error abort reception and reset status and queues + 0x04 save value ( complete after translation ) + 0x02 decrement count of bytes to expected + + Codes like EE, AA and FC ( Echo, BAT pass and fail) treated as valid codes + return code 6 +*/ +uint8_t decode_key( uint8_t value ) +{ +uint8_t state; + +state = 6; // default state save and decrement + +// Anything but resend received clear valid value to resend +if( value != PS2_KC_RESEND ) + _ps2mode &= ~( _LAST_VALID ); + +// First check not a valid response code from a host command +if( _ps2mode & _WAIT_RESPONSE ) + if( value < 0xF0 ) + return state; // Save response and decrement + +// E1 Pause mode special case just decrement +if( _ps2mode & _E1_MODE ) + return 2; + +switch( value ) + { + case 0: // Buffer overrun Errors Reset modes and buffers + case PS2_KC_OVERRUN: + ps2_reset( ); + state = 0xC; + break; + case PS2_KC_RESEND: // Resend last byte if we have sent something + if( ( _ps2mode & _LAST_VALID ) ) + { + _now_send = _last_sent; + state = 0x10; + } + else + state = 0; + break; + case PS2_KC_ERROR: // General error pass up but stop any sending or receiving + _bytes_expected = 0; + _ps2mode = 0; + _tx_ready = 0; + state = 0xE; + break; + case PS2_KC_KEYBREAK: // break Code - wait the final key byte + _bytes_expected = 1; + _ps2mode |= _BREAK_KEY; + state = 0; + break; + case PS2_KC_ECHO: // Echo if we did not originate echo back + state = 4; // always save + if( _ps2mode & _LAST_VALID && _last_sent != PS2_KC_ECHO ) + { + _now_send = PS2_KC_ECHO; + state |= 0x10; // send _command on exit + } + break; + case PS2_KC_BAT: // BAT pass + _bytes_expected = 0; // reset as if in middle of something lost now + state = 4; + break; + case PS2_KC_EXTEND1: // Major extend code (PAUSE key only) + if( !( _ps2mode & _E1_MODE ) ) // First E1 only + { + _bytes_expected = 7; // seven more bytes + _ps2mode |= _E1_MODE; + _ps2mode &= ~_BREAK_KEY; // Always a make + } + state = 0; + break; + case PS2_KC_EXTEND: // Two byte Extend code + _bytes_expected = 1; // one more byte at least to wait for + _ps2mode |= _E0_MODE; + state = 0; + break; + } +return state; +} + + +/* Send data to keyboard + Data pin direction should already be changed + Start bit would be already set so each clock setup for next clock + parity and _bitcount should be 0 already and busy should be set + + Start bit setting is due to bug in attachinterrupt not clearing pending interrupts + Also no clear pending interrupt function */ +void send_bit( void ) +{ +uint8_t val; + +_bitcount++; // Now point to next bit +switch( _bitcount ) + { + case 1: +#if defined( PS2_CLEAR_PENDING_IRQ ) + // Start bit due to Arduino bug + digitalWrite( PS2_DataPin, LOW ); + break; +#endif + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + // Data bits + val = _shiftdata & 0x01; // get LSB + digitalWrite( PS2_DataPin, val ); // send start bit + _parity += val; // another one received ? + _shiftdata >>= 1; // right _SHIFT one place for next bit + break; + case 10: + // Parity - Send LSB if 1 = odd number of 1's so parity should be 0 + digitalWrite( PS2_DataPin, ( ~_parity & 1 ) ); + break; + case 11: // Stop bit write change to input pull up for high stop bit + pininput( PS2_DataPin ); + break; + case 12: // Acknowledge bit low we cannot do anything if high instead of low + if( !( _now_send == PS2_KC_ECHO || _now_send == PS2_KC_RESEND ) ) + { + _last_sent = _now_send; // save in case of resend request + _ps2mode |= _LAST_VALID; + } + // clear modes to receive again + _ps2mode &= ~_TX_MODE; + if( _tx_ready & _HANDSHAKE ) // If _HANDSHAKE done + _tx_ready &= ~_HANDSHAKE; + else // else we finished a command + _tx_ready &= ~_COMMAND; + if( !( _ps2mode & _WAIT_RESPONSE ) ) // if not wait response + send_next( ); // check anything else to queue up + _bitcount = 0; // end of byte + break; + default: // in case of weird error and end of byte reception re-sync + _bitcount = 0; + } +} + + +/* Takes a byte sets up variables and starts the data sending processes + Starts the actual byte transmission + calling code must make sure line is idle and able to send + Whilst this function adds long delays the process of the delays + will STOP the interrupt source (keyboard) externally when clock held low + _tx_ready contains 2 flags checked in this order + _HANDSHAKE command sent as part of receiving e.g. ECHO, RESEND + _COMMAND other commands not part of receiving + Main difference _bytes_expected is NOT altered in _HANDSHAKE mode + in command mode we update _bytes_expected with number of response bytes +*/ +void send_now( uint8_t command ) +{ +_shiftdata = command; +_now_send = command; // copy for later to save in last sent +#if defined( PS2_CLEAR_PENDING_IRQ ) +_bitcount = 0; // AVR/SAM ignore extra interrupt +#else +_bitcount = 1; // Normal processors +#endif +_parity = 0; +_ps2mode |= _TX_MODE + _PS2_BUSY; + +// Only do this if sending a command not from Handshaking +if( !( _tx_ready & _HANDSHAKE ) && ( _tx_ready & _COMMAND ) ) + { + _bytes_expected = _response_count; // How many bytes command will generate + _ps2mode |= _WAIT_RESPONSE; + } + +// STOP interrupt handler +// Setting pin output low will cause interrupt before ready +detachInterrupt( digitalPinToInterrupt( PS2_IrqPin ) ); +// set pins to outputs and high +digitalWrite( PS2_DataPin, HIGH ); +pinMode( PS2_DataPin, OUTPUT ); +digitalWrite( PS2_IrqPin, HIGH ); +pinMode( PS2_IrqPin, OUTPUT ); +// Essential for PS2 spec compliance +delayMicroseconds( 10 ); +// set Clock LOW +digitalWrite( PS2_IrqPin, LOW ); +// Essential for PS2 spec compliance +// set clock low for 60us +delayMicroseconds( 60 ); +// Set data low - Start bit +digitalWrite( PS2_DataPin, LOW ); +// set clock to input_pullup data stays output while writing to keyboard +pininput( PS2_IrqPin ); +// Restart interrupt handler +attachInterrupt( digitalPinToInterrupt( PS2_IrqPin ), ps2interrupt, FALLING ); +// wait clock interrupt to send data +} + + +/* Send next byte/command from TX queue and start sending + Must be ready to send and idle + Assumes commands consist of 1 or more bytes and wait for response then may or + not be followed by further bytes to send with or without response + Checks + 1/ Buffer empty return empty buffer + 2/ Busy return busy (will be checked by interrupt routines later) + 3/ Read next byte (next byte to send) + 4/ Check if following byte(s) are command/data or response + + Returns 1 if started transmission or queued + -134 if already busy + -2 if buffer empty + + Note PS2_KEY_IGNORE is used to denote a byte(s) expected in response */ +int16_t send_next( void ) +{ +uint8_t i; +int16_t val; + +val = -1; +// Check buffer not empty +i = _tx_tail; +if( i == _tx_head ) + return -2; + +// set command bit in _tx_ready as another command to do +_tx_ready |= _COMMAND; + +// Already item waiting to be sent or sending interrupt routines will call back +if( _tx_ready & _HANDSHAKE ) + return -134; + +// if busy let interrupt catch and call us again +if( _ps2mode & _PS2_BUSY ) + return -134; + +// Following only accessed when not receiving or sending protocol bytes +// Scan for command response and expected bytes to follow +_response_count = 0; +do + { + i++; + if( i >= _TX_BUFFER_SIZE ) + i = 0; + if( val == -1 ) + val = _tx_buff[ i ]; + else + if( _tx_buff[ i ] != PS2_KEY_IGNORE ) + break; + else + _response_count++; + _tx_tail = i; + } +while( i != _tx_head ); +// Now know what to send and expect start the actual wire sending +send_now( val ); +return 1; +} + + +/* Send a byte to the TX buffer + Value in buffer of PS2_KEY_IGNORE signifies wait for response, + use one for each byte expected + + Returns -4 - if buffer full (buffer overrun not written) + Returns 1 byte written when done */ +int send_byte( uint8_t val ) +{ +uint8_t ret; + +ret = _tx_head + 1; +if( ret >= _TX_BUFFER_SIZE ) + ret = 0; +if( ret != _tx_tail ) + { + _tx_buff[ ret ] = val; + _tx_head = ret; + return 1; + } +return -4; +} + + +// initialize a data pin for input +void pininput( uint8_t pin ) +{ +#ifdef INPUT_PULLUP +pinMode( pin, INPUT_PULLUP ); +#else +digitalWrite( pin, HIGH ); +pinMode( pin, INPUT ); +#endif +} + + +void ps2_reset( void ) +{ +/* reset buffers and states */ +_tx_head = 0; +_tx_tail = 0; +_tx_ready = 0; +_response_count = 0; +_head = 0; +_tail = 0; +_bitcount = 0; +PS2_keystatus = 0; +PS2_led_lock = 0; +_ps2mode = 0; +} + + + +/* Translate PS2 keyboard code sequence into our key code data + PAUSE key (_E1_MODE) is de_ALT with as special case, and + command responses not translated + + Called from read function as too long for in interrupt + + Returns 0 for no valid key or processed internally ignored or similar + 0 for empty buffer + */ +uint16_t translate( void ) +{ + uint8_t index, length, data, status; + uint16_t retdata; + + // get next character + // Check first something to fetch + index = _tail; + + // check for empty buffer + if( index == _head ) + return 0; + index++; + if( index >= _RX_BUFFER_SIZE ) + index = 0; + + // Special handling for PAUSE/BREAK, PAUSE key doesnt send a BREAK code yet MZ machines need SHIFT (hold) -> BREAK to recognise a BREAK, CTRL+BREAK will not work. + // In this case we inject a BREAK code by setting the flag on the received code. + status = (( _rx_buffer[ index ] & 0xFF00 ) >> 8); + if( (status & _E1_MODE) && (status & _BREAK)) + { + _rx_buffer[index] &= ~PS2_BREAK; + } else + { + _tail = index; + } + + // Get the flags byte break modes etc in this order + data = _rx_buffer[ index ] & 0xFF; + index = ( _rx_buffer[ index ] & 0xFF00 ) >> 8; + + // Catch special case of PAUSE key + if( index & _E1_MODE ) + { + return ( (uint16_t)PS2_keystatus << 8 ) | PS2_KEY_PAUSE | PS2_FUNCTION | (status & _BREAK ? 0 : PS2_BREAK); + } + + // Ignore anything not actual keycode but command/response + // Return untranslated as valid + if( ( data >= PS2_KC_BAT && data != PS2_KC_LANG1 && data != PS2_KC_LANG2 ) || ( index & _WAIT_RESPONSE ) ) + { + return ( uint16_t )data; + } + + // Gather the break of key status + if( index & _BREAK_KEY ) + { + PS2_keystatus |= _BREAK; + } else + { + PS2_keystatus &= ~_BREAK; + } + + retdata = 0; // error code by default + + // Scan appropriate table + if( index & _E0_MODE ) + { + length = sizeof( extended_key ) / sizeof( extended_key[ 0 ] ); + for( index = 0; index < length; index++ ) + { + #if defined( PS2_REQUIRES_PROGMEM ) + if( data == pgm_read_byte( &extended_key[ index ][ 0 ] ) ) + { + retdata = pgm_read_byte( &extended_key[ index ][ 1 ] ); + #else + if( data == extended_key[ index ][ 0 ] ) + { + retdata = extended_key[ index ][ 1 ]; + #endif + break; + } + } + } else + { + length = sizeof( single_key ) / sizeof( single_key[ 0 ] ); + for( index = 0; index < length; index++ ) + { + #if defined( PS2_REQUIRES_PROGMEM ) + if( data == pgm_read_byte( &single_key[ index ][ 0 ] ) ) + { + retdata = pgm_read_byte( &single_key[ index ][ 1 ] ); + #else + if( data == single_key[ index ][ 0 ] ) + { + retdata = single_key[ index ][ 1 ]; + #endif + break; + } + } + } + + // trap not found key + if( index == length ) + { + retdata = 0; + } + + /* valid found values only */ + if( retdata > 0 ) + { + if( retdata <= PS2_KEY_CAPS ) + { // process lock keys need second make to turn off + if( PS2_keystatus & _BREAK ) + { + PS2_lockstate[ retdata ] = 0; // Set received a break so next make toggles LOCK status + // MZ-2500 uses one make-break cycle to enable and one make-break to disable, so the BREAK is needed. + if(retdata != PS2_KEY_CAPS) + { + retdata = PS2_KEY_IGNORE; // ignore key + } + } else { + + if( PS2_lockstate[ retdata ] == 1 ) + { +printf("PLEASE REMOVE ME translate: %04x, %d\n", retdata, PS2_lockstate[ retdata ]); + retdata = PS2_KEY_IGNORE; // ignore key if make and not received break + // As per above, MZ-2500 needs both events, so this code changed from original authors. + } else + { + PS2_lockstate[ retdata ] = 1; + switch( retdata ) + { + case PS2_KEY_CAPS: + index = PS2_LOCK_CAPS; + + // Set CAPS lock if not set before + if( PS2_keystatus & _CAPS ) + { + PS2_keystatus &= ~_CAPS; + } else + { + PS2_keystatus |= _CAPS; + } + break; + case PS2_KEY_SCROLL: + index = PS2_LOCK_SCROLL; + break; + case PS2_KEY_NUM: + index = PS2_LOCK_NUM; + break; + } + // Now update PS2_led_lock status to match + if( PS2_led_lock & index ) + { + PS2_led_lock &= ~index; + if(index != PS2_LOCK_CAPS) + { + PS2_keystatus |= _BREAK; // send as break + } + } else + { + PS2_led_lock |= index; + } + set_lock( ); + } + } + } else + { + + if( retdata >= PS2_KEY_L_SHIFT && retdata <= PS2_KEY_R_GUI ) + { // Update bits for _SHIFT, _CTRL, _ALT, _ALT GR, _GUI in status + #if defined( PS2_REQUIRES_PROGMEM ) + index = pgm_read_byte( &control_flags[ retdata - PS2_KEY_L_SHIFT ] ); + #else + index = control_flags[ retdata - PS2_KEY_L_SHIFT ]; + #endif + if( PS2_keystatus & _BREAK ) + { + PS2_keystatus &= ~index; + } + + // if already set ignore repeats if flag set + else if( ( PS2_keystatus & index ) && ( _mode & _NO_REPEATS ) ) + { + retdata = PS2_KEY_IGNORE; // ignore repeat _SHIFT, _CTRL, _ALT, _GUI + } else + { + PS2_keystatus |= index; + } + } else + { + // Numeric keypad ONLY works in numlock state or when _SHIFT status + if( retdata >= PS2_KEY_KP0 && retdata <= PS2_KEY_KP_DOT ) + { + if( !( PS2_led_lock & PS2_LOCK_NUM ) || ( PS2_keystatus & _SHIFT ) ) + { + #if defined( PS2_REQUIRES_PROGMEM ) + retdata = pgm_read_byte( &scroll_remap[ retdata - PS2_KEY_KP0 ] ); + #else + retdata = scroll_remap[ retdata - PS2_KEY_KP0 ]; + #endif + } + } + } + + // Sort break code handling or ignore for all having processed the _SHIFT etc status + if( ( PS2_keystatus & _BREAK ) && ( _mode & _NO_BREAKS ) ) + { + return ( uint16_t )PS2_KEY_IGNORE; + } + + // Assign Function keys _mode + if( ( retdata <= PS2_KEY_SPACE || retdata >= PS2_KEY_F1 ) && retdata != PS2_KEY_EUROPE2 ) + { + PS2_keystatus |= _FUNCTION; + } else + { + PS2_keystatus &= ~_FUNCTION; + } + } + } + return ( retdata | ( (uint16_t)PS2_keystatus << 8 ) ); +} + + +/* Build command to send lock status + Assumes data is within range */ +void set_lock( ) +{ +// ESP32: Heltec 32 Wifi - Bug found with a DELL KB-3926 keyboard. Basically sending more than one byte using this class +// mechanism of waiting for a response in the send/interrupt procedures results in a lockup. +// Workaround: Send one byte, wait for one response with a delay loop, send next byte. +send_byte( PS2_KC_LOCK ); // send command +if( ( send_byte( PS2_KEY_IGNORE ) ) ) // wait ACK + send_next( ); // if idle start transmission +// A delay of less than 10mS will cause lockup or abort!!! +delayMicroseconds( 10000 ); +send_byte( PS2_led_lock ); // send data from internal variable +if( ( send_byte( PS2_KEY_IGNORE ) ) ) // wait ACK + send_next( ); // if idle start transmission +} + + +/* Send echo command to keyboard + returned data in keyboard buffer read as keys */ +void PS2KeyAdvanced::echo( void ) +{ +send_byte( PS2_KC_ECHO ); // send command +if( ( send_byte( PS2_KEY_IGNORE ) ) ) // wait data PS2_KC_ECHO + send_next( ); // if idle start transmission +} + + +/* Get the ID used in keyboard + returned data in keyboard buffer read as keys */ +void PS2KeyAdvanced::readID( void ) +{ +send_byte( PS2_KC_READID ); // send command +send_byte( PS2_KEY_IGNORE ); // wait ACK +send_byte( PS2_KEY_IGNORE ); // wait data +if( ( send_byte( PS2_KEY_IGNORE ) ) ) // wait data + send_next( ); // if idle start transmission +} + + +/* Get the current Scancode Set used in keyboard + returned data in keyboard buffer read as keys */ +void PS2KeyAdvanced::getScanCodeSet( void ) +{ +send_byte( PS2_KC_SCANCODE ); // send command +if( ( send_byte( PS2_KEY_IGNORE ) ) ) // wait data + send_next( ); // if idle start transmission +delayMicroseconds( 10000 ); +send_byte( 0 ); // send data 0 = read +if( ( send_byte( PS2_KEY_IGNORE ) ) ) // wait data + send_next( ); // if idle start transmission +} + + +/* Returns the current status of Locks */ +uint8_t PS2KeyAdvanced::getLock( ) +{ +return( PS2_led_lock ); +} + + +/* Sets the current status of Locks and LEDs */ +void PS2KeyAdvanced::setLock( uint8_t code ) +{ +code &= 0xF; // To allow for rare keyboards with extra LED +PS2_led_lock = code; // update our lock copy +PS2_keystatus &= ~_CAPS; // Update copy of _CAPS lock as well +PS2_keystatus |= ( code & PS2_LOCK_CAPS ) ? _CAPS : 0; +set_lock( ); +} + + +/* Set library to not send break key codes + 1 = no break codes + 0 = send break codes */ +void PS2KeyAdvanced::setNoBreak( uint8_t data ) +{ +_mode &= ~_NO_BREAKS; +_mode |= data ? _NO_BREAKS : 0; +} + + /* Set library to not repeat make codes for _CTRL, _ALT, _GUI, _SHIFT + 1 = no repeat codes + 0 = send repeat codes */ +void PS2KeyAdvanced::setNoRepeat( uint8_t data ) +{ +_mode &= ~_NO_REPEATS; +_mode |= data ? _NO_REPEATS : 0; +} + + +/* Resets keyboard when reset has completed + keyboard sends AA - Pass or FC for fail */ +void PS2KeyAdvanced::resetKey( ) +{ +send_byte( PS2_KC_RESET ); // send command +send_byte( PS2_KEY_IGNORE ); // wait ACK +if( ( send_byte( PS2_KEY_IGNORE ) ) ) // wait data PS2_KC_BAT or PS2_KC_ERROR + send_next( ); // if idle start transmission +// LEDs and KeyStatus Reset too... to match keyboard +PS2_led_lock = 0; +PS2_keystatus = 0; +} + + +/* Send Typematic rate/delay command to keyboard + First Parameter rate is 0 - 0x1F (31) + 0 = 30 CPS + 0x1F = 2 CPS + default in keyboard is 0xB (10.9 CPS) + Second Parameter delay is 0 - 3 for 0.25s to 1s in 0.25 increments + default in keyboard is 1 = 0.5 second delay + Returned data in keyboard buffer read as keys + + Error returns 0 OK + -5 parameter error + */ +int PS2KeyAdvanced::typematic( uint8_t rate, uint8_t delay ) +{ +if( rate > 31 || delay > 3 ) + return -5; +send_byte( PS2_KC_RATE ); // send command +if( ( send_byte( PS2_KEY_IGNORE ) ) ) // wait ACK + send_next( ); // if idle start transmission +delayMicroseconds( 10000 ); +send_byte( ( delay << 5 ) + rate ); // Send values +if( ( send_byte( PS2_KEY_IGNORE ) ) ) // wait ACK + send_next( ); // if idle start transmission +return 0; +} + +uint8_t PS2KeyAdvanced::keyAvailable( ) +{ +int8_t i; + +i = _head - _tail; +if( i < 0 ) + i += _RX_BUFFER_SIZE; +return uint8_t( i ); +} + + +/* Returns count of available processed key codes + + If processed key buffer (_key_buffer) buffer returns max count + else processes input key code buffer until + either input buffer empty + or output buffer full + returns actual count + + Returns 0 buffer empty + 1 to buffer size less 1 as 1 to full buffer + + As with other ring buffers here when pointers match + buffer empty so cannot actually hold buffer size values */ +uint8_t PS2KeyAdvanced::available( ) +{ +int8_t i, idx; +uint16_t data; + +// check output queue +i = _key_head - _key_tail; +if( i < 0 ) + i += _KEY_BUFF_SIZE; +while( i < ( _KEY_BUFF_SIZE - 1 ) ) // process if not full +{ + if( keyAvailable( ) ) // not check for more keys to process + { + data = translate( ); // get next translated key + + if( data == 0 ) // unless in buffer is empty + break; + if( (data & 0xFF) != PS2_KEY_IGNORE && (data & 0xFF) > 0) + { + idx = _key_head + 1; // point to next space + if( idx >= _KEY_BUFF_SIZE ) // loop to front if necessary + idx = 0; + _key_buffer[ idx ] = data; // save the data to out buffer + _key_head = idx; + i++; // update count + } + } + else + break; // exit nothing coming in +} +return uint8_t( i ); +} + + +/* read a decoded key from the keyboard buffer + returns 0 for empty buffer */ +uint16_t PS2KeyAdvanced::read( ) +{ +uint16_t result; +uint8_t idx; + +while( ( result = available( ) ) ) + { + idx = _key_tail; + idx++; + if( idx >= _KEY_BUFF_SIZE ) // loop to front if necessary + idx = 0; + _key_tail = idx; + result = _key_buffer[ idx ]; + + // Filter out unwanted control data. + if((result & 0xFF) != PS2_KC_ACK && (result & 0xFF) != PS2_KC_RESEND && (result & 0xFF) != 0) + break; + } +return result; +} + + +PS2KeyAdvanced::PS2KeyAdvanced( ) +{ +// nothing to do here, begin( ) does it all +} + + +/* instantiate class for keyboard */ +void PS2KeyAdvanced::begin( uint8_t data_pin, uint8_t irq_pin ) +{ +/* PS2 variables reset */ +ps2_reset( ); + +PS2_DataPin = data_pin; +PS2_IrqPin = irq_pin; + +// initialize the pins +pininput( PS2_IrqPin ); /* Setup Clock pin */ +pininput( PS2_DataPin ); /* Setup Data pin */ + +// Start interrupt handler +attachInterrupt( digitalPinToInterrupt( irq_pin ), ps2interrupt, FALLING ); +} diff --git a/v1.2/main/PS2KeyAdvanced.h b/v1.2/main/PS2KeyAdvanced.h new file mode 100644 index 0000000..8fde6bb --- /dev/null +++ b/v1.2/main/PS2KeyAdvanced.h @@ -0,0 +1,445 @@ +/* Version V1.0.9 + PS2KeyAdvanced.h - PS2KeyAdvanced library + Copyright (c) 2007 Free Software Foundation. All right reserved. + Written by Paul Carpenter, PC Services + Created September 2014 + Updated January 2016 - Paul Carpenter - add tested on Due and tidy ups for V1.5 Library Management + January 2020 Fix typos, correct keyboard reset status improve library.properties + and additional platform handling and some documentation + March 2020 Add SAMD1 as recognised support as has been tested by user + Improve different architecture handling + November 2020 Add support for STM32 from user Hiabuto-de + Tested on STM32Duino-Framework and PlatformIO on STM32F103C8T6 and an IBM Model M + July 2021 Add workaround for ESP32 issue with Silicon (hardware) from user submissions + + IMPORTANT WARNING + + If using a DUE or similar board with 3V3 I/O you MUST put a level translator + like a Texas Instruments TXS0102 or FET circuit as the signals are + Bi-directional (signals transmitted from both ends on same wire). + + Failure to do so may damage your Arduino Due or similar board. + + Test History + September 2014 Uno and Mega 2560 September 2014 using Arduino V1.6.0 + January 2016 Uno, Mega 2560 and Due using Arduino 1.6.7 and Due Board + Manager V1.6.6 + + ONLY use defines in this file others may disappear on updates. + + This is for a LATIN style keyboard using Scan code set 2. See various + websites on what different scan code sets use. Scan Code Set 2 is the + default scan code set for PS2 keyboards on power up. + + Will support most keyboards even ones with multimedia keys or even 24 function keys. + + Fully featured PS2 keyboard library to provide + All function and movement keys supported even multi-lingual + Parity checking of data sent/received on receive request keyboard resend + Resends data when needed handles keyboard protocol for RESEND and ECHO + Functions for get and set of + Scancode set in use READ only + LED and LOCK control + ReadID + Reset keyboard + Send ECHO + Ignore Break codes for keys + Ignore typematic repeat of CTRL, SHIFT, ALT, Num, Scroll, Caps + Handles NUM, CAPS and SCROLL lock keys to LEDs + Handles NUM/SCROLL internally + + Read function Returns an UNSIGNED INT containing + Make/Break status + Caps status + Shift, CTRL, ALT, ALT GR, GUI keys + Flag for function key not a displayable/printable character + 8 bit key code + + Code Ranges (bottom byte of unsigned int) + 0 invalid/error + 1-1F Functions (Caps, Shift, ALT, Enter, DEL... ) + 1A-1F Functions with ASCII control code + (DEL, BS, TAB, ESC, ENTER, SPACE) + 20-61 Printable characters noting + 0-9 = 0x30 to 0x39 as ASCII + A to Z = 0x41 to 0x5A as upper case ASCII type codes + 8B Extra European key + 61-A0 Function keys and other special keys (plus F2 and F1) + 61-78 F1 to F24 + 79-8A Multimedia + 8B NOT included + 8C-8E ACPI power + 91-A0 and F2 and F1 - Special multilingual + A8-FF Keyboard communications commands (note F2 and F1 are special + codes for special multi-lingual keyboards) + + By using these ranges it is possible to perform detection of any key and do + easy translation to ASCII/UTF-8 avoiding keys that do not have a valid code. + + Top Byte is 8 bits denoting as follows with defines for bit code + + Define name bit description + PS2_BREAK 15 1 = Break key code + (MSB) 0 = Make Key code + PS2_SHIFT 14 1 = Shift key pressed as well (either side) + 0 = NO shift key + PS2_CTRL 13 1 = Ctrl key pressed as well (either side) + 0 = NO Ctrl key + PS2_CAPS 12 1 = Caps Lock ON + 0 = Caps lock OFF + PS2_ALT 11 1 = Left Alt key pressed as well + 0 = NO Left Alt key + PS2_ALT_GR 10 1 = Right Alt (Alt GR) key pressed as well + 0 = NO Right Alt key + PS2_GUI 9 1 = GUI key pressed as well (either) + 0 = NO GUI key + PS2_FUNCTION 8 1 = FUNCTION key non-printable character (plus space, tab, enter) + 0 = standard character key + + Error Codes + Most functions return 0 or 0xFFFF as error, other codes to note and + handle appropriately + 0xAA keyboard has reset and passed power up tests + will happen if keyboard plugged in after code start + 0xFC Keyboard General error or power up fail + + It is responsibility of your programme to deal with converting special cases like + + sends a special code to something else. If you wish to do that make a + NEW library called SOMETHING different NOT a variant or revision of this one, as you + are changing base functionality + + See PS2KeyCode.h for codes from the keyboard this library uses to decode. + (may disappear in updates do not rely on that file or definitions) + + See this file for returned definitions of Keys + + Note defines starting + PS2_KC_* are internal defines for codes from the keyboard + PS2_KEY_* are the codes this library returns + PS2_* remaining defines for use in higher levels + + To get the key as ASCII/UTF-8 single byte character conversion requires use + of PS2KeyMap library AS WELL. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef PS2KeyAdvanced_h +#define PS2KeyAdvanced_h + +// Platform specific areas +// Harvard architecture settings for PROGMEM +// Add separate for EACH architecture as easier to maintain +// AVR (includes Teensy 2.0) +#if defined( ARDUINO_ARCH_AVR ) +#define PS2_SUPPORTED 1 +#define PS2_REQUIRES_PROGMEM 1 +#define PS2_CLEAR_PENDING_IRQ 1 +#endif +// SAM (Due) +#if defined( ARDUINO_ARCH_SAM ) +#define PS2_SUPPORTED 1 +#define PS2_CLEAR_PENDING_IRQ 1 +#endif +// SAMD1 +#if defined( ARDUINO_ARCH_SAMD1 ) +#define PS2_SUPPORTED 1 +#define PS2_CLEAR_PENDING_IRQ 1 +#endif +// STM32 +#if defined( ARDUINO_ARCH_STM32 ) +#define PS2_SUPPORTED 1 +#define PS2_CLEAR_PENDING_IRQ 1 +#endif +// ESP32 +#if defined( ARDUINO_ARCH_ESP32 ) +#define PS2_SUPPORTED 1 +#define PS2_ONLY_CHANGE_IRQ 1 +#endif + +// Invalid architecture +#if !( defined( PS2_SUPPORTED ) ) +#warning Library is NOT supported on this board Use at your OWN risk +#endif + +/* Flags/bit masks for status bits in returned unsigned int value */ +#define PS2_BREAK 0x8000 +#define PS2_SHIFT 0x4000 +#define PS2_CTRL 0x2000 +#define PS2_CAPS 0x1000 +#define PS2_ALT 0x800 +#define PS2_ALT_GR 0x400 +#define PS2_GUI 0x200 +#define PS2_FUNCTION 0x100 + +/* General defines of communications codes */ +/* Command or response */ +#define PS2_KEY_RESEND 0xFE +#define PS2_KEY_ACK 0xFA +#define PS2_KEY_ECHO 0xEE +/* Responses */ +#define PS2_KEY_BAT 0xAA +// Actually buffer overrun +#define PS2_KEY_OVERRUN 0xFF +// Below is general error code +#define PS2_KEY_ERROR 0xFC + +/* Command parameters for functions */ +/* LED codes OR together */ +#define PS2_LOCK_SCROLL 0x01 +#define PS2_LOCK_NUM 0x02 +#define PS2_LOCK_CAPS 0x04 +/* Only useful for very few keyboards */ +#define PS2_LOCK_EXTRA 0x08 + +/* Returned keycode definitions */ +/* Do NOT change these codings as you will break base + functionality use PS2KeyMap for that and internationalisation */ +#define PS2_KEY_NUM 0x01 +#define PS2_KEY_SCROLL 0x02 +#define PS2_KEY_CAPS 0x03 +#define PS2_KEY_PRTSCR 0x04 +#define PS2_KEY_PAUSE 0x05 +#define PS2_KEY_L_SHIFT 0x06 +#define PS2_KEY_R_SHIFT 0x07 +#define PS2_KEY_L_CTRL 0X08 +#define PS2_KEY_R_CTRL 0X09 +#define PS2_KEY_L_ALT 0x0A +#define PS2_KEY_R_ALT 0x0B +/* Sometimes called windows key */ +#define PS2_KEY_L_GUI 0x0C +#define PS2_KEY_R_GUI 0x0D +#define PS2_KEY_MENU 0x0E +/* Break is CTRL + PAUSE generated inside keyboard */ +#define PS2_KEY_BREAK 0x0F +/* Generated by some keyboards by ALT and PRTSCR */ +#define PS2_KEY_SYSRQ 0x10 +#define PS2_KEY_HOME 0x11 +#define PS2_KEY_END 0x12 +#define PS2_KEY_PGUP 0x13 +#define PS2_KEY_PGDN 0x14 +#define PS2_KEY_L_ARROW 0x15 +#define PS2_KEY_R_ARROW 0x16 +#define PS2_KEY_UP_ARROW 0x17 +#define PS2_KEY_DN_ARROW 0x18 +#define PS2_KEY_INSERT 0x19 +#define PS2_KEY_DELETE 0x1A +#define PS2_KEY_ESC 0x1B +#define PS2_KEY_BS 0x1C +#define PS2_KEY_TAB 0x1D +#define PS2_KEY_ENTER 0x1E +#define PS2_KEY_SPACE 0x1F +#define PS2_KEY_KP0 0x20 +#define PS2_KEY_KP1 0x21 +#define PS2_KEY_KP2 0x22 +#define PS2_KEY_KP3 0x23 +#define PS2_KEY_KP4 0x24 +#define PS2_KEY_KP5 0x25 +#define PS2_KEY_KP6 0x26 +#define PS2_KEY_KP7 0x27 +#define PS2_KEY_KP8 0x28 +#define PS2_KEY_KP9 0x29 +#define PS2_KEY_KP_DOT 0x2A +#define PS2_KEY_KP_ENTER 0x2B +#define PS2_KEY_KP_PLUS 0x2C +#define PS2_KEY_KP_MINUS 0x2D +#define PS2_KEY_KP_TIMES 0x2E +#define PS2_KEY_KP_DIV 0x2F +#define PS2_KEY_0 0X30 +#define PS2_KEY_1 0X31 +#define PS2_KEY_2 0X32 +#define PS2_KEY_3 0X33 +#define PS2_KEY_4 0X34 +#define PS2_KEY_5 0X35 +#define PS2_KEY_6 0X36 +#define PS2_KEY_7 0X37 +#define PS2_KEY_8 0X38 +#define PS2_KEY_9 0X39 +#define PS2_KEY_APOS 0X3A +#define PS2_KEY_COMMA 0X3B +#define PS2_KEY_MINUS 0X3C +#define PS2_KEY_DOT 0X3D +#define PS2_KEY_DIV 0X3E +/* Some Numeric keyboards have an '=' on right keypad */ +#define PS2_KEY_KP_EQUAL 0x3F +/* Single quote or back quote */ +#define PS2_KEY_SINGLE 0X40 +#define PS2_KEY_A 0X41 +#define PS2_KEY_B 0X42 +#define PS2_KEY_C 0X43 +#define PS2_KEY_D 0X44 +#define PS2_KEY_E 0X45 +#define PS2_KEY_F 0X46 +#define PS2_KEY_G 0X47 +#define PS2_KEY_H 0X48 +#define PS2_KEY_I 0X49 +#define PS2_KEY_J 0X4A +#define PS2_KEY_K 0X4B +#define PS2_KEY_L 0X4C +#define PS2_KEY_M 0X4D +#define PS2_KEY_N 0X4E +#define PS2_KEY_O 0X4F +#define PS2_KEY_P 0X50 +#define PS2_KEY_Q 0X51 +#define PS2_KEY_R 0X52 +#define PS2_KEY_S 0X53 +#define PS2_KEY_T 0X54 +#define PS2_KEY_U 0X55 +#define PS2_KEY_V 0X56 +#define PS2_KEY_W 0X57 +#define PS2_KEY_X 0X58 +#define PS2_KEY_Y 0X59 +#define PS2_KEY_Z 0X5A +#define PS2_KEY_SEMI 0X5B +#define PS2_KEY_BACK 0X5C +#define PS2_KEY_OPEN_SQ 0X5D +#define PS2_KEY_CLOSE_SQ 0X5E +#define PS2_KEY_EQUAL 0X5F +/* Some Numeric keypads have a comma key */ +#define PS2_KEY_KP_COMMA 0x60 +#define PS2_KEY_F1 0X61 +#define PS2_KEY_F2 0X62 +#define PS2_KEY_F3 0X63 +#define PS2_KEY_F4 0X64 +#define PS2_KEY_F5 0X65 +#define PS2_KEY_F6 0X66 +#define PS2_KEY_F7 0X67 +#define PS2_KEY_F8 0X68 +#define PS2_KEY_F9 0X69 +#define PS2_KEY_F10 0X6A +#define PS2_KEY_F11 0X6B +#define PS2_KEY_F12 0X6C +#define PS2_KEY_F13 0X6D +#define PS2_KEY_F14 0X6E +#define PS2_KEY_F15 0X6F +#define PS2_KEY_F16 0X70 +#define PS2_KEY_F17 0X71 +#define PS2_KEY_F18 0X72 +#define PS2_KEY_F19 0X73 +#define PS2_KEY_F20 0X74 +#define PS2_KEY_F21 0X75 +#define PS2_KEY_F22 0X76 +#define PS2_KEY_F23 0X77 +#define PS2_KEY_F24 0X78 +#define PS2_KEY_NEXT_TR 0X79 +#define PS2_KEY_PREV_TR 0X7A +#define PS2_KEY_STOP 0X7B +#define PS2_KEY_PLAY 0X7C +#define PS2_KEY_MUTE 0X7D +#define PS2_KEY_VOL_UP 0X7E +#define PS2_KEY_VOL_DN 0X7F +#define PS2_KEY_MEDIA 0X80 +#define PS2_KEY_EMAIL 0X81 +#define PS2_KEY_CALC 0X82 +#define PS2_KEY_COMPUTER 0X83 +#define PS2_KEY_WEB_SEARCH 0X84 +#define PS2_KEY_WEB_HOME 0X85 +#define PS2_KEY_WEB_BACK 0X86 +#define PS2_KEY_WEB_FORWARD 0X87 +#define PS2_KEY_WEB_STOP 0X88 +#define PS2_KEY_WEB_REFRESH 0X89 +#define PS2_KEY_WEB_FAVOR 0X8A +#define PS2_KEY_EUROPE2 0X8B +#define PS2_KEY_POWER 0X8C +#define PS2_KEY_SLEEP 0X8D +#define PS2_KEY_WAKE 0X90 +#define PS2_KEY_INTL1 0X91 +#define PS2_KEY_INTL2 0X92 +#define PS2_KEY_INTL3 0X93 +#define PS2_KEY_INTL4 0X94 +#define PS2_KEY_INTL5 0X95 +#define PS2_KEY_LANG1 0X96 +#define PS2_KEY_LANG2 0X97 +#define PS2_KEY_LANG3 0X98 +#define PS2_KEY_LANG4 0X99 +#define PS2_KEY_LANG5 0xA0 +#define PS2_KEY_BTICK 0X9A +#define PS2_KEY_HASH 0X9B + +/* + Purpose: Provides advanced access to PS2 keyboards + Public class definitions + + See standard error codes for error code returns + */ +class PS2KeyAdvanced { + public: + /* This constructor does basically nothing. Please call the begin(int,int) + method before using any other method of this class. */ + PS2KeyAdvanced( ); + + /* Starts the keyboard "service" by registering the external interrupt. + setting the pin modes correctly and driving those needed to high. + Sets default LOCK status (LEDs) to passed in value or default of all off + The best place to call this method is in the setup routine. */ + void begin( uint8_t, uint8_t ); + + // Additional key available check which doesnt affect the queue. + uint8_t keyAvailable(void); + + /* Returns number of codes available or 0 for none */ + uint8_t available( ); + + /* Returns the key last read from the keyboard. + If there is no key available, 0 is returned. */ + uint16_t read( ); + + /* Returns the current status of Locks + Use Macro to mask out bits from + PS2_LOCK_NUM PS2_LOCK_CAPS PS2_LOCK_SCROLL */ + uint8_t getLock( ); + + /* Sets the current status of Locks and LEDs + Use macro defines added together from + PS2_LOCK_NUM PS2_LOCK_CAPS PS2_LOCK_SCROLL */ + void setLock( byte ); + + /* Set library to not send break key codes + 1 = no break codes + 0 = send break codes */ + void setNoBreak( uint8_t ); + + /* Set library to not repeat make codes for CTRL, ALT, GUI, SHIFT + 1 = no repeat codes + 0 = send repeat codes */ + void setNoRepeat( uint8_t ); + + /* Resets keyboard when reset has completed + keyboard sends AA - Pass or FC for fail + Read from keyboard data buffer */ + void resetKey( ); + + /* Get the current Scancode Set used in keyboard + returned data in keyboard buffer read as keys */ + void getScanCodeSet( void ); + + /* Get the current Scancode Set used in keyboard + returned data in keyboard buffer read as keys */ + void readID( void ); + + /* Send Echo command to keyboard + returned data in keyboard buffer read as keys */ + void echo( void ); + + /* Send Typematic rate/delay command to keyboard + First Parameter rate is 0 - 0x1F (31) + 0 = 30 CPS + 0x1F = 2 CPS + default in keyboard is 0xB (10.9 CPS) + Second Parameter delay is 0 - 3 for 0.25s to 1s in 0.25 increments + default in keyboard is 1 = 0.5 second delay + Returned data in keyboard buffer read as keys */ + int typematic( uint8_t , uint8_t ); +}; +#endif diff --git a/v1.2/main/PS2KeyCode.h b/v1.2/main/PS2KeyCode.h new file mode 100644 index 0000000..ec4da88 --- /dev/null +++ b/v1.2/main/PS2KeyCode.h @@ -0,0 +1,276 @@ +/* Version V1.0.8 + PS2KeyCode.h - PS2KeyAdvanced library Internal actual PS2 key code sequences + Copyright (c) 2007 Free Software Foundation. All right reserved. + Written by Paul Carpenter, PC Services + Created September 2014 + Updated January 2016 - Paul Carpenter - add tested on Due and tidy ups for V1.5 Library Management + Updated December 2019 - Paul Carpenter - Fix typo in code for Multimedia STOP + + PRIVATE to library + + Test History + September 2014 Uno and Mega 2560 September 2014 using Arduino V1.6.0 + January 2016 Uno, Mega 2560 and Due using Arduino 1.6.7 and Due Board + Manager V1.6.6 + + This is for a LATIN style keyboard. Will support most keyboards even ones + with multimedia keys or even 24 function keys. + + Definitions used for key codes from a PS2 keyboard, do not use in your + code these are to be handled INTERNALLY by the library. + (may disappear in updates do not rely on this file or definitions) + + See PS2KeyAdvanced.h for codes returned from library and flag settings + + Defines are in three groups + + Special codes definition of communications bytes + + Single Byte codes returned as key codes + + Two byte Codes preceded by E0 code returned as keycodes + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef PS2KeyCode_h +#define PS2KeyCode_h + +/* Ignore code for key code translation */ +#define PS2_KEY_IGNORE 0xBB + +// buffer sizes keyboard RX and TX, then key reading buffer +// Minimum size 8 can be larger +#define _RX_BUFFER_SIZE 8 +// Minimum size 6 can be larger +#define _TX_BUFFER_SIZE 6 +// Output Buffer of unsigned int values. Minimum size 4 can be larger +#define _KEY_BUFF_SIZE 4 + +/* private defines for library files not global */ +/* _ps2mode status flags */ +#define _PS2_BUSY 0x80 +#define _TX_MODE 0x40 +#define _BREAK_KEY 0x20 +#define _WAIT_RESPONSE 0x10 +#define _E0_MODE 0x08 +#define _E1_MODE 0x04 +#define _LAST_VALID 0x02 + +/* _tx_ready flags */ +#define _HANDSHAKE 0x80 +#define _COMMAND 0x01 + +/* Key Repeat defines */ +#define _NO_BREAKS 0x08 +#define _NO_REPEATS 0x80 + +/* PS2_keystatus byte masks (from 16 bit int masks) */ +#define _BREAK ( PS2_BREAK >> 8 ) +#define _SHIFT ( PS2_SHIFT >> 8 ) +#define _CTRL ( PS2_CTRL >> 8 ) +#define _CAPS ( PS2_CAPS >> 8 ) +#define _ALT ( PS2_ALT >> 8 ) +#define _ALT_GR ( PS2_ALT_GR >> 8 ) +#define _GUI ( PS2_GUI >> 8 ) +#define _FUNCTION ( PS2_FUNCTION >> 8 ) + +/* General defines of comms codes */ +/* Command or response */ +#define PS2_KC_RESEND 0xFE +#define PS2_KC_ACK 0xFA +#define PS2_KC_ECHO 0xEE +/* Responses */ +#define PS2_KC_BAT 0xAA +// Actually buffer overrun +#define PS2_KC_OVERRUN 0xFF +// Below is general error code +#define PS2_KC_ERROR 0xFC +#define PS2_KC_KEYBREAK 0xF0 +#define PS2_KC_EXTEND1 0xE1 +#define PS2_KC_EXTEND 0xE0 +/* Commands */ +#define PS2_KC_RESET 0xFF +#define PS2_KC_DEFAULTS 0xF6 +#define PS2_KC_DISABLE 0xF5 +#define PS2_KC_ENABLE 0xF4 +#define PS2_KC_RATE 0xF3 +#define PS2_KC_READID 0xF2 +#define PS2_KC_SCANCODE 0xF0 +#define PS2_KC_LOCK 0xED + +/* Single Byte Key Codes */ +#define PS2_KC_NUM 0x77 +#define PS2_KC_SCROLL 0x7E +#define PS2_KC_CAPS 0x58 +#define PS2_KC_L_SHIFT 0x12 +#define PS2_KC_R_SHIFT 0x59 +/* This is Left CTRL and ALT but Right version is in E0 with same code */ +#define PS2_KC_CTRL 0X14 +#define PS2_KC_ALT 0x11 +/* Generated by some keyboards by ALT and PRTSCR */ +#define PS2_KC_SYSRQ 0x84 +#define PS2_KC_ESC 0x76 +#define PS2_KC_BS 0x66 +#define PS2_KC_TAB 0x0D +#define PS2_KC_ENTER 0x5A +#define PS2_KC_SPACE 0x29 +#define PS2_KC_KP0 0x70 +#define PS2_KC_KP1 0x69 +#define PS2_KC_KP2 0x72 +#define PS2_KC_KP3 0x7A +#define PS2_KC_KP4 0x6B +#define PS2_KC_KP5 0x73 +#define PS2_KC_KP6 0x74 +#define PS2_KC_KP7 0x6C +#define PS2_KC_KP8 0x75 +#define PS2_KC_KP9 0x7D +#define PS2_KC_KP_DOT 0x71 +#define PS2_KC_KP_PLUS 0x79 +#define PS2_KC_KP_MINUS 0x7B +#define PS2_KC_KP_TIMES 0x7C +/* Some keyboards have an '=' on right keypad */ +#define PS2_KC_KP_EQUAL 0x0F +#define PS2_KC_0 0X45 +#define PS2_KC_1 0X16 +#define PS2_KC_2 0X1E +#define PS2_KC_3 0X26 +#define PS2_KC_4 0X25 +#define PS2_KC_5 0X2E +#define PS2_KC_6 0X36 +#define PS2_KC_7 0X3D +#define PS2_KC_8 0X3E +#define PS2_KC_9 0X46 +#define PS2_KC_APOS 0X52 +#define PS2_KC_COMMA 0X41 +#define PS2_KC_MINUS 0X4E +#define PS2_KC_DOT 0X49 +#define PS2_KC_DIV 0X4A +/* Single quote or back apostrophe */ +#define PS2_KC_BTICK 0X0E +#define PS2_KC_A 0X1C +#define PS2_KC_B 0X32 +#define PS2_KC_C 0X21 +#define PS2_KC_D 0X23 +#define PS2_KC_E 0X24 +#define PS2_KC_F 0X2B +#define PS2_KC_G 0X34 +#define PS2_KC_H 0X33 +#define PS2_KC_I 0X43 +#define PS2_KC_J 0X3B +#define PS2_KC_K 0X42 +#define PS2_KC_L 0X4B +#define PS2_KC_M 0X3A +#define PS2_KC_N 0X31 +#define PS2_KC_O 0X44 +#define PS2_KC_P 0X4D +#define PS2_KC_Q 0X15 +#define PS2_KC_R 0X2D +#define PS2_KC_S 0X1B +#define PS2_KC_T 0X2C +#define PS2_KC_U 0X3C +#define PS2_KC_V 0X2A +#define PS2_KC_W 0X1D +#define PS2_KC_X 0X22 +#define PS2_KC_Y 0X35 +#define PS2_KC_Z 0X1A +#define PS2_KC_SEMI 0X4C +#define PS2_KC_BACK 0X5D +// Extra key left of Z on 102 keyboards +#define PS2_KC_EUROPE2 0x61 +#define PS2_KC_OPEN_SQ 0X54 +#define PS2_KC_CLOSE_SQ 0X5B +#define PS2_KC_EQUAL 0X55 +#define PS2_KC_F1 0X05 +#define PS2_KC_F2 0X06 +#define PS2_KC_F3 0X04 +#define PS2_KC_F4 0X0C +#define PS2_KC_F5 0X03 +#define PS2_KC_F6 0X0B +#define PS2_KC_F7 0X83 +#define PS2_KC_F8 0X0A +#define PS2_KC_F9 0X01 +#define PS2_KC_F10 0X09 +#define PS2_KC_F11 0X78 +#define PS2_KC_F12 0X07 +#define PS2_KC_F13 0X08 +#define PS2_KC_F14 0X10 +#define PS2_KC_F15 0X18 +#define PS2_KC_F16 0X20 +#define PS2_KC_F17 0X28 +#define PS2_KC_F18 0X30 +#define PS2_KC_F19 0X38 +#define PS2_KC_F20 0X40 +#define PS2_KC_F21 0X48 +#define PS2_KC_F22 0X50 +#define PS2_KC_F23 0X57 +#define PS2_KC_F24 0X5F +#define PS2_KC_KP_COMMA 0X6D +#define PS2_KC_INTL1 0X51 +#define PS2_KC_INTL2 0X13 +#define PS2_KC_INTL3 0X6A +#define PS2_KC_INTL4 0X64 +#define PS2_KC_INTL5 0X67 +#define PS2_KC_LANG1 0XF2 +#define PS2_KC_LANG2 0XF1 +#define PS2_KC_LANG3 0X63 +#define PS2_KC_LANG4 0X62 +#define PS2_KC_LANG5 0X5F + +/* Extended key codes E0 table for two byte codes */ +/* PS2_CTRL and PS2_ALT Need using in any table for the right keys */ +/* first is special case for PRTSCR not always used so ignored by decoding */ +#define PS2_KC_IGNORE 0x12 +#define PS2_KC_PRTSCR 0x7C +/* Sometimes called windows key */ +#define PS2_KC_L_GUI 0x1F +#define PS2_KC_R_GUI 0x27 +#define PS2_KC_MENU 0x2F +/* Break is CTRL + PAUSE generated inside keyboard */ +#define PS2_KC_BREAK 0x7E +#define PS2_KC_HOME 0x6C +#define PS2_KC_END 0x69 +#define PS2_KC_PGUP 0x7D +#define PS2_KC_PGDN 0x7A +#define PS2_KC_L_ARROW 0x6B +#define PS2_KC_R_ARROW 0x74 +#define PS2_KC_UP_ARROW 0x75 +#define PS2_KC_DN_ARROW 0x72 +#define PS2_KC_INSERT 0x70 +#define PS2_KC_DELETE 0x71 +#define PS2_KC_KP_ENTER 0x5A +#define PS2_KC_KP_DIV 0x4A +#define PS2_KC_NEXT_TR 0X4D +#define PS2_KC_PREV_TR 0X15 +#define PS2_KC_STOP 0X3B +#define PS2_KC_PLAY 0X34 +#define PS2_KC_MUTE 0X23 +#define PS2_KC_VOL_UP 0X32 +#define PS2_KC_VOL_DN 0X21 +#define PS2_KC_MEDIA 0X50 +#define PS2_KC_EMAIL 0X48 +#define PS2_KC_CALC 0X2B +#define PS2_KC_COMPUTER 0X40 +#define PS2_KC_WEB_SEARCH 0X10 +#define PS2_KC_WEB_HOME 0X3A +#define PS2_KC_WEB_BACK 0X38 +#define PS2_KC_WEB_FORWARD 0X30 +#define PS2_KC_WEB_STOP 0X28 +#define PS2_KC_WEB_REFRESH 0X20 +#define PS2_KC_WEB_FAVOR 0X18 +#define PS2_KC_POWER 0X37 +#define PS2_KC_SLEEP 0X3F +#define PS2_KC_WAKE 0X5E +#endif diff --git a/v1.2/main/PS2KeyTable.h b/v1.2/main/PS2KeyTable.h new file mode 100644 index 0000000..dbc4d99 --- /dev/null +++ b/v1.2/main/PS2KeyTable.h @@ -0,0 +1,397 @@ +/* Version V1.0.8 + PS2KeyTable.h - PS2KeyAdvanced library keycode values to return values + Copyright (c) 2007 Free Software Foundation. All right reserved. + Written by Paul Carpenter, PC Services + Created September 2014 + V1.0.2 Updated January 2016 - Paul Carpenter - add tested on Due and tidy ups for V1.5 Library Management + + PRIVATE to library + + Test History + September 2014 Uno and Mega 2560 September 2014 using Arduino V1.6.0 + January 2016 Uno, Mega 2560 and Due using Arduino 1.6.7 and Due Board + Manager V1.6.6 + + Internal to library private tables + (may disappear in updates do not rely on this file or definitions) + + This is for a LATIN style keyboard. Will support most keyboards even ones + with multimedia keys or even 24 function keys. + + Definitions used for key codes from a PS2 keyboard, do not use in your + code these are handled by the library. + + See PS2KeyAdvanced.h for codes returned from library and flag settings + + Two sets of tables + + Single Byte codes returned as key codes + + Two byte Codes preceded by E0 code returned as keycodes + + Same tables used for make and break decode + + Special cases are - + + PRTSCR that ignores one of the sequences (E0,12) as this is not always sent + especially with modifier keys or some keyboards when typematic repeat comes on. + + PAUSE as this is an 8 byte sequence only one starting E1 so main code gets E1 + and waits for 7 more valid bytes to make the coding. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef PS2KeyTable_h +#define PS2KeyTable_h + +/* Table contents are pairs of numbers + first code from keyboard + second is either PS2_KEY_IGNOPRE code or key code to return + + Single byte Key table + In codes can only be 1 - 0x9F, plus 0xF2 and 0xF1 + Out Codes in range 1 to 0x9F +*/ +#if defined(CONFIG_KEYMAP_WYSE_KB3926) +const uint8_t single_key[][ 2 ] = { + { PS2_KC_NUM, PS2_KEY_NUM }, + { PS2_KC_SCROLL, PS2_KEY_SCROLL }, + { PS2_KC_CAPS, PS2_KEY_CAPS }, + { PS2_KC_L_SHIFT, PS2_KEY_L_SHIFT }, + { PS2_KC_R_SHIFT, PS2_KEY_R_SHIFT }, + { PS2_KC_CTRL, PS2_KEY_L_CTRL }, + { PS2_KC_ALT, PS2_KEY_L_ALT }, + { PS2_KC_SYSRQ, PS2_KEY_SYSRQ }, + { PS2_KC_ESC, PS2_KEY_ESC }, + { PS2_KC_BS, PS2_KEY_BS }, + { PS2_KC_TAB, PS2_KEY_TAB }, + { PS2_KC_ENTER, PS2_KEY_ENTER }, + { PS2_KC_SPACE, PS2_KEY_SPACE }, + { PS2_KC_KP0, PS2_KEY_KP0 }, + { PS2_KC_KP1, PS2_KEY_KP1 }, + { PS2_KC_KP2, PS2_KEY_KP2 }, + { PS2_KC_KP3, PS2_KEY_KP3 }, + { PS2_KC_KP4, PS2_KEY_KP4 }, + { PS2_KC_KP5, PS2_KEY_KP5 }, + { PS2_KC_KP6, PS2_KEY_KP6 }, + { PS2_KC_KP7, PS2_KEY_KP7 }, + { PS2_KC_KP8, PS2_KEY_KP8 }, + { PS2_KC_KP9, PS2_KEY_KP9 }, + { PS2_KC_KP_DOT, PS2_KEY_KP_DOT }, + { PS2_KC_KP_PLUS, PS2_KEY_KP_PLUS }, + { PS2_KC_KP_MINUS, PS2_KEY_KP_MINUS }, + { PS2_KC_KP_TIMES, PS2_KEY_KP_TIMES }, + { PS2_KC_KP_EQUAL, PS2_KEY_KP_EQUAL }, + { PS2_KC_0, PS2_KEY_0 }, + { PS2_KC_1, PS2_KEY_1 }, + { PS2_KC_2, PS2_KEY_2 }, + { PS2_KC_3, PS2_KEY_3 }, + { PS2_KC_4, PS2_KEY_4 }, + { PS2_KC_5, PS2_KEY_5 }, + { PS2_KC_6, PS2_KEY_6 }, + { PS2_KC_7, PS2_KEY_7 }, + { PS2_KC_8, PS2_KEY_8 }, + { PS2_KC_9, PS2_KEY_9 }, + { PS2_KC_APOS, PS2_KEY_APOS }, + { PS2_KC_COMMA, PS2_KEY_COMMA }, + { PS2_KC_MINUS, PS2_KEY_MINUS }, + { PS2_KC_DOT, PS2_KEY_DOT }, + { PS2_KC_DIV, PS2_KEY_DIV }, + { PS2_KC_BTICK, PS2_KEY_BTICK }, + { PS2_KC_A, PS2_KEY_A }, + { PS2_KC_B, PS2_KEY_B }, + { PS2_KC_C, PS2_KEY_C }, + { PS2_KC_D, PS2_KEY_D }, + { PS2_KC_E, PS2_KEY_E }, + { PS2_KC_F, PS2_KEY_F }, + { PS2_KC_G, PS2_KEY_G }, + { PS2_KC_H, PS2_KEY_H }, + { PS2_KC_I, PS2_KEY_I }, + { PS2_KC_J, PS2_KEY_J }, + { PS2_KC_K, PS2_KEY_K }, + { PS2_KC_L, PS2_KEY_L }, + { PS2_KC_M, PS2_KEY_M }, + { PS2_KC_N, PS2_KEY_N }, + { PS2_KC_O, PS2_KEY_O }, + { PS2_KC_P, PS2_KEY_P }, + { PS2_KC_Q, PS2_KEY_Q }, + { PS2_KC_R, PS2_KEY_R }, + { PS2_KC_S, PS2_KEY_S }, + { PS2_KC_T, PS2_KEY_T }, + { PS2_KC_U, PS2_KEY_U }, + { PS2_KC_V, PS2_KEY_V }, + { PS2_KC_W, PS2_KEY_W }, + { PS2_KC_X, PS2_KEY_X }, + { PS2_KC_Y, PS2_KEY_Y }, + { PS2_KC_Z, PS2_KEY_Z }, + { PS2_KC_SEMI, PS2_KEY_SEMI }, + { PS2_KC_BACK, PS2_KEY_HASH }, + { PS2_KC_OPEN_SQ, PS2_KEY_OPEN_SQ }, + { PS2_KC_CLOSE_SQ, PS2_KEY_CLOSE_SQ }, + { PS2_KC_EQUAL, PS2_KEY_EQUAL }, + { PS2_KC_EUROPE2, PS2_KEY_BACK }, + { PS2_KC_F1, PS2_KEY_F1 }, + { PS2_KC_F2, PS2_KEY_F2 }, + { PS2_KC_F3, PS2_KEY_F3 }, + { PS2_KC_F4, PS2_KEY_F4 }, + { PS2_KC_F5, PS2_KEY_F5 }, + { PS2_KC_F6, PS2_KEY_F6 }, + { PS2_KC_F7, PS2_KEY_F7 }, + { PS2_KC_F8, PS2_KEY_F8 }, + { PS2_KC_F9, PS2_KEY_F9 }, + { PS2_KC_F10, PS2_KEY_F10 }, + { PS2_KC_F11, PS2_KEY_F11 }, + { PS2_KC_F12, PS2_KEY_F12 }, + { PS2_KC_KP_COMMA, PS2_KEY_KP_COMMA }, + { PS2_KC_INTL1, PS2_KEY_INTL1 }, + { PS2_KC_INTL2, PS2_KEY_INTL2 }, + { PS2_KC_INTL3, PS2_KEY_INTL3 }, + { PS2_KC_INTL4, PS2_KEY_INTL4 }, + { PS2_KC_INTL5, PS2_KEY_INTL5 }, + { PS2_KC_LANG1, PS2_KEY_LANG1 }, + { PS2_KC_LANG2, PS2_KEY_LANG2 }, + { PS2_KC_LANG3, PS2_KEY_LANG3 }, + { PS2_KC_LANG4, PS2_KEY_LANG4 }, + { PS2_KC_LANG5, PS2_KEY_LANG5 } + }; + +/* Two byte Key table after an E0 byte received */ +const uint8_t extended_key[][ 2 ] = { + { PS2_KC_IGNORE, PS2_KEY_IGNORE }, + { PS2_KC_PRTSCR, PS2_KEY_PRTSCR }, + { PS2_KC_CTRL, PS2_KEY_R_CTRL }, + { PS2_KC_ALT, PS2_KEY_R_ALT }, + { PS2_KC_L_GUI, PS2_KEY_L_GUI }, + { PS2_KC_R_GUI, PS2_KEY_R_GUI }, + { PS2_KC_MENU, PS2_KEY_MENU }, + { PS2_KC_BREAK, PS2_KEY_BREAK }, + { PS2_KC_HOME, PS2_KEY_HOME }, + { PS2_KC_END, PS2_KEY_END }, + { PS2_KC_PGUP, PS2_KEY_PGUP }, + { PS2_KC_PGDN, PS2_KEY_PGDN }, + { PS2_KC_L_ARROW, PS2_KEY_L_ARROW }, + { PS2_KC_R_ARROW, PS2_KEY_R_ARROW }, + { PS2_KC_UP_ARROW, PS2_KEY_UP_ARROW }, + { PS2_KC_DN_ARROW, PS2_KEY_DN_ARROW }, + { PS2_KC_INSERT, PS2_KEY_INSERT }, + { PS2_KC_DELETE, PS2_KEY_DELETE }, + { PS2_KC_KP_ENTER, PS2_KEY_KP_ENTER }, + { PS2_KC_KP_DIV, PS2_KEY_KP_DIV }, + { PS2_KC_NEXT_TR, PS2_KEY_NEXT_TR }, + { PS2_KC_PREV_TR, PS2_KEY_PREV_TR }, + { PS2_KC_STOP, PS2_KEY_STOP }, + { PS2_KC_PLAY, PS2_KEY_PLAY }, + { PS2_KC_MUTE, PS2_KEY_MUTE }, + { PS2_KC_VOL_UP, PS2_KEY_VOL_UP }, + { PS2_KC_VOL_DN, PS2_KEY_VOL_DN }, + { PS2_KC_MEDIA, PS2_KEY_MEDIA }, + { PS2_KC_EMAIL, PS2_KEY_EMAIL }, + { PS2_KC_CALC, PS2_KEY_CALC }, + { PS2_KC_COMPUTER, PS2_KEY_COMPUTER }, + { PS2_KC_WEB_SEARCH, PS2_KEY_WEB_SEARCH }, + { PS2_KC_WEB_HOME, PS2_KEY_WEB_HOME }, + { PS2_KC_WEB_BACK, PS2_KEY_WEB_BACK }, + { PS2_KC_WEB_FORWARD, PS2_KEY_WEB_FORWARD }, + { PS2_KC_WEB_STOP, PS2_KEY_WEB_STOP }, + { PS2_KC_WEB_REFRESH, PS2_KEY_WEB_REFRESH }, + { PS2_KC_WEB_FAVOR, PS2_KEY_WEB_FAVOR }, + { PS2_KC_POWER, PS2_KEY_POWER }, + { PS2_KC_SLEEP, PS2_KEY_SLEEP }, + { PS2_KC_WAKE, PS2_KEY_WAKE } + }; + +/* Scroll lock numeric keypad re-mappings for NOT NUMLOCK */ +/* in translated code order order is important */ +const uint8_t scroll_remap[] = { + PS2_KEY_INSERT, // PS2_KEY_KP0 + PS2_KEY_END, // PS2_KEY_KP1 + PS2_KEY_DN_ARROW, // PS2_KEY_KP2 + PS2_KEY_PGDN, // PS2_KEY_KP3 + PS2_KEY_L_ARROW, // PS2_KEY_KP4 + PS2_KEY_IGNORE, // PS2_KEY_KP5 + PS2_KEY_R_ARROW, // PS2_KEY_KP6 + PS2_KEY_HOME, // PS2_KEY_KP7 + PS2_KEY_UP_ARROW, // PS2_KEY_KP8 + PS2_KEY_PGUP, // PS2_KEY_KP9 + PS2_KEY_DELETE // PS2_KEY_KP_DOT + }; +#endif + +#if defined(CONFIG_KEYMAP_STANDARD) +const uint8_t single_key[][ 2 ] = { + { PS2_KC_NUM, PS2_KEY_NUM }, + { PS2_KC_SCROLL, PS2_KEY_SCROLL }, + { PS2_KC_CAPS, PS2_KEY_CAPS }, + { PS2_KC_L_SHIFT, PS2_KEY_L_SHIFT }, + { PS2_KC_R_SHIFT, PS2_KEY_R_SHIFT }, + { PS2_KC_CTRL, PS2_KEY_L_CTRL }, + { PS2_KC_ALT, PS2_KEY_L_ALT }, + { PS2_KC_SYSRQ, PS2_KEY_SYSRQ }, + { PS2_KC_ESC, PS2_KEY_ESC }, + { PS2_KC_BS, PS2_KEY_BS }, + { PS2_KC_TAB, PS2_KEY_TAB }, + { PS2_KC_ENTER, PS2_KEY_ENTER }, + { PS2_KC_SPACE, PS2_KEY_SPACE }, + { PS2_KC_KP0, PS2_KEY_KP0 }, + { PS2_KC_KP1, PS2_KEY_KP1 }, + { PS2_KC_KP2, PS2_KEY_KP2 }, + { PS2_KC_KP3, PS2_KEY_KP3 }, + { PS2_KC_KP4, PS2_KEY_KP4 }, + { PS2_KC_KP5, PS2_KEY_KP5 }, + { PS2_KC_KP6, PS2_KEY_KP6 }, + { PS2_KC_KP7, PS2_KEY_KP7 }, + { PS2_KC_KP8, PS2_KEY_KP8 }, + { PS2_KC_KP9, PS2_KEY_KP9 }, + { PS2_KC_KP_DOT, PS2_KEY_KP_DOT }, + { PS2_KC_KP_PLUS, PS2_KEY_KP_PLUS }, + { PS2_KC_KP_MINUS, PS2_KEY_KP_MINUS }, + { PS2_KC_KP_TIMES, PS2_KEY_KP_TIMES }, + { PS2_KC_KP_EQUAL, PS2_KEY_KP_EQUAL }, + { PS2_KC_0, PS2_KEY_0 }, + { PS2_KC_1, PS2_KEY_1 }, + { PS2_KC_2, PS2_KEY_2 }, + { PS2_KC_3, PS2_KEY_3 }, + { PS2_KC_4, PS2_KEY_4 }, + { PS2_KC_5, PS2_KEY_5 }, + { PS2_KC_6, PS2_KEY_6 }, + { PS2_KC_7, PS2_KEY_7 }, + { PS2_KC_8, PS2_KEY_8 }, + { PS2_KC_9, PS2_KEY_9 }, + { PS2_KC_APOS, PS2_KEY_APOS }, + { PS2_KC_COMMA, PS2_KEY_COMMA }, + { PS2_KC_MINUS, PS2_KEY_MINUS }, + { PS2_KC_DOT, PS2_KEY_DOT }, + { PS2_KC_DIV, PS2_KEY_DIV }, + { PS2_KC_BTICK, PS2_KEY_BTICK }, + { PS2_KC_A, PS2_KEY_A }, + { PS2_KC_B, PS2_KEY_B }, + { PS2_KC_C, PS2_KEY_C }, + { PS2_KC_D, PS2_KEY_D }, + { PS2_KC_E, PS2_KEY_E }, + { PS2_KC_F, PS2_KEY_F }, + { PS2_KC_G, PS2_KEY_G }, + { PS2_KC_H, PS2_KEY_H }, + { PS2_KC_I, PS2_KEY_I }, + { PS2_KC_J, PS2_KEY_J }, + { PS2_KC_K, PS2_KEY_K }, + { PS2_KC_L, PS2_KEY_L }, + { PS2_KC_M, PS2_KEY_M }, + { PS2_KC_N, PS2_KEY_N }, + { PS2_KC_O, PS2_KEY_O }, + { PS2_KC_P, PS2_KEY_P }, + { PS2_KC_Q, PS2_KEY_Q }, + { PS2_KC_R, PS2_KEY_R }, + { PS2_KC_S, PS2_KEY_S }, + { PS2_KC_T, PS2_KEY_T }, + { PS2_KC_U, PS2_KEY_U }, + { PS2_KC_V, PS2_KEY_V }, + { PS2_KC_W, PS2_KEY_W }, + { PS2_KC_X, PS2_KEY_X }, + { PS2_KC_Y, PS2_KEY_Y }, + { PS2_KC_Z, PS2_KEY_Z }, + { PS2_KC_SEMI, PS2_KEY_SEMI }, + { PS2_KC_BACK, PS2_KEY_BACK }, + { PS2_KC_OPEN_SQ, PS2_KEY_OPEN_SQ }, + { PS2_KC_CLOSE_SQ, PS2_KEY_CLOSE_SQ }, + { PS2_KC_EQUAL, PS2_KEY_EQUAL }, + { PS2_KC_EUROPE2, PS2_KEY_BACK }, + { PS2_KC_F1, PS2_KEY_F1 }, + { PS2_KC_F2, PS2_KEY_F2 }, + { PS2_KC_F3, PS2_KEY_F3 }, + { PS2_KC_F4, PS2_KEY_F4 }, + { PS2_KC_F5, PS2_KEY_F5 }, + { PS2_KC_F6, PS2_KEY_F6 }, + { PS2_KC_F7, PS2_KEY_F7 }, + { PS2_KC_F8, PS2_KEY_F8 }, + { PS2_KC_F9, PS2_KEY_F9 }, + { PS2_KC_F10, PS2_KEY_F10 }, + { PS2_KC_F11, PS2_KEY_F11 }, + { PS2_KC_F12, PS2_KEY_F12 }, + { PS2_KC_KP_COMMA, PS2_KEY_KP_COMMA }, + { PS2_KC_INTL1, PS2_KEY_INTL1 }, + { PS2_KC_INTL2, PS2_KEY_INTL2 }, + { PS2_KC_INTL3, PS2_KEY_INTL3 }, + { PS2_KC_INTL4, PS2_KEY_INTL4 }, + { PS2_KC_INTL5, PS2_KEY_INTL5 }, + { PS2_KC_LANG1, PS2_KEY_LANG1 }, + { PS2_KC_LANG2, PS2_KEY_LANG2 }, + { PS2_KC_LANG3, PS2_KEY_LANG3 }, + { PS2_KC_LANG4, PS2_KEY_LANG4 }, + { PS2_KC_LANG5, PS2_KEY_LANG5 } + }; + +/* Two byte Key table after an E0 byte received */ +const uint8_t extended_key[][ 2 ] = { + { PS2_KC_IGNORE, PS2_KEY_IGNORE }, + { PS2_KC_PRTSCR, PS2_KEY_PRTSCR }, + { PS2_KC_CTRL, PS2_KEY_R_CTRL }, + { PS2_KC_ALT, PS2_KEY_R_ALT }, + { PS2_KC_L_GUI, PS2_KEY_L_GUI }, + { PS2_KC_R_GUI, PS2_KEY_R_GUI }, + { PS2_KC_MENU, PS2_KEY_MENU }, + { PS2_KC_BREAK, PS2_KEY_BREAK }, + { PS2_KC_HOME, PS2_KEY_HOME }, + { PS2_KC_END, PS2_KEY_END }, + { PS2_KC_PGUP, PS2_KEY_PGUP }, + { PS2_KC_PGDN, PS2_KEY_PGDN }, + { PS2_KC_L_ARROW, PS2_KEY_L_ARROW }, + { PS2_KC_R_ARROW, PS2_KEY_R_ARROW }, + { PS2_KC_UP_ARROW, PS2_KEY_UP_ARROW }, + { PS2_KC_DN_ARROW, PS2_KEY_DN_ARROW }, + { PS2_KC_INSERT, PS2_KEY_INSERT }, + { PS2_KC_DELETE, PS2_KEY_DELETE }, + { PS2_KC_KP_ENTER, PS2_KEY_KP_ENTER }, + { PS2_KC_KP_DIV, PS2_KEY_KP_DIV }, + { PS2_KC_NEXT_TR, PS2_KEY_NEXT_TR }, + { PS2_KC_PREV_TR, PS2_KEY_PREV_TR }, + { PS2_KC_STOP, PS2_KEY_STOP }, + { PS2_KC_PLAY, PS2_KEY_PLAY }, + { PS2_KC_MUTE, PS2_KEY_MUTE }, + { PS2_KC_VOL_UP, PS2_KEY_VOL_UP }, + { PS2_KC_VOL_DN, PS2_KEY_VOL_DN }, + { PS2_KC_MEDIA, PS2_KEY_MEDIA }, + { PS2_KC_EMAIL, PS2_KEY_EMAIL }, + { PS2_KC_CALC, PS2_KEY_CALC }, + { PS2_KC_COMPUTER, PS2_KEY_COMPUTER }, + { PS2_KC_WEB_SEARCH, PS2_KEY_WEB_SEARCH }, + { PS2_KC_WEB_HOME, PS2_KEY_WEB_HOME }, + { PS2_KC_WEB_BACK, PS2_KEY_WEB_BACK }, + { PS2_KC_WEB_FORWARD, PS2_KEY_WEB_FORWARD }, + { PS2_KC_WEB_STOP, PS2_KEY_WEB_STOP }, + { PS2_KC_WEB_REFRESH, PS2_KEY_WEB_REFRESH }, + { PS2_KC_WEB_FAVOR, PS2_KEY_WEB_FAVOR }, + { PS2_KC_POWER, PS2_KEY_POWER }, + { PS2_KC_SLEEP, PS2_KEY_SLEEP }, + { PS2_KC_WAKE, PS2_KEY_WAKE } + }; + +/* Scroll lock numeric keypad re-mappings for NOT NUMLOCK */ +/* in translated code order order is important */ +const uint8_t scroll_remap[] = { + PS2_KEY_INSERT, // PS2_KEY_KP0 + PS2_KEY_END, // PS2_KEY_KP1 + PS2_KEY_DN_ARROW, // PS2_KEY_KP2 + PS2_KEY_PGDN, // PS2_KEY_KP3 + PS2_KEY_L_ARROW, // PS2_KEY_KP4 + PS2_KEY_IGNORE, // PS2_KEY_KP5 + PS2_KEY_R_ARROW, // PS2_KEY_KP6 + PS2_KEY_HOME, // PS2_KEY_KP7 + PS2_KEY_UP_ARROW, // PS2_KEY_KP8 + PS2_KEY_PGUP, // PS2_KEY_KP9 + PS2_KEY_DELETE // PS2_KEY_KP_DOT + }; +#endif + +#endif diff --git a/v1.2/main/component.mk b/v1.2/main/component.mk new file mode 100644 index 0000000..61f8990 --- /dev/null +++ b/v1.2/main/component.mk @@ -0,0 +1,8 @@ +# +# Main component makefile. +# +# This Makefile can be left empty. By default, it will take the sources in the +# src/ directory, compile them and link them into lib(subdirectory_name).a +# in the build directory. This behaviour is entirely configurable, +# please read the ESP-IDF documents if you need to do this. +# diff --git a/v1.2/main/font8x8_basic.h b/v1.2/main/font8x8_basic.h new file mode 100644 index 0000000..413825e --- /dev/null +++ b/v1.2/main/font8x8_basic.h @@ -0,0 +1,174 @@ +/* + * font8x8_basic.h + * + * Created on: 2017/05/03 + * Author: yanbe + */ + +#ifndef MAIN_FONT8X8_BASIC_H_ +#define MAIN_FONT8X8_BASIC_H_ + +/* + Constant: font8x8_basic_tr + Contains an 90 digree transposed 8x8 font map for unicode points + U+0000 - U+007F (basic latin) + + To make it easy to use with SSD1306's GDDRAM mapping and API, + this constant is an 90 degree transposed. + The original version written by Marcel Sondaar is availble at: + https://github.com/dhepper/font8x8/blob/master/font8x8_basic.h + + Conversion is done via following procedure: + + for (int code = 0; code < 128; code++) { + uint8_t trans[8]; + for (int w = 0; w < 8; w++) { + trans[w] = 0x00; + for (int b = 0; b < 8; b++) { + trans[w] |= ((font8x8_basic[code][b] & (1 << w)) >> w) << b; + } + } + + for (int w = 0; w < 8; w++) { + if (w == 0) { printf(" { "); } + printf("0x%.2X", trans[w]); + if (w < 7) { printf(", "); } + if (w == 7) { printf(" }, // U+00%.2X (%c)\n", code, code); } + } + } +*/ + +static uint8_t font8x8_basic_tr[128][8] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0000 (nul) + { 0x00, 0x04, 0x02, 0xFF, 0x02, 0x04, 0x00, 0x00 }, // U+0001 (Up Allow) + { 0x00, 0x20, 0x40, 0xFF, 0x40, 0x20, 0x00, 0x00 }, // U+0002 (Down Allow) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0003 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0004 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0005 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0006 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0007 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0008 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0009 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0010 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0011 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0012 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0013 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0014 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0015 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0016 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0017 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0018 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0019 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0020 (space) + { 0x00, 0x00, 0x06, 0x5F, 0x5F, 0x06, 0x00, 0x00 }, // U+0021 (!) + { 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x00 }, // U+0022 (") + { 0x14, 0x7F, 0x7F, 0x14, 0x7F, 0x7F, 0x14, 0x00 }, // U+0023 (#) + { 0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00, 0x00 }, // U+0024 ($) + { 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, 0x00 }, // U+0025 (%) + { 0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x7A, 0x48, 0x00 }, // U+0026 (&) + { 0x04, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0027 (') + { 0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00, 0x00, 0x00 }, // U+0028 (() + { 0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00, 0x00 }, // U+0029 ()) + { 0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08 }, // U+002A (*) + { 0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00, 0x00 }, // U+002B (+) + { 0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00 }, // U+002C (,) + { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 }, // U+002D (-) + { 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 }, // U+002E (.) + { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 }, // U+002F (/) + { 0x3E, 0x7F, 0x71, 0x59, 0x4D, 0x7F, 0x3E, 0x00 }, // U+0030 (0) + { 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, 0x00 }, // U+0031 (1) + { 0x62, 0x73, 0x59, 0x49, 0x6F, 0x66, 0x00, 0x00 }, // U+0032 (2) + { 0x22, 0x63, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 }, // U+0033 (3) + { 0x18, 0x1C, 0x16, 0x53, 0x7F, 0x7F, 0x50, 0x00 }, // U+0034 (4) + { 0x27, 0x67, 0x45, 0x45, 0x7D, 0x39, 0x00, 0x00 }, // U+0035 (5) + { 0x3C, 0x7E, 0x4B, 0x49, 0x79, 0x30, 0x00, 0x00 }, // U+0036 (6) + { 0x03, 0x03, 0x71, 0x79, 0x0F, 0x07, 0x00, 0x00 }, // U+0037 (7) + { 0x36, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 }, // U+0038 (8) + { 0x06, 0x4F, 0x49, 0x69, 0x3F, 0x1E, 0x00, 0x00 }, // U+0039 (9) + { 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 }, // U+003A (:) + { 0x00, 0x80, 0xE6, 0x66, 0x00, 0x00, 0x00, 0x00 }, // U+003B (;) + { 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, 0x00 }, // U+003C (<) + { 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00 }, // U+003D (=) + { 0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00 }, // U+003E (>) + { 0x02, 0x03, 0x51, 0x59, 0x0F, 0x06, 0x00, 0x00 }, // U+003F (?) + { 0x3E, 0x7F, 0x41, 0x5D, 0x5D, 0x1F, 0x1E, 0x00 }, // U+0040 (@) + { 0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00, 0x00 }, // U+0041 (A) + { 0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00 }, // U+0042 (B) + { 0x1C, 0x3E, 0x63, 0x41, 0x41, 0x63, 0x22, 0x00 }, // U+0043 (C) + { 0x41, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00 }, // U+0044 (D) + { 0x41, 0x7F, 0x7F, 0x49, 0x5D, 0x41, 0x63, 0x00 }, // U+0045 (E) + { 0x41, 0x7F, 0x7F, 0x49, 0x1D, 0x01, 0x03, 0x00 }, // U+0046 (F) + { 0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00 }, // U+0047 (G) + { 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00 }, // U+0048 (H) + { 0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00, 0x00 }, // U+0049 (I) + { 0x30, 0x70, 0x40, 0x41, 0x7F, 0x3F, 0x01, 0x00 }, // U+004A (J) + { 0x41, 0x7F, 0x7F, 0x08, 0x1C, 0x77, 0x63, 0x00 }, // U+004B (K) + { 0x41, 0x7F, 0x7F, 0x41, 0x40, 0x60, 0x70, 0x00 }, // U+004C (L) + { 0x7F, 0x7F, 0x0E, 0x1C, 0x0E, 0x7F, 0x7F, 0x00 }, // U+004D (M) + { 0x7F, 0x7F, 0x06, 0x0C, 0x18, 0x7F, 0x7F, 0x00 }, // U+004E (N) + { 0x1C, 0x3E, 0x63, 0x41, 0x63, 0x3E, 0x1C, 0x00 }, // U+004F (O) + { 0x41, 0x7F, 0x7F, 0x49, 0x09, 0x0F, 0x06, 0x00 }, // U+0050 (P) + { 0x1E, 0x3F, 0x21, 0x71, 0x7F, 0x5E, 0x00, 0x00 }, // U+0051 (Q) + { 0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00 }, // U+0052 (R) + { 0x26, 0x6F, 0x4D, 0x59, 0x73, 0x32, 0x00, 0x00 }, // U+0053 (S) + { 0x03, 0x41, 0x7F, 0x7F, 0x41, 0x03, 0x00, 0x00 }, // U+0054 (T) + { 0x7F, 0x7F, 0x40, 0x40, 0x7F, 0x7F, 0x00, 0x00 }, // U+0055 (U) + { 0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F, 0x00, 0x00 }, // U+0056 (V) + { 0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00 }, // U+0057 (W) + { 0x43, 0x67, 0x3C, 0x18, 0x3C, 0x67, 0x43, 0x00 }, // U+0058 (X) + { 0x07, 0x4F, 0x78, 0x78, 0x4F, 0x07, 0x00, 0x00 }, // U+0059 (Y) + { 0x47, 0x63, 0x71, 0x59, 0x4D, 0x67, 0x73, 0x00 }, // U+005A (Z) + { 0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x00 }, // U+005B ([) + { 0x01, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00 }, // U+005C (\) + { 0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00, 0x00 }, // U+005D (]) + { 0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00 }, // U+005E (^) + { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, // U+005F (_) + { 0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, 0x00 }, // U+0060 (`) + { 0x20, 0x74, 0x54, 0x54, 0x3C, 0x78, 0x40, 0x00 }, // U+0061 (a) + { 0x41, 0x7F, 0x3F, 0x48, 0x48, 0x78, 0x30, 0x00 }, // U+0062 (b) + { 0x38, 0x7C, 0x44, 0x44, 0x6C, 0x28, 0x00, 0x00 }, // U+0063 (c) + { 0x30, 0x78, 0x48, 0x49, 0x3F, 0x7F, 0x40, 0x00 }, // U+0064 (d) + { 0x38, 0x7C, 0x54, 0x54, 0x5C, 0x18, 0x00, 0x00 }, // U+0065 (e) + { 0x48, 0x7E, 0x7F, 0x49, 0x03, 0x02, 0x00, 0x00 }, // U+0066 (f) + { 0x98, 0xBC, 0xA4, 0xA4, 0xF8, 0x7C, 0x04, 0x00 }, // U+0067 (g) + { 0x41, 0x7F, 0x7F, 0x08, 0x04, 0x7C, 0x78, 0x00 }, // U+0068 (h) + { 0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00, 0x00 }, // U+0069 (i) + { 0x60, 0xE0, 0x80, 0x80, 0xFD, 0x7D, 0x00, 0x00 }, // U+006A (j) + { 0x41, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00 }, // U+006B (k) + { 0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00, 0x00 }, // U+006C (l) + { 0x7C, 0x7C, 0x18, 0x38, 0x1C, 0x7C, 0x78, 0x00 }, // U+006D (m) + { 0x7C, 0x7C, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00 }, // U+006E (n) + { 0x38, 0x7C, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00 }, // U+006F (o) + { 0x84, 0xFC, 0xF8, 0xA4, 0x24, 0x3C, 0x18, 0x00 }, // U+0070 (p) + { 0x18, 0x3C, 0x24, 0xA4, 0xF8, 0xFC, 0x84, 0x00 }, // U+0071 (q) + { 0x44, 0x7C, 0x78, 0x4C, 0x04, 0x1C, 0x18, 0x00 }, // U+0072 (r) + { 0x48, 0x5C, 0x54, 0x54, 0x74, 0x24, 0x00, 0x00 }, // U+0073 (s) + { 0x00, 0x04, 0x3E, 0x7F, 0x44, 0x24, 0x00, 0x00 }, // U+0074 (t) + { 0x3C, 0x7C, 0x40, 0x40, 0x3C, 0x7C, 0x40, 0x00 }, // U+0075 (u) + { 0x1C, 0x3C, 0x60, 0x60, 0x3C, 0x1C, 0x00, 0x00 }, // U+0076 (v) + { 0x3C, 0x7C, 0x70, 0x38, 0x70, 0x7C, 0x3C, 0x00 }, // U+0077 (w) + { 0x44, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0x44, 0x00 }, // U+0078 (x) + { 0x9C, 0xBC, 0xA0, 0xA0, 0xFC, 0x7C, 0x00, 0x00 }, // U+0079 (y) + { 0x4C, 0x64, 0x74, 0x5C, 0x4C, 0x64, 0x00, 0x00 }, // U+007A (z) + { 0x08, 0x08, 0x3E, 0x77, 0x41, 0x41, 0x00, 0x00 }, // U+007B ({) + { 0x00, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x00 }, // U+007C (|) + { 0x41, 0x41, 0x77, 0x3E, 0x08, 0x08, 0x00, 0x00 }, // U+007D (}) + { 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, 0x00 }, // U+007E (~) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // U+007F +}; + +#endif /* MAIN_FONT8X8_BASIC_H_ */ + + diff --git a/v1.2/main/main.cpp b/v1.2/main/main.cpp new file mode 100644 index 0000000..9d4b10e --- /dev/null +++ b/v1.2/main/main.cpp @@ -0,0 +1,1254 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Name: main.cpp +// Created: Jan 2022 +// Version: v1.0 +// Author(s): Philip Smart +// Description: MZ2500/2800 Key Matrix logic. +// This source file contains the application logic to obtain PS/2 scan codes, map them +// into a virtual keyboard matrix as per the Sharp MZ series key matrix and the +// logic to transmit the virtual key matrix to the MZ2500/2800. +// +// The application uses a modified version of the PS2KeyAdvanced +// https://github.com/techpaul/PS2KeyAdvanced class from Paul Carpenter. +// +// The application uses, for debug purposes, the esp-idf-ssd1306 class from nopnop2002 +// https://github.com/nopnop2002/esp-idf-ssd1306. +// +// The application uses the Espressif Development environment with Arduino components. +// This is necessary for the PS2KeyAdvanced class, which I may in future convert to +// use esp-idf library calls rather than Arduino. +// +// The Espressif environment is necessary in order to have more control over the build. +// It is important, for timing, that Core 1 is dedicated to MZ Interface +// logic and Core 0 is used for all RTOS/Interrupts tasks. +// +// The application is configured via the Kconfig system. Use 'idf.py menuconfig' to +// configure. +// Credits: +// Copyright: (c) 2022 Philip Smart +// +// History: Jan 2022 - Initial write. +// Feb 2022 - Updates and fixes. Added logic to detect PS/2 disconnect and reconnect, +// added 3 alternative maps selected by ALT+F1 (MZ2500), ALT+F2(MZ2000) +// ALT+F3(MZ80B) due to slight differences in the key layout. +// Added framework for wifi so that the interface can enter AP mode to +// acquire local net parameters then connect to local net. Needs the web +// interface writing. +// +// Notes: See Makefile to enable/disable conditional components +// +///////////////////////////////////////////////////////////////////////////////////////////////////////// +// This source file is free software: you can redistribute it and#or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_log.h" +#if defined(CONFIG_MZ_WIFI_ENABLED) + #include "freertos/event_groups.h" + #include "esp_system.h" + #include "esp_wifi.h" + #include "esp_event.h" + #include "nvs_flash.h" + #include "lwip/err.h" + #include "lwip/sys.h" +#endif +#include "Arduino.h" +#include "driver/gpio.h" +#include "soc/timer_group_struct.h" +#include "soc/timer_group_reg.h" +#include "PS2KeyAdvanced.h" +#include "MZKeyTable.h" +#include "ssd1306.h" +#include "font8x8_basic.h" +#include "sdkconfig.h" + +////////////////////////////////////////////////////////////////////////// +// Important: +// +// All configuration is performed via the 'idf.py menuconfig' command. +// The file 'sdkconfig' contains the configured parameter defines. +////////////////////////////////////////////////////////////////////////// + +// Macros. +// +#define NUMELEM(a) (sizeof(a)/sizeof(a[0])) + +// Structure to manage the translated key matrix. This is updated by the ps2Interface thread and read by the mzInterface thead. +typedef struct { + uint8_t strobeAll; + uint32_t strobeAllAsGPIO; + uint8_t keyMatrix[16]; + uint32_t keyMatrixAsGPIO[16]; + uint8_t activeKeyMap; +} t_mzControl; +volatile t_mzControl mzControl = { 0xFF, 0x00000000, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + MZ_ALL + }; + +// Instantiate base classes. First, production required objects. +PS2KeyAdvanced Keyboard; + +// Debug required objects. +SSD1306_t SSD1306; + +// Handle to interact with the mz-2500/mz-2800 interface, ps/2 interface and wifi threads. +#if defined(CONFIG_MODEL_MZ2500) + TaskHandle_t TaskMZ25IF = NULL; +#endif +#if defined(CONFIG_MODEL_MZ2800) + TaskHandle_t TaskMZ28IF = NULL; +#endif +TaskHandle_t TaskPS2IF = NULL; +#if defined(CONFIG_MZ_WIFI_ENABLED) + TaskHandle_t TaskWIFI = NULL; +#endif + +// Spin lock mutex to hold a core tied to an uninterruptable method. This only works on dual core ESP32's. +static portMUX_TYPE mzMutex = portMUX_INITIALIZER_UNLOCKED; + +// Tag for ESP main application logging. +#if defined(CONFIG_MODEL_MZ2500) + #define MAINTAG "mz25key" +#endif +#if defined(CONFIG_MODEL_MZ2800) + #define MAINTAG "mz28key" +#endif + +#if defined(CONFIG_MZ_WIFI_ENABLED) + // The event group allows multiple bits for each event, but we only care about two events: + // - we are connected to the AP with an IP + // - we failed to connect after the maximum amount of retries + #define WIFI_CONNECTED_BIT BIT0 + #define WIFI_FAIL_BIT BIT1 + + // Tag for ESP WiFi logging. + #define WIFITAG "wifi" + + // Menu selection types. + enum WIFIMODES { + WIFI_OFF = 0x00, // WiFi is disabled. + WIFI_ON = 0x01, // WiFi is enabled. + WIFI_CONFIG_AP = 0x02 // WiFi is set to enable Access Point to configure WiFi settings. + }; + + // Flag to indicate WiFi is active. Whilst active the MZ25 interface cannot run as it has to + // free the core. Need to find a way around this to make wifi only work on one core! + static bool wifiActivated = 0; + + // FreeRTOS event group to signal when we are connected + static EventGroupHandle_t s_wifi_event_group; + + + static int clientRetryCnt = 0; +#endif + +#if defined(CONFIG_DEBUG_OLED) || !defined(CONFIG_OLED_DISABLED) + // Printf to debug console terminal. + void dbgprintf(const char * format, ...) + { + // Locals. + va_list ap; + + // Commence variable argument processing. + va_start(ap, format); + // Use vararg printf to expand and return the buffer size needed. + int size = vsnprintf(nullptr, 0, format, ap) + 1; + if (size > 0) + { + va_end(ap); + + // Repeat and this time output the expanded string to a buffer for printing. + va_start(ap, format); + char buf[size + 1]; + vsnprintf(buf, size, format, ap); + + // Output to LED or console, currently via printf! + printf(buf); + } + va_end(ap); + } +#else + #define dbgprintf(a, ...) {}; +#endif + +// Method to connect and interact with the MZ-2500 keyboard controller. This method is seperate from the MZ-2800 +// as the scan is different and as it is time critical it is better to be per target machine. +// +// The basic requirement is to: +// 1. Detect a falling edge on the RTSN signal +// 2. Read the provided ROW number. +// 3. Lookup the matrix data for given ROW. +// 4. Output data to LS257 Mux. +// 5. Wait for RTSN to return inactive. +// 5. Loop +// +// The ps2Interface method is responsible for obtaining a PS/2 Keyboard scancode and +// creating the corresponding virtual matrix. +// +// NB: As this method holds Core 1 under spinlock, no FreeRTOS or Arduino access +// can be made except for basic I/O ports. The spinlock has to be released for non +// I/O work. +// +// The MZ timing period is ~600ns RTSN Low to High (Latch Row data coming from MZ machine), +// MPX (connected direct to external Quad 2-1 Mux goes high as RTSN goes low, the MPX +// signal is held high for 300ns then goes low for 300ns. The period when RTSN is low is +// when the MZ machine reads the scan row data. The cycle is ~1.2uS repeating, 14 rows +// so ~16.8uS for one full key matrix, The MZ machine if stuck in a tight loop will take +// approx 100uS to scan the matrix so the Gate Arrays are over sampling 6 times. +// +// WARNING: The GPIO's are configurable via menuconfig BUT it is assumed all except RTSNi +// are in the first GPIO bank and RTSNi is in the second GPIO bank. Modify the code +// if RTSNi is set in the first bank or KDB[3:0], KDI4 are in the second bank. +// +#if defined(CONFIG_MODEL_MZ2500) + IRAM_ATTR void mz25Interface( void * pvParameters ) + { + // Locals. + volatile uint32_t gpioIN; + volatile uint8_t strobeRow = 1; + + // Mask values declared as variables, let the optimiser decide wether they are constants or placed in-memory. + uint32_t rowBitMask = (1 << CONFIG_MZ_KDB3) | (1 << CONFIG_MZ_KDB2) | (1 << CONFIG_MZ_KDB1) | (1 << CONFIG_MZ_KDB0); + uint32_t colBitMask = (1 << CONFIG_MZ_KDO7) | (1 << CONFIG_MZ_KDO6) | (1 << CONFIG_MZ_KDO5) | (1 << CONFIG_MZ_KDO4) | + (1 << CONFIG_MZ_KDO3) | (1 << CONFIG_MZ_KDO2) | (1 << CONFIG_MZ_KDO1) | (1 << CONFIG_MZ_KDO0); + uint32_t KDB3_MASK = (1 << CONFIG_MZ_KDB3); + uint32_t KDB2_MASK = (1 << CONFIG_MZ_KDB2); + uint32_t KDB1_MASK = (1 << CONFIG_MZ_KDB1); + uint32_t KDB0_MASK = (1 << CONFIG_MZ_KDB0); + uint32_t KDI4_MASK = (1 << CONFIG_MZ_KDI4); + uint32_t RTSNI_MASK = (1 << (CONFIG_MZ_RTSNI - 32)); + + ESP_LOGI(MAINTAG, "Starting mz25Interface thread, colBitMask=%08x, rowBitMask=%08x.", colBitMask, rowBitMask); + + // Create, initialise and hold a spinlock so the current core is bound to this one method. + portENTER_CRITICAL(&mzMutex); + + // Permanent loop, just wait for an RTSN strobe, latch the row, lookup matrix and output. + // Timings with Power LED = LED Off to On = 108ns, LED On to Off = 392ns + for(;;) + { + #if defined(CONFIG_MZ_WIFI_ENABLED) + // Whilst Wifi is active, suspend processing as we need to free up the core. + if(wifiActivated) + { + portEXIT_CRITICAL(&mzMutex); + while(wifiActivated); + portENTER_CRITICAL(&mzMutex); + } + #endif + + // Detect RTSN going high, the MZ will send the required row during this cycle. + if(REG_READ(GPIO_IN1_REG) & RTSNI_MASK) + { + // Read the GPIO ports to get latest Row and KDI4 states. + gpioIN = REG_READ(GPIO_IN_REG); + + // Assemble the required matrix row from the configured bits. + strobeRow = ((gpioIN&KDB3_MASK) >> (CONFIG_MZ_KDB3-3)) | ((gpioIN&KDB2_MASK) >> (CONFIG_MZ_KDB2-2)) | ((gpioIN&KDB1_MASK) >> (CONFIG_MZ_KDB1-1)) | ((gpioIN&KDB0_MASK) >> CONFIG_MZ_KDB0); + + // Clear all KDO bits - clear state = '1' + GPIO.out_w1ts = colBitMask; // Reset all scan data bits to '1', inactive. + + // KDI4 indicates if row data is needed or a single byte ANDing all the keys together, ie. to detect a key press without strobing all rows. + if(gpioIN & KDI4_MASK) + { + // Set all required KDO bits according to keyMatrix, set state = '0'. + GPIO.out_w1tc = mzControl.keyMatrixAsGPIO[strobeRow]; // Set to '0' active bits. + } else + { + // Set all required KDO bits according to the strobe all value. set state = '0'. + GPIO.out_w1tc = mzControl.strobeAllAsGPIO; // Set to '0' active bits. + } + + // Wait for RTSN to go low. No lockup guarding as timing is critical also the watchdog is disabled, if RTSN never goes low then the user has probably unplugged the interface! + while(REG_READ(GPIO_IN1_REG) & RTSNI_MASK); + } + + // Logic to feed the watchdog if needed. Watchdog disabled in menuconfig but if enabled this will need to be used. + //TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable + //TIMERG0.wdt_feed=1; // feed dog + //TIMERG0.wdt_wprotect=0; // write protect + //TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable + //TIMERG1.wdt_feed=1; // feed dog + //TIMERG1.wdt_wprotect=0; // write protect + } + } +#endif + +// Method to connect and interact with the MZ-2800 keyboard controller. This method is seperate from the MZ-2500 +// as the scan is different and as it is time critical it needs to be per target machine. +// +// The basic requirement is to: +// 1. Detect a rising edge on the RTSN signal +// 2. Wait at least 200ns before sampling KD4 +// 3. Wait at least 650ns before reading ROW. +// 4. Read the provided ROW number. +// 5. If KD4 = 0 then output logical AND of all columns to LS257 Mux. +// 6. If KD4 = 1 then lookup data for given row and output to LS257 Mux. +// 7. Wait for RTSN to return low. +// 7. Loop +// +// The ps2Interface method is responsible for obtaining a PS/2 Keyboard scancode and +// creating the corresponding virtual matrix. +// +// NB: As this method holds Core 1 under spinlock, no FreeRTOS or Arduino access +// can be made except for basic I/O ports. The spinlock has to be released for non +// I/O work. +// +// The MZ 2800 timing period is 1.78uS RTSN going active high, KD4 changing state 150ns after RTSN goes active, +// ROW number being set 650ns after RTSN goes active. MPX directly controls the LS257 latch so only need to write out +// and 8 bit value prior to RTSN going inactive. +// Normally the keyboard is in STROBE ALL mode. When a key is pressed, it commences a scan and when it arrives at the pressed +// key, RTSN cycle is suspended for varying amounts of time (ie 500us or 19ms) as the controller is looking for debounce and repeat. +// +// WARNING: The GPIO's are configurable via menuconfig BUT it is assumed all except RTSNi +// are in the first GPIO bank and RTSNi is in the second GPIO bank. Modify the code +// if RTSNi is set in the first bank or KDB[3:0], KDI4 are in the second bank. +// +#if defined(CONFIG_MODEL_MZ2800) + IRAM_ATTR void mz28Interface( void * pvParameters ) + { + // Locals. + volatile uint32_t gpioIN; + volatile uint8_t strobeRow = 1; + + // Mask values declared as variables, let the optimiser decide wether they are constants or placed in-memory. + uint32_t rowBitMask = (1 << CONFIG_MZ_KDB3) | (1 << CONFIG_MZ_KDB2) | (1 << CONFIG_MZ_KDB1) | (1 << CONFIG_MZ_KDB0); + uint32_t colBitMask = (1 << CONFIG_MZ_KDO7) | (1 << CONFIG_MZ_KDO6) | (1 << CONFIG_MZ_KDO5) | (1 << CONFIG_MZ_KDO4) | + (1 << CONFIG_MZ_KDO3) | (1 << CONFIG_MZ_KDO2) | (1 << CONFIG_MZ_KDO1) | (1 << CONFIG_MZ_KDO0); + uint32_t KDB3_MASK = (1 << CONFIG_MZ_KDB3); + uint32_t KDB2_MASK = (1 << CONFIG_MZ_KDB2); + uint32_t KDB1_MASK = (1 << CONFIG_MZ_KDB1); + uint32_t KDB0_MASK = (1 << CONFIG_MZ_KDB0); + uint32_t KDI4_MASK = (1 << CONFIG_MZ_KDI4); + uint32_t RTSNI_MASK = (1 << (CONFIG_MZ_RTSNI - 32)); + + ESP_LOGI(MAINTAG, "Starting mz28Interface thread, colBitMask=%08x, rowBitMask=%08x.", colBitMask, rowBitMask); + + // Create, initialise and hold a spinlock so the current core is bound to this one method. + portENTER_CRITICAL(&mzMutex); + + // Permanent loop, just wait for an RTSN strobe, latch the row, lookup matrix and output. + for(;;) + { + #if defined(CONFIG_MZ_WIFI_ENABLED) + // Whilst Wifi is active, suspend processing as we need to free up the core. + if(wifiActivated) + { + portEXIT_CRITICAL(&mzMutex); + while(wifiActivated); + portENTER_CRITICAL(&mzMutex); + } + #endif + + // Detect RTSN going high, the MZ will send the required row during this cycle. + if(REG_READ(GPIO_IN1_REG) & RTSNI_MASK) + { + // Slight delay needed as KD4 lags behind RTSN by approx 200ns and ROW number lags 850ns behind RTSN. + for(volatile uint32_t delay=0; delay < 8; delay++); + + // Read the GPIO ports to get latest Row and KDI4 states. + gpioIN = REG_READ(GPIO_IN_REG); + + // Assemble the required matrix row from the configured bits. + strobeRow = ((gpioIN&KDB3_MASK) >> (CONFIG_MZ_KDB3-3)) | ((gpioIN&KDB2_MASK) >> (CONFIG_MZ_KDB2-2)) | ((gpioIN&KDB1_MASK) >> (CONFIG_MZ_KDB1-1)) | ((gpioIN&KDB0_MASK) >> CONFIG_MZ_KDB0); + + // Clear all KDO bits - clear state = '1' + GPIO.out_w1ts = colBitMask; // Reset all scan data bits to '1', inactive. + + // Another short delay once the row has been assembled as we dont want to change the latch setting too soon, changing too soon leads to ghosting on previous row. + for(volatile uint32_t delay=0; delay < 5; delay++); + + // KDI4 indicates if row data is needed or a single byte ANDing all the keys together, ie. to detect a key press without strobing all rows. + if(gpioIN & KDI4_MASK) + { + // Set all required KDO bits according to keyMatrix, set state = '0'. + GPIO.out_w1tc = mzControl.keyMatrixAsGPIO[strobeRow]; // Set to '0' active bits. + } else + { + // Set all required KDO bits according to the strobe all value. set state = '0'. + GPIO.out_w1tc = mzControl.strobeAllAsGPIO; // Set to '0' active bits. + } + + // Wait for RTSN to go low. No lockup guarding as timing is critical also the watchdog is disabled, if RTSN never goes low then the user has probably unplugged the interface! + while(REG_READ(GPIO_IN1_REG) & RTSNI_MASK); + } + + // Logic to feed the watchdog if needed. Watchdog disabled in menuconfig but if enabled this will need to be used. + //TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable + //TIMERG0.wdt_feed=1; // feed dog + //TIMERG0.wdt_wprotect=0; // write protect + //TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable + //TIMERG1.wdt_feed=1; // feed dog + //TIMERG1.wdt_wprotect=0; // write protect + } + } +#endif + +// Method to refresh the transposed matrix used in the MZ interface. The normal key matrix is transposed to save valuable time +// because even though a core is dedicated to the MZ interface the timing is critical and the ESP-32 doesnt have spare horse power! +// +IRAM_ATTR void updateMirrorMatrix(void) +{ + // Locals. + + // To save time in the MZ Interface, a mirror keyMatrix is built up, 32bit (GPIO Bank 0) wide, with the keyMatrix 8 bit data + // mapped onto the configured pins in the 32bit register. This saves previous time in order to meet the tight 1.2uS cycle. + // + for(int idx=0; idx < 15; idx++) + { + mzControl.keyMatrixAsGPIO[idx] = (((mzControl.keyMatrix[idx] >> 7) & 0x01) ^ 0x01) << CONFIG_MZ_KDO7 | + (((mzControl.keyMatrix[idx] >> 6) & 0x01) ^ 0x01) << CONFIG_MZ_KDO6 | + (((mzControl.keyMatrix[idx] >> 5) & 0x01) ^ 0x01) << CONFIG_MZ_KDO5 | + (((mzControl.keyMatrix[idx] >> 4) & 0x01) ^ 0x01) << CONFIG_MZ_KDO4 | + (((mzControl.keyMatrix[idx] >> 3) & 0x01) ^ 0x01) << CONFIG_MZ_KDO3 | + (((mzControl.keyMatrix[idx] >> 2) & 0x01) ^ 0x01) << CONFIG_MZ_KDO2 | + (((mzControl.keyMatrix[idx] >> 1) & 0x01) ^ 0x01) << CONFIG_MZ_KDO1 | + (((mzControl.keyMatrix[idx] ) & 0x01) ^ 0x01) << CONFIG_MZ_KDO0 ; + } + + // Re-calculate the Strobe All (KD4 = 1) signal, this indicates if any bit (key) in the matrix is active. + mzControl.strobeAll = 0xFF; + mzControl.strobeAllAsGPIO = 0x00000000; + for(int idx2=0; idx2 < 15; idx2++) + { + mzControl.strobeAll &= mzControl.keyMatrix[idx2]; + } + + // To speed up the mzInterface logic, pre-calculate the strobeAll value as a 32bit GPIO output value. + mzControl.strobeAllAsGPIO |= (((mzControl.strobeAll >> 7) & 0x01) ^ 0x01) << CONFIG_MZ_KDO7 | + (((mzControl.strobeAll >> 6) & 0x01) ^ 0x01) << CONFIG_MZ_KDO6 | + (((mzControl.strobeAll >> 5) & 0x01) ^ 0x01) << CONFIG_MZ_KDO5 | + (((mzControl.strobeAll >> 4) & 0x01) ^ 0x01) << CONFIG_MZ_KDO4 | + (((mzControl.strobeAll >> 3) & 0x01) ^ 0x01) << CONFIG_MZ_KDO3 | + (((mzControl.strobeAll >> 2) & 0x01) ^ 0x01) << CONFIG_MZ_KDO2 | + (((mzControl.strobeAll >> 1) & 0x01) ^ 0x01) << CONFIG_MZ_KDO1 | + (((mzControl.strobeAll ) & 0x01) ^ 0x01) << CONFIG_MZ_KDO0 ; + + return; +} + +// Method to convert the PS2 scan code into a key matrix representation which the MZ-2500/2800 is expecting. +// +IRAM_ATTR unsigned char updateMatrix(uint16_t data) +{ + // Locals. + uint8_t idx; + uint8_t changed = 0; + uint8_t matchExact = 0; + + // Loop through the entire conversion table to find a match on this key, if found appy the conversion to the virtual + // switch matrix. + // + for(idx=0, changed=0, matchExact=0; idx < NUMELEM(PS2toMZ) && (changed == 0 || (changed == 1 && matchExact == 0)); idx++) + { + // Match key code? + if(PS2toMZ[idx][PSMZTBL_KEYPOS] == (uint8_t)(data&0xFF) && ((PS2toMZ[idx][PSMZTBL_MACHINE] == MZ_ALL) || (PS2toMZ[idx][PSMZTBL_MACHINE] == mzControl.activeKeyMap))) + { + // Match Raw, Shift, Function, Control, ALT or ALT-Gr? + if( (PS2toMZ[idx][PSMZTBL_SHIFTPOS] == 0 && PS2toMZ[idx][PSMZTBL_FUNCPOS] == 0 && PS2toMZ[idx][PSMZTBL_CTRLPOS] == 0 && PS2toMZ[idx][PSMZTBL_ALTPOS] == 0 && PS2toMZ[idx][PSMZTBL_ALTGRPOS] == 0) || + ((data & PS2_SHIFT) && PS2toMZ[idx][PSMZTBL_SHIFTPOS] == 1) || + ((data & PS2_CTRL) && PS2toMZ[idx][PSMZTBL_CTRLPOS] == 1) || + ((data & PS2_ALT) && PS2toMZ[idx][PSMZTBL_ALTPOS] == 1) || + ((data & PS2_ALT_GR) && PS2toMZ[idx][PSMZTBL_ALTGRPOS] == 1) || + ((data & PS2_GUI) && PS2toMZ[idx][PSMZTBL_SHIFTPOS] == 1) || + ((data & PS2_FUNCTION) && PS2toMZ[idx][PSMZTBL_FUNCPOS] == 1) ) + { + + // Exact entry match, data + control key? On an exact match we only process the first key. On a data only match we fall through to include additional data and control key matches to allow for un-mapped key combinations, ie. Japanese characters. + matchExact = ((data & PS2_SHIFT) && PS2toMZ[idx][PSMZTBL_SHIFTPOS] == 1) || + ((data & PS2_CTRL) && PS2toMZ[idx][PSMZTBL_CTRLPOS] == 1) || + ((data & PS2_ALT_GR) && PS2toMZ[idx][PSMZTBL_ALTGRPOS] == 1) || + ((data & PS2_ALT) && PS2toMZ[idx][PSMZTBL_ALTPOS] == 1) || + ((data & PS2_GUI) && PS2toMZ[idx][PSMZTBL_ALTPOS] == 1) || + ((data & PS2_FUNCTION) && PS2toMZ[idx][PSMZTBL_FUNCPOS] == 1) ? 1 : 0; + + // RELEASE (PS2_BREAK == 1) or PRESS? + if((data & PS2_BREAK)) + { + // Special case for the PAUSE / BREAK key. The underlying logic has been modified to send a BREAK key event immediately + // after a PAUSE make, this is necessary as the Sharp MZ machines require SHIFT (pause) BREAK so the PS/2 CTRL+BREAK wont + // work (unless logic is added to insert a SHIFT, pause, add BREAK). The solution was to generate a BREAK event + // and add a slight delay for the key matrix to register it. + if((data&0x00FF) == PS2_KEY_PAUSE) + { + vTaskDelay(100); + } + + // Loop through all the row/column combinations and if valid, apply to the matrix. + for(int row=PSMZTBL_MK_ROW1; row < PSMZTBL_MK_ROW3+1; row+=2) + { + // Reset the matrix bit according to the lookup table. 1 = No key, 0 = key in the matrix. + if(PS2toMZ[idx][row] != 0xFF) + { + mzControl.keyMatrix[PS2toMZ[idx][row]] |= PS2toMZ[idx][row+1]; + changed = 1; + } + } + + // Loop through all the key releases associated with this key and reset the relevant matrix bit which was cleared on + // initial keydown. + // + for(int row=PSMZTBL_BRK_ROW1; row < PSMZTBL_BRK_ROW2+1; row+=2) + { + if(PS2toMZ[idx][row] != 0xFF) + { + mzControl.keyMatrix[PS2toMZ[idx][row]] &= ~PS2toMZ[idx][row+1]; + changed = 1; + } + } + } else + { + // Loop through all the key releases associated with this key and clear the relevant matrix bit. + // This is done first so as to avoid false key detection in the MZ logic. + // + for(int row=PSMZTBL_BRK_ROW1; row < PSMZTBL_BRK_ROW2+1; row+=2) + { + if(PS2toMZ[idx][row] != 0xFF) + { + mzControl.keyMatrix[PS2toMZ[idx][row]] |= PS2toMZ[idx][row+1]; + changed = 1; + } + } + + // If a release key has been actioned, update the matrix and insert a slight pause to avoid + // the MZ logic seeing the released keys in combination with the newly pressed keys. + if(changed) + { + updateMirrorMatrix(); + changed = 0; + vTaskDelay(10); + } + + // Loop through all the row/column combinations and if valid, apply to the matrix. + for(int row=PSMZTBL_MK_ROW1; row < PSMZTBL_MK_ROW3+1; row+=2) + { + // Set the matrix bit according to the lookup table. 1 = No key, 0 = key in the matrix. + if(PS2toMZ[idx][row] != 0xFF) + { + mzControl.keyMatrix[PS2toMZ[idx][row]] &= ~PS2toMZ[idx][row+1]; + changed = 1; + } + } + } + + // Only spend time updating signals if an actual change occurred. Some keys arent valid so no change will be effected. + if(changed) + { + updateMirrorMatrix(); + } + } // match key or a special function + } // match key code + } // for loop + + // Return flag to indicate if a match occurred and the matrix updated. + return(changed); +} + +// Primary PS/2 thread, running on Core 1. +// This thread is responsible for receiving PS/2 scan codes and mapping them to an MZ-2500/2800 keyboard matrix. +// The PS/2 data is received via interrupt. +// +IRAM_ATTR void ps2Interface( void * pvParameters ) +{ + // Locals. + uint16_t scanCode = 0x0000; + bool activityLED = 0; + TickType_t ps2CheckTimer = 0; + TickType_t ps2LedTimer = 0; + bool ps2Active = 0; // Flag to indicate the PS/2 keyboard is connected and online. + #if defined(CONFIG_DEBUG_OLED) || !defined(CONFIG_OLED_DISABLED) + uint8_t dataChange = 0; + static int scanPrtCol = 0; + static uint32_t rfshTimer = 0; + #endif + + // Thread never exits, just polls the keyboard and updates the matrix. + while(1) + { + // Check the keyboard is online, this is done at startup and periodically to cater for user disconnect. + if((xTaskGetTickCount() - ps2CheckTimer) > 1000 && (Keyboard.keyAvailable() == 0 || ps2Active == 0)) + { + // Check to see if the keyboard is still available, no keyboard = no point!! + // Firstly, ping keyboard to see if it is there. + Keyboard.echo(); + vTaskDelay(6); + scanCode = Keyboard.read(); + + // If the keyboard doesnt answer back, then it has been disconnected. + if( (scanCode & 0xFF) != PS2_KEY_ECHO && (scanCode & 0xFF) != PS2_KEY_BAT) + { + // Re-initialise the subsystem, if the keyboard is plugged in then it will be detected on next loop. + Keyboard.begin(CONFIG_PS2_HW_DATAPIN, CONFIG_PS2_HW_CLKPIN); + + // First entry print out message that the keyboard has disconnected. + if(ps2Active == 1 || ps2CheckTimer == 0) + { + ESP_LOGE(MAINTAG, "No PS2 keyboard detected, please connect.\n"); + #if defined(CONFIG_DEBUG_OLED) || !defined(CONFIG_OLED_DISABLED) + ssd1306_display_text(&SSD1306, 0, (char *)"No PS2 Keyboard", 15, false); + #endif + } + ps2Active = 0; + + // Turn on LED when keyboard is detached. + gpio_set_level((gpio_num_t)CONFIG_PWRLED, 1); + } else + { + // First entry after keyboard starts responding, print out message. + if(ps2Active == 0) + { + ESP_LOGI(MAINTAG, "PS2 keyboard detected and online.\n"); + ps2Active = 1; + + // Flash LED to indicate Keyboard recognised. + gpio_set_level((gpio_num_t)CONFIG_PWRLED, 1); + ps2LedTimer = xTaskGetTickCount() - 400; + } + } + ps2CheckTimer = xTaskGetTickCount(); // Check every second. + } else + { + // Check for PS/2 keyboard scan codes. + while((scanCode = Keyboard.read()) != 0) + { + #if defined(CONFIG_DEBUG_OLED) || !defined(CONFIG_OLED_DISABLED) + // Output the scan code for verification. + dbgprintf("%04x,", scanCode); + if(scanPrtCol++ >= 3) scanPrtCol = 0; + #else + dbgprintf("%04x\n", scanCode); + #endif + + // Filter out ALT+F1..3 keys as these select the active keymap. + switch(scanCode) + { + case 0x0961: + mzControl.activeKeyMap = MZ_2500; + break; + case 0x0962: + mzControl.activeKeyMap = MZ_2000; + break; + case 0x0963: + mzControl.activeKeyMap = MZ_80B; + break; + + default: + // Update the virtual matrix with the new key value. + dataChange |= updateMatrix(scanCode); + break; + } + + // Toggle LED to indicate data flow. + gpio_set_level((gpio_num_t)CONFIG_PWRLED, activityLED); + activityLED = !activityLED; + + // Reset the check keyboard timer, no need to check as activity is seen. + ps2CheckTimer = xTaskGetTickCount(); // Check every second. + ps2LedTimer = xTaskGetTickCount(); + } + + // If no activity has been seen for 100ms then switch off the LED. + if(ps2LedTimer > 0 && (xTaskGetTickCount() - ps2LedTimer) > 100) + { + activityLED = 0; + ps2LedTimer = 0; + gpio_set_level((gpio_num_t)CONFIG_PWRLED, activityLED); + } + + #if defined(CONFIG_DEBUG_OLED) || !defined(CONFIG_OLED_DISABLED) + if(dataChange || (rfshTimer > 0 && --rfshTimer == 0)) + { + // Output the MZ virtual keyboard matrix for verification. + uint8_t oledBuf[8][16]; + for(int idx=0; idx < 15; idx++) + { + for(int idx2=0; idx2 < 8; idx2++) + { + oledBuf[idx2][idx] = ((mzControl.keyMatrix[idx] >> idx2)&0x01) == 1 ? '1' : '0'; + } + } + + // Print out the matrix, transposed - see MZKeyTable.h for the map, second table. + for(int idx=0; idx < 8; idx++) + { + ssd1306_display_text(&SSD1306, idx, (char *)oledBuf[idx], 15, false); + } + + // Clear timer for next refresh. + rfshTimer = 2000000; + dataChange = 0; + } + #endif + } + + // Let other tasks run. + vTaskDelay(10); + } +} + +#if defined(CONFIG_MZ_WIFI_ENABLED) +// Event handler for Client mode Wifi event callback. +// +IRAM_ATTR void wifiClientHandler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +{ + // Locals. + // + + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) + { + esp_wifi_connect(); + } + else if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) + { + if(clientRetryCnt < CONFIG_MZ_WIFI_MAX_RETRIES) + { + esp_wifi_connect(); + clientRetryCnt++; + ESP_LOGI(WIFITAG, "retry to connect to the AP"); + } else + { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } + ESP_LOGI(WIFITAG,"connect to the AP fail"); + } + else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) + { + ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + ESP_LOGI(WIFITAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); + clientRetryCnt = 0; + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } + return; +} + +// Event handler for Access Point mode Wifi event callback. +// +IRAM_ATTR void wifiAPHandler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +{ + // Locals. + // + + + if (event_id == WIFI_EVENT_AP_STACONNECTED) + { + wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data; + ESP_LOGI(WIFITAG, "station " MACSTR " join, AID=%d", MAC2STR(event->mac), event->aid); + } + else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) + { + wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; + ESP_LOGI(WIFITAG, "station " MACSTR " leave, AID=%d", MAC2STR(event->mac), event->aid); + } + return; +} + +// Method to initialise the interface as a client to a known network, the SSID +// and password have already been setup. +// +uint8_t setupWifiClient(void) +{ + // Locals. + // + wifi_init_config_t wifiInitConfig; + esp_event_handler_instance_t instID; + esp_event_handler_instance_t instIP; + EventBits_t bits; + wifi_config_t wifiConfig = { .sta = { + /* ssid */ CONFIG_MZ_SSID, + /* password */ CONFIG_MZ_DEFAULT_SSID_PWD, + /* scan_method */ {}, + /* bssid_set */ {}, + /* bssid */ {}, + /* channel */ {}, + /* listen_interval */ {}, + /* sort_method */ {}, + /* threshold */ { + /* rssi */ {}, + /* authmode */ WIFI_AUTH_WPA2_PSK + }, + /* pmf_cfg */ { + /* capable */ true, + /* required */ false + }, + /* rm_enabled */ {}, + /* btm_enabled */ {}, + /* mbo_enabled */ {}, // For IDF 4.4 and higher + /* reserved */ {} + } + }; + + // Create an event handler group to manage callbacks. + s_wifi_event_group = xEventGroupCreate(); + + // Setup the network interface. + if(esp_netif_init()) + { + ESP_LOGI(WIFITAG, "Couldnt initialise netif, disabling WiFi."); + return(1); + } + + // Setup the event loop. + if(esp_event_loop_create_default()) + { + ESP_LOGI(WIFITAG, "Couldnt initialise event loop, disabling WiFi."); + return(1); + } + + // Setup the wifi client (station). + esp_netif_create_default_wifi_sta(); + + // Setup the config for wifi. + wifiInitConfig = WIFI_INIT_CONFIG_DEFAULT(); + if(esp_wifi_init(&wifiInitConfig)) + { + ESP_LOGI(WIFITAG, "Couldnt initialise wifi with default parameters, disabling WiFi."); + return(1); + } + + // Register event handlers. + if(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifiClientHandler, NULL, &instID)) + { + ESP_LOGI(WIFITAG, "Couldnt register event handler for ID, disabling WiFi."); + return(1); + } + if(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifiClientHandler, NULL, &instIP)) + { + ESP_LOGI(WIFITAG, "Couldnt register event handler for IP, disabling WiFi."); + return(1); + } + if(esp_wifi_set_mode(WIFI_MODE_STA)) + { + ESP_LOGI(WIFITAG, "Couldnt set Wifi mode to Client, disabling WiFi."); + return(1); + } + if(esp_wifi_set_config(WIFI_IF_STA, &wifiConfig)) + { + ESP_LOGI(WIFITAG, "Couldnt configure client mode, disabling WiFi."); + return(1); + } + if(esp_wifi_start()) + { + ESP_LOGI(WIFITAG, "Couldnt start Client session, disabling WiFi."); + return(1); + } + + // Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum + // number of re-tries (WIFI_FAIL_BIT). The bits are set by wifiClientHandler() (see above) + bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY); + + // xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually + // happened. + if(bits & WIFI_CONNECTED_BIT) + { + ESP_LOGI(WIFITAG, "Connected: SSID:%s password:%s", CONFIG_MZ_SSID, CONFIG_MZ_DEFAULT_SSID_PWD); + } + else if (bits & WIFI_FAIL_BIT) + { + ESP_LOGI(WIFITAG, "Connection Fail: SSID:%s, password:%s", CONFIG_MZ_SSID, CONFIG_MZ_DEFAULT_SSID_PWD); + } + else + { + ESP_LOGE(WIFITAG, "Unknown evemt, bits:%d", bits); + } + + // Close connection, not yet ready with application. + if(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instIP)) + { + ESP_LOGI(WIFITAG, "Couldnt unregister IP assignment halder, disabling WiFi."); + return(1); + } + if(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instID)) + { + ESP_LOGI(WIFITAG, "Couldnt unregister ID assignment halder, disabling WiFi."); + return(1); + } + vEventGroupDelete(s_wifi_event_group); + + // No errors. + return(0); +} + +// Method to initialise the interface as a Soft Access point with a given SSID +// and password. +// The Access Point mode is basically to bootstrap a Client connection where the +// client connecting provides the credentials in order to connect as a client to +// another AP to join a local network. +// +uint8_t setupWifiAP(void) +{ + // Locals. + // + esp_err_t retcode; + wifi_init_config_t wifiInitConfig; + wifi_config_t wifiConfig = { .ap = { + /* ssid */ CONFIG_MZ_SSID, + /* password */ CONFIG_MZ_DEFAULT_SSID_PWD, + /* ssid_len */ strlen(CONFIG_MZ_SSID), + /* channel */ CONFIG_MZ_WIFI_AP_CHANNEL, + /* authmode */ WIFI_AUTH_WPA_WPA2_PSK, + /* hidden */ CONFIG_MZ_WIFI_SSID_HIDDEN, + /* nax_connection */ CONFIG_MZ_WIFI_MAX_CONNECTIONS, + /* beacon_interval */ 100, + /* pairwise_cipher */ WIFI_CIPHER_TYPE_TKIP, + /* ftm_responder */ 0, + // /* pmf_cfg */ { + // /* capable */ true, + // /* required */ false + // } + } + }; + + // Intialise the network interface. + if(esp_netif_init()) + { + ESP_LOGI(WIFITAG, "Couldnt initialise network interface, disabling WiFi."); + return(1); + } + if((retcode = esp_event_loop_create_default())) + { + ESP_LOGI(WIFITAG, "Couldnt create default loop(%d), disabling WiFi.", retcode); + return(1); + } + + // Create the default Access Point. + // + esp_netif_create_default_wifi_ap(); + + // Initialise AP with default parameters. + wifiInitConfig = WIFI_INIT_CONFIG_DEFAULT(); + if(esp_wifi_init(&wifiInitConfig)) + { + ESP_LOGI(WIFITAG, "Couldnt setup AP with default parameters, disabling WiFi."); + return(1); + } + + // Setup callback handlers for wifi events. + if(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifiAPHandler, NULL, NULL)) + { + ESP_LOGI(WIFITAG, "Couldnt setup event handlers, disabling WiFi."); + return(1); + } + + // If there is no password for the access point set authentication to open. + if (strlen(CONFIG_MZ_DEFAULT_SSID_PWD) == 0) + { + wifiConfig.ap.authmode = WIFI_AUTH_OPEN; + } + + // Setup as an Access Point. + if(esp_wifi_set_mode(WIFI_MODE_AP)) + { + ESP_LOGI(WIFITAG, "Couldnt set mode to Access Point, disabling WiFi."); + return(1); + } + // Configure the Access Point + if(esp_wifi_set_config(WIFI_IF_AP, &wifiConfig)) + { + ESP_LOGI(WIFITAG, "Couldnt configure Access Point, disabling WiFi."); + return(1); + } + // Start the Access Point. + if(esp_wifi_start()) + { + ESP_LOGI(WIFITAG, "Couldnt start Access Point session, disabling WiFi."); + return(1); + } + + // No errors. + return(0); +} +#endif + +// Work in progress. Intention is to add a WiFi access point to garner local net details, +// connect to local net then offer a browser interface to change keys. +#if defined(CONFIG_MZ_WIFI_ENABLED) +IRAM_ATTR void wifiInterface( void * pvParameters ) +{ + // Locals. + uint32_t keyDebCtr = 0; + uint32_t WIFIEN_MASK = (1 << (CONFIG_MZ_WIFI_EN_KEY - 32)); + esp_err_t nvsStatus; + enum WIFIMODES wifiMode = WIFI_OFF; + + + // Loop forever, detecting the Wifi activation/de-activation and subsequent processing. + while(1) + { + // Has wifi been activated? If the Wifi switch has been pressed, initialise Wifi according to desired mode. + // + if(wifiMode != WIFI_OFF) + { + if(!wifiActivated) + { + // Initialise the NVS storage, needed for WiFi parameters. + nvsStatus = nvs_flash_init(); + if (nvsStatus == ESP_ERR_NVS_NO_FREE_PAGES || nvsStatus == ESP_ERR_NVS_NEW_VERSION_FOUND) + { + ESP_ERROR_CHECK(nvs_flash_erase()); + nvsStatus = nvs_flash_init(); + } + + if(nvsStatus) + { + ESP_LOGI(WIFITAG, "Couldnt initialise NVS, disabling WiFi."); + wifiActivated = 0; + wifiMode = WIFI_OFF; + } else + { + if(wifiMode == WIFI_ON) + { + if(setupWifiClient()) + { + wifiActivated = 0; + wifiMode = WIFI_OFF; + } else + { + dbgprintf("Wifi Client %s\n", wifiActivated ? "activated" : "de-activated"); + wifiActivated = 1; + } + } + else if(wifiMode == WIFI_CONFIG_AP) + { + if(setupWifiAP()) + { + wifiActivated = 0; + wifiMode = WIFI_OFF; + } else + { + dbgprintf("Wifi AP %s\n", wifiActivated ? "activated" : "de-activated"); + wifiActivated = 1; + } + } + } + + // Re-init switch variables for next activation. + keyDebCtr = 0; + } + + } + + // Check the switch, has it gone to zero, ie. pressed? + // + if((REG_READ(GPIO_IN1_REG) & WIFIEN_MASK) == 0) + { + // On first press, wait 1 second to see if user is selecting WiFi on or WiFi Config. + if(keyDebCtr == 0) + { + wifiMode = WIFI_OFF; + keyDebCtr = 10; + } + // If counter gets to 1 then assume WiFi on. + else if(keyDebCtr == 1) + { + wifiMode = WIFI_ON; + // Reset counter for 10 seconds, 10 being required to enter WiFi Config AP mode. + keyDebCtr = 100; + } + // 9 seconds later, mode is Wifi Config AP. + else if(keyDebCtr == 11) + { + wifiMode = WIFI_CONFIG_AP; + } + else if(keyDebCtr > 0) + { + keyDebCtr--; + } + } + + // Let other tasks run. NB. This value affects the debounce counter, update as necessary. + vTaskDelay(100); + } +} +#endif + +// Setup method to configure ports, devices and threads prior to application run. +// Configuration: +// PS/2 Keyboard over 2 wire interface +// Power/Status LED +// Optional OLED debug output screen +// 4 bit input - MZ-2500/2800 Row Number +// 8 bit output - MZ-2500/2800 Scan data +// 1 bit input - RTSN strobe line, low indicating a new Row Number available. +// 1 bit input - KD4, High = Key scan data required, Low = AND of all key matrix rows required. +// +void setup() +{ + // Locals. + gpio_config_t io_conf; + + // Setup power LED first to show life. + ESP_LOGI(MAINTAG, "Configuring Power LED."); + io_conf.intr_type = GPIO_INTR_DISABLE; + io_conf.mode = GPIO_MODE_OUTPUT; + io_conf.pin_bit_mask = (1ULL< + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "esp_log.h" + +#include "ssd1306.h" +#include "font8x8_basic.h" + +#define tag "SSD1306" + +void ssd1306_init(SSD1306_t * dev, int width, int height) +{ + if (dev->_address == SPIAddress) { + spi_init(dev, width, height); + } else { + i2c_init(dev, width, height); + } +} + +void ssd1306_display_text(SSD1306_t * dev, int page, char * text, int text_len, bool invert) +{ + if (page >= dev->_pages) return; + int _text_len = text_len; + if (_text_len > 16) _text_len = 16; + + uint8_t seg = 0; + uint8_t image[8]; + for (uint8_t i = 0; i < _text_len; i++) { + memcpy(image, font8x8_basic_tr[(uint8_t)text[i]], 8); + if (invert) ssd1306_invert(image, 8); + if (dev->_flip) ssd1306_flip(image, 8); + if (dev->_address == SPIAddress) { + spi_display_image(dev, page, seg, image, 8); + } else { + i2c_display_image(dev, page, seg, image, 8); + } + seg = seg + 8; + } +} + +void ssd1306_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width) +{ + if (dev->_address == SPIAddress) { + spi_display_image(dev, page, seg, images, width); + } else { + i2c_display_image(dev, page, seg, images, width); + } +} + +void ssd1306_clear_screen(SSD1306_t * dev, bool invert) +{ + char space[16]; + memset(space, 0x20, sizeof(space)); + for (int page = 0; page < dev->_pages; page++) { + ssd1306_display_text(dev, page, space, sizeof(space), invert); + } +} + +void ssd1306_clear_line(SSD1306_t * dev, int page, bool invert) +{ + char space[16]; + memset(space, 0x20, sizeof(space)); + ssd1306_display_text(dev, page, space, sizeof(space), invert); +} + +void ssd1306_contrast(SSD1306_t * dev, int contrast) +{ + if (dev->_address == SPIAddress) { + spi_contrast(dev, contrast); + } else { + i2c_contrast(dev, contrast); + } +} + +void ssd1306_software_scroll(SSD1306_t * dev, int start, int end) +{ + ESP_LOGD(tag, "software_scroll start=%d end=%d _pages=%d", start, end, dev->_pages); + if (start < 0 || end < 0) { + dev->_scEnable = false; + } else if (start >= dev->_pages || end >= dev->_pages) { + dev->_scEnable = false; + } else { + dev->_scEnable = true; + dev->_scStart = start; + dev->_scEnd = end; + dev->_scDirection = 1; + if (start > end ) dev->_scDirection = -1; + for (int i=0;i_pages;i++) { + dev->_page[i]._valid = false; + dev->_page[i]._segLen = 0; + } + } +} + + +void ssd1306_scroll_text(SSD1306_t * dev, char * text, int text_len, bool invert) +{ + ESP_LOGD(tag, "dev->_scEnable=%d", dev->_scEnable); + if (dev->_scEnable == false) return; + + void (*func)(SSD1306_t * dev, int page, int seg, uint8_t * images, int width); + if (dev->_address == SPIAddress) { + func = spi_display_image; + } else { + func = i2c_display_image; + } + + int srcIndex = dev->_scEnd - dev->_scDirection; + while(1) { + int dstIndex = srcIndex + dev->_scDirection; + ESP_LOGD(tag, "srcIndex=%d dstIndex=%d", srcIndex,dstIndex); + dev->_page[dstIndex]._valid = dev->_page[srcIndex]._valid; + dev->_page[dstIndex]._segLen = dev->_page[srcIndex]._segLen; + for(int seg = 0; seg < dev->_width; seg++) { + dev->_page[dstIndex]._segs[seg] = dev->_page[srcIndex]._segs[seg]; + } + ESP_LOGD(tag, "_valid=%d", dev->_page[dstIndex]._valid); + if (dev->_page[dstIndex]._valid) (*func)(dev, dstIndex, 0, dev->_page[dstIndex]._segs, dev->_page[srcIndex]._segLen); + if (srcIndex == dev->_scStart) break; + srcIndex = srcIndex - dev->_scDirection; + } + + int _text_len = text_len; + if (_text_len > 16) _text_len = 16; + + uint8_t seg = 0; + uint8_t image[8]; + for (uint8_t i = 0; i < _text_len; i++) { + memcpy(image, font8x8_basic_tr[(uint8_t)text[i]], 8); + if (invert) ssd1306_invert(image, 8); + if (dev->_flip) ssd1306_flip(image, 8); + (*func)(dev, srcIndex, seg, image, 8); + for(int j=0;j<8;j++) dev->_page[srcIndex]._segs[seg+j] = image[j]; + seg = seg + 8; + } + dev->_page[srcIndex]._valid = true; + dev->_page[srcIndex]._segLen = seg; +} + +void ssd1306_scroll_clear(SSD1306_t * dev) +{ + ESP_LOGD(tag, "dev->_scEnable=%d", dev->_scEnable); + if (dev->_scEnable == false) return; + + int srcIndex = dev->_scEnd - dev->_scDirection; + while(1) { + int dstIndex = srcIndex + dev->_scDirection; + ESP_LOGD(tag, "srcIndex=%d dstIndex=%d", srcIndex,dstIndex); + ssd1306_clear_line(dev, dstIndex, false); + dev->_page[dstIndex]._valid = false; + if (dstIndex == dev->_scStart) break; + srcIndex = srcIndex - dev->_scDirection; + } +} + + +void ssd1306_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll) +{ + if (dev->_address == SPIAddress) { + spi_hardware_scroll(dev, scroll); + } else { + i2c_hardware_scroll(dev, scroll); + } +} + +void ssd1306_invert(uint8_t *buf, size_t blen) +{ + uint8_t wk; + for(int i=0; i0x48 +uint8_t ssd1306_rotate(uint8_t ch1) { + uint8_t ch2 = 0; + for (int j=0;j<8;j++) { + ch2 = (ch2 << 1) + (ch1 & 0x01); + ch1 = ch1 >> 1; + } + return ch2; +} + + +void ssd1306_fadeout(SSD1306_t * dev) +{ + void (*func)(SSD1306_t * dev, int page, int seg, uint8_t * images, int width); + if (dev->_address == SPIAddress) { + func = spi_display_image; + } else { + func = i2c_display_image; + } + + uint8_t image[1]; + for(int page=0; page_pages; page++) { + image[0] = 0xFF; + for(int line=0; line<8; line++) { + if (dev->_flip) { + image[0] = image[0] >> 1; + } else { + image[0] = image[0] << 1; + } + for(int seg=0; seg<128; seg++) { + (*func)(dev, page, seg, image, 1); + } + } + } +} + +void ssd1306_dump(SSD1306_t dev) +{ + printf("_address=%x\n",dev._address); + printf("_width=%x\n",dev._width); + printf("_height=%x\n",dev._height); + printf("_pages=%x\n",dev._pages); +} + diff --git a/v1.2/main/ssd1306.h b/v1.2/main/ssd1306.h new file mode 100644 index 0000000..d8e2483 --- /dev/null +++ b/v1.2/main/ssd1306.h @@ -0,0 +1,143 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MAIN_SSD1306_H_ +#define MAIN_SSD1306_H_ + +#include "driver/spi_master.h" + +// Following definitions are bollowed from +// http://robotcantalk.blogspot.com/2015/03/interfacing-arduino-with-ssd1306-driven.html + +/* Control byte for i2c +Co : bit 8 : Continuation Bit + * 1 = no-continuation (only one byte to follow) + * 0 = the controller should expect a stream of bytes. +D/C# : bit 7 : Data/Command Select bit + * 1 = the next byte or byte stream will be Data. + * 0 = a Command byte or byte stream will be coming up next. + Bits 6-0 will be all zeros. +Usage: +0x80 : Single Command byte +0x00 : Command Stream +0xC0 : Single Data byte +0x40 : Data Stream +*/ +#define OLED_CONTROL_BYTE_CMD_SINGLE 0x80 +#define OLED_CONTROL_BYTE_CMD_STREAM 0x00 +#define OLED_CONTROL_BYTE_DATA_SINGLE 0xC0 +#define OLED_CONTROL_BYTE_DATA_STREAM 0x40 + +// Fundamental commands (pg.28) +#define OLED_CMD_SET_CONTRAST 0x81 // follow with 0x7F +#define OLED_CMD_DISPLAY_RAM 0xA4 +#define OLED_CMD_DISPLAY_ALLON 0xA5 +#define OLED_CMD_DISPLAY_NORMAL 0xA6 +#define OLED_CMD_DISPLAY_INVERTED 0xA7 +#define OLED_CMD_DISPLAY_OFF 0xAE +#define OLED_CMD_DISPLAY_ON 0xAF + +// Addressing Command Table (pg.30) +#define OLED_CMD_SET_MEMORY_ADDR_MODE 0x20 +#define OLED_CMD_SET_HORI_ADDR_MODE 0x00 // Horizontal Addressing Mode +#define OLED_CMD_SET_VERT_ADDR_MODE 0x01 // Vertical Addressing Mode +#define OLED_CMD_SET_PAGE_ADDR_MODE 0x02 // Page Addressing Mode +#define OLED_CMD_SET_COLUMN_RANGE 0x21 // can be used only in HORZ/VERT mode - follow with 0x00 and 0x7F = COL127 +#define OLED_CMD_SET_PAGE_RANGE 0x22 // can be used only in HORZ/VERT mode - follow with 0x00 and 0x07 = PAGE7 + +// Hardware Config (pg.31) +#define OLED_CMD_SET_DISPLAY_START_LINE 0x40 +#define OLED_CMD_SET_SEGMENT_REMAP_0 0xA0 +#define OLED_CMD_SET_SEGMENT_REMAP_1 0xA1 +#define OLED_CMD_SET_MUX_RATIO 0xA8 // follow with 0x3F = 64 MUX +#define OLED_CMD_SET_COM_SCAN_MODE 0xC8 +#define OLED_CMD_SET_DISPLAY_OFFSET 0xD3 // follow with 0x00 +#define OLED_CMD_SET_COM_PIN_MAP 0xDA // follow with 0x12 +#define OLED_CMD_NOP 0xE3 // NOP + +// Timing and Driving Scheme (pg.32) +#define OLED_CMD_SET_DISPLAY_CLK_DIV 0xD5 // follow with 0x80 +#define OLED_CMD_SET_PRECHARGE 0xD9 // follow with 0xF1 +#define OLED_CMD_SET_VCOMH_DESELCT 0xDB // follow with 0x30 + +// Charge Pump (pg.62) +#define OLED_CMD_SET_CHARGE_PUMP 0x8D // follow with 0x14 + +// Scrolling Command +#define OLED_CMD_HORIZONTAL_RIGHT 0x26 +#define OLED_CMD_HORIZONTAL_LEFT 0x27 +#define OLED_CMD_CONTINUOUS_SCROLL 0x29 +#define OLED_CMD_DEACTIVE_SCROLL 0x2E +#define OLED_CMD_ACTIVE_SCROLL 0x2F +#define OLED_CMD_VERTICAL 0xA3 + +#define I2CAddress 0x3C +#define SPIAddress 0xFF + +typedef enum { + SCROLL_RIGHT = 1, + SCROLL_LEFT = 2, + SCROLL_DOWN = 3, + SCROLL_UP = 4, + SCROLL_STOP = 5 +} ssd1306_scroll_type_t; + +typedef struct { + bool _valid; + int _segLen; // 0-128 + uint8_t _segs[128]; +} PAGE_t; + +typedef struct { + int _address; + int _width; + int _height; + int _pages; + int _dc; + spi_device_handle_t _SPIHandle; + bool _scEnable; + int _scStart; + int _scEnd; + int _scDirection; + PAGE_t _page[8]; + bool _flip; +} SSD1306_t; + +void ssd1306_init(SSD1306_t * dev, int width, int height); +void ssd1306_display_text(SSD1306_t * dev, int page, char * text, int text_len, bool invert); +void ssd1306_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width); +void ssd1306_clear_screen(SSD1306_t * dev, bool invert); +void ssd1306_clear_line(SSD1306_t * dev, int page, bool invert); +void ssd1306_contrast(SSD1306_t * dev, int contrast); +void ssd1306_software_scroll(SSD1306_t * dev, int start, int end); +void ssd1306_scroll_text(SSD1306_t * dev, char * text, int text_len, bool invert); +void ssd1306_scroll_clear(SSD1306_t * dev); +void ssd1306_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll); +void ssd1306_invert(uint8_t *buf, size_t blen); +void ssd1306_flip(uint8_t *buf, size_t blen); +uint8_t ssd1306_rotate(uint8_t ch1); +void ssd1306_fadeout(SSD1306_t * dev); +void ssd1306_dump(SSD1306_t dev); + +void i2c_master_init(SSD1306_t * dev, int16_t sda, int16_t scl, int16_t reset); +void i2c_init(SSD1306_t * dev, int width, int height); +void i2c_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width); +void i2c_contrast(SSD1306_t * dev, int contrast); +void i2c_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll); + +void spi_master_init(SSD1306_t * dev, int16_t GPIO_MOSI, int16_t GPIO_SCLK, int16_t GPIO_CS, int16_t GPIO_DC, int16_t GPIO_RESET); +bool spi_master_write_byte(spi_device_handle_t SPIHandle, const uint8_t* Data, size_t DataLength ); +bool spi_master_write_command(SSD1306_t * dev, uint8_t Command ); +bool spi_master_write_data(SSD1306_t * dev, const uint8_t* Data, size_t DataLength ); +void spi_init(SSD1306_t * dev, int width, int height); +void spi_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width); +void spi_contrast(SSD1306_t * dev, int contrast); +void spi_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll); + +#endif /* MAIN_SSD1306_H_ */ + +#ifdef __cplusplus +} +#endif + diff --git a/v1.2/main/ssd1306_i2c.c b/v1.2/main/ssd1306_i2c.c new file mode 100644 index 0000000..8f49e2e --- /dev/null +++ b/v1.2/main/ssd1306_i2c.c @@ -0,0 +1,253 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "driver/i2c.h" +#include "esp_log.h" + +#include "ssd1306.h" + +#define tag "SSD1306" + +#define I2C_NUM I2C_NUM_0 +//#define I2C_NUM I2C_NUM_1 + +#define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency. no higher than 1MHz for now */ + +void i2c_master_init(SSD1306_t * dev, int16_t sda, int16_t scl, int16_t reset) +{ + i2c_config_t i2c_config = { + .mode = I2C_MODE_MASTER, + .sda_io_num = sda, + .scl_io_num = scl, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master.clk_speed = I2C_MASTER_FREQ_HZ + }; + ESP_ERROR_CHECK(i2c_param_config(I2C_NUM, &i2c_config)); + ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM, I2C_MODE_MASTER, 0, 0, 0)); + + if (reset >= 0) { + //gpio_pad_select_gpio(reset); + gpio_reset_pin(reset); + gpio_set_direction(reset, GPIO_MODE_OUTPUT); + gpio_set_level(reset, 0); + vTaskDelay(50 / portTICK_PERIOD_MS); + gpio_set_level(reset, 1); + } + dev->_address = I2CAddress; + dev->_flip = false; +} + +void i2c_init(SSD1306_t * dev, int width, int height) { + dev->_width = width; + dev->_height = height; + dev->_pages = 8; + if (dev->_height == 32) dev->_pages = 4; + + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev->_address << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); + i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_OFF, true); // AE + i2c_master_write_byte(cmd, OLED_CMD_SET_MUX_RATIO, true); // A8 + if (dev->_height == 64) i2c_master_write_byte(cmd, 0x3F, true); + if (dev->_height == 32) i2c_master_write_byte(cmd, 0x1F, true); + i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_OFFSET, true); // D3 + i2c_master_write_byte(cmd, 0x00, true); + i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true); // 40 + //i2c_master_write_byte(cmd, OLED_CMD_SET_SEGMENT_REMAP, true); // A1 + if (dev->_flip) { + i2c_master_write_byte(cmd, OLED_CMD_SET_SEGMENT_REMAP_0, true); // A0 + } else { + i2c_master_write_byte(cmd, OLED_CMD_SET_SEGMENT_REMAP_1, true); // A1 + } + i2c_master_write_byte(cmd, OLED_CMD_SET_COM_SCAN_MODE, true); // C8 + i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_CLK_DIV, true); // D5 + i2c_master_write_byte(cmd, 0x80, true); + i2c_master_write_byte(cmd, OLED_CMD_SET_COM_PIN_MAP, true); // DA + if (dev->_height == 64) i2c_master_write_byte(cmd, 0x12, true); + if (dev->_height == 32) i2c_master_write_byte(cmd, 0x02, true); + i2c_master_write_byte(cmd, OLED_CMD_SET_CONTRAST, true); // 81 + i2c_master_write_byte(cmd, 0xFF, true); + i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_RAM, true); // A4 + i2c_master_write_byte(cmd, OLED_CMD_SET_VCOMH_DESELCT, true); // DB + i2c_master_write_byte(cmd, 0x40, true); + i2c_master_write_byte(cmd, OLED_CMD_SET_MEMORY_ADDR_MODE, true); // 20 + //i2c_master_write_byte(cmd, OLED_CMD_SET_HORI_ADDR_MODE, true); // 00 + i2c_master_write_byte(cmd, OLED_CMD_SET_PAGE_ADDR_MODE, true); // 02 + // Set Lower Column Start Address for Page Addressing Mode + i2c_master_write_byte(cmd, 0x00, true); + // Set Higher Column Start Address for Page Addressing Mode + i2c_master_write_byte(cmd, 0x10, true); + i2c_master_write_byte(cmd, OLED_CMD_SET_CHARGE_PUMP, true); // 8D + i2c_master_write_byte(cmd, 0x14, true); + i2c_master_write_byte(cmd, OLED_CMD_DEACTIVE_SCROLL, true); // 2E + i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_NORMAL, true); // A6 + i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_ON, true); // AF + + i2c_master_stop(cmd); + + esp_err_t espRc = i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); + if (espRc == ESP_OK) { + ESP_LOGI(tag, "OLED configured successfully"); + } else { + ESP_LOGE(tag, "OLED configuration failed. code: 0x%.2X", espRc); + } + i2c_cmd_link_delete(cmd); +} + + +void i2c_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width) { + i2c_cmd_handle_t cmd; + + if (page >= dev->_pages) return; + if (seg >= dev->_width) return; + + int _seg = seg + CONFIG_OFFSETX; + uint8_t columLow = _seg & 0x0F; + uint8_t columHigh = (_seg >> 4) & 0x0F; + + int _page = page; + if (dev->_flip) { + _page = (dev->_pages - page) - 1; + } + + cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev->_address << 1) | I2C_MASTER_WRITE, true); + + i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); + // Set Lower Column Start Address for Page Addressing Mode + i2c_master_write_byte(cmd, (0x00 + columLow), true); + // Set Higher Column Start Address for Page Addressing Mode + i2c_master_write_byte(cmd, (0x10 + columHigh), true); + // Set Page Start Address for Page Addressing Mode + i2c_master_write_byte(cmd, 0xB0 | _page, true); + + i2c_master_stop(cmd); + i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); + i2c_cmd_link_delete(cmd); + + cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev->_address << 1) | I2C_MASTER_WRITE, true); + + i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true); + i2c_master_write(cmd, images, width, true); + + i2c_master_stop(cmd); + i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); + i2c_cmd_link_delete(cmd); +} + +void i2c_contrast(SSD1306_t * dev, int contrast) { + i2c_cmd_handle_t cmd; + int _contrast = contrast; + if (contrast < 0x0) _contrast = 0; + if (contrast > 0xFF) _contrast = 0xFF; + + cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev->_address << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); + i2c_master_write_byte(cmd, OLED_CMD_SET_CONTRAST, true); // 81 + i2c_master_write_byte(cmd, _contrast, true); + i2c_master_stop(cmd); + i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); + i2c_cmd_link_delete(cmd); +} + + +void i2c_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll) { + esp_err_t espRc; + + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + + i2c_master_write_byte(cmd, (dev->_address << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); + + if (scroll == SCROLL_RIGHT) { + i2c_master_write_byte(cmd, OLED_CMD_HORIZONTAL_RIGHT, true); // 26 + i2c_master_write_byte(cmd, 0x00, true); // Dummy byte + i2c_master_write_byte(cmd, 0x00, true); // Define start page address + i2c_master_write_byte(cmd, 0x07, true); // Frame frequency + i2c_master_write_byte(cmd, 0x07, true); // Define end page address + i2c_master_write_byte(cmd, 0x00, true); // + i2c_master_write_byte(cmd, 0xFF, true); // + i2c_master_write_byte(cmd, OLED_CMD_ACTIVE_SCROLL, true); // 2F + } + + if (scroll == SCROLL_LEFT) { + i2c_master_write_byte(cmd, OLED_CMD_HORIZONTAL_LEFT, true); // 27 + i2c_master_write_byte(cmd, 0x00, true); // Dummy byte + i2c_master_write_byte(cmd, 0x00, true); // Define start page address + i2c_master_write_byte(cmd, 0x07, true); // Frame frequency + i2c_master_write_byte(cmd, 0x07, true); // Define end page address + i2c_master_write_byte(cmd, 0x00, true); // + i2c_master_write_byte(cmd, 0xFF, true); // + i2c_master_write_byte(cmd, OLED_CMD_ACTIVE_SCROLL, true); // 2F + } + + if (scroll == SCROLL_DOWN) { + i2c_master_write_byte(cmd, OLED_CMD_CONTINUOUS_SCROLL, true); // 29 + i2c_master_write_byte(cmd, 0x00, true); // Dummy byte + i2c_master_write_byte(cmd, 0x00, true); // Define start page address + i2c_master_write_byte(cmd, 0x07, true); // Frame frequency + //i2c_master_write_byte(cmd, 0x01, true); // Define end page address + i2c_master_write_byte(cmd, 0x00, true); // Define end page address + i2c_master_write_byte(cmd, 0x3F, true); // Vertical scrolling offset + + i2c_master_write_byte(cmd, OLED_CMD_VERTICAL, true); // A3 + i2c_master_write_byte(cmd, 0x00, true); + if (dev->_height == 64) + //i2c_master_write_byte(cmd, 0x7F, true); + i2c_master_write_byte(cmd, 0x40, true); + if (dev->_height == 32) + i2c_master_write_byte(cmd, 0x20, true); + i2c_master_write_byte(cmd, OLED_CMD_ACTIVE_SCROLL, true); // 2F + } + + if (scroll == SCROLL_UP) { + i2c_master_write_byte(cmd, OLED_CMD_CONTINUOUS_SCROLL, true); // 29 + i2c_master_write_byte(cmd, 0x00, true); // Dummy byte + i2c_master_write_byte(cmd, 0x00, true); // Define start page address + i2c_master_write_byte(cmd, 0x07, true); // Frame frequency + //i2c_master_write_byte(cmd, 0x01, true); // Define end page address + i2c_master_write_byte(cmd, 0x00, true); // Define end page address + i2c_master_write_byte(cmd, 0x01, true); // Vertical scrolling offset + + i2c_master_write_byte(cmd, OLED_CMD_VERTICAL, true); // A3 + i2c_master_write_byte(cmd, 0x00, true); + if (dev->_height == 64) + //i2c_master_write_byte(cmd, 0x7F, true); + i2c_master_write_byte(cmd, 0x40, true); + if (dev->_height == 32) + i2c_master_write_byte(cmd, 0x20, true); + i2c_master_write_byte(cmd, OLED_CMD_ACTIVE_SCROLL, true); // 2F + } + + if (scroll == SCROLL_STOP) { + i2c_master_write_byte(cmd, OLED_CMD_DEACTIVE_SCROLL, true); // 2E + } + + i2c_master_stop(cmd); + espRc = i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); + if (espRc == ESP_OK) { + ESP_LOGD(tag, "Scroll command succeeded"); + } else { + ESP_LOGE(tag, "Scroll command failed. code: 0x%.2X", espRc); + } + + i2c_cmd_link_delete(cmd); +} +#ifdef __cplusplus +} +#endif diff --git a/v1.2/main/ssd1306_spi.c b/v1.2/main/ssd1306_spi.c new file mode 100644 index 0000000..ac5b7e9 --- /dev/null +++ b/v1.2/main/ssd1306_spi.c @@ -0,0 +1,253 @@ +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "driver/spi_master.h" +#include "driver/gpio.h" +#include "esp_log.h" + +#include "ssd1306.h" + +#define tag "SSD1306" + +#ifdef CONFIG_IDF_TARGET_ESP32 +#define LCD_HOST HSPI_HOST +#elif defined CONFIG_IDF_TARGET_ESP32S2 +#define LCD_HOST SPI2_HOST +#elif defined CONFIG_IDF_TARGET_ESP32C3 +#define LCD_HOST SPI2_HOST +#endif + +static const int SPI_Command_Mode = 0; +static const int SPI_Data_Mode = 1; +static const int SPI_Frequency = 1000000; + +void spi_master_init(SSD1306_t * dev, int16_t GPIO_MOSI, int16_t GPIO_SCLK, int16_t GPIO_CS, int16_t GPIO_DC, int16_t GPIO_RESET) +{ + esp_err_t ret; + + //gpio_pad_select_gpio( GPIO_CS ); + gpio_reset_pin( GPIO_CS ); + gpio_set_direction( GPIO_CS, GPIO_MODE_OUTPUT ); + gpio_set_level( GPIO_CS, 0 ); + + //gpio_pad_select_gpio( GPIO_DC ); + gpio_reset_pin( GPIO_DC ); + gpio_set_direction( GPIO_DC, GPIO_MODE_OUTPUT ); + gpio_set_level( GPIO_DC, 0 ); + + if ( GPIO_RESET >= 0 ) { + //gpio_pad_select_gpio( GPIO_RESET ); + gpio_reset_pin( GPIO_RESET ); + gpio_set_direction( GPIO_RESET, GPIO_MODE_OUTPUT ); + gpio_set_level( GPIO_RESET, 0 ); + vTaskDelay( pdMS_TO_TICKS( 100 ) ); + gpio_set_level( GPIO_RESET, 1 ); + } + + spi_bus_config_t spi_bus_config = { + .mosi_io_num = GPIO_MOSI, + .miso_io_num = -1, + .sclk_io_num = GPIO_SCLK, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = 0, + .flags = 0 + }; + + ret = spi_bus_initialize( LCD_HOST, &spi_bus_config, SPI_DMA_CH_AUTO ); + ESP_LOGI(tag, "spi_bus_initialize=%d",ret); + assert(ret==ESP_OK); + + spi_device_interface_config_t devcfg; + memset( &devcfg, 0, sizeof( spi_device_interface_config_t ) ); + devcfg.clock_speed_hz = SPI_Frequency; + devcfg.spics_io_num = GPIO_CS; + devcfg.queue_size = 1; + + spi_device_handle_t handle; + ret = spi_bus_add_device( LCD_HOST, &devcfg, &handle); + ESP_LOGI(tag, "spi_bus_add_device=%d",ret); + assert(ret==ESP_OK); + dev->_dc = GPIO_DC; + dev->_SPIHandle = handle; + dev->_address = SPIAddress; + dev->_flip = false; +} + + +bool spi_master_write_byte(spi_device_handle_t SPIHandle, const uint8_t* Data, size_t DataLength ) +{ + spi_transaction_t SPITransaction; + + if ( DataLength > 0 ) { + memset( &SPITransaction, 0, sizeof( spi_transaction_t ) ); + SPITransaction.length = DataLength * 8; + SPITransaction.tx_buffer = Data; + spi_device_transmit( SPIHandle, &SPITransaction ); + } + + return true; +} + +bool spi_master_write_command(SSD1306_t * dev, uint8_t Command ) +{ + static uint8_t CommandByte = 0; + CommandByte = Command; + gpio_set_level( dev->_dc, SPI_Command_Mode ); + return spi_master_write_byte( dev->_SPIHandle, &CommandByte, 1 ); +} + +bool spi_master_write_data(SSD1306_t * dev, const uint8_t* Data, size_t DataLength ) +{ + gpio_set_level( dev->_dc, SPI_Data_Mode ); + return spi_master_write_byte( dev->_SPIHandle, Data, DataLength ); +} + + +void spi_init(SSD1306_t * dev, int width, int height) +{ + dev->_width = width; + dev->_height = height; + dev->_pages = 8; + if (dev->_height == 32) dev->_pages = 4; + + spi_master_write_command(dev, OLED_CMD_DISPLAY_OFF); // AE + spi_master_write_command(dev, OLED_CMD_SET_MUX_RATIO); // A8 + if (dev->_height == 64) spi_master_write_command(dev, 0x3F); + if (dev->_height == 32) spi_master_write_command(dev, 0x1F); + spi_master_write_command(dev, OLED_CMD_SET_DISPLAY_OFFSET); // D3 + spi_master_write_command(dev, 0x00); + spi_master_write_command(dev, OLED_CONTROL_BYTE_DATA_STREAM); // 40 + if (dev->_flip) { + spi_master_write_command(dev, OLED_CMD_SET_SEGMENT_REMAP_0); // A0 + } else { + spi_master_write_command(dev, OLED_CMD_SET_SEGMENT_REMAP_1); // A1 + } + //spi_master_write_command(dev, OLED_CMD_SET_SEGMENT_REMAP); // A1 + spi_master_write_command(dev, OLED_CMD_SET_COM_SCAN_MODE); // C8 + spi_master_write_command(dev, OLED_CMD_SET_DISPLAY_CLK_DIV); // D5 + spi_master_write_command(dev, 0x80); + spi_master_write_command(dev, OLED_CMD_SET_COM_PIN_MAP); // DA + if (dev->_height == 64) spi_master_write_command(dev, 0x12); + if (dev->_height == 32) spi_master_write_command(dev, 0x02); + spi_master_write_command(dev, OLED_CMD_SET_CONTRAST); // 81 + spi_master_write_command(dev, 0xFF); + spi_master_write_command(dev, OLED_CMD_DISPLAY_RAM); // A4 + spi_master_write_command(dev, OLED_CMD_SET_VCOMH_DESELCT); // DB + spi_master_write_command(dev, 0x40); + spi_master_write_command(dev, OLED_CMD_SET_MEMORY_ADDR_MODE); // 20 + //spi_master_write_command(dev, OLED_CMD_SET_HORI_ADDR_MODE); // 00 + spi_master_write_command(dev, OLED_CMD_SET_PAGE_ADDR_MODE); // 02 + // Set Lower Column Start Address for Page Addressing Mode + spi_master_write_command(dev, 0x00); + // Set Higher Column Start Address for Page Addressing Mode + spi_master_write_command(dev, 0x10); + spi_master_write_command(dev, OLED_CMD_SET_CHARGE_PUMP); // 8D + spi_master_write_command(dev, 0x14); + spi_master_write_command(dev, OLED_CMD_DEACTIVE_SCROLL); // 2E + spi_master_write_command(dev, OLED_CMD_DISPLAY_NORMAL); // A6 + spi_master_write_command(dev, OLED_CMD_DISPLAY_ON); // AF +} + + +void spi_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width) +{ + if (page >= dev->_pages) return; + if (seg >= dev->_width) return; + + int _seg = seg + CONFIG_OFFSETX; + uint8_t columLow = _seg & 0x0F; + uint8_t columHigh = (_seg >> 4) & 0x0F; + + int _page = page; + if (dev->_flip) { + _page = (dev->_pages - page) - 1; + } + + // Set Lower Column Start Address for Page Addressing Mode + spi_master_write_command(dev, (0x00 + columLow)); + // Set Higher Column Start Address for Page Addressing Mode + spi_master_write_command(dev, (0x10 + columHigh)); + // Set Page Start Address for Page Addressing Mode + spi_master_write_command(dev, 0xB0 | _page); + + spi_master_write_data(dev, images, width); + +} + +void spi_contrast(SSD1306_t * dev, int contrast) { + int _contrast = contrast; + if (contrast < 0x0) _contrast = 0; + if (contrast > 0xFF) _contrast = 0xFF; + + spi_master_write_command(dev, OLED_CMD_SET_CONTRAST); // 81 + spi_master_write_command(dev, _contrast); +} + +void spi_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll) +{ + + if (scroll == SCROLL_RIGHT) { + spi_master_write_command(dev, OLED_CMD_HORIZONTAL_RIGHT); // 26 + spi_master_write_command(dev, 0x00); // Dummy byte + spi_master_write_command(dev, 0x00); // Define start page address + spi_master_write_command(dev, 0x07); // Frame frequency + spi_master_write_command(dev, 0x07); // Define end page address + spi_master_write_command(dev, 0x00); // + spi_master_write_command(dev, 0xFF); // + spi_master_write_command(dev, OLED_CMD_ACTIVE_SCROLL); // 2F + } + + if (scroll == SCROLL_LEFT) { + spi_master_write_command(dev, OLED_CMD_HORIZONTAL_LEFT); // 27 + spi_master_write_command(dev, 0x00); // Dummy byte + spi_master_write_command(dev, 0x00); // Define start page address + spi_master_write_command(dev, 0x07); // Frame frequency + spi_master_write_command(dev, 0x07); // Define end page address + spi_master_write_command(dev, 0x00); // + spi_master_write_command(dev, 0xFF); // + spi_master_write_command(dev, OLED_CMD_ACTIVE_SCROLL); // 2F + } + + if (scroll == SCROLL_DOWN) { + spi_master_write_command(dev, OLED_CMD_CONTINUOUS_SCROLL); // 29 + spi_master_write_command(dev, 0x00); // Dummy byte + spi_master_write_command(dev, 0x00); // Define start page address + spi_master_write_command(dev, 0x07); // Frame frequency + //spi_master_write_command(dev, 0x01); // Define end page address + spi_master_write_command(dev, 0x00); // Define end page address + spi_master_write_command(dev, 0x3F); // Vertical scrolling offset + + spi_master_write_command(dev, OLED_CMD_VERTICAL); // A3 + spi_master_write_command(dev, 0x00); + if (dev->_height == 64) + spi_master_write_command(dev, 0x40); + if (dev->_height == 32) + spi_master_write_command(dev, 0x20); + spi_master_write_command(dev, OLED_CMD_ACTIVE_SCROLL); // 2F + } + + if (scroll == SCROLL_UP) { + spi_master_write_command(dev, OLED_CMD_CONTINUOUS_SCROLL); // 29 + spi_master_write_command(dev, 0x00); // Dummy byte + spi_master_write_command(dev, 0x00); // Define start page address + spi_master_write_command(dev, 0x07); // Frame frequency + //spi_master_write_command(dev, 0x01); // Define end page address + spi_master_write_command(dev, 0x00); // Define end page address + spi_master_write_command(dev, 0x01); // Vertical scrolling offset + + spi_master_write_command(dev, OLED_CMD_VERTICAL); // A3 + spi_master_write_command(dev, 0x00); + if (dev->_height == 64) + spi_master_write_command(dev, 0x40); + if (dev->_height == 32) + spi_master_write_command(dev, 0x20); + spi_master_write_command(dev, OLED_CMD_ACTIVE_SCROLL); // 2F + } + + if (scroll == SCROLL_STOP) { + spi_master_write_command(dev, OLED_CMD_DEACTIVE_SCROLL); // 2E + } +} diff --git a/v1.2/sdkconfig b/v1.2/sdkconfig new file mode 100644 index 0000000..4cfa3b2 --- /dev/null +++ b/v1.2/sdkconfig @@ -0,0 +1,1493 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET="esp32" +CONFIG_IDF_TARGET_ESP32=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 + +# +# SDK tool configuration +# +CONFIG_SDK_TOOLPREFIX="xtensa-esp32-elf-" +# CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS is not set +# end of SDK tool configuration + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# end of Build type + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +# +# Arduino Configuration +# +CONFIG_ENABLE_ARDUINO_DEPENDS=y +# CONFIG_AUTOSTART_ARDUINO is not set +CONFIG_ARDUINO_RUN_CORE0=y +# CONFIG_ARDUINO_RUN_CORE1 is not set +# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_RUNNING_CORE=0 +CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 +CONFIG_ARDUINO_EVENT_RUN_CORE0=y +# CONFIG_ARDUINO_EVENT_RUN_CORE1 is not set +# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_EVENT_RUNNING_CORE=0 +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_TASK_PRIORITY=3 +CONFIG_ARDUINO_UDP_RUNNING_CORE=0 +CONFIG_ARDUINO_ISR_IRAM=y +CONFIG_DISABLE_HAL_LOCKS=y + +# +# 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 is not set +# end of Arduino Configuration + +# +# Bootloader config +# +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 +# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Bootloader config + +# +# Security features +# +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# end of Security features + +# +# Serial flasher config +# +CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +# CONFIG_ESPTOOLPY_MONITOR_BAUD_CONSOLE is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y +# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# MZ25Key Configuration +# + +# +# PS2 Keyboard +# +CONFIG_PS2_HW_DATAPIN=32 +CONFIG_PS2_HW_CLKPIN=33 +CONFIG_KEYMAP_WYSE_KB3926=y +# CONFIG_KEYMAP_STANDARD is not set +# end of PS2 Keyboard + +# +# MZ-2500/2800 Interface +# +# CONFIG_MODEL_MZ2500 is not set +CONFIG_MODEL_MZ2800=y + +# +# 4Bit Strobe Input +# +CONFIG_MZ_KDB0=23 +CONFIG_MZ_KDB1=25 +CONFIG_MZ_KDB2=26 +CONFIG_MZ_KDB3=27 +# end of 4Bit Strobe Input + +# +# 8Bit Scan Data Output +# +CONFIG_MZ_KDO0=14 +CONFIG_MZ_KDO1=15 +CONFIG_MZ_KDO2=16 +CONFIG_MZ_KDO3=17 +CONFIG_MZ_KDO4=18 +CONFIG_MZ_KDO5=19 +CONFIG_MZ_KDO6=21 +CONFIG_MZ_KDO7=22 +# end of 8Bit Scan Data Output + +CONFIG_MZ_RTSNI=35 +CONFIG_MZ_KDI4=13 +# end of MZ-2500/2800 Interface + +# +# WiFi +# +# CONFIG_MZ_WIFI_ENABLED is not set +# end of WiFi + +# +# Debug Options +# + +# +# OLED +# +# CONFIG_OLED_DISABLED is not set +CONFIG_I2C_INTERFACE=y +# CONFIG_SPI_INTERFACE is not set +# CONFIG_SSD1306_128x32 is not set +CONFIG_SSD1306_128x64=y +CONFIG_OFFSETX=0 +# CONFIG_FLIP is not set +CONFIG_SCL_GPIO=4 +CONFIG_SDA_GPIO=5 +CONFIG_RESET_GPIO=16 +# end of OLED + +# CONFIG_MZ_DEBUG_SERIAL is not set +# CONFIG_MZ_DISABLE_KDB is not set +# CONFIG_MZ_DISABLE_KDO is not set +# CONFIG_MZ_DISABLE_RTSNI is not set +# CONFIG_MZ_DISABLE_KDI is not set +# end of Debug Options + +CONFIG_PWRLED=2 +# end of MZ25Key Configuration + +# +# Compiler options +# +CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +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_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# ESP-ASIO +# +# CONFIG_ASIO_SSL_SUPPORT is not set +# end of ESP-ASIO + +# +# Bluetooth +# +# CONFIG_BT_ENABLED is not set +# end of Bluetooth + +# +# CoAP Configuration +# +CONFIG_COAP_MBEDTLS_PSK=y +# CONFIG_COAP_MBEDTLS_PKI is not set +# CONFIG_COAP_MBEDTLS_DEBUG is not set +CONFIG_COAP_LOG_DEFAULT_LEVEL=0 +# end of CoAP Configuration + +# +# Driver configurations +# + +# +# ADC configuration +# +# CONFIG_ADC_FORCE_XPD_FSM is not set +CONFIG_ADC_DISABLE_DAC=y +# end of ADC configuration + +# +# MCPWM configuration +# +# CONFIG_MCPWM_ISR_IN_IRAM is not set +# end of MCPWM configuration + +# +# SPI configuration +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of SPI configuration + +# +# TWAI configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +# CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC is not set +# CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST is not set +# CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID is not set +# CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT is not set +# end of TWAI configuration + +# +# UART configuration +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of UART configuration + +# +# RTCIO configuration +# +# CONFIG_RTCIO_SUPPORT_RTC_GPIO_DESC is not set +# end of RTCIO configuration + +# +# GPIO Configuration +# +# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# end of GPIO Configuration + +# +# GDMA Configuration +# +# CONFIG_GDMA_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GDMA_ISR_IRAM_SAFE is not set +# end of GDMA Configuration +# end of Driver configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set +CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set +CONFIG_EFUSE_MAX_BLK_LEN=192 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# CONFIG_ESP_TLS_SERVER is not set +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ESP32-specific +# +CONFIG_ESP32_REV_MIN_0=y +# CONFIG_ESP32_REV_MIN_1 is not set +# CONFIG_ESP32_REV_MIN_2 is not set +# CONFIG_ESP32_REV_MIN_3 is not set +CONFIG_ESP32_REV_MIN=0 +CONFIG_ESP32_DPORT_WORKAROUND=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +# CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 +# CONFIG_ESP32_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_TRAX is not set +CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ESP32_ULP_COPROC_ENABLED is not set +CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=0 +CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_ESP32_BROWNOUT_DET=y +CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_ESP32_BROWNOUT_DET_LVL=0 +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32_XTAL_FREQ_40=y +# CONFIG_ESP32_XTAL_FREQ_26 is not set +# CONFIG_ESP32_XTAL_FREQ_AUTO is not set +CONFIG_ESP32_XTAL_FREQ=40 +# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set +# CONFIG_ESP32_NO_BLOBS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set +CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL=5 +# end of ESP32-specific + +# +# ADC-Calibration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y +# end of ADC-Calibration + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# Ethernet +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_ESP32_EMAC=y +CONFIG_ETH_PHY_INTERFACE_RMII=y +CONFIG_ETH_RMII_CLK_INPUT=y +# CONFIG_ETH_RMII_CLK_OUTPUT is not set +CONFIG_ETH_RMII_CLK_IN_GPIO=0 +CONFIG_ETH_DMA_BUFFER_SIZE=512 +CONFIG_ETH_DMA_RX_BUFFER_NUM=10 +CONFIG_ETH_DMA_TX_BUFFER_NUM=10 +CONFIG_ETH_USE_SPI_ETHERNET=y +# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set +# CONFIG_ETH_SPI_ETHERNET_W5500 is not set +# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set +# CONFIG_ETH_USE_OPENETH is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +# end of GDB Stub + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# end of MAC Config + +# +# Sleep Config +# +CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +# CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND is not set +# end of Sleep Config +# end of Hardware Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_IPC_ISR_ENABLE=y +# end of IPC (Inter-Processor Call) + +# +# LCD and Touch Panel +# + +# +# LCD Peripheral Configuration +# +CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y +# end of ESP NETIF Adapter + +# +# PHY +# +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +CONFIG_ESP_PHY_REDUCE_TX_POWER=y +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# end of Power Management + +# +# ESP System Settings +# +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set + +# +# Memory protection +# +# 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=3584 +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 +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_MULTIPLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=1000 +# CONFIG_ESP_INT_WDT_CHECK_CPU1 is not set +CONFIG_ESP_TASK_WDT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set +# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y +# end of ESP System Settings + +# +# High resolution timer (esp_timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +# CONFIG_ESP_TIMER_IMPL_FRC2 is not set +CONFIG_ESP_TIMER_IMPL_TG0_LAC=y +# end of High resolution timer (esp_timer) + +# +# Wi-Fi +# +CONFIG_ESP32_WIFI_ENABLED=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 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +# end of FAT Filesystem support + +# +# Modbus configuration +# +CONFIG_FMB_COMM_MODE_TCP_EN=y +CONFIG_FMB_TCP_PORT_DEFAULT=502 +CONFIG_FMB_TCP_PORT_MAX_CONN=5 +CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 +CONFIG_FMB_COMM_MODE_RTU_EN=y +CONFIG_FMB_COMM_MODE_ASCII_EN=y +CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_FMB_QUEUE_LENGTH=20 +CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 +CONFIG_FMB_SERIAL_BUF_SIZE=256 +CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 +CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 +CONFIG_FMB_PORT_TASK_PRIO=10 +# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y +# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set +CONFIG_FMB_PORT_TASK_AFFINITY=0x0 +CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 +CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_FMB_TIMER_PORT_ENABLED is not set +CONFIG_FMB_TIMER_GROUP=0 +CONFIG_FMB_TIMER_INDEX=0 +CONFIG_FMB_MASTER_TIMER_GROUP=0 +CONFIG_FMB_MASTER_TIMER_INDEX=0 +# CONFIG_FMB_TIMER_ISR_IN_IRAM is not set +# end of Modbus configuration + +# +# FreeRTOS +# +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y +# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set +# CONFIG_FREERTOS_ASSERT_DISABLE is not set +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +# CONFIG_FREERTOS_LEGACY_HOOKS is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +# CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# end of Heap memory debugging + +# +# jsmn +# +# CONFIG_JSMN_PARENT_LINKS is not set +# CONFIG_JSMN_STRICT is not set +# end of jsmn + +# +# libsodium +# +# end of libsodium + +# +# Log output +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=3 +CONFIG_LOG_COLORS=y +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +CONFIG_LWIP_SO_RCVBUF=y +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +# end of SNTP + +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y +# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set +# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +# CONFIG_MBEDTLS_CMAC_C is not set +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set +CONFIG_MBEDTLS_SSL_PROTO_TLS1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_X509_CHECK_KEY_USAGE=y +CONFIG_MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +CONFIG_MBEDTLS_RC4_DISABLED=y +# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set +# CONFIG_MBEDTLS_RC4_ENABLED is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +# CONFIG_MBEDTLS_SECURITY_RISKS is not set +# end of mbedTLS + +# +# mDNS +# +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set +CONFIG_MDNS_TASK_AFFINITY=0x0 +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +# CONFIG_MDNS_STRICT_MODE is not set +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y +# end of mDNS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +# end of Newlib + +# +# NVS +# +# end of NVS + +# +# OpenSSL +# +# CONFIG_OPENSSL_DEBUG is not set +CONFIG_OPENSSL_ERROR_STACK=y +# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set +CONFIG_OPENSSL_ASSERT_EXIT=y +# end of OpenSSL + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set +# end of OpenThread + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y +# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set +# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# end of Websocket +# end of TCP Transport + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_VFS_SUPPORT_TERMIOS=y + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# end of Wi-Fi Provisioning Manager + +# +# Supplicant +# +CONFIG_WPA_MBEDTLS_CRYPTO=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_SUITE_B_192 is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# end of Supplicant +# end of Component config + +# +# Compatibility options +# +# CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set +# end of Compatibility options + +# Deprecated options for backward compatibility +CONFIG_TOOLPREFIX="xtensa-esp32-elf-" +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +# CONFIG_MONITOR_BAUD_9600B is not set +# CONFIG_MONITOR_BAUD_57600B is not set +CONFIG_MONITOR_BAUD_115200B=y +# CONFIG_MONITOR_BAUD_230400B is not set +# CONFIG_MONITOR_BAUD_921600B is not set +# CONFIG_MONITOR_BAUD_2MB is not set +# CONFIG_MONITOR_BAUD_OTHER is not set +CONFIG_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_MONITOR_BAUD=115200 +CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_DISABLE_GCC8_WARNINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_SPIRAM_SUPPORT is not set +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ULP_COPROC_ENABLED is not set +CONFIG_ULP_COPROC_RESERVE_MEM=0 +CONFIG_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_BROWNOUT_DET_LVL=0 +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set +# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set +CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y +CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +CONFIG_ESP_SYSTEM_PD_FLASH=y +# CONFIG_ESP32C3_LIGHTSLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +CONFIG_ESP32_REDUCE_PHY_TX_POWER=y +# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set +CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32S2_PANIC_GDBSTUB is not set +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=1000 +# CONFIG_INT_WDT_CHECK_CPU1 is not set +CONFIG_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +# CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set +# CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set +CONFIG_TIMER_TASK_STACK_SIZE=3584 +# 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 +CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_MB_QUEUE_LENGTH=20 +CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 +CONFIG_MB_SERIAL_BUF_SIZE=256 +CONFIG_MB_SERIAL_TASK_PRIO=10 +CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_MB_CONTROLLER_STACK_SIZE=4096 +CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_MB_TIMER_PORT_ENABLED is not set +CONFIG_MB_TIMER_GROUP=0 +CONFIG_MB_TIMER_INDEX=0 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_L2_TO_L3_COPY is not set +# CONFIG_USE_ONLY_LWIP_SELECT is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5744 +CONFIG_TCP_WND_DEFAULT=5744 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +# CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 +# End of deprecated options