commit f828445b7600819467ac6bd21183c4df6713d407 Author: Philip Smart Date: Sat Jan 29 16:16:02 2022 +0000 Initial push diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..66016fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +.metadata +.dm +.gradle +/Releases +/.nb-gradle/ +*.bin +*.dmp +*.elf +*.lss +*.map +*.rpt +*.srec +*.swp +*.zpu +*.log +*.done +*.smsg +*.summary +*.jdi +*.pin +*.out.sdc +*.sof +*.sld +*.rbf +*.qws +*.sav +*.pof +*.qdf +*.srf +*.swo +build/ +old/ +*/old/ +*/*/old/ +*/*/*/old/ +*.o +Manuals/ +schematics/previous +*.bak +*.test +*.old +build_properties.temp.cmake +component_properties.temp.cmake +components_with_manifests_list.temp +main/CMakeLists.txt.orig +sdkconfigq diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f0aff97 --- /dev/null +++ b/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/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100644 index 0000000..910363b --- /dev/null +++ b/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/main/Kconfig.projbuild b/main/Kconfig.projbuild new file mode 100644 index 0000000..001d91b --- /dev/null +++ b/main/Kconfig.projbuild @@ -0,0 +1,308 @@ +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" + 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 "KDB1 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 "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 DEBUG_SERIAL + bool "Serial debug output" + default false + help + Enable debug output (non ESP logging) on the serial port. + 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/main/MZKeyTable.h b/main/MZKeyTable.h new file mode 100644 index 0000000..88403e8 --- /dev/null +++ b/main/MZKeyTable.h @@ -0,0 +1,189 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Name: keytable.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 13x8 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. +// +// 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 - + . , 9 8 F1O F9 +// 2 7 6 5 4 3 2 1 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 <¿ .>¿ ¿¿ ¿ | '¿ Z ¿ Y X ¿ +// 8 7' 6& 5% 4$ 3# 2" 1! 0 +// 9 [( @ -= ;+ :* 9) 8( +// 10 / * ESC BACKSPACE INST/DEL CLR/HOME COPY ]} +// 11 CTRL ¿¿ SHIFT LOCK GRAPH +// 12 ¿¿ ¿¿¿ +// 13 HELP ARGO + +#define PSMZTBL_KEYPOS 0 +#define PSMZTBL_SHIFTPOS 1 +#define PSMZTBL_FUNCPOS 2 +#define PSMZTBL_CTRLPOS 3 +#define PSMZTBL_ALTPOS 4 +#define PSMZTBL_ALTGRPOS 5 +#define PSMZTBL_MXROW1 6 +#define PSMZTBL_MXKEY1 7 +#define PSMZTBL_MXROW2 8 +#define PSMZTBL_MXKEY2 9 +#define PSMZTBL_MXROW3 10 +#define PSMZTBL_MXKEY3 11 +#define PSMZTBL_MAXROWS 12 + +// Lookup table to matrix row/column co-ordinates. If a PS2 key is matched, then the Matrix is updated +// using ROW to point into the array, equivalent of strobe line, and the KEY defines the bits to be set. +// A set bit = 0, reset bits = 1. The KEY value needs to be inverted and masked with the matrix +// to affect change. +const unsigned char PS2toMZ[][PSMZTBL_MAXROWS] = +{ +// PS2 Code Shift Function Ctrl ALT ALT-Gr MXROW1 MXKEY1 MXROW2 MXKEY2 MXROW3 MXKEY3 + PS2_KEY_F1, 0, 0, 0, 0, 0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_F2, 0, 0, 0, 0, 0, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_F3, 0, 0, 0, 0, 0, 0x00, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_F4, 0, 0, 0, 0, 0, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_F5, 0, 0, 0, 0, 0, 0x00, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_F6, 0, 0, 0, 0, 0, 0x00, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_F7, 0, 0, 0, 0, 0, 0x00, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_F8, 0, 0, 0, 0, 0, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_F9, 0, 0, 0, 0, 0, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_F10, 0, 0, 0, 0, 0, 0x01, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_F11, 0, 0, 0, 0, 0, 0x0D, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, // HELP + PS2_KEY_F12, 0, 0, 0, 0, 0, 0x03, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, // BREAK + PS2_KEY_TAB, 0, 0, 0, 0, 0, 0x03, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_PIPE, 0, 0, 0, 0, 0, 0x07, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_L_ALT, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_R_ALT, 0, 0, 0, 0, 0, 0x0B, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, // GRAPH + PS2_KEY_L_SHIFT, 0, 0, 0, 0, 0, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_L_CTRL, 0, 0, 0, 0, 0, 0x0B, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_R_CTRL, 0, 0, 0, 0, 0, 0x0B, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_0, 0, 0, 0, 0, 0, 0x02, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_1, 0, 0, 0, 0, 0, 0x02, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_2, 0, 0, 0, 0, 0, 0x02, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_3, 0, 0, 0, 0, 0, 0x02, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_4, 0, 0, 0, 0, 0, 0x02, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_5, 0, 0, 0, 0, 0, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_6, 0, 0, 0, 0, 0, 0x02, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_7, 0, 0, 0, 0, 0, 0x02, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_8, 0, 0, 0, 0, 0, 0x01, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_9, 0, 0, 0, 0, 0, 0x01, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_A, 0, 0, 0, 0, 0, 0x04, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_B, 0, 0, 0, 0, 0, 0x04, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_C, 0, 0, 0, 0, 0, 0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_D, 0, 0, 0, 0, 0, 0x04, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_E, 0, 0, 0, 0, 0, 0x04, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_F, 0, 0, 0, 0, 0, 0x04, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_G, 0, 0, 0, 0, 0, 0x04, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_H, 0, 0, 0, 0, 0, 0x05, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_I, 0, 0, 0, 0, 0, 0x05, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_J, 0, 0, 0, 0, 0, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_K, 0, 0, 0, 0, 0, 0x05, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_L, 0, 0, 0, 0, 0, 0x05, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_M, 0, 0, 0, 0, 0, 0x05, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_N, 0, 0, 0, 0, 0, 0x05, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_O, 0, 0, 0, 0, 0, 0x05, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_P, 0, 0, 0, 0, 0, 0x06, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_Q, 0, 0, 0, 0, 0, 0x06, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_R, 0, 0, 0, 0, 0, 0x06, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_S, 0, 0, 0, 0, 0, 0x06, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_T, 0, 0, 0, 0, 0, 0x06, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_U, 0, 0, 0, 0, 0, 0x06, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_V, 0, 0, 0, 0, 0, 0x06, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_W, 0, 0, 0, 0, 0, 0x06, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_X, 0, 0, 0, 0, 0, 0x07, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_Y, 0, 0, 0, 0, 0, 0x07, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_Z, 0, 0, 0, 0, 0, 0x07, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_SPACE, 0, 0, 0, 0, 0, 0x03, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_COMMA, 0, 0, 0, 0, 0, 0x01, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_SEMI, 0, 0, 0, 0, 0, 0x09, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_STOP, 0, 0, 0, 0, 0, 0x01, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_DIV, 0, 0, 0, 0, 0, 0x0A, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_MINUS, 0, 0, 0, 0, 0, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_APOS, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_OPEN_SQ, 0, 0, 0, 0, 0, 0x09, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_EQUAL, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_CAPS, 0, 0, 0, 0, 0, 0x08, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, // LOCK + PS2_KEY_R_SHIFT, 0, 0, 0, 0, 0, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_ENTER, 0, 0, 0, 0, 0, 0x03, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_CLOSE_SQ, 0, 0, 0, 0, 0, 0x0A, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_BACK, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_LESSTHAN, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_BS, 0, 0, 0, 0, 0, 0x0A, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_ESC, 0, 0, 0, 0, 0, 0x0A, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP1, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP2, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP3, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP4, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP5, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP6, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP7, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP8, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP9, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP_COMMA, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP_PLUS, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP_MINUS, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP_TIMES, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_KP_DIV, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_SCROLL, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_INSERT, 0, 0, 0, 0, 0, 0x0A, 0x08, 0x0B, 0x04, 0xFF, 0xFF, // SHIFT + INST/DEL + PS2_KEY_HOME, 0, 0, 0, 0, 0, 0x0A, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, // CLR/HOME + PS2_KEY_PGUP, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_DELETE, 0, 0, 0, 0, 0, 0x0A, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, // INST/DEL + PS2_KEY_END, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_PGDN, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_UP_ARROW, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_L_ARROW, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_DN_ARROW, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_R_ARROW, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + PS2_KEY_NUM, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +// PS/2 BREAK key code string +const unsigned char BREAK_CODE[8]={0xE1,0x14,0x77,0xE1,0xF0,0x14,0xF0,0x77}; + +#endif // KEYTABLE_H diff --git a/main/PS2KeyAdvanced.cpp b/main/PS2KeyAdvanced.cpp new file mode 100644 index 0000000..b3f668a --- /dev/null +++ b/main/PS2KeyAdvanced.cpp @@ -0,0 +1,1030 @@ +/* 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; +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; +_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 PS2_KEY_PAUSE + _FUNCTION; + +// 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 + retdata = PS2_KEY_IGNORE; // ignore key + } + else + { + if( PS2_lockstate[ retdata ] == 1 ) + retdata = PS2_KEY_IGNORE; // ignore key if make and not received break + 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; + 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; + else + // if already set ignore repeats if flag set + 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/main/PS2KeyAdvanced.h b/main/PS2KeyAdvanced.h new file mode 100644 index 0000000..829bae1 --- /dev/null +++ b/main/PS2KeyAdvanced.h @@ -0,0 +1,433 @@ +/* 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 0x08 +#define PS2_KEY_TAB 0x09 +#define PS2_KEY_ENTER 0x0D +#define PS2_KEY_SPACE 0x20 +#define PS2_KEY_KP0 0xA0 +#define PS2_KEY_KP1 0xA1 +#define PS2_KEY_KP2 0xA2 +#define PS2_KEY_KP3 0xA3 +#define PS2_KEY_KP4 0xA4 +#define PS2_KEY_KP5 0xA5 +#define PS2_KEY_KP6 0xA6 +#define PS2_KEY_KP7 0xA7 +#define PS2_KEY_KP8 0xA8 +#define PS2_KEY_KP9 0xA9 +#define PS2_KEY_KP_DOT 0xAA +#define PS2_KEY_KP_ENTER 0xAB +#define PS2_KEY_KP_PLUS 0xAC +#define PS2_KEY_KP_MINUS 0xAD +#define PS2_KEY_KP_TIMES 0xAE +#define PS2_KEY_KP_DIV 0xAF +#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 0X27 +#define PS2_KEY_COMMA 0X2C +#define PS2_KEY_MINUS 0X2D +#define PS2_KEY_DOT 0X2E +#define PS2_KEY_DIV 0X2F +#define PS2_KEY_AT 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 0X3B +#define PS2_KEY_BACK 0X5C +#define PS2_KEY_OPEN_SQ 0X5B +#define PS2_KEY_CLOSE_SQ 0X5D +#define PS2_KEY_EQUAL 0X3D +#define PS2_KEY_HASH 0x23 +#define PS2_KEY_PIPE 0x7C +#define PS2_KEY_LESSTHAN 0x3C +#define PS2_KEY_BTICK 0x60 +/* Some Numeric keypads have a comma key */ +#define PS2_KEY_KP_COMMA 0xB0 +#define PS2_KEY_F1 0XB1 +#define PS2_KEY_F2 0XB2 +#define PS2_KEY_F3 0XB3 +#define PS2_KEY_F4 0XB4 +#define PS2_KEY_F5 0XB5 +#define PS2_KEY_F6 0XB6 +#define PS2_KEY_F7 0XB7 +#define PS2_KEY_F8 0XB8 +#define PS2_KEY_F9 0XB9 +#define PS2_KEY_F10 0XBA +#define PS2_KEY_F11 0XBB +#define PS2_KEY_F12 0XBC +#define PS2_KEY_NEXT_TR 0XBD +#define PS2_KEY_PREV_TR 0XBE +#define PS2_KEY_STOP 0XBF +#define PS2_KEY_PLAY 0XC0 +#define PS2_KEY_MUTE 0XC1 +#define PS2_KEY_VOL_UP 0XC2 +#define PS2_KEY_VOL_DN 0XC3 +#define PS2_KEY_MEDIA 0XC4 +#define PS2_KEY_EMAIL 0XC5 +#define PS2_KEY_CALC 0XC6 +#define PS2_KEY_COMPUTER 0XC7 +#define PS2_KEY_WEB_SEARCH 0XC8 +#define PS2_KEY_WEB_HOME 0XC9 +#define PS2_KEY_WEB_BACK 0XCA +#define PS2_KEY_WEB_FORWARD 0XCB +#define PS2_KEY_WEB_STOP 0XCC +#define PS2_KEY_WEB_REFRESH 0XCD +#define PS2_KEY_WEB_FAVOR 0XCE +#define PS2_KEY_EUROPE2 0XCF +#define PS2_KEY_POWER 0XD0 +#define PS2_KEY_SLEEP 0XD1 +#define PS2_KEY_WAKE 0XD2 +#define PS2_KEY_INTL1 0XD3 +#define PS2_KEY_INTL2 0XD4 +#define PS2_KEY_INTL3 0XD5 +#define PS2_KEY_INTL4 0XD6 +#define PS2_KEY_INTL5 0XD7 +#define PS2_KEY_LANG1 0XD8 +#define PS2_KEY_LANG2 0XD9 +#define PS2_KEY_LANG3 0XDA +#define PS2_KEY_LANG4 0XDB +#define PS2_KEY_LANG5 0xDC +/* Some Numeric keyboards have an '=' on right keypad */ +#define PS2_KEY_KP_EQUAL 0xDD + +/* + 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 ); + + uint8_t keyAvailable(); + + /* 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( uint8_t ); + + /* 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/main/PS2KeyCode.h b/main/PS2KeyCode.h new file mode 100644 index 0000000..ec4da88 --- /dev/null +++ b/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/main/PS2KeyTable.h b/main/PS2KeyTable.h new file mode 100644 index 0000000..dbc4d99 --- /dev/null +++ b/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/main/component.mk b/main/component.mk new file mode 100644 index 0000000..61f8990 --- /dev/null +++ b/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/main/font8x8_basic.h b/main/font8x8_basic.h new file mode 100644 index 0000000..413825e --- /dev/null +++ b/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/main/main.cpp b/main/main.cpp new file mode 100644 index 0000000..5664b09 --- /dev/null +++ b/main/main.cpp @@ -0,0 +1,462 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Name: mz25key.ino +// Created: Jan 2022 +// Version: v1.0 +// Author(s): Philip Smart +// Description: MZ2500/2800 Key Matrix logic. +// This source file contains the logic to transmit the virtual key matrix, which is +// built from PS/2 scan codes, to the MZ2500/2800. +// Credits: +// Copyright: (c) 2022 Philip Smart +// +// History: Jan 2022 - Initial write. +// +// 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" +#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" + +// ESP Logging tag. +#define tag "mz25key" + +////////////////////////////////////////////////////////////////////////// +// Important: +// +// All configuration is performed via the 'idf.py menuconfig' command. +// Optionally override via the definitions below. +// Debugging options. +////////////////////////////////////////////////////////////////////////// +//#define CONFIG_DEBUG_OLED !CONFIG_OLED_DISABLED +//#define CONFIG_PWRLED 25 +//#define CONFIG_PS2_HW_DATAPIN 14 +//#define CONFIG_PS2_HW_CLKPIN 13 + +// 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; + uint8_t keyMatrix[15]; +} t_mzControl; +volatile t_mzControl mzControl = { 0xFF, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; + +// Instantiate base classes. First, production required objects. +PS2KeyAdvanced Keyboard; +// Nex/t, debug required objects. +SSD1306_t SSD1306; + +// Handle to interact with the mz-2500 interface thread. +TaskHandle_t TaskMZ25IF = NULL; +TaskHandle_t TaskPS2IF = NULL; + +// 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; + +#if defined(CONFIG_DEBUG_OLED) || !defined(CONFIG_OLED_DISABLED) +// Printf to terminal, needed when OLED is connected for debugging. +void terminalPrintf(const char * format, ...) +{ + va_list ap; + va_start(ap, format); + int size = vsnprintf(nullptr, 0, format, ap) + 1; + if (size > 0) + { + va_end(ap); + va_start(ap, format); + char buf[size + 1]; + vsnprintf(buf, size, format, ap); + // u8g2.print(buf); + // u8g2.sendBuffer(); + } + va_end(ap); +} +#endif + +// Method to connect and interact with the MZ-2500/MZ-2800 keyboard controller. +// 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. 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. +// +IRAM_ATTR void mz25Interface( void * pvParameters ) +{ + // Locals. + volatile unsigned long idx; + + // 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(;;) + { + gpio_set_level((gpio_num_t)CONFIG_PWRLED, 1); + // digitalWrite(CONFIG_PWRLED, HIGH); + for(idx=0; idx < 10000000; idx++) + { + if(idx % 1000 == 0) + { + 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 + } + } + // digitalWrite(CONFIG_PWRLED, LOW); + gpio_set_level((gpio_num_t)CONFIG_PWRLED, 0); + for(idx=0; idx < 10000000; idx++) + { + if(idx % 1000 == 0) + { + 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 + } + } + } +} + +// 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 idx2; + + // 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; idx < NUMELEM(PS2toMZ); idx++) + { + // Match key code? + if(PS2toMZ[idx][PSMZTBL_KEYPOS] == (uint8_t)(data&0xFF)) + { + // 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_FUNCTION) && PS2toMZ[idx][PSMZTBL_FUNCPOS] == 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) ) + { + // RELEASE (PS2_BREAK == 1) or PRESS? + if((data & PS2_BREAK)) + { + // Reset the matrix bit according to the lookup table. 1 = No key, 0 = key in the matrix. + if(PS2toMZ[idx][PSMZTBL_MXROW1] != 0xFF) + { + mzControl.keyMatrix[PS2toMZ[idx][PSMZTBL_MXROW1]] |= PS2toMZ[idx][PSMZTBL_MXKEY1]; + } + if(PS2toMZ[idx][PSMZTBL_MXROW2] != 0xFF) + { + mzControl.keyMatrix[PS2toMZ[idx][PSMZTBL_MXROW2]] |= PS2toMZ[idx][PSMZTBL_MXKEY2]; + } + if(PS2toMZ[idx][PSMZTBL_MXROW3] != 0xFF) + { + mzControl.keyMatrix[PS2toMZ[idx][PSMZTBL_MXROW3]] |= PS2toMZ[idx][PSMZTBL_MXKEY3]; + } + } else + { + // Set the matrix bit according to the lookup table. 1 = No key, 0 = key in the matrix. + if(PS2toMZ[idx][PSMZTBL_MXROW1] != 0xFF) + { + mzControl.keyMatrix[PS2toMZ[idx][PSMZTBL_MXROW1]] &= ~PS2toMZ[idx][PSMZTBL_MXKEY1]; + } + if(PS2toMZ[idx][PSMZTBL_MXROW2] != 0xFF) + { + mzControl.keyMatrix[PS2toMZ[idx][PSMZTBL_MXROW2]] &= ~PS2toMZ[idx][PSMZTBL_MXKEY2]; + } + if(PS2toMZ[idx][PSMZTBL_MXROW3] != 0xFF) + { + mzControl.keyMatrix[PS2toMZ[idx][PSMZTBL_MXROW3]] &= ~PS2toMZ[idx][PSMZTBL_MXKEY3]; + } + } + } + + // Re-calculate the Strobe All (KD4 = 1) signal, this indicates if any bit (key) in the matrix is active. + mzControl.strobeAll = 0xFF; + for(idx2=0; idx2 < 15; idx2++) + { + mzControl.strobeAll &= mzControl.keyMatrix[idx2]; + } + } + } + return data; +} + +// 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 ) +//IRAM_ATTR void ps2Interface( ) +{ + // Locals. + uint16_t scanCode = 0x0000; + #if defined(CONFIG_DEBUG_OLED) || !defined(CONFIG_OLED_DISABLED) + uint8_t dataChange = 0; + static int clrScreen = 1; + static int scanPrtCol = 0; + static uint32_t clrTimer = 0; + #endif + + #if defined(CONFIG_DEBUG_OLED) || !defined(CONFIG_OLED_DISABLED) + if((clrTimer > 0 && --clrTimer == 0) || ((scanCode&0xFF) == PS2_KEY_C && scanCode & PS2_BREAK )) + { + // Clear old scan code data. + // u8g2.drawStr(0, 8*7, " "); + // u8g2.sendBuffer(); + scanPrtCol = 0; + } + #endif + + while(1) + { + // Check for PS/2 keyboard scan codes. + while((scanCode = Keyboard.read()) != 0) + { + printf("%04x\n", scanCode); + #if defined(CONFIG_DEBUG_OLED) || !defined(CONFIG_OLED_DISABLED) + // Clear screen as requested. + if(clrScreen == 1) + { + ssd1306_clear_screen(&SSD1306, false); + clrScreen = 0; + } + + // Output the scan code for verification. + // u8g2.setCursor((scanPrtCol*5)*6, 8*7); + terminalPrintf("%04x,", scanCode); + if(scanPrtCol++ >= 3) scanPrtCol = 0; + // u8g2.sendBuffer(); + clrTimer = 2000000; + dataChange = 1; + #endif + + // Update the virtual matrix with the new key value. + updateMatrix(scanCode); + } + + #if defined(CONFIG_DEBUG_OLED) || !defined(CONFIG_OLED_DISABLED) + // Output the MZ virtual keyboard matrix for verification. + uint8_t oledBuf[8][16]; + if(dataChange) + { + 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'; + } + } + + for(int idx=0; idx < 8; idx++) + { + ssd1306_display_text(&SSD1306, idx, (char *)oledBuf[idx], 15, false); + } + } + #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; + + // Start the keyboard, no mouse. + ESP_LOGI(tag, "Initialise PS2 keyboard."); + Keyboard.begin(CONFIG_PS2_HW_DATAPIN, CONFIG_PS2_HW_CLKPIN); + + // If OLED connected and enabled, include the screen controller for debug output. + // + #if defined(CONFIG_DEBUG_OLED) || !defined(CONFIG_OLED_DISABLED) + #if CONFIG_I2C_INTERFACE + ESP_LOGI(tag, "INTERFACE is i2c"); + ESP_LOGI(tag, "CONFIG_SDA_GPIO=%d", CONFIG_SDA_GPIO); + ESP_LOGI(tag, "CONFIG_SCL_GPIO=%d", CONFIG_SCL_GPIO); + ESP_LOGI(tag, "CONFIG_RESET_GPIO=%d", CONFIG_RESET_GPIO); + i2c_master_init(&SSD1306, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO); + #endif // CONFIG_I2C_INTERFACE + #if CONFIG_SPI_INTERFACE + ESP_LOGI(tag, "INTERFACE is SPI"); + ESP_LOGI(tag, "CONFIG_MOSI_GPIO=%d", CONFIG_MOSI_GPIO); + ESP_LOGI(tag, "CONFIG_SCLK_GPIO=%d", CONFIG_SCLK_GPIO); + ESP_LOGI(tag, "CONFIG_CS_GPIO=%d", CONFIG_CS_GPIO); + ESP_LOGI(tag, "CONFIG_DC_GPIO=%d", CONFIG_DC_GPIO); + ESP_LOGI(tag, "CONFIG_RESET_GPIO=%d", CONFIG_RESET_GPIO); + spi_master_init(&SSD1306, CONFIG_MOSI_GPIO, CONFIG_SCLK_GPIO, CONFIG_CS_GPIO, CONFIG_DC_GPIO, CONFIG_RESET_GPIO); + #endif // CONFIG_SPI_INTERFACE + + #if CONFIG_SSD1306_128x64 + ESP_LOGI(tag, "Panel is 128x64"); + ssd1306_init(&SSD1306, 128, 64); + #endif // CONFIG_SSD1306_128x64 + #if CONFIG_SSD1306_128x32 + ESP_LOGI(tag, "Panel is 128x32"); + ssd1306_init(&SSD1306, 128, 32); + #endif // CONFIG_SSD1306_128x32 + + ssd1306_clear_screen(&SSD1306, false); + ssd1306_contrast(&SSD1306, 0xff); + #endif + + // Setup power LED. + //pinMode(CONFIG_PWRLED, OUTPUT); + //#define GPIO_OUTPUT_PIN_SEL ((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/main/ssd1306.h b/main/ssd1306.h new file mode 100644 index 0000000..d8e2483 --- /dev/null +++ b/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/main/ssd1306_i2c.c b/main/ssd1306_i2c.c new file mode 100644 index 0000000..8f49e2e --- /dev/null +++ b/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/main/ssd1306_spi.c b/main/ssd1306_spi.c new file mode 100644 index 0000000..ac5b7e9 --- /dev/null +++ b/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/sdkconfig b/sdkconfig new file mode 100644 index 0000000..ea054e4 --- /dev/null +++ b/sdkconfig @@ -0,0 +1,1481 @@ +# +# 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 + +# +# 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 is not set +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="8MB" +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=14 +CONFIG_PS2_HW_CLKPIN=13 +CONFIG_KEYMAP_WYSE_KB3926=y +# CONFIG_KEYMAP_STANDARD is not set +# end of PS2 Keyboard + +# +# MZ-2500/2800 Interface +# + +# +# 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=21 +# end of 8Bit Scan Data Output + +CONFIG_MZ_RTSNI=35 +CONFIG_MZ_KDI4=13 +# end of MZ-2500/2800 Interface + +# +# 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=15 +CONFIG_SDA_GPIO=4 +CONFIG_RESET_GPIO=16 +# end of OLED + +# CONFIG_DEBUG_SERIAL is not set +# end of Debug Options + +CONFIG_PWRLED=25 +# end of MZ25Key Configuration + +# +# 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 + +# +# 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 is not set +CONFIG_ESP32_XTAL_FREQ_26=y +# CONFIG_ESP32_XTAL_FREQ_AUTO is not set +CONFIG_ESP32_XTAL_FREQ=26 +# 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=300 +CONFIG_ESP_INT_WDT_CHECK_CPU1=y +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=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# 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=300 +CONFIG_INT_WDT_CHECK_CPU1=y +CONFIG_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +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