Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a85ae7346a | |||
|
|
4a44cc79af | ||
|
|
95a639d665 | ||
|
|
112a9593e0 | ||
|
|
5e89baeadd | ||
|
|
4f1d985473 | ||
|
|
5da8f8fe0e | ||
|
|
021b648636 | ||
|
|
ab9531488b | ||
|
|
29527bea3f | ||
|
|
4ba087e591 |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.html linguist-detectable=false
|
||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -28,6 +28,7 @@
|
||||
*.qdf
|
||||
*.srf
|
||||
*.swo
|
||||
*efuse*
|
||||
build/
|
||||
old/
|
||||
*/old/
|
||||
@@ -44,3 +45,12 @@ component_properties.temp.cmake
|
||||
components_with_manifests_list.temp
|
||||
main/CMakeLists.txt.orig
|
||||
sdkconfigq
|
||||
0001-flash-permance.patch
|
||||
0001-flash-permance.zip
|
||||
components.x/
|
||||
components/
|
||||
main/main.cpp.bak2
|
||||
webfs/
|
||||
webserver/font-awesome/fonts/fontawesome-webfont.ttf.orig
|
||||
webserver/font-awesome/fonts/fontawesome-webfont.woff.orig
|
||||
|
||||
|
||||
@@ -6,3 +6,6 @@ cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(main)
|
||||
|
||||
# Create the default filesystem with files loaded from the webserver directory.
|
||||
littlefs_create_partition_image(filesys webfs)
|
||||
|
||||
624
README.md
Normal file
624
README.md
Normal file
@@ -0,0 +1,624 @@
|
||||
# mz25key
|
||||
|
||||
**Website:** [engineers@work](https://eaw.app) | **Repository:** [git.eaw.app/eaw/mz25key](https://git.eaw.app/eaw/mz25key)
|
||||
|
||||
---
|
||||
|
||||
## <font style="color: yellow;" size="6">Overview</font>
|
||||
|
||||
<div style="text-align: justify">
|
||||
<br>
|
||||
A major issue with later vintage Sharp computers is keyboards. For whatever reason, either lost, in storage or bought by collectors, a large majority of MZ-2500/2800/3500/X1/X68000 machines
|
||||
are now sold without keyboard. Apart from the X68000 where you can still 'kind of' use it with a joystick, the machine is just a paper weight without one. Sellers know this and those that come
|
||||
up for sale can be GBP100-200 or more.
|
||||
</div>
|
||||
Some resourceful Japanese guys (classicpc.org, or [Youkan](http://www.maroon.dti.ne.jp/youkan/mz2500/kbd.html)) and [Martin](https://www.8bity.cz/2016/sharp-x68000-ps2-keyboard-adapter/) at 8bity.cz have developed interfaces to convert common PS/2 or USB PC keyboards so that they
|
||||
work with these keyboardless Sharp machines. On the whole, for the X1 and X68000 these interfaces work perfectly and are wrapped up in a professional small form factor case. The MZ-2500 interface though has some issues, not least the
|
||||
available design is based on an ST Development board and the firmware is closed source. It was made into a professional adapter for sale in Akihabara but seems no longer available. For me the development version of the MZ-2500 interface on the web, at
|
||||
least the version I made up, is temperamental and doesn't work with the MZ-2800 (as confirmed by some Japanese contacts). As I need a working reliable unit so that I can complete my MZ-2500/MZ-2800 machines I have under renovation (all without keyboards) I had to consider other options.
|
||||
<br>
|
||||
I'm currently renovating 2x MZ-2500 machines, one of which I will be keeping and also an MZ-2800. Given the limitations of Youkan's development board based interface, I decided on designing my own using the physical format used by Martin at 8bity.cz,
|
||||
namely a KM24 small form factor cased device. Initially looking at the Renesas R8C processor used by [Sato Kyouchi](https://kyouichisato.blogspot.com/2014/07/sharp-x1-ps2.html) for his very reliable X1 interface, I hoped to build on the
|
||||
design adding supporting hardware and make a 2 in 1 device, PS/2 -> X1/MZ-2500/2800. The R8C is a lovely small MCU, easy to work with and program but it suffered from performance issues for this requrement, even at 20MHz it would take
|
||||
1uS to respond to an interrupt, which is fine for most applications, including PS/2 and X1 keyboard protocol's, but for the MZ-2500 is was too slow.
|
||||
<div style="text-align: justify">
|
||||
The MZ-2500 uses an almost identical keyboard matrix as the MZ-80B, albeit enhanced with two rows and serialised over a 4 bit bus between main unit and keyboard. The main unit sends a row in 600nS and the keyboard returns the key data in 2 nibbles, 300nS apart.
|
||||
Thus 1 row of the keyboard matrix takes 1.2uS from keyboard to the main unit, repeated for 14 rows in a tight loop. You thus need to be able to detect the main unit sending the row (RTSN), read it and lookup the key matrix value for this row in less than 600nS.
|
||||
The data then needs to be presented to the main unit as nibbles (MPX), high nibble first in 300nS then lower nibble in the next 300nS.
|
||||
<br><br>
|
||||
In order to understand the requirements of interfacing to an MZ-2500/MZ-2800 the following section describes the hardware and its protocol in more detail.
|
||||
</div>
|
||||
|
||||
## <font style="color: yellow;" size="6">MZ-2500 Keyboard Protocol</font>
|
||||
|
||||
The hardware interface comprises of 7 signals, 5V and GND using a shielded 8pin mini-din socket and plug, with plug wiring below.
|
||||
|
||||

|
||||
|
||||
<div style="text-align: justify">
|
||||
RTSN, KD4, MPX are output signals from the main unit side. KD [3:0] is a bidirectional bus between the main unit and the keyboard, direction under main unit control using RTSN.
|
||||
<br><br>
|
||||
</div>
|
||||
|
||||
| Signal | Direction | Logic State | Description |
|
||||
| ------ | --------- | ----------- | ----------- |
|
||||
| RTSN <br>Row Strobe | Main Unit -> Keyboard | HIGH ('1') | A Row address is being transmitted from the main unit to the keyboard. |
|
||||
| | | LOW ('0') | The keyboard is transmitting requested data over the 4 bit bidirectional bus KD[3:0]. |
|
||||
| KD4<br>Type Strobe | Main Unit -> Keyboard | HIGH ('1') | The keyboard must return the actual key matrix data as referenced by the Row number. |
|
||||
| | | LOW ('0') | The keyboard must return a logical AND of all the keys, ie. D0 = AND of bit 0 on ROWS 0 to 13, D1 = AND of bit 1 on ROWS 0 to 13 etc.|
|
||||
| MPX<br>Nibble MUX Strobe | Main Unit -> Keyboard | HIGH ('1') | The upper nibble of the requested ROW (or AND of row data as directed by KD4) is sent from the keyboard to the main unit. |
|
||||
| | | LOW ('0') | The lower nibble of the requested ROW (or AND of row data as directed by KD4) is sent from the keyboard to the main unit. |
|
||||
| KD[3:0]<br>Bi-dir bus | Main Unit -> Keyboard | | Active when RTSN = HIGH ('1'), transmits the 4 bit row number of the row data from the keyboard matrix. |
|
||||
| | Keyboard -> Main Unit | | Active when RTSN = LOW ('0'), transmits 4 bits of the 8 bit column data of the requested row. 4 bits is selected by KD4 & MPX. |
|
||||
|
||||
<br>
|
||||
There are two main modes of operation, a test all (STROBEALL) keys mode, used whilst waiting for a key to be pressed which is followed on by a manual scan of all rows to retrieve column data to locate the pressed key.
|
||||
|
||||
For key data retrieval the protocol is as follows:
|
||||
|
||||
1. RTSN goes active HIGH and remains active for 1.08us. The initial RTSN period, after detection of a key via STROBEALL, is 1.08us active HIGH and 660ns inactive LOW. Thereafter the period is a uniform 660ns active HIGH and 680ns inactive LOW.
|
||||
2. The mainboard sends a scan row to the keyboard which becomes valid 160ns after the rising edge of RTSN.
|
||||
2. The scan row is read by the keyboard in the remaining 920ns from KD[3:0]. KD4 state (or state change) precedes the rising edge of RTSN, generally changes on the falling edge prior to the triggering active edge of RTSN.
|
||||
3. KD4 is sampled, when LOW the logical AND of all keys per column is set for retrieval, when HIGH the actual column of the selected row is set for retrieval.
|
||||
4. On the RTSN falling edge (RTSN goes inactive LOW), MPX goes HIGH for 320ns and the upper nibble of the data set for retrieval is output by the keyboard on KD[3:0] after 20ns from the MPX rising edge. The data is then read by the mainboard within the remaining 300ns before MPX goes LOW.. When MPX goes LOW ') the lower
|
||||
nibble of the data set for retrieval is output on KD[3:0] with the same 320ns timing interval. After 320ns RTSN will then rise again.
|
||||
5. The above repeats whilst a key is being pressed, the row sent can vary or remain static, for example if reading the same key to determine bounce or repeat.
|
||||
6. If no key is being pressed, switch to STROBEALL mode.
|
||||
|
||||
For the STROBEALL mode, the protocol is as follows:
|
||||
|
||||
1. During the STROBEALL mode, KD4 is held LOW and apart from a 20ns glitch which varies from 18.996ms to 198.83ms it doesn't change state. The glitch looks like a hardware oversight.
|
||||
2. During STROBEALL mode, RTSN has an even period, 660ns active HIGH, 660ns active LOW. When RTSN goes HIGH, the hardware switches for the mainboard to send a ROW to the keyboard as in the protocol above. The row is ignored (or appears to be ignored as it repeats ad-infinitum with a constant value of 4 which is not a meaningful row).
|
||||
3. KD4 is sampled, when LOW the logical AND of all keys per column is set for retrieval, when HIGH the actual column of the selected row is set for retrieval.
|
||||
4. On the RTSN falling edge (RTSN goes inactive LOW), MPX goes HIGH for 320ns and the upper nibble of the data set for retrieval is output by the keyboard on KD[3:0], which is valid 20ns after the MPX rising edge. The data is then read by the mainboard within the remaining 300ns before MPX goes LOW. When MPX goes LOW the lower
|
||||
nibble of the data set for retrieval is output on KD[3:0] with the same 320ns timing interval. After 320ns RTSN will then rise again.
|
||||
5. If a key is being pressed, switch to key data retrieval mode else repeat the above in a loop.
|
||||
|
||||
The signals can be visualised by the following logic analyzer diagrams below:
|
||||
|
||||

|
||||
|
||||
During inactivity, the gatearray on the mainboard sends a STROBEALL command, this is recognised by KD4 being LOW, the ROW, which is sent, isn't taken into consideration as the data returned is the logical AND of all keys in a given column across all rows.
|
||||
|
||||

|
||||
|
||||
When a key is pressed, detected by the STROBEALL, KD4 goes high and the mainboard starts probing the keyboard to determine which key was pressed. It starts by sending a request to return column data for Row 11, this row contains the special keys, CTRL, SHIFT, LOCK, KANA, GRAPH.
|
||||
|
||||

|
||||
|
||||
Scan of Row 11 takes place for around 30us, I believe this is to cater for switch bounce.
|
||||
|
||||

|
||||
|
||||
After probe of Row 11 it switches to Row 12 which contains the Japanese Transform keys. This can be seen on the left of the image, the wide RTSN pulse, look at the KD[3:0] values below and it will read 12 in binary. Row 12 is then scanned for around 50us.
|
||||
|
||||

|
||||
|
||||
Once row 11 and 12 have been probed, the mainboard commences a sequential scan of all the rows, starting at row 0, looking for the pressed key. Again look at the wide RTSN signal pulse and you will notice KD[3:0] incrementing.
|
||||
|
||||

|
||||
|
||||
The sequential scan continues until it locates the pressed key, which in this case is 'C' on Row 4 Column 3. The row is scanned for more than 600us to determine key bounce. The sequential scan of the remaining rows then continues and then it repeats from row 0 until the key is released.
|
||||
|
||||
The hardware used by the MZ-2500 can be seen in the following two circuits.
|
||||
|
||||

|
||||
|
||||
This schematic represents the keyboard circuitry which is composed of a gate array (or custom MCU, the part number doesn't reveal the type of device) and a bi-directional buffer. The gate array receives the row from the main unit and applies it to
|
||||
the keyboard strobe outputs. The key data is then read and returned under control of the MPX signal.
|
||||
|
||||

|
||||
|
||||
This schematic represents the main unit circuitry which comprises a gate array connected to the Z-80B PIO, which like the MZ-2000/80B expects to output a strobe row and read back an 8 bit value. The gate array appears to buffer the keyboard matrix internally
|
||||
so that Z80B PIO requests are acted on immediately. In order to do this, the gate array sends out a row number, 0 .. 13 and receives 8bit block of data, in 2 nibbles from the keyboard. It does this continuously, regardless of what the main computer is doing.
|
||||
|
||||
|
||||
|
||||
## <font style="color: yellow;" size="6">MZ-2800 Keyboard Protocol</font>
|
||||
|
||||
The MZ-2800 is the successor to the MZ-2500 and its design incorporates an 8 bit Z80 based MZ-2500 mode and a 16bit 80286 mode which can run MS-DOS and other 16bit 80x86 based programs. Like the MZ-2500, the keyboard hardware
|
||||
interface comprises of 7 signals, 5V and GND but uses an obsolete AMP 9 pin USB style connector in a D-Sub housing. I have searched high and low for this connector or specifications on it but cannot find anything useful.
|
||||
|
||||
On the MZ-2800 motherboard is a standard low profile board to board 9 pin header which has the signals below, this is fed to a daughter board on which the AMP socket is mounted and then screwed to the outside casing. As I don't believe in hacking vintage equipment I searched for an alternative
|
||||
and found one (currently under development, which will appear here when proof tested), which uses a D-Sub with the same dimensions as the AMP connector so will screw onto the casing panel and will be a drop in replacement for the existing AMP connector. This solution means that should you ever be lucky
|
||||
enough to buy a real MZ-2800 keyboard, you can revert very quickly to the original AMP connector.
|
||||
|
||||
A recap of the signals are in the table below. They are identical physically to the MZ-2500.
|
||||
|
||||
<div style="text-align: justify">
|
||||
RTSN, KD4, MPX are output signals from the main unit side. KD [3:0] is a bidirectional bus between the main unit and the keyboard, direction under main unit control using RTSN.
|
||||
<br><br>
|
||||
</div>
|
||||
|
||||
| Signal | Direction | Logic State | Description |
|
||||
| ------ | --------- | ----------- | ----------- |
|
||||
| RTSN <br>Row Strobe | Main Unit -> Keyboard | HIGH ('1') | A Row address is being transmitted from the main unit to the keyboard. |
|
||||
| | | LOW ('0') | The keyboard is transmitting requested data over the 4 bit bidirectional bus KD[3:0]. |
|
||||
| KD4<br>Type Strobe | Main Unit -> Keyboard | HIGH ('1') | The keyboard must return the actual key matrix data as referenced by the Row number. |
|
||||
| | | LOW ('0') | The keyboard must return a logical AND of all the keys, ie. D0 = AND of bit 0 on ROWS 0 to 13, D1 = AND of bit 1 on ROWS 0 to 13 etc.|
|
||||
| MPX<br>Nibble MUX Strobe | Main Unit -> Keyboard | HIGH ('1') | The upper nibble of the requested ROW (or AND of row data as directed by KD4) is sent from the keyboard to the main unit. |
|
||||
| | | LOW ('0') | The lower nibble of the requested ROW (or AND of row data as directed by KD4) is sent from the keyboard to the main unit. |
|
||||
| KD[3:0]<br>Bi-dir bus | Main Unit -> Keyboard | | Active when RTSN = HIGH ('1'), transmits the 4 bit row number of the row data from the keyboard matrix. |
|
||||
| | Keyboard -> Main Unit | | Active when RTSN = LOW ('0'), transmits 4 bits of the 8 bit column data of the requested row. 4 bits is selected by KD4 & MPX. |
|
||||
|
||||
The protocol for the MZ-2800, although sharing the same physical signals as the MZ-2500, is a bit different, primarily timing. The same basic principles apply, ie. RTSN goes HIGH then a row number is sent to the keyboard, RTSN goes LOW then keyboard STROBEALL or data is returned. The essential difference is timing
|
||||
and the way the protocol is used to probe keys.
|
||||
|
||||
The primary protocol in both STROBEALL and key data retrieval modes is the same:
|
||||
1. RTSN goes active HIGH, the mainboard sends a scan row to the keyboard.
|
||||
2. Wait at least 200ns after RTSN goes active before sampling KD4 - KD4 trails RTSN
|
||||
3. Wait at least 650ns after RTSN goes active before reading ROW - KD[3:0] significantly trails RTSN.
|
||||
4. The scan row is read from KD[3:0]. In STROBEALL mode, as per the MZ-2500, the row repeats ad-infinitum with a constant value of 4 and doesn't appear to be used.
|
||||
5. KD4 is sampled, when LOW the logical AND of all keys per column is set for retrieval, when HIGH the actual column of the selected row is set for retrieval.
|
||||
6. Wait for RTSN to go inactive LOW.
|
||||
7. When MPX = HIGH the upper nibble of the data set for retrieval is output by the keyboard on KD[3:0] and read by the mainboard. When MPX = LOW the lower
|
||||
nibble of the data set for retrieval is output on KD[3:0]. MPX has the same period as the MZ-2500, ie. 640ns, 320ns active HIGH and 320ns LOW.
|
||||
8. The above repeats, the row sent can vary or remain static, for example if reading the same key to determine bounce or repeat.
|
||||
|
||||
|
||||

|
||||
|
||||
STROBEALL mode, the mainboard is waiting for a key to be pressed so it holds KD4 LOW. The row sent in this diagram is row 0 but it has no obvious purpose as STROBEALL mode logically AND's all rows for a given column together.
|
||||
|
||||

|
||||
|
||||
Once a key has been pressed, the mode changes to key retrieval mode. KD4 goes HIGH and the mainboard starts sending valid row numbers to retrieve column data. As per the MZ-2500, row 11 is interrogated first followed by row 12 and then a sequential sweep from row 0 occurs.
|
||||
|
||||

|
||||
|
||||
The timing delay between RTSN going active and row data being available can be seen in this diagram. Unfortunately I seem to have mislaid the timing diagram showing KD4 trailing RTSN, next time I rig up the logic analyser I will snapshot it.
|
||||
|
||||

|
||||
|
||||
The sequential scan can be seen in the image above.
|
||||
|
||||

|
||||
|
||||
The sequential scan can be seen here. When the scan reaches the row of the pressed key ('C' - row 4 column 3) the same row is read for 100us to cater for debounce before the scan continues.
|
||||
|
||||

|
||||
|
||||
The sequential scan repeats whilst a key is being held down. When the scan arrives at the pressed key a second time it sans for over 300us before proceeding (NB. Key 'A' pressed in example above).
|
||||
|
||||

|
||||
|
||||
A full cycle, where a key press is detected until the moment it is released.
|
||||
|
||||

|
||||
|
||||
One of the differences between the MZ-2800 keyboard and the MZ-2500 keyboard is the addition of a 14th row, scan of which can be seen above. On the MZ-2800 in MZ-2500 mode, row 14 isn't scanned, it is only scanned when in MZ-2800 mode.
|
||||
|
||||
The hardware used by the MZ-2800 can be seen in the following two circuits.
|
||||
|
||||

|
||||
|
||||
This schematic represents the keyboard circuitry which is composed of a gate array (or custom MCU, the part number doesn't reveal the type of device) and a bi-directional buffer. The gate array receives the row from the main unit and applies it to
|
||||
the keyboard strobe outputs. The key data is then read and returned under control of the MPX signal.
|
||||
|
||||

|
||||
|
||||
This schematic represents the main unit circuitry which comprises a gate array connected to the Z-80B PIO, which expects to output a strobe row and read back an 8 bit value. The gate array appears to buffer the keyboard matrix internally
|
||||
so that Z80B PIO requests are acted on immediately. In order to do this, the gate array sends out a row number, 0 .. 14 (13 in MZ-2500 mode) and receives 8bit block of data, in 2 nibbles from the keyboard. It does this continuously, regardless of what the main computer is doing.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
## <font style="color: yellow;" size="6">ESP-32S AI Thinker</font>
|
||||
|
||||
<div style="text-align: justify">
|
||||
Understanding in more depth what was required I contemplated adding a 4 bit latch to the R8C along with the already included 74LS257 2-1 Quad multiplexer, this would solve part of the problem responding to the RTSN signal to latch the row and
|
||||
outputting 2 nibbles under MPX control, the short coming was GPIO bits available (8 data out, 4 data in, 3 control in) and also the latency of the interrupt could not meet the virtual matrix to data output timing.
|
||||
<br><br>
|
||||
|
||||
Looking at some of my evaluation boards, I started to venture on using a Gowin G1WN-4NSR FPGA, the best solution as everything would be done in hardware with finite state machines and no restrictions to meeting the tight MZ-2500 timing as I would be working
|
||||
at gate level not microcoded CPU instructions. The G1WN-4NSR also embeds an ARM Cortex-M3 which could have been used for configurable mapping. Unfortunately I was having a lot of issues programming the device from a Virtual Linux Machine running on a Mac
|
||||
and with no native Mac support I had to give up on the idea.
|
||||
<br><br>
|
||||
|
||||
A few years back I tinkered with the ESP-8266 from Espressif and closely followed the development of its 32bit product, the ESP-32. I bought 5 sample units from AI Thinker (ESP-32S WROOM) two years back intending to use them with my tranZPUter project but for various
|
||||
reasons I ended up using the ARM Cortex-M4 from NXP. The ESP-32's thus lay idle, until now, a case of a solution looking for a problem and one had been found, a PS/2 to MZ-2500 interface! Digging out and reading the data sheet, looking at available hardware and software resources such as
|
||||
libraries (ie. PS/2) and the development eco system, the ESP-32 seemed to fit the requirements of this project. It had a rich library and development system through use of the Arduino platform and also its own CMake/Ninja IDF build environment. I initially looked at using Arduino
|
||||
as it has a lot more libraries but after a while it became obvious Arduino was a limitation in that I needed to dedicate one CPU core to the MZ-2500 side of the interface whilst the second core serviced the PS/2 keyboard in order to meet required timings. The setup of FreeRTOS under Arduino
|
||||
didn't easily allow for detaching a core (using FreeRTOS spinlock or disabling interrupts within a core and setting FreeRTOS to not schedule tasks on a core didn't work). I spent quite a bit of time looking for a solution and eventually decided to use a more native FreeRTOS environment which was
|
||||
offered by Espressif using FreeRTOS and a lot of their own support libraries under the CMake/Ninja build system. Having worked with CMake/Ninja n the past, including the Linux Kernel build environment, I felt right at home and decided to progress on this path. A few configurations later,
|
||||
one core was detached from FreeRTOS (using a spinlock) running a permanent tight loop to manage the MZ-2500 interface whilst the other core read PS/2 codes and assembled a virtual matrix. After all this analysis and investigation, the decision was made to base the interface on an ESP-32S dual core
|
||||
SoC using FreeRTOS under Espressif's development eco system.
|
||||
<br><br>
|
||||
Next decision, how should the interface be constructed? The solution immediately became apparent after building several of Martin's @ 8bity.cz X68000 interfaces. I would use a KM-24 case, small compact and neat.
|
||||
A quick mockup of an ESP-32S and some other components on an unused X68000 board, it all seemed to fit into a KM-24 case, so started the actual prototype design!
|
||||
</div>
|
||||
|
||||
## <font style="color: yellow;" size="6">Schematic</font>
|
||||
|
||||
<div style="text-align: justify">
|
||||
Reading up on the ESP-32S from AI Thinker I soon pieced together a potential circuit using reference designs as a starting point, I then made required changes, assembled a prototype, tested it and two revisions later settled on the final circuit below.
|
||||
</div>
|
||||
|
||||

|
||||
|
||||
<div style="text-align: justify">
|
||||
The design is based around the ESP-32S WROOM which is a dual core 240MHz WiFi/BT enabled SoC requiring minimal support components to operate.
|
||||
<br><br>
|
||||
|
||||
The device is 5V tolerant but operates at 3.3V, so the obvious choice for the PSU, having used them for the tranZPUter and had plenty in stock, was
|
||||
the AMS1117 3.3v converter. It is relatively efficient, only dropping 1.1v at approx 30mA (150mA if the WiFi mode is enabled) and supplies a stabilised low ripple output. Under normal conditions the device would be powered from the MZ-2500 keyboard interface but on occasion it will need
|
||||
to be connected to a programming interface. In order to avoid 'mistakes', connecting the MZ-2500 and programming interface simultaneously, rectifier diodes are used to isolate the two power sources. A fuse is also used to protect the MZ-2500 should something go faulty or a short occur during
|
||||
development and probing.
|
||||
<br><br>
|
||||
|
||||
The programming interface is very simplistic (no convoluted ARM Cortex programming here), two serial wires from a 3.3/5V UART. In order to work seamlessly with the Espressif IDF build and programming system, an automated bootstrap circuit (Q1A/B) is added and driven by RTS/DTR, this allows the build system
|
||||
to place the ESP-32S into programming mode, program it and then force a reset. Makes for very easy development, CI/CD eat your heart out!!!
|
||||
<br><br>
|
||||
|
||||
The PS/2 interface is a standard design used in Espressif solutions. 2 bi-directional pins driving a PS/2 keyboard with a protocol similar to I2C. The ESP32 can sink/source sufficient current to meet the PS/2 specifications without need for additional transistors.
|
||||
<br><br>
|
||||
|
||||
As the timing of the MZ-2500 interface is time critical and 2 nibbles need to be delivered 300ns apart, I thought it prudent to drive out a byte from the ESP32 into a 2-1 multiplexer under control of the MZ-2500, so the timing requirements were lessened. On detection of the RTSN signal going high
|
||||
the ESP32 would read in the row number, lookup the matrix value (built up from incoming PS/2 keys) and output a byte to the mux. Resistors are added on all the MZ-2500 signals to limit current and reduce line reflection.
|
||||
<br><br>
|
||||
|
||||
Given the potential power of the ESP32 I added an additional switch to allow enabling of the onboard WiFi transceiver. Normally this would be powered down to conserve power and to prevent interference but I have the intention to allow this device to be configured OTA. Under normal circumstances, if I find
|
||||
a key mapping which hasn't been configured then it is a quick fix by editing the source and recompiling, but it would be nice to be able to change a key mapping via a web browser.
|
||||
<br><br>
|
||||
|
||||
The beauty of this ESP-32 design is it could quite easily be used for other machines, ie. X1 or X68000 as 5 bidirectional signals and 1 input provide the option, with a different cable and firmware, of driving these machines.
|
||||
<br><br>
|
||||
If the interface is constructed for an MZ-2800 then the cable end differs, on an MZ-2500 it is an 8pin mini-din whereas on the MZ-2800 with the alternative connector, it is a D-sub connector.
|
||||
</div>
|
||||
|
||||
## <font style="color: yellow;" size="6">PCB</font>
|
||||
|
||||
Having prototyped the designed circuit and written the majority of its control software, I set about designing the PCB. It had to be small to fit inside a KM24 case and given the number of components and size, both sides of the PCB needed to be used.
|
||||
|
||||

|
||||
|
||||
The finished circuit board which went into fabrication.
|
||||

|
||||

|
||||
|
||||
|
||||
## <font style="color: yellow;" size="6">Assembled Interface</font>
|
||||
|
||||
The pictures below highlight the completed, assembled and working interface.
|
||||
|
||||

|
||||
Top side of the interface, there are some optional components installed such as the 2mm pin headers, the 8pin programming interface is needed but the 9pin MZ2500 interface header can see the cable directly soldered to the board. There are optional 1.27mm headers for manual RESET and Programming (PGM)
|
||||
modes but these arent needed under normal use (unless you use a UART without DTR/RTS in which case they are needed).
|
||||
|
||||

|
||||
The underside of the interface, the ESP32 takes up most of the space. What looks like solder bridges on some of the pins is actually the ABS plastic from the case as I test assembled it before cleaning the drilled case!
|
||||
|
||||

|
||||
Installation inside a KM-24 case, tight fit and the case cutouts could be more professional (hint to diary, need more tools!).
|
||||
|
||||

|
||||
By using pin headers it is possible to disconnect the pre-made 8pin mini din cable, either to change it (for example to an MZ-2800 cable) or develop the firmware to drive another machine, ie. the X1. The X1 only needs GND, 5V and 1 bi-directional pin so would work well.
|
||||
|
||||

|
||||
The programming harness. This comprises a generic USB to TTL UART adapter, an optional OLED display to output the current key matrix and the 2mm header to plug into the interface.
|
||||
|
||||

|
||||

|
||||
Finished product, ready to be used with an MZ-2500. I am still looking at options for the MZ-2800 as the interface works but the strange AMP 9 pin socket can no longer be sourced so need to think of a non-destructive solution, perhaps change the socket on the MZ-2800 for an 8pin mini din.
|
||||
|
||||

|
||||
The interface connected to my MZ-2500 during development. The OLED screen is used to display the virtual key matrix.
|
||||
|
||||

|
||||
The completed interface connected to my MZ-2500.
|
||||
|
||||
|
||||
## <font style="color: yellow;" size="6">Assembled MZ-2800 Interface</font>
|
||||
|
||||
The MZ-2800 as shown earlier uses what appears to be the same hardware interface as the MZ-2500 but the protocol and its associated timing is different. The MZ-2800 also used a different keyboard plug and socket, instead of the 8pin mini-din chosen on the
|
||||
MZ-2500, Sharp decided to use a chunkier AMP 9 pin D-Sub plug and socket, presumably to make it sturdier. Unfortunately the 9pin AMP D-Sub went the way of the Dodo and can no longer be sourced, at least from all the major vendors and also ebay! This required sourcing
|
||||
an alternative, bodging wasn't an option, ie. hacking wires onto the mainboard to circumvent the connector.
|
||||
|
||||

|
||||
The MZ-2800 used a 9 pin AMP socket which is no longer available so an alternative had to be found. Also the mainboard JST header into which the leads from the AMP connector plug is no longer available. The mainboard 9pin male header uses spade terminals whereas JST now only seem
|
||||
to sell connectors with the more standard square needle terminals. The solution is to replace the mainboard 9pin header (CN1) with a JST XH2.50mm which has the advantage of still working with the original AMP socket as the square pins fit into the spade receptacles on the AMP daughter board plug.
|
||||
|
||||

|
||||
A look through various parts catalogues located a compatible socket and plug made by 3M, namely 10120-6000L plug and 10220-5212PL socket. These are 20 pin devices but with the exact dimensions to fit and mount onto the MZ-2800 casing. The socket was wired up to a JH 9pin header socket
|
||||
allowing the assembly to replace the original.
|
||||
|
||||

|
||||
The socket fits perfectly into the case, the new socket being threaded made the job easier, just two screws to fasten it onto the case wall. The short leads of the assembly connect into the CN1 mainboard header socket.
|
||||
|
||||

|
||||
The socket on the case exterior, just need to make up the interface and plug.
|
||||
|
||||

|
||||
Taking an MZ25KEY interface, a short length of ribbon cable and an IDC plug, the MZ-2800 interface was finally assembled. The firmware loaded into the interface is specific to the MZ-2800.
|
||||
|
||||

|
||||
The underside of the interface.
|
||||
|
||||

|
||||
A one eyed mouse with a snake head?
|
||||
|
||||

|
||||
Testing, the PS/2 keyboard plugs into the interface and the interface then plugs into the MZ-2800.
|
||||
|
||||

|
||||
Job done!
|
||||
|
||||
## <font style="color: yellow;" size="6">Firmware</font>
|
||||
|
||||
The firmware is written under the Espressif IDF build system comprising of gcc(++) git, CMake and Ninja. The build system works under Windows, Linux or MacOS but in this instance, Linux was used. It has the Arduino compatibility component installed as the PS/2 Library was originally written for Arduino. The firmware is written in a mix of C and C++ with C++ being the primary language.
|
||||
|
||||
### <font style="color: yellow;" size="5">Firmware installation</font>
|
||||
|
||||
Use git clone to pull the software repository onto your computer.
|
||||
|
||||
```
|
||||
git clone https://git.eaw.app/eaw/mz25key.git
|
||||
```
|
||||
|
||||
### <font style="color: yellow;" size="5">Build System Installation</font>
|
||||
|
||||
To create an Espressif IDF build system, follow the guides from Espressif as follows:
|
||||
|
||||
1. Ensure you have python v3.7 or higher installed. Once installed, use 'update-alternatives' to select the latest version as the primary interpreter, some Linux installations default to the older universal version of Python, v2.7.
|
||||
2. Install the Espressif repository using this [guide.](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/get-started/) Be sure to either install v4.4 with the '-b v4.4' flag on 'git clone'
|
||||
or use 'git checkout' after clone. v4.4 is needed for Arduino compatibility module support. If you install the IDF for system wide use, ensure write settings are changed so that your user, not root,
|
||||
has write access for the next step.
|
||||
3. Install the Espressif Arduino compatibility module support using this [guide.](https://docs.espressif.com/projects/arduino-esp32/en/latest/esp-idf_component.html). Do this under your own user id or the one
|
||||
you will develop with and in the mz25key directory cloned earlier where you will compile the mz25key interface firmware.
|
||||
|
||||
### <font style="color: yellow;" size="5">Firmware compilation</font>
|
||||
|
||||
After pulling the repository from git and installing the Espressif IDF you will need to configure the project. A KConfig file, 'sdkconfig' is included with the firmware but you may want to change some of the options. This can be accomplished by the command:
|
||||
|
||||
```
|
||||
idf.py menuconfig
|
||||
```
|
||||
|
||||
This will lead to a set of menus as highlighted in the images below.
|
||||
|
||||

|
||||
|
||||
The root screen allows to configure various aspects of the Espressif IDF installation, the compiler, ESP32, FreeRTOS settings etc. Many settings can be changed but for the interface, the 'MZ25Key Configuration' option should be selected.
|
||||
|
||||

|
||||
|
||||
You have the option to configure the PS/2 Keyboard interface, the MZ-2500/2800 interface, Wifi and Debug options.
|
||||
|
||||

|
||||
|
||||
In the PS/2 configuration, you can set the GPIO pins used for the interface, unless you have built your own board and used different GPIO's these don't need changing.
|
||||
|
||||

|
||||
|
||||
The other option to select under the PS/2 menu is the type of keyboard mapping, currently there is only the mapping for a Wyse KB-3926 keyboard.
|
||||
|
||||

|
||||
|
||||
Under the MZ-2500/2800 Interface menu, you can select the target machine (MZ-2500 or MZ-2800) and also configure the GPIO's used for strobe input, scan data output and the RTSN/KDI4 inputs. These don't normally need changing unless building different hardware.
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
|
||||
Under the WiFi menu, currently a work in progress, you can enable the Wifi module and set the various default parameters.
|
||||
|
||||

|
||||
|
||||
Under the debug menu you can enable various debug aids. The OLED screen, if connected, can be useful for outputting real time data. You can also disable various components of the interface for testing.
|
||||
The ESP32, by default, outputs text messages via the serial port, so if a USB to TTL UART adapter is connected to the programming connector, these messages can be viewed. The ESP mechanism includes a logger to output
|
||||
text to the UART.
|
||||
|
||||

|
||||
|
||||
The OLED type needs to be configured. The hardware accommodates an I2C interface and the resolution is 128x64 pixels.
|
||||
|
||||

|
||||

|
||||
|
||||
Once configured, perform a test build via the command:
|
||||
|
||||
```
|
||||
idf.py build
|
||||
```
|
||||
|
||||
If all is successful, connect a USB to TTL UART adapter to your computer and connect it to the mz25key interface programming connector. The wiring is as follows:
|
||||
|
||||

|
||||
|
||||
Obtain the dev port of the USB to TTL UART adapter by looking in /dev for ttyUSB\* devices, normally it would be /dev/ttyUSB0. Perform a full build, flash and monitor via the command:
|
||||
|
||||
```
|
||||
idf.py -p /dev/ttyUSB0 build flash monitor
|
||||
```
|
||||
|
||||
The system will compile the firmware, flash it onto the mz25key interface and run the UART monitor so you can view any messages output. ie:
|
||||
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## <font style="color: yellow;" size="6">Usage</font>
|
||||
|
||||
A keyboard is a keyboard, right? Well, not exactly, especially when one keyboard is pretending to be another!
|
||||
|
||||
A PS/2 keyboard was created for an IBM PC or compatible several years after the advent of an MZ-2500/MZ-2800, also the keyboards I have access to are not Japanese PS/2 units, so several Japanese specific keys are missing. This requires
|
||||
mapping, selecting an unused key on the PS/2 keyboard to pretend to be a Japanese key on an MZ-2500/MZ-2800 keyboard.
|
||||
|
||||
As the MZ-2500/MZ-2800 machines are an office cream colour in appearance and having previously used Wyse keyboards in the past, I opted for a Wyse KB-3926 cream model to best match the MZ. The MZ-2500, MZ-2800 and Wyse KB-3926 keyboards can be seen below and the mapping table, mapping PS/2 keys to MZ-2500
|
||||
keys appears below.
|
||||
|
||||

|
||||
Original Sharp MZ-2500 keyboard.
|
||||
|
||||

|
||||
Original Sharp MZ-2800 keyboard.
|
||||
|
||||

|
||||
Wyse KB-3926 PS/2 keyboard.
|
||||
|
||||
Mapping Table
|
||||
|
||||
| MZ-2500 Key | MZ-2800 Key | PS/2 Key | Description | PS/2 Keyboard |
|
||||
| ----------- | -------- | ----------- | ------------- | ------------- |
|
||||
| LOCK | LOCK\* | Caps Lock | Shifts and locks upper/lower case characters. Press once to lock upper case, LED light comes on, press again to release and return to lower case characters. | Wyse KB-3926 |
|
||||
| HELP | HELP\* | F11 | HELP functionality | |
|
||||
| BREAK | BREAK\* | Pause | BREAK key. PS/2 normally use CTRL+BREAK to generate a BREAK but the MZ-2500 requires SHIFT+BREAK which doesn't yield BREAK, thus a mapping is created for SHIFT+PAUSE (which is also the same key as BREAK) to create an MZ-2500 BREAK. | |
|
||||
| COPY | COPY\* | F12 | COPY functionality | |
|
||||
| CLR | CLR\* | Shift+Home | Clear screen | |
|
||||
| HOME | HOME\* | Home | Set cursor to 0,0 position ie. HOME. | |
|
||||
| INST | INST\* | Insert | Insert characters at cursor position. | |
|
||||
| DEL | DEL\* | Delete | Delete characters from cursor position. | |
|
||||
| ARGO | ARGO | Print Screen | ARGO functionality. ie. Bring up applets menu in BASIC v2 | |
|
||||
| GRAPH | GRAPH | Left GUI | Change to Graphics character entry. | |
|
||||
| Yen | Yen | \|\ | Insert a Yen symbol | |
|
||||
| KANA | KANA | Right GUI | Select KANA functionality. | |
|
||||
| KJ1 Sentence | KJ1 Sentence | Left ALT | KJ1 functionality | |
|
||||
| KJ2 Transform | KJ2 Transform | Right ALT | KJ2 functionality | |
|
||||
| | PREVIOUS\* | PGDN | Previous Key | |
|
||||
| | CANCEL\* | Right CTRL | Cancel Key | |
|
||||
| | SF1 | | Special Function 1 | Not yet mapped |
|
||||
| | SF2 | | Special Function 2 | Not yet mapped |
|
||||
| | SF3 | | Special Function 3 | Not yet mapped |
|
||||
| | SF4 | | Special Function 4 | Not yet mapped |
|
||||
|
||||
\* = Written in Japanese on the MZ-2800.
|
||||
|
||||
All other keys are as per the symbol on the PS/2 keyboard. The <b>Num Lock</b> key toggles the keypad between numeric and cursor functions. The keyboard mapping passes through modifier keys unless there is an exact map, ie. SHIFT. Thus key combinations not catered for
|
||||
in the ESP32-S mapping table may work, ie. SHIFT+KANA.
|
||||
|
||||
The MZ-2500 can emulate the MZ-2000 and MZ-80B and each machine has slightly different mappings. I'm not sure how the MZ-2500 keyboard got around this as there is no obvious communications protocols sent from the main unit to the keyboard so I'm guessing the gate array
|
||||
on the main unit performs in-situ mapping according to the model mode switch. To cater for this I have placed machine model as a component of the mapping table, normally a key is assigned to all models but when a difference occurs, the difference is tagged to the model accordingly.
|
||||
In order to invoke this functionality it is necessary to press a key combination according to the machine whose mapping you wish to use, listed in the table below.
|
||||
|
||||
| Hot Key | Mode |
|
||||
| ------- | ---- |
|
||||
| ALT+F1 | MZ-2500 Keyboard mapping |
|
||||
| ALT+F2 | MZ-2000 Keyboard mapping |
|
||||
| ALT+F3 | MZ-80B Keyboard mapping |
|
||||
|
||||
On power up, the default mapping is set to MZ-2500.
|
||||
|
||||
The PS/2 keyboard can be connected/disconnected from the interface whilst the MZ-2500/MZ-2800 is powered up, likewise the interface from the MZ-2500/MZ-2800. The reservoir capacitors on the AMS1117-3.3 are larger than needed to cater for sudden power drops as the keyboard is plugged in. The software checks
|
||||
every second for the presence of a keyboard and should it be unplugged, performs a re-initialisation and check in anticipation of the keyboard being plugged back in.
|
||||
|
||||
<u>WiFi</u>
|
||||
|
||||
<div style="text-align: justify">
|
||||
The WiFi functionality is currently under development. It will offer a web based interface similar to most IoT devices. Pushing the WiFi button for 1 second enables WiFi, for 10 seconds enables Access Point mode. If the unit hasn't been configured then on first press Access Point mode will
|
||||
be enabled by default.
|
||||
<br><br>
|
||||
|
||||
Access Point mode allows a user to connect to the interface as a client, invoke a web browser and setup the credentials to allow the interface to connect to a local WiFi router (ie. local net).
|
||||
<br><br>
|
||||
|
||||
Once configured, enabling WiFi mode will automatically join with the configured local Wifi network and present a browser interface for key map configuration.
|
||||
</div>
|
||||
|
||||
## <font style="color: yellow;" size="6">Pricing</font>
|
||||
|
||||
<div style="text-align: justify">
|
||||
The tables below shows the parts and the cost. The prices are based on purchasing at least 10 of each component as some parts are not sold individually or are more expensive as a one off. You may be able to buy some parts cheaper from China or miss out things
|
||||
like the 9pin 2.00mm header and socket or make up the 8pin mini din connector (connectors are around GBP2 plus wire) but for a 1 off it would almost certainly cost more than the indicated price.
|
||||
<br><br>
|
||||
The PCB boards can be ordered up from any PCB Fab such as pcbway and will cost typically about USD5+USD20 P&P for 10. Ordering 1-10 is the same price, so better to take 10.
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<u>MZ-2500 Interface</u>
|
||||
|
||||
| Part | References | Quantity | Value | Price Each | Price Net | Price Total |
|
||||
| ---- | ------------------------------------ | -------- | ------------------ | ---------- | --------- | ----------- |
|
||||
| 1 | C1, C2 | 2 | 100uF | £0.44 | £0.89 | £0.89 |
|
||||
| 2 | C3, C4 | 2 | 100nF | £0.06 | £0.11 | £0.11 |
|
||||
| 3 | R1, R2, R3, R4, R5, R6, R7, R12, R13 | 9 | 100R | £0.02 | £0.18 | £0.18 |
|
||||
| 4 | R10, R11, R14, R15, R16, R18, R19 | 7 | 10K | £0.02 | £0.14 | £0.14 |
|
||||
| 5 | R8, R9 | 2 | 2K | £0.02 | £0.04 | £0.04 |
|
||||
| 6 | R17 | 1 | 1K | £0.02 | £0.02 | £0.02 |
|
||||
| 7 | D1, D2 | 2 | 1N4001 | £0.26 | £0.53 | £0.53 |
|
||||
| 8 | D3 | 1 | Power | £0.20 | £0.20 | £0.20 |
|
||||
| 9 | U1 | 1 | AMS1117-3.3 | £0.33 | £0.33 | £0.33 |
|
||||
| 10 | U2 | 1 | 74LS257 | £1.00 | £1.00 | £1.00 |
|
||||
| 11 | U3 | 1 | ESP32-S AI Thinker | £2.08 | £2.08 | £2.08 |
|
||||
| 12 | F1 | 1 | 500mA | £0.99 | £0.99 | £0.99 |
|
||||
| 13 | SW1 | 1 | WiFi EN | £0.09 | £0.09 | £0.09 |
|
||||
| 14 | JP1 | 1 | PGM | | £0.00 | £0.00 |
|
||||
| 15 | JP2 | 1 | ~{RESET} | | £0.00 | £0.00 |
|
||||
| 16 | LG1 | 1 | Argo Logo | | £0.00 | £0.00 |
|
||||
| 17 | Q1 | 1 | MMDT3904 | £0.43 | £0.43 | £0.43 |
|
||||
| 18 | J1 | 1 | MZ2500 Keyboard | £0.03 | £0.26 | £0.26 |
|
||||
| 19 | J2 | 1 | PS/2 Keyboard | £1.33 | £1.33 | £1.33 |
|
||||
| 20 | J3 | 1 | PGM/OLED | £0.03 | £0.23 | £0.23 |
|
||||
| 21 | 9 pin 2.0mm DuPont Housing | 1 | 9pin DuPont | £1.32 | £0.33 | £0.33 |
|
||||
| 22 | PCB | 1 | PCB | £2.60 | £2.60 | £2.60 |
|
||||
| 23 | Case KM24 | 1 | KM24 | £2.35 | £2.35 | £2.35 |
|
||||
| 24 | Prefab 8pin mini-din wire | 1 | MZ-2500 Connector | £5.83 | £5.83 | £5.83 |
|
||||
| | Total | | | | £19.96 | £19.96 |
|
||||
|
||||
|
||||
<u>MZ-2800 Interface</u>
|
||||
|
||||
| Part | References | Quantity | Value | Price Each | Price Net | Price Total |
|
||||
| ---- | ------------------------------------ | -------- | ------------------ | ---------- | --------- | ----------- |
|
||||
| 1 | C1, C2 | 2 | 100uF | £0.44 | £0.89 | £0.89 |
|
||||
| 2 | C3, C4 | 2 | 100nF | £0.06 | £0.11 | £0.11 |
|
||||
| 3 | R1, R2, R3, R4, R5, R6, R7, R12, R13 | 9 | 100R | £0.02 | £0.18 | £0.18 |
|
||||
| 4 | R10, R11, R14, R15, R16, R18, R19 | 7 | 10K | £0.02 | £0.14 | £0.14 |
|
||||
| 5 | R8, R9 | 2 | 2K | £0.02 | £0.04 | £0.04 |
|
||||
| 6 | R17 | 1 | 1K | £0.02 | £0.02 | £0.02 |
|
||||
| 7 | D1, D2 | 2 | 1N4001 | £0.26 | £0.53 | £0.53 |
|
||||
| 8 | D3 | 1 | Power | £0.20 | £0.20 | £0.20 |
|
||||
| 9 | U1 | 1 | AMS1117-3.3 | £0.33 | £0.33 | £0.33 |
|
||||
| 10 | U2 | 1 | 74LS257 | £1.00 | £1.00 | £1.00 |
|
||||
| 11 | U3 | 1 | ESP32-S AI Thinker | £2.08 | £2.08 | £2.08 |
|
||||
| 12 | F1 | 1 | 500mA | £0.99 | £0.99 | £0.99 |
|
||||
| 13 | SW1 | 1 | WiFi EN | £0.09 | £0.09 | £0.09 |
|
||||
| 14 | JP1 | 1 | PGM | | £0.00 | £0.00 |
|
||||
| 15 | JP2 | 1 | ~{RESET} | | £0.00 | £0.00 |
|
||||
| 16 | LG1 | 1 | Argo Logo | | £0.00 | £0.00 |
|
||||
| 17 | Q1 | 1 | MMDT3904 | £0.43 | £0.43 | £0.43 |
|
||||
| 18 | J1 | 1 | MZ2500 Keyboard | £0.03 | £0.26 | £0.26 |
|
||||
| 19 | J2 | 1 | PS/2 Keyboard | £1.33 | £1.33 | £1.33 |
|
||||
| 20 | J3 | 1 | PGM/OLED | £0.03 | £0.23 | £0.23 |
|
||||
| 21 | 9 pin 2.0mm DuPont Housing | 1 | 9pin DuPont | £1.32 | £0.33 | £0.33 |
|
||||
| 22 | PCB | 1 | PCB | £2.60 | £2.60 | £2.60 |
|
||||
| 23 | Case KM24 | 1 | KM24 | £2.35 | £2.35 | £2.35 |
|
||||
| 24 | Host side Plug | 1 | 3M 10120-6000EL Plug | £3.90 | £3.90 | £3.90 |
|
||||
| 25 | Host side plug hood | 1 | 3M 10320-3210-000 Hood | £5.14 | £5.14 | £5.14 |
|
||||
| 26 | Main unit Replacement Socket | 1 | 3M 10220-5212PL Socket | £3.86 | £3.86 | £3.86 |
|
||||
| 27 | Main unit replacement 9pin header and socket | 1 | JST XH2.50mm 9 way | $2.68 | £2.68 | £2.68 |
|
||||
| | Total | | | | £29.71 | £29.71 |
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
## <font style="color: yellow;" size="6">Credits</font>
|
||||
|
||||
<div style="text-align: justify">
|
||||
Espressif IDF development environment and use of the ESP-32S reference material was used in the design of this keyboard interface.
|
||||
</div>
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
## <font style="color: yellow;" size="6">Licenses</font>
|
||||
|
||||
<div style="text-align: justify">
|
||||
This design, hardware and software, is licensed under the GNU Public Licence v3.
|
||||
<br><br>
|
||||
No commercial use to be made of this design or any hardware/firmware component without express permission from the author. This condition overrides
|
||||
any rights afforded by the GNU GPL 3 license.
|
||||
</div>
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
### <font style="color: yellow;" size="5">The Gnu Public License v3</font>
|
||||
|
||||
<div style="text-align: justify">
|
||||
The source and binary files in this project marked as GPL v3 are 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.
|
||||
<br><br>
|
||||
|
||||
The source files are 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.
|
||||
<br><br>
|
||||
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
</div>
|
||||
63
build_webfs.sh
Executable file
63
build_webfs.sh
Executable file
@@ -0,0 +1,63 @@
|
||||
#!/bin/bash
|
||||
|
||||
SRCDIR=`pwd`/webserver
|
||||
WEBFSDIR=`pwd`/webfs
|
||||
echo "Building into:$WEBFSDIR from $SRCDIR..."
|
||||
|
||||
mkdir -p webfs/css
|
||||
mkdir -p webfs/js
|
||||
mkdir -p webfs/font-awesome
|
||||
mkdir -p webfs/font-awesome/css
|
||||
mkdir -p webfs/font-awesome/fonts
|
||||
mkdir -p webfs/images
|
||||
|
||||
(cd ${SRCDIR}/;
|
||||
cp favicon.ico ${WEBFSDIR}/
|
||||
cp version.txt ${WEBFSDIR}/
|
||||
cp index.html ${WEBFSDIR}/
|
||||
cp keymap.html ${WEBFSDIR}/keymap.html
|
||||
cp mouse.html ${WEBFSDIR}/mouse.html
|
||||
cp ota.html ${WEBFSDIR}/ota.html
|
||||
cp wifimanager.html ${WEBFSDIR}/wifimanager.html
|
||||
|
||||
|
||||
(cd ${SRCDIR}/css;
|
||||
cp bootstrap.min.css.gz ${WEBFSDIR}/css/
|
||||
gzip -c jquery.edittable.min.css > ${WEBFSDIR}/css/jquery.edittable.min.css.gz
|
||||
gzip -c sb-admin.css > ${WEBFSDIR}/css/sb-admin.css.gz
|
||||
gzip -c sharpkey.css > ${WEBFSDIR}/css/sharpkey.css.gz
|
||||
gzip -c style.css > ${WEBFSDIR}/css/style.css.gz
|
||||
gzip -c styles.css > ${WEBFSDIR}/css/styles.css.gz
|
||||
)
|
||||
|
||||
(cd ${SRCDIR}/font-awesome
|
||||
)
|
||||
|
||||
(cd ${SRCDIR}/font-awesome/css
|
||||
#cp font-awesome.min.css.gz ${WEBFSDIR}/font-awesome/css/
|
||||
gzip -c font-awesome.css > ${WEBFSDIR}/font-awesome/css/font-awesome.min.css.gz
|
||||
)
|
||||
|
||||
(cd ${SRCDIR}/font-awesome/fonts
|
||||
gzip -c fontawesome-webfont.woff > ${WEBFSDIR}/font-awesome/fonts/fontawesome-webfont.woff.gz
|
||||
#cp fontawesome-webfont.ttf.gz ${WEBFSDIR}/font-awesome/fonts/
|
||||
#cp fontawesome-webfont.woff.gz ${WEBFSDIR}/font-awesome/fonts/
|
||||
)
|
||||
|
||||
(cd ${SRCDIR}/images;
|
||||
)
|
||||
|
||||
(cd ${SRCDIR}/js;
|
||||
cp 140medley.min.js ${WEBFSDIR}/js/
|
||||
cp bootstrap.min.js.gz ${WEBFSDIR}/js/
|
||||
gzip -c index.js > ${WEBFSDIR}/js/index.js.gz
|
||||
gzip -c jquery.edittable.js > ${WEBFSDIR}/js/jquery.edittable.js.gz
|
||||
gzip -c jquery.edittable.min.js > ${WEBFSDIR}/js/jquery.edittable.min.j.gz
|
||||
cp jquery.min.js.gz ${WEBFSDIR}/js/
|
||||
gzip -c keymap.js > ${WEBFSDIR}/js/keymap.js.gz
|
||||
gzip -c mouse.js > ${WEBFSDIR}/js/mouse.js.gz
|
||||
gzip -c ota.js > ${WEBFSDIR}/js/ota.js.gz
|
||||
gzip -c wifimanager.js > ${WEBFSDIR}/js/wifimanager.js.gz
|
||||
)
|
||||
|
||||
)
|
||||
10594
docs/OMOTON_K8508.pdf
Normal file
10594
docs/OMOTON_K8508.pdf
Normal file
File diff suppressed because one or more lines are too long
BIN
docs/PERIBOARD-810.pdf
Normal file
BIN
docs/PERIBOARD-810.pdf
Normal file
Binary file not shown.
BIN
docs/PERIBOARD-810_Intl.pdf
Normal file
BIN
docs/PERIBOARD-810_Intl.pdf
Normal file
Binary file not shown.
BIN
docs/PS2_Mouse.pdf
Normal file
BIN
docs/PS2_Mouse.pdf
Normal file
Binary file not shown.
BIN
docs/Sanwa_SKB-L1_Keyboard.pdf
Normal file
BIN
docs/Sanwa_SKB-L1_Keyboard.pdf
Normal file
Binary file not shown.
6148
kicad/Output/v1.2/mz25key-B_Cu.gbr
Normal file
6148
kicad/Output/v1.2/mz25key-B_Cu.gbr
Normal file
File diff suppressed because it is too large
Load Diff
3688
kicad/Output/v1.2/mz25key-B_Mask.gbr
Normal file
3688
kicad/Output/v1.2/mz25key-B_Mask.gbr
Normal file
File diff suppressed because it is too large
Load Diff
1438
kicad/Output/v1.2/mz25key-B_Paste.gbr
Normal file
1438
kicad/Output/v1.2/mz25key-B_Paste.gbr
Normal file
File diff suppressed because it is too large
Load Diff
762
kicad/Output/v1.2/mz25key-B_SilkS.gbr
Normal file
762
kicad/Output/v1.2/mz25key-B_SilkS.gbr
Normal file
@@ -0,0 +1,762 @@
|
||||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,(5.1.2-1)-1*
|
||||
G04 #@! TF.CreationDate,2022-01-26T01:19:45+00:00*
|
||||
G04 #@! TF.ProjectId,mz25key,6d7a3235-6b65-4792-9e6b-696361645f70,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Legend,Bot*
|
||||
G04 #@! TF.FilePolarity,Positive*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW (5.1.2-1)-1) date 2022-01-26 01:19:45*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G04 APERTURE LIST*
|
||||
%ADD10C,0.120000*%
|
||||
%ADD11C,0.200000*%
|
||||
%ADD12C,0.150000*%
|
||||
%ADD13C,0.500000*%
|
||||
G04 APERTURE END LIST*
|
||||
D10*
|
||||
X71330000Y-83420000D02*
|
||||
X56330000Y-83420000D01*
|
||||
X99160000Y-100300000D02*
|
||||
X99170000Y-86360000D01*
|
||||
X89020000Y-100290000D02*
|
||||
X99160000Y-100300000D01*
|
||||
X89020000Y-86360000D02*
|
||||
X89020000Y-100290000D01*
|
||||
X99170000Y-86360000D02*
|
||||
X89020000Y-86360000D01*
|
||||
X57400000Y-102790000D02*
|
||||
X57400000Y-83790000D01*
|
||||
X54400000Y-102790000D02*
|
||||
X57400000Y-102790000D01*
|
||||
X54400000Y-83800000D02*
|
||||
X54400000Y-102790000D01*
|
||||
X57400000Y-83790000D02*
|
||||
X54400000Y-83800000D01*
|
||||
X54830000Y-80420000D02*
|
||||
X54830000Y-83420000D01*
|
||||
X71330000Y-80420000D02*
|
||||
X54830000Y-80420000D01*
|
||||
X71330000Y-83420000D02*
|
||||
X71330000Y-80420000D01*
|
||||
D11*
|
||||
X79453333Y-86628571D02*
|
||||
X79120000Y-86628571D01*
|
||||
X78977142Y-87152380D02*
|
||||
X79453333Y-87152380D01*
|
||||
X79453333Y-86152380D01*
|
||||
X78977142Y-86152380D01*
|
||||
X78596190Y-87104761D02*
|
||||
X78453333Y-87152380D01*
|
||||
X78215238Y-87152380D01*
|
||||
X78120000Y-87104761D01*
|
||||
X78072380Y-87057142D01*
|
||||
X78024761Y-86961904D01*
|
||||
X78024761Y-86866666D01*
|
||||
X78072380Y-86771428D01*
|
||||
X78120000Y-86723809D01*
|
||||
X78215238Y-86676190D01*
|
||||
X78405714Y-86628571D01*
|
||||
X78500952Y-86580952D01*
|
||||
X78548571Y-86533333D01*
|
||||
X78596190Y-86438095D01*
|
||||
X78596190Y-86342857D01*
|
||||
X78548571Y-86247619D01*
|
||||
X78500952Y-86200000D01*
|
||||
X78405714Y-86152380D01*
|
||||
X78167619Y-86152380D01*
|
||||
X78024761Y-86200000D01*
|
||||
X77596190Y-87152380D02*
|
||||
X77596190Y-86152380D01*
|
||||
X77215238Y-86152380D01*
|
||||
X77120000Y-86200000D01*
|
||||
X77072380Y-86247619D01*
|
||||
X77024761Y-86342857D01*
|
||||
X77024761Y-86485714D01*
|
||||
X77072380Y-86580952D01*
|
||||
X77120000Y-86628571D01*
|
||||
X77215238Y-86676190D01*
|
||||
X77596190Y-86676190D01*
|
||||
X76691428Y-86152380D02*
|
||||
X76072380Y-86152380D01*
|
||||
X76405714Y-86533333D01*
|
||||
X76262857Y-86533333D01*
|
||||
X76167619Y-86580952D01*
|
||||
X76120000Y-86628571D01*
|
||||
X76072380Y-86723809D01*
|
||||
X76072380Y-86961904D01*
|
||||
X76120000Y-87057142D01*
|
||||
X76167619Y-87104761D01*
|
||||
X76262857Y-87152380D01*
|
||||
X76548571Y-87152380D01*
|
||||
X76643809Y-87104761D01*
|
||||
X76691428Y-87057142D01*
|
||||
X75691428Y-86247619D02*
|
||||
X75643809Y-86200000D01*
|
||||
X75548571Y-86152380D01*
|
||||
X75310476Y-86152380D01*
|
||||
X75215238Y-86200000D01*
|
||||
X75167619Y-86247619D01*
|
||||
X75120000Y-86342857D01*
|
||||
X75120000Y-86438095D01*
|
||||
X75167619Y-86580952D01*
|
||||
X75739047Y-87152380D01*
|
||||
X75120000Y-87152380D01*
|
||||
X74691428Y-86771428D02*
|
||||
X73929523Y-86771428D01*
|
||||
X73500952Y-87104761D02*
|
||||
X73358095Y-87152380D01*
|
||||
X73120000Y-87152380D01*
|
||||
X73024761Y-87104761D01*
|
||||
X72977142Y-87057142D01*
|
||||
X72929523Y-86961904D01*
|
||||
X72929523Y-86866666D01*
|
||||
X72977142Y-86771428D01*
|
||||
X73024761Y-86723809D01*
|
||||
X73120000Y-86676190D01*
|
||||
X73310476Y-86628571D01*
|
||||
X73405714Y-86580952D01*
|
||||
X73453333Y-86533333D01*
|
||||
X73500952Y-86438095D01*
|
||||
X73500952Y-86342857D01*
|
||||
X73453333Y-86247619D01*
|
||||
X73405714Y-86200000D01*
|
||||
X73310476Y-86152380D01*
|
||||
X73072380Y-86152380D01*
|
||||
X72929523Y-86200000D01*
|
||||
X71786666Y-86866666D02*
|
||||
X71310476Y-86866666D01*
|
||||
X71881904Y-87152380D02*
|
||||
X71548571Y-86152380D01*
|
||||
X71215238Y-87152380D01*
|
||||
X70881904Y-87152380D02*
|
||||
X70881904Y-86152380D01*
|
||||
X69786666Y-86152380D02*
|
||||
X69215238Y-86152380D01*
|
||||
X69500952Y-87152380D02*
|
||||
X69500952Y-86152380D01*
|
||||
X68881904Y-87152380D02*
|
||||
X68881904Y-86152380D01*
|
||||
X68453333Y-87152380D02*
|
||||
X68453333Y-86628571D01*
|
||||
X68500952Y-86533333D01*
|
||||
X68596190Y-86485714D01*
|
||||
X68739047Y-86485714D01*
|
||||
X68834285Y-86533333D01*
|
||||
X68881904Y-86580952D01*
|
||||
X67977142Y-87152380D02*
|
||||
X67977142Y-86485714D01*
|
||||
X67977142Y-86152380D02*
|
||||
X68024761Y-86200000D01*
|
||||
X67977142Y-86247619D01*
|
||||
X67929523Y-86200000D01*
|
||||
X67977142Y-86152380D01*
|
||||
X67977142Y-86247619D01*
|
||||
X67500952Y-86485714D02*
|
||||
X67500952Y-87152380D01*
|
||||
X67500952Y-86580952D02*
|
||||
X67453333Y-86533333D01*
|
||||
X67358095Y-86485714D01*
|
||||
X67215238Y-86485714D01*
|
||||
X67120000Y-86533333D01*
|
||||
X67072380Y-86628571D01*
|
||||
X67072380Y-87152380D01*
|
||||
X66596190Y-87152380D02*
|
||||
X66596190Y-86152380D01*
|
||||
X66500952Y-86771428D02*
|
||||
X66215238Y-87152380D01*
|
||||
X66215238Y-86485714D02*
|
||||
X66596190Y-86866666D01*
|
||||
X65405714Y-87104761D02*
|
||||
X65500952Y-87152380D01*
|
||||
X65691428Y-87152380D01*
|
||||
X65786666Y-87104761D01*
|
||||
X65834285Y-87009523D01*
|
||||
X65834285Y-86628571D01*
|
||||
X65786666Y-86533333D01*
|
||||
X65691428Y-86485714D01*
|
||||
X65500952Y-86485714D01*
|
||||
X65405714Y-86533333D01*
|
||||
X65358095Y-86628571D01*
|
||||
X65358095Y-86723809D01*
|
||||
X65834285Y-86819047D01*
|
||||
X64929523Y-87152380D02*
|
||||
X64929523Y-86485714D01*
|
||||
X64929523Y-86676190D02*
|
||||
X64881904Y-86580952D01*
|
||||
X64834285Y-86533333D01*
|
||||
X64739047Y-86485714D01*
|
||||
X64643809Y-86485714D01*
|
||||
X74500952Y-88852380D02*
|
||||
X74500952Y-87852380D01*
|
||||
X74167619Y-88566666D01*
|
||||
X73834285Y-87852380D01*
|
||||
X73834285Y-88852380D01*
|
||||
X73215238Y-88852380D02*
|
||||
X73310476Y-88804761D01*
|
||||
X73358095Y-88757142D01*
|
||||
X73405714Y-88661904D01*
|
||||
X73405714Y-88376190D01*
|
||||
X73358095Y-88280952D01*
|
||||
X73310476Y-88233333D01*
|
||||
X73215238Y-88185714D01*
|
||||
X73072380Y-88185714D01*
|
||||
X72977142Y-88233333D01*
|
||||
X72929523Y-88280952D01*
|
||||
X72881904Y-88376190D01*
|
||||
X72881904Y-88661904D01*
|
||||
X72929523Y-88757142D01*
|
||||
X72977142Y-88804761D01*
|
||||
X73072380Y-88852380D01*
|
||||
X73215238Y-88852380D01*
|
||||
X72024761Y-88852380D02*
|
||||
X72024761Y-87852380D01*
|
||||
X72024761Y-88804761D02*
|
||||
X72120000Y-88852380D01*
|
||||
X72310476Y-88852380D01*
|
||||
X72405714Y-88804761D01*
|
||||
X72453333Y-88757142D01*
|
||||
X72500952Y-88661904D01*
|
||||
X72500952Y-88376190D01*
|
||||
X72453333Y-88280952D01*
|
||||
X72405714Y-88233333D01*
|
||||
X72310476Y-88185714D01*
|
||||
X72120000Y-88185714D01*
|
||||
X72024761Y-88233333D01*
|
||||
X71120000Y-88185714D02*
|
||||
X71120000Y-88852380D01*
|
||||
X71548571Y-88185714D02*
|
||||
X71548571Y-88709523D01*
|
||||
X71500952Y-88804761D01*
|
||||
X71405714Y-88852380D01*
|
||||
X71262857Y-88852380D01*
|
||||
X71167619Y-88804761D01*
|
||||
X71120000Y-88757142D01*
|
||||
X70500952Y-88852380D02*
|
||||
X70596190Y-88804761D01*
|
||||
X70643809Y-88709523D01*
|
||||
X70643809Y-87852380D01*
|
||||
X69739047Y-88804761D02*
|
||||
X69834285Y-88852380D01*
|
||||
X70024761Y-88852380D01*
|
||||
X70120000Y-88804761D01*
|
||||
X70167619Y-88709523D01*
|
||||
X70167619Y-88328571D01*
|
||||
X70120000Y-88233333D01*
|
||||
X70024761Y-88185714D01*
|
||||
X69834285Y-88185714D01*
|
||||
X69739047Y-88233333D01*
|
||||
X69691428Y-88328571D01*
|
||||
X69691428Y-88423809D01*
|
||||
X70167619Y-88519047D01*
|
||||
D12*
|
||||
X87730000Y-84220000D02*
|
||||
X87730000Y-102220000D01*
|
||||
X62230000Y-84220000D02*
|
||||
X62230000Y-102220000D01*
|
||||
X87730000Y-84220000D02*
|
||||
X62230000Y-84220000D01*
|
||||
X87730000Y-102220000D02*
|
||||
X62230000Y-102220000D01*
|
||||
X81730000Y-84220000D02*
|
||||
X81730000Y-102220000D01*
|
||||
D13*
|
||||
X81867981Y-103126000D02*
|
||||
G75*
|
||||
G03X81867981Y-103126000I-283981J0D01*
|
||||
G01*
|
||||
D10*
|
||||
X91878578Y-103730000D02*
|
||||
X91361422Y-103730000D01*
|
||||
X91878578Y-102310000D02*
|
||||
X91361422Y-102310000D01*
|
||||
X59508578Y-85300000D02*
|
||||
X58991422Y-85300000D01*
|
||||
X59508578Y-83880000D02*
|
||||
X58991422Y-83880000D01*
|
||||
X91361422Y-100240000D02*
|
||||
X91878578Y-100240000D01*
|
||||
X91361422Y-101660000D02*
|
||||
X91878578Y-101660000D01*
|
||||
X83681422Y-104270000D02*
|
||||
X84198578Y-104270000D01*
|
||||
X83681422Y-105690000D02*
|
||||
X84198578Y-105690000D01*
|
||||
X87040000Y-103410000D02*
|
||||
X88440000Y-103410000D01*
|
||||
X88440000Y-105730000D02*
|
||||
X86540000Y-105730000D01*
|
||||
X91351422Y-104300000D02*
|
||||
X91868578Y-104300000D01*
|
||||
X91351422Y-105720000D02*
|
||||
X91868578Y-105720000D01*
|
||||
X91878578Y-99580000D02*
|
||||
X91361422Y-99580000D01*
|
||||
X91878578Y-98160000D02*
|
||||
X91361422Y-98160000D01*
|
||||
X90998578Y-88140000D02*
|
||||
X90481422Y-88140000D01*
|
||||
X90998578Y-86720000D02*
|
||||
X90481422Y-86720000D01*
|
||||
X91210000Y-93341422D02*
|
||||
X91210000Y-93858578D01*
|
||||
X89790000Y-93341422D02*
|
||||
X89790000Y-93858578D01*
|
||||
X96061422Y-96370000D02*
|
||||
X96578578Y-96370000D01*
|
||||
X96061422Y-97790000D02*
|
||||
X96578578Y-97790000D01*
|
||||
D12*
|
||||
X62049523Y-84141904D02*
|
||||
X62049523Y-84789523D01*
|
||||
X62011428Y-84865714D01*
|
||||
X61973333Y-84903809D01*
|
||||
X61897142Y-84941904D01*
|
||||
X61744761Y-84941904D01*
|
||||
X61668571Y-84903809D01*
|
||||
X61630476Y-84865714D01*
|
||||
X61592380Y-84789523D01*
|
||||
X61592380Y-84141904D01*
|
||||
X61287619Y-84141904D02*
|
||||
X60792380Y-84141904D01*
|
||||
X61059047Y-84446666D01*
|
||||
X60944761Y-84446666D01*
|
||||
X60868571Y-84484761D01*
|
||||
X60830476Y-84522857D01*
|
||||
X60792380Y-84599047D01*
|
||||
X60792380Y-84789523D01*
|
||||
X60830476Y-84865714D01*
|
||||
X60868571Y-84903809D01*
|
||||
X60944761Y-84941904D01*
|
||||
X61173333Y-84941904D01*
|
||||
X61249523Y-84903809D01*
|
||||
X61287619Y-84865714D01*
|
||||
X65953333Y-105466666D02*
|
||||
X65953333Y-105966666D01*
|
||||
X65986666Y-106066666D01*
|
||||
X66053333Y-106133333D01*
|
||||
X66153333Y-106166666D01*
|
||||
X66220000Y-106166666D01*
|
||||
X65620000Y-106166666D02*
|
||||
X65620000Y-105466666D01*
|
||||
X65353333Y-105466666D01*
|
||||
X65286666Y-105500000D01*
|
||||
X65253333Y-105533333D01*
|
||||
X65220000Y-105600000D01*
|
||||
X65220000Y-105700000D01*
|
||||
X65253333Y-105766666D01*
|
||||
X65286666Y-105800000D01*
|
||||
X65353333Y-105833333D01*
|
||||
X65620000Y-105833333D01*
|
||||
X64953333Y-105533333D02*
|
||||
X64920000Y-105500000D01*
|
||||
X64853333Y-105466666D01*
|
||||
X64686666Y-105466666D01*
|
||||
X64620000Y-105500000D01*
|
||||
X64586666Y-105533333D01*
|
||||
X64553333Y-105600000D01*
|
||||
X64553333Y-105666666D01*
|
||||
X64586666Y-105766666D01*
|
||||
X64986666Y-106166666D01*
|
||||
X64553333Y-106166666D01*
|
||||
X69543333Y-105456666D02*
|
||||
X69543333Y-105956666D01*
|
||||
X69576666Y-106056666D01*
|
||||
X69643333Y-106123333D01*
|
||||
X69743333Y-106156666D01*
|
||||
X69810000Y-106156666D01*
|
||||
X69210000Y-106156666D02*
|
||||
X69210000Y-105456666D01*
|
||||
X68943333Y-105456666D01*
|
||||
X68876666Y-105490000D01*
|
||||
X68843333Y-105523333D01*
|
||||
X68810000Y-105590000D01*
|
||||
X68810000Y-105690000D01*
|
||||
X68843333Y-105756666D01*
|
||||
X68876666Y-105790000D01*
|
||||
X68943333Y-105823333D01*
|
||||
X69210000Y-105823333D01*
|
||||
X68143333Y-106156666D02*
|
||||
X68543333Y-106156666D01*
|
||||
X68343333Y-106156666D02*
|
||||
X68343333Y-105456666D01*
|
||||
X68410000Y-105556666D01*
|
||||
X68476666Y-105623333D01*
|
||||
X68543333Y-105656666D01*
|
||||
X94750000Y-103346666D02*
|
||||
X94983333Y-103013333D01*
|
||||
X95150000Y-103346666D02*
|
||||
X95150000Y-102646666D01*
|
||||
X94883333Y-102646666D01*
|
||||
X94816666Y-102680000D01*
|
||||
X94783333Y-102713333D01*
|
||||
X94750000Y-102780000D01*
|
||||
X94750000Y-102880000D01*
|
||||
X94783333Y-102946666D01*
|
||||
X94816666Y-102980000D01*
|
||||
X94883333Y-103013333D01*
|
||||
X95150000Y-103013333D01*
|
||||
X94083333Y-103346666D02*
|
||||
X94483333Y-103346666D01*
|
||||
X94283333Y-103346666D02*
|
||||
X94283333Y-102646666D01*
|
||||
X94350000Y-102746666D01*
|
||||
X94416666Y-102813333D01*
|
||||
X94483333Y-102846666D01*
|
||||
X93450000Y-102646666D02*
|
||||
X93783333Y-102646666D01*
|
||||
X93816666Y-102980000D01*
|
||||
X93783333Y-102946666D01*
|
||||
X93716666Y-102913333D01*
|
||||
X93550000Y-102913333D01*
|
||||
X93483333Y-102946666D01*
|
||||
X93450000Y-102980000D01*
|
||||
X93416666Y-103046666D01*
|
||||
X93416666Y-103213333D01*
|
||||
X93450000Y-103280000D01*
|
||||
X93483333Y-103313333D01*
|
||||
X93550000Y-103346666D01*
|
||||
X93716666Y-103346666D01*
|
||||
X93783333Y-103313333D01*
|
||||
X93816666Y-103280000D01*
|
||||
X59710000Y-86346666D02*
|
||||
X59943333Y-86013333D01*
|
||||
X60110000Y-86346666D02*
|
||||
X60110000Y-85646666D01*
|
||||
X59843333Y-85646666D01*
|
||||
X59776666Y-85680000D01*
|
||||
X59743333Y-85713333D01*
|
||||
X59710000Y-85780000D01*
|
||||
X59710000Y-85880000D01*
|
||||
X59743333Y-85946666D01*
|
||||
X59776666Y-85980000D01*
|
||||
X59843333Y-86013333D01*
|
||||
X60110000Y-86013333D01*
|
||||
X59043333Y-86346666D02*
|
||||
X59443333Y-86346666D01*
|
||||
X59243333Y-86346666D02*
|
||||
X59243333Y-85646666D01*
|
||||
X59310000Y-85746666D01*
|
||||
X59376666Y-85813333D01*
|
||||
X59443333Y-85846666D01*
|
||||
X58443333Y-85880000D02*
|
||||
X58443333Y-86346666D01*
|
||||
X58610000Y-85613333D02*
|
||||
X58776666Y-86113333D01*
|
||||
X58343333Y-86113333D01*
|
||||
X89390000Y-101296666D02*
|
||||
X89623333Y-100963333D01*
|
||||
X89790000Y-101296666D02*
|
||||
X89790000Y-100596666D01*
|
||||
X89523333Y-100596666D01*
|
||||
X89456666Y-100630000D01*
|
||||
X89423333Y-100663333D01*
|
||||
X89390000Y-100730000D01*
|
||||
X89390000Y-100830000D01*
|
||||
X89423333Y-100896666D01*
|
||||
X89456666Y-100930000D01*
|
||||
X89523333Y-100963333D01*
|
||||
X89790000Y-100963333D01*
|
||||
X88723333Y-101296666D02*
|
||||
X89123333Y-101296666D01*
|
||||
X88923333Y-101296666D02*
|
||||
X88923333Y-100596666D01*
|
||||
X88990000Y-100696666D01*
|
||||
X89056666Y-100763333D01*
|
||||
X89123333Y-100796666D01*
|
||||
X88056666Y-101296666D02*
|
||||
X88456666Y-101296666D01*
|
||||
X88256666Y-101296666D02*
|
||||
X88256666Y-100596666D01*
|
||||
X88323333Y-100696666D01*
|
||||
X88390000Y-100763333D01*
|
||||
X88456666Y-100796666D01*
|
||||
X84380000Y-103866666D02*
|
||||
X84613333Y-103533333D01*
|
||||
X84780000Y-103866666D02*
|
||||
X84780000Y-103166666D01*
|
||||
X84513333Y-103166666D01*
|
||||
X84446666Y-103200000D01*
|
||||
X84413333Y-103233333D01*
|
||||
X84380000Y-103300000D01*
|
||||
X84380000Y-103400000D01*
|
||||
X84413333Y-103466666D01*
|
||||
X84446666Y-103500000D01*
|
||||
X84513333Y-103533333D01*
|
||||
X84780000Y-103533333D01*
|
||||
X83713333Y-103866666D02*
|
||||
X84113333Y-103866666D01*
|
||||
X83913333Y-103866666D02*
|
||||
X83913333Y-103166666D01*
|
||||
X83980000Y-103266666D01*
|
||||
X84046666Y-103333333D01*
|
||||
X84113333Y-103366666D01*
|
||||
X83280000Y-103166666D02*
|
||||
X83213333Y-103166666D01*
|
||||
X83146666Y-103200000D01*
|
||||
X83113333Y-103233333D01*
|
||||
X83080000Y-103300000D01*
|
||||
X83046666Y-103433333D01*
|
||||
X83046666Y-103600000D01*
|
||||
X83080000Y-103733333D01*
|
||||
X83113333Y-103800000D01*
|
||||
X83146666Y-103833333D01*
|
||||
X83213333Y-103866666D01*
|
||||
X83280000Y-103866666D01*
|
||||
X83346666Y-103833333D01*
|
||||
X83380000Y-103800000D01*
|
||||
X83413333Y-103733333D01*
|
||||
X83446666Y-103600000D01*
|
||||
X83446666Y-103433333D01*
|
||||
X83413333Y-103300000D01*
|
||||
X83380000Y-103233333D01*
|
||||
X83346666Y-103200000D01*
|
||||
X83280000Y-103166666D01*
|
||||
X87796666Y-103053333D02*
|
||||
X87863333Y-103020000D01*
|
||||
X87930000Y-102953333D01*
|
||||
X88030000Y-102853333D01*
|
||||
X88096666Y-102820000D01*
|
||||
X88163333Y-102820000D01*
|
||||
X88130000Y-102986666D02*
|
||||
X88196666Y-102953333D01*
|
||||
X88263333Y-102886666D01*
|
||||
X88296666Y-102753333D01*
|
||||
X88296666Y-102520000D01*
|
||||
X88263333Y-102386666D01*
|
||||
X88196666Y-102320000D01*
|
||||
X88130000Y-102286666D01*
|
||||
X87996666Y-102286666D01*
|
||||
X87930000Y-102320000D01*
|
||||
X87863333Y-102386666D01*
|
||||
X87830000Y-102520000D01*
|
||||
X87830000Y-102753333D01*
|
||||
X87863333Y-102886666D01*
|
||||
X87930000Y-102953333D01*
|
||||
X87996666Y-102986666D01*
|
||||
X88130000Y-102986666D01*
|
||||
X87163333Y-102986666D02*
|
||||
X87563333Y-102986666D01*
|
||||
X87363333Y-102986666D02*
|
||||
X87363333Y-102286666D01*
|
||||
X87430000Y-102386666D01*
|
||||
X87496666Y-102453333D01*
|
||||
X87563333Y-102486666D01*
|
||||
X94166666Y-105240000D02*
|
||||
X94200000Y-105273333D01*
|
||||
X94300000Y-105306666D01*
|
||||
X94366666Y-105306666D01*
|
||||
X94466666Y-105273333D01*
|
||||
X94533333Y-105206666D01*
|
||||
X94566666Y-105140000D01*
|
||||
X94600000Y-105006666D01*
|
||||
X94600000Y-104906666D01*
|
||||
X94566666Y-104773333D01*
|
||||
X94533333Y-104706666D01*
|
||||
X94466666Y-104640000D01*
|
||||
X94366666Y-104606666D01*
|
||||
X94300000Y-104606666D01*
|
||||
X94200000Y-104640000D01*
|
||||
X94166666Y-104673333D01*
|
||||
X93566666Y-104840000D02*
|
||||
X93566666Y-105306666D01*
|
||||
X93733333Y-104573333D02*
|
||||
X93900000Y-105073333D01*
|
||||
X93466666Y-105073333D01*
|
||||
X55943333Y-82906666D02*
|
||||
X55943333Y-83406666D01*
|
||||
X55976666Y-83506666D01*
|
||||
X56043333Y-83573333D01*
|
||||
X56143333Y-83606666D01*
|
||||
X56210000Y-83606666D01*
|
||||
X55676666Y-82906666D02*
|
||||
X55243333Y-82906666D01*
|
||||
X55476666Y-83173333D01*
|
||||
X55376666Y-83173333D01*
|
||||
X55310000Y-83206666D01*
|
||||
X55276666Y-83240000D01*
|
||||
X55243333Y-83306666D01*
|
||||
X55243333Y-83473333D01*
|
||||
X55276666Y-83540000D01*
|
||||
X55310000Y-83573333D01*
|
||||
X55376666Y-83606666D01*
|
||||
X55576666Y-83606666D01*
|
||||
X55643333Y-83573333D01*
|
||||
X55676666Y-83540000D01*
|
||||
X94706666Y-92861904D02*
|
||||
X94706666Y-93433333D01*
|
||||
X94744761Y-93547619D01*
|
||||
X94820952Y-93623809D01*
|
||||
X94935238Y-93661904D01*
|
||||
X95011428Y-93661904D01*
|
||||
X94363809Y-92938095D02*
|
||||
X94325714Y-92900000D01*
|
||||
X94249523Y-92861904D01*
|
||||
X94059047Y-92861904D01*
|
||||
X93982857Y-92900000D01*
|
||||
X93944761Y-92938095D01*
|
||||
X93906666Y-93014285D01*
|
||||
X93906666Y-93090476D01*
|
||||
X93944761Y-93204761D01*
|
||||
X94401904Y-93661904D01*
|
||||
X93906666Y-93661904D01*
|
||||
X89346666Y-99156666D02*
|
||||
X89580000Y-98823333D01*
|
||||
X89746666Y-99156666D02*
|
||||
X89746666Y-98456666D01*
|
||||
X89480000Y-98456666D01*
|
||||
X89413333Y-98490000D01*
|
||||
X89380000Y-98523333D01*
|
||||
X89346666Y-98590000D01*
|
||||
X89346666Y-98690000D01*
|
||||
X89380000Y-98756666D01*
|
||||
X89413333Y-98790000D01*
|
||||
X89480000Y-98823333D01*
|
||||
X89746666Y-98823333D01*
|
||||
X89013333Y-99156666D02*
|
||||
X88880000Y-99156666D01*
|
||||
X88813333Y-99123333D01*
|
||||
X88780000Y-99090000D01*
|
||||
X88713333Y-98990000D01*
|
||||
X88680000Y-98856666D01*
|
||||
X88680000Y-98590000D01*
|
||||
X88713333Y-98523333D01*
|
||||
X88746666Y-98490000D01*
|
||||
X88813333Y-98456666D01*
|
||||
X88946666Y-98456666D01*
|
||||
X89013333Y-98490000D01*
|
||||
X89046666Y-98523333D01*
|
||||
X89080000Y-98590000D01*
|
||||
X89080000Y-98756666D01*
|
||||
X89046666Y-98823333D01*
|
||||
X89013333Y-98856666D01*
|
||||
X88946666Y-98890000D01*
|
||||
X88813333Y-98890000D01*
|
||||
X88746666Y-98856666D01*
|
||||
X88713333Y-98823333D01*
|
||||
X88680000Y-98756666D01*
|
||||
X91240000Y-85956666D02*
|
||||
X91473333Y-85623333D01*
|
||||
X91640000Y-85956666D02*
|
||||
X91640000Y-85256666D01*
|
||||
X91373333Y-85256666D01*
|
||||
X91306666Y-85290000D01*
|
||||
X91273333Y-85323333D01*
|
||||
X91240000Y-85390000D01*
|
||||
X91240000Y-85490000D01*
|
||||
X91273333Y-85556666D01*
|
||||
X91306666Y-85590000D01*
|
||||
X91373333Y-85623333D01*
|
||||
X91640000Y-85623333D01*
|
||||
X90573333Y-85956666D02*
|
||||
X90973333Y-85956666D01*
|
||||
X90773333Y-85956666D02*
|
||||
X90773333Y-85256666D01*
|
||||
X90840000Y-85356666D01*
|
||||
X90906666Y-85423333D01*
|
||||
X90973333Y-85456666D01*
|
||||
X90306666Y-85323333D02*
|
||||
X90273333Y-85290000D01*
|
||||
X90206666Y-85256666D01*
|
||||
X90040000Y-85256666D01*
|
||||
X89973333Y-85290000D01*
|
||||
X89940000Y-85323333D01*
|
||||
X89906666Y-85390000D01*
|
||||
X89906666Y-85456666D01*
|
||||
X89940000Y-85556666D01*
|
||||
X90340000Y-85956666D01*
|
||||
X89906666Y-85956666D01*
|
||||
X90940000Y-91836666D02*
|
||||
X91173333Y-91503333D01*
|
||||
X91340000Y-91836666D02*
|
||||
X91340000Y-91136666D01*
|
||||
X91073333Y-91136666D01*
|
||||
X91006666Y-91170000D01*
|
||||
X90973333Y-91203333D01*
|
||||
X90940000Y-91270000D01*
|
||||
X90940000Y-91370000D01*
|
||||
X90973333Y-91436666D01*
|
||||
X91006666Y-91470000D01*
|
||||
X91073333Y-91503333D01*
|
||||
X91340000Y-91503333D01*
|
||||
X90273333Y-91836666D02*
|
||||
X90673333Y-91836666D01*
|
||||
X90473333Y-91836666D02*
|
||||
X90473333Y-91136666D01*
|
||||
X90540000Y-91236666D01*
|
||||
X90606666Y-91303333D01*
|
||||
X90673333Y-91336666D01*
|
||||
X90040000Y-91136666D02*
|
||||
X89606666Y-91136666D01*
|
||||
X89840000Y-91403333D01*
|
||||
X89740000Y-91403333D01*
|
||||
X89673333Y-91436666D01*
|
||||
X89640000Y-91470000D01*
|
||||
X89606666Y-91536666D01*
|
||||
X89606666Y-91703333D01*
|
||||
X89640000Y-91770000D01*
|
||||
X89673333Y-91803333D01*
|
||||
X89740000Y-91836666D01*
|
||||
X89940000Y-91836666D01*
|
||||
X90006666Y-91803333D01*
|
||||
X90040000Y-91770000D01*
|
||||
X96416666Y-95996666D02*
|
||||
X96650000Y-95663333D01*
|
||||
X96816666Y-95996666D02*
|
||||
X96816666Y-95296666D01*
|
||||
X96550000Y-95296666D01*
|
||||
X96483333Y-95330000D01*
|
||||
X96450000Y-95363333D01*
|
||||
X96416666Y-95430000D01*
|
||||
X96416666Y-95530000D01*
|
||||
X96450000Y-95596666D01*
|
||||
X96483333Y-95630000D01*
|
||||
X96550000Y-95663333D01*
|
||||
X96816666Y-95663333D01*
|
||||
X96016666Y-95596666D02*
|
||||
X96083333Y-95563333D01*
|
||||
X96116666Y-95530000D01*
|
||||
X96150000Y-95463333D01*
|
||||
X96150000Y-95430000D01*
|
||||
X96116666Y-95363333D01*
|
||||
X96083333Y-95330000D01*
|
||||
X96016666Y-95296666D01*
|
||||
X95883333Y-95296666D01*
|
||||
X95816666Y-95330000D01*
|
||||
X95783333Y-95363333D01*
|
||||
X95750000Y-95430000D01*
|
||||
X95750000Y-95463333D01*
|
||||
X95783333Y-95530000D01*
|
||||
X95816666Y-95563333D01*
|
||||
X95883333Y-95596666D01*
|
||||
X96016666Y-95596666D01*
|
||||
X96083333Y-95630000D01*
|
||||
X96116666Y-95663333D01*
|
||||
X96150000Y-95730000D01*
|
||||
X96150000Y-95863333D01*
|
||||
X96116666Y-95930000D01*
|
||||
X96083333Y-95963333D01*
|
||||
X96016666Y-95996666D01*
|
||||
X95883333Y-95996666D01*
|
||||
X95816666Y-95963333D01*
|
||||
X95783333Y-95930000D01*
|
||||
X95750000Y-95863333D01*
|
||||
X95750000Y-95730000D01*
|
||||
X95783333Y-95663333D01*
|
||||
X95816666Y-95630000D01*
|
||||
X95883333Y-95596666D01*
|
||||
X56153333Y-102926666D02*
|
||||
X56153333Y-103426666D01*
|
||||
X56186666Y-103526666D01*
|
||||
X56253333Y-103593333D01*
|
||||
X56353333Y-103626666D01*
|
||||
X56420000Y-103626666D01*
|
||||
X55453333Y-103626666D02*
|
||||
X55853333Y-103626666D01*
|
||||
X55653333Y-103626666D02*
|
||||
X55653333Y-102926666D01*
|
||||
X55720000Y-103026666D01*
|
||||
X55786666Y-103093333D01*
|
||||
X55853333Y-103126666D01*
|
||||
M02*
|
||||
55
kicad/Output/v1.2/mz25key-Edge_Cuts.gbr
Normal file
55
kicad/Output/v1.2/mz25key-Edge_Cuts.gbr
Normal file
@@ -0,0 +1,55 @@
|
||||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,(5.1.2-1)-1*
|
||||
G04 #@! TF.CreationDate,2022-01-26T01:19:45+00:00*
|
||||
G04 #@! TF.ProjectId,mz25key,6d7a3235-6b65-4792-9e6b-696361645f70,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Profile,NP*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW (5.1.2-1)-1) date 2022-01-26 01:19:45*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G04 APERTURE LIST*
|
||||
%ADD10C,0.050000*%
|
||||
G04 APERTURE END LIST*
|
||||
D10*
|
||||
X100000000Y-84000000D02*
|
||||
G75*
|
||||
G02X96000000Y-80000000I-2000000J2000000D01*
|
||||
G01*
|
||||
X96000000Y-106500000D02*
|
||||
G75*
|
||||
G02X100000000Y-102500000I2000000J2000000D01*
|
||||
G01*
|
||||
X50000001Y-102500002D02*
|
||||
G75*
|
||||
G02X54000001Y-106500002I2000000J-2000000D01*
|
||||
G01*
|
||||
X71500000Y-83000000D02*
|
||||
X78500000Y-83000000D01*
|
||||
X78500000Y-83000000D02*
|
||||
X78500000Y-80000000D01*
|
||||
X71500000Y-83000000D02*
|
||||
X71500000Y-80000000D01*
|
||||
X78500000Y-106500000D02*
|
||||
X78500000Y-103500000D01*
|
||||
X71500000Y-106500000D02*
|
||||
X71500000Y-103500000D01*
|
||||
X71500000Y-103500000D02*
|
||||
X78500000Y-103500000D01*
|
||||
X78500000Y-106500000D02*
|
||||
X96000000Y-106500000D01*
|
||||
X54000000Y-106500000D02*
|
||||
X71500000Y-106500000D01*
|
||||
X78500000Y-80000000D02*
|
||||
X96000000Y-80000000D01*
|
||||
X54000000Y-80000000D02*
|
||||
G75*
|
||||
G02X50000000Y-84000000I-2000000J-2000000D01*
|
||||
G01*
|
||||
X50000000Y-84000000D02*
|
||||
X50000000Y-102500000D01*
|
||||
X100000000Y-84000000D02*
|
||||
X100000000Y-102500000D01*
|
||||
X54000000Y-80000000D02*
|
||||
X71500000Y-80000000D01*
|
||||
M02*
|
||||
7916
kicad/Output/v1.2/mz25key-F_Cu.gbr
Normal file
7916
kicad/Output/v1.2/mz25key-F_Cu.gbr
Normal file
File diff suppressed because it is too large
Load Diff
3531
kicad/Output/v1.2/mz25key-F_Mask.gbr
Normal file
3531
kicad/Output/v1.2/mz25key-F_Mask.gbr
Normal file
File diff suppressed because it is too large
Load Diff
3834
kicad/Output/v1.2/mz25key-F_Paste.gbr
Normal file
3834
kicad/Output/v1.2/mz25key-F_Paste.gbr
Normal file
File diff suppressed because it is too large
Load Diff
2758
kicad/Output/v1.2/mz25key-F_SilkS.gbr
Normal file
2758
kicad/Output/v1.2/mz25key-F_SilkS.gbr
Normal file
File diff suppressed because it is too large
Load Diff
545
kicad/Output/v1.2/mz25key-NPTH-drl_map.gbr
Normal file
545
kicad/Output/v1.2/mz25key-NPTH-drl_map.gbr
Normal file
@@ -0,0 +1,545 @@
|
||||
%FSLAX45Y45*%
|
||||
G04 Gerber Fmt 4.5, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW (5.1.2-1)-1) date 2022-01-26 01:19:42*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G04 APERTURE LIST*
|
||||
%ADD10C,0.050000*%
|
||||
%ADD11C,0.200000*%
|
||||
%ADD12C,0.300000*%
|
||||
G04 APERTURE END LIST*
|
||||
D10*
|
||||
X10000000Y-8400000D02*
|
||||
G75*
|
||||
G02X9600000Y-8000000I-200000J200000D01*
|
||||
G01*
|
||||
X9600000Y-10650000D02*
|
||||
G75*
|
||||
G02X10000000Y-10250000I200000J200000D01*
|
||||
G01*
|
||||
X5000000Y-10250000D02*
|
||||
G75*
|
||||
G02X5400000Y-10650000I200000J-200000D01*
|
||||
G01*
|
||||
X7150000Y-8300000D02*
|
||||
X7850000Y-8300000D01*
|
||||
X7850000Y-8300000D02*
|
||||
X7850000Y-8000000D01*
|
||||
X7150000Y-8300000D02*
|
||||
X7150000Y-8000000D01*
|
||||
X7850000Y-10650000D02*
|
||||
X7850000Y-10350000D01*
|
||||
X7150000Y-10650000D02*
|
||||
X7150000Y-10350000D01*
|
||||
X7150000Y-10350000D02*
|
||||
X7850000Y-10350000D01*
|
||||
X7850000Y-10650000D02*
|
||||
X9600000Y-10650000D01*
|
||||
X5400000Y-10650000D02*
|
||||
X7150000Y-10650000D01*
|
||||
X7850000Y-8000000D02*
|
||||
X9600000Y-8000000D01*
|
||||
X5400000Y-8000000D02*
|
||||
G75*
|
||||
G02X5000000Y-8400000I-200000J-200000D01*
|
||||
G01*
|
||||
X5000000Y-8400000D02*
|
||||
X5000000Y-10250000D01*
|
||||
X10000000Y-8400000D02*
|
||||
X10000000Y-10250000D01*
|
||||
X5400000Y-8000000D02*
|
||||
X7150000Y-8000000D01*
|
||||
D11*
|
||||
X8995000Y-8245000D02*
|
||||
X9205000Y-8455000D01*
|
||||
X9205000Y-8245000D02*
|
||||
X8995000Y-8455000D01*
|
||||
X5815000Y-10165000D02*
|
||||
X6025000Y-10375000D01*
|
||||
X6025000Y-10165000D02*
|
||||
X5815000Y-10375000D01*
|
||||
D12*
|
||||
X5283928Y-11118215D02*
|
||||
X5283928Y-10818215D01*
|
||||
X5355357Y-10818215D01*
|
||||
X5398214Y-10832500D01*
|
||||
X5426786Y-10861072D01*
|
||||
X5441071Y-10889643D01*
|
||||
X5455357Y-10946786D01*
|
||||
X5455357Y-10989643D01*
|
||||
X5441071Y-11046786D01*
|
||||
X5426786Y-11075357D01*
|
||||
X5398214Y-11103929D01*
|
||||
X5355357Y-11118215D01*
|
||||
X5283928Y-11118215D01*
|
||||
X5583928Y-11118215D02*
|
||||
X5583928Y-10918215D01*
|
||||
X5583928Y-10975357D02*
|
||||
X5598214Y-10946786D01*
|
||||
X5612500Y-10932500D01*
|
||||
X5641071Y-10918215D01*
|
||||
X5669643Y-10918215D01*
|
||||
X5769643Y-11118215D02*
|
||||
X5769643Y-10918215D01*
|
||||
X5769643Y-10818215D02*
|
||||
X5755357Y-10832500D01*
|
||||
X5769643Y-10846786D01*
|
||||
X5783928Y-10832500D01*
|
||||
X5769643Y-10818215D01*
|
||||
X5769643Y-10846786D01*
|
||||
X5955357Y-11118215D02*
|
||||
X5926786Y-11103929D01*
|
||||
X5912500Y-11075357D01*
|
||||
X5912500Y-10818215D01*
|
||||
X6112500Y-11118215D02*
|
||||
X6083928Y-11103929D01*
|
||||
X6069643Y-11075357D01*
|
||||
X6069643Y-10818215D01*
|
||||
X6455357Y-11118215D02*
|
||||
X6455357Y-10818215D01*
|
||||
X6555357Y-11032500D01*
|
||||
X6655357Y-10818215D01*
|
||||
X6655357Y-11118215D01*
|
||||
X6926786Y-11118215D02*
|
||||
X6926786Y-10961072D01*
|
||||
X6912500Y-10932500D01*
|
||||
X6883928Y-10918215D01*
|
||||
X6826786Y-10918215D01*
|
||||
X6798214Y-10932500D01*
|
||||
X6926786Y-11103929D02*
|
||||
X6898214Y-11118215D01*
|
||||
X6826786Y-11118215D01*
|
||||
X6798214Y-11103929D01*
|
||||
X6783928Y-11075357D01*
|
||||
X6783928Y-11046786D01*
|
||||
X6798214Y-11018215D01*
|
||||
X6826786Y-11003929D01*
|
||||
X6898214Y-11003929D01*
|
||||
X6926786Y-10989643D01*
|
||||
X7069643Y-10918215D02*
|
||||
X7069643Y-11218214D01*
|
||||
X7069643Y-10932500D02*
|
||||
X7098214Y-10918215D01*
|
||||
X7155357Y-10918215D01*
|
||||
X7183928Y-10932500D01*
|
||||
X7198214Y-10946786D01*
|
||||
X7212500Y-10975357D01*
|
||||
X7212500Y-11061072D01*
|
||||
X7198214Y-11089643D01*
|
||||
X7183928Y-11103929D01*
|
||||
X7155357Y-11118215D01*
|
||||
X7098214Y-11118215D01*
|
||||
X7069643Y-11103929D01*
|
||||
X7341071Y-11089643D02*
|
||||
X7355357Y-11103929D01*
|
||||
X7341071Y-11118215D01*
|
||||
X7326786Y-11103929D01*
|
||||
X7341071Y-11089643D01*
|
||||
X7341071Y-11118215D01*
|
||||
X7341071Y-10932500D02*
|
||||
X7355357Y-10946786D01*
|
||||
X7341071Y-10961072D01*
|
||||
X7326786Y-10946786D01*
|
||||
X7341071Y-10932500D01*
|
||||
X7341071Y-10961072D01*
|
||||
X4787500Y-11507500D02*
|
||||
X4997500Y-11717500D01*
|
||||
X4997500Y-11507500D02*
|
||||
X4787500Y-11717500D01*
|
||||
X5269643Y-11476786D02*
|
||||
X5283928Y-11462500D01*
|
||||
X5312500Y-11448214D01*
|
||||
X5383928Y-11448214D01*
|
||||
X5412500Y-11462500D01*
|
||||
X5426786Y-11476786D01*
|
||||
X5441071Y-11505357D01*
|
||||
X5441071Y-11533929D01*
|
||||
X5426786Y-11576786D01*
|
||||
X5255357Y-11748214D01*
|
||||
X5441071Y-11748214D01*
|
||||
X5569643Y-11719643D02*
|
||||
X5583928Y-11733929D01*
|
||||
X5569643Y-11748214D01*
|
||||
X5555357Y-11733929D01*
|
||||
X5569643Y-11719643D01*
|
||||
X5569643Y-11748214D01*
|
||||
X5869643Y-11748214D02*
|
||||
X5698214Y-11748214D01*
|
||||
X5783928Y-11748214D02*
|
||||
X5783928Y-11448214D01*
|
||||
X5755357Y-11491072D01*
|
||||
X5726786Y-11519643D01*
|
||||
X5698214Y-11533929D01*
|
||||
X6055357Y-11448214D02*
|
||||
X6083928Y-11448214D01*
|
||||
X6112500Y-11462500D01*
|
||||
X6126786Y-11476786D01*
|
||||
X6141071Y-11505357D01*
|
||||
X6155357Y-11562500D01*
|
||||
X6155357Y-11633929D01*
|
||||
X6141071Y-11691072D01*
|
||||
X6126786Y-11719643D01*
|
||||
X6112500Y-11733929D01*
|
||||
X6083928Y-11748214D01*
|
||||
X6055357Y-11748214D01*
|
||||
X6026786Y-11733929D01*
|
||||
X6012500Y-11719643D01*
|
||||
X5998214Y-11691072D01*
|
||||
X5983928Y-11633929D01*
|
||||
X5983928Y-11562500D01*
|
||||
X5998214Y-11505357D01*
|
||||
X6012500Y-11476786D01*
|
||||
X6026786Y-11462500D01*
|
||||
X6055357Y-11448214D01*
|
||||
X6283928Y-11748214D02*
|
||||
X6283928Y-11548214D01*
|
||||
X6283928Y-11576786D02*
|
||||
X6298214Y-11562500D01*
|
||||
X6326786Y-11548214D01*
|
||||
X6369643Y-11548214D01*
|
||||
X6398214Y-11562500D01*
|
||||
X6412500Y-11591072D01*
|
||||
X6412500Y-11748214D01*
|
||||
X6412500Y-11591072D02*
|
||||
X6426786Y-11562500D01*
|
||||
X6455357Y-11548214D01*
|
||||
X6498214Y-11548214D01*
|
||||
X6526786Y-11562500D01*
|
||||
X6541071Y-11591072D01*
|
||||
X6541071Y-11748214D01*
|
||||
X6683928Y-11748214D02*
|
||||
X6683928Y-11548214D01*
|
||||
X6683928Y-11576786D02*
|
||||
X6698214Y-11562500D01*
|
||||
X6726786Y-11548214D01*
|
||||
X6769643Y-11548214D01*
|
||||
X6798214Y-11562500D01*
|
||||
X6812500Y-11591072D01*
|
||||
X6812500Y-11748214D01*
|
||||
X6812500Y-11591072D02*
|
||||
X6826786Y-11562500D01*
|
||||
X6855357Y-11548214D01*
|
||||
X6898214Y-11548214D01*
|
||||
X6926786Y-11562500D01*
|
||||
X6941071Y-11591072D01*
|
||||
X6941071Y-11748214D01*
|
||||
X7526786Y-11433929D02*
|
||||
X7269643Y-11819643D01*
|
||||
X7912500Y-11448214D02*
|
||||
X7941071Y-11448214D01*
|
||||
X7969643Y-11462500D01*
|
||||
X7983928Y-11476786D01*
|
||||
X7998214Y-11505357D01*
|
||||
X8012500Y-11562500D01*
|
||||
X8012500Y-11633929D01*
|
||||
X7998214Y-11691072D01*
|
||||
X7983928Y-11719643D01*
|
||||
X7969643Y-11733929D01*
|
||||
X7941071Y-11748214D01*
|
||||
X7912500Y-11748214D01*
|
||||
X7883928Y-11733929D01*
|
||||
X7869643Y-11719643D01*
|
||||
X7855357Y-11691072D01*
|
||||
X7841071Y-11633929D01*
|
||||
X7841071Y-11562500D01*
|
||||
X7855357Y-11505357D01*
|
||||
X7869643Y-11476786D01*
|
||||
X7883928Y-11462500D01*
|
||||
X7912500Y-11448214D01*
|
||||
X8141071Y-11719643D02*
|
||||
X8155357Y-11733929D01*
|
||||
X8141071Y-11748214D01*
|
||||
X8126786Y-11733929D01*
|
||||
X8141071Y-11719643D01*
|
||||
X8141071Y-11748214D01*
|
||||
X8341071Y-11448214D02*
|
||||
X8369643Y-11448214D01*
|
||||
X8398214Y-11462500D01*
|
||||
X8412500Y-11476786D01*
|
||||
X8426786Y-11505357D01*
|
||||
X8441071Y-11562500D01*
|
||||
X8441071Y-11633929D01*
|
||||
X8426786Y-11691072D01*
|
||||
X8412500Y-11719643D01*
|
||||
X8398214Y-11733929D01*
|
||||
X8369643Y-11748214D01*
|
||||
X8341071Y-11748214D01*
|
||||
X8312500Y-11733929D01*
|
||||
X8298214Y-11719643D01*
|
||||
X8283928Y-11691072D01*
|
||||
X8269643Y-11633929D01*
|
||||
X8269643Y-11562500D01*
|
||||
X8283928Y-11505357D01*
|
||||
X8298214Y-11476786D01*
|
||||
X8312500Y-11462500D01*
|
||||
X8341071Y-11448214D01*
|
||||
X8612500Y-11576786D02*
|
||||
X8583928Y-11562500D01*
|
||||
X8569643Y-11548214D01*
|
||||
X8555357Y-11519643D01*
|
||||
X8555357Y-11505357D01*
|
||||
X8569643Y-11476786D01*
|
||||
X8583928Y-11462500D01*
|
||||
X8612500Y-11448214D01*
|
||||
X8669643Y-11448214D01*
|
||||
X8698214Y-11462500D01*
|
||||
X8712500Y-11476786D01*
|
||||
X8726786Y-11505357D01*
|
||||
X8726786Y-11519643D01*
|
||||
X8712500Y-11548214D01*
|
||||
X8698214Y-11562500D01*
|
||||
X8669643Y-11576786D01*
|
||||
X8612500Y-11576786D01*
|
||||
X8583928Y-11591072D01*
|
||||
X8569643Y-11605357D01*
|
||||
X8555357Y-11633929D01*
|
||||
X8555357Y-11691072D01*
|
||||
X8569643Y-11719643D01*
|
||||
X8583928Y-11733929D01*
|
||||
X8612500Y-11748214D01*
|
||||
X8669643Y-11748214D01*
|
||||
X8698214Y-11733929D01*
|
||||
X8712500Y-11719643D01*
|
||||
X8726786Y-11691072D01*
|
||||
X8726786Y-11633929D01*
|
||||
X8712500Y-11605357D01*
|
||||
X8698214Y-11591072D01*
|
||||
X8669643Y-11576786D01*
|
||||
X8826786Y-11448214D02*
|
||||
X9012500Y-11448214D01*
|
||||
X8912500Y-11562500D01*
|
||||
X8955357Y-11562500D01*
|
||||
X8983928Y-11576786D01*
|
||||
X8998214Y-11591072D01*
|
||||
X9012500Y-11619643D01*
|
||||
X9012500Y-11691072D01*
|
||||
X8998214Y-11719643D01*
|
||||
X8983928Y-11733929D01*
|
||||
X8955357Y-11748214D01*
|
||||
X8869643Y-11748214D01*
|
||||
X8841071Y-11733929D01*
|
||||
X8826786Y-11719643D01*
|
||||
X9126786Y-11448214D02*
|
||||
X9126786Y-11505357D01*
|
||||
X9241071Y-11448214D02*
|
||||
X9241071Y-11505357D01*
|
||||
X9683928Y-11862500D02*
|
||||
X9669643Y-11848214D01*
|
||||
X9641071Y-11805357D01*
|
||||
X9626786Y-11776786D01*
|
||||
X9612500Y-11733929D01*
|
||||
X9598214Y-11662500D01*
|
||||
X9598214Y-11605357D01*
|
||||
X9612500Y-11533929D01*
|
||||
X9626786Y-11491072D01*
|
||||
X9641071Y-11462500D01*
|
||||
X9669643Y-11419643D01*
|
||||
X9683928Y-11405357D01*
|
||||
X9783928Y-11476786D02*
|
||||
X9798214Y-11462500D01*
|
||||
X9826786Y-11448214D01*
|
||||
X9898214Y-11448214D01*
|
||||
X9926786Y-11462500D01*
|
||||
X9941071Y-11476786D01*
|
||||
X9955357Y-11505357D01*
|
||||
X9955357Y-11533929D01*
|
||||
X9941071Y-11576786D01*
|
||||
X9769643Y-11748214D01*
|
||||
X9955357Y-11748214D01*
|
||||
X10312500Y-11748214D02*
|
||||
X10312500Y-11448214D01*
|
||||
X10441071Y-11748214D02*
|
||||
X10441071Y-11591072D01*
|
||||
X10426786Y-11562500D01*
|
||||
X10398214Y-11548214D01*
|
||||
X10355357Y-11548214D01*
|
||||
X10326786Y-11562500D01*
|
||||
X10312500Y-11576786D01*
|
||||
X10626786Y-11748214D02*
|
||||
X10598214Y-11733929D01*
|
||||
X10583928Y-11719643D01*
|
||||
X10569643Y-11691072D01*
|
||||
X10569643Y-11605357D01*
|
||||
X10583928Y-11576786D01*
|
||||
X10598214Y-11562500D01*
|
||||
X10626786Y-11548214D01*
|
||||
X10669643Y-11548214D01*
|
||||
X10698214Y-11562500D01*
|
||||
X10712500Y-11576786D01*
|
||||
X10726786Y-11605357D01*
|
||||
X10726786Y-11691072D01*
|
||||
X10712500Y-11719643D01*
|
||||
X10698214Y-11733929D01*
|
||||
X10669643Y-11748214D01*
|
||||
X10626786Y-11748214D01*
|
||||
X10898214Y-11748214D02*
|
||||
X10869643Y-11733929D01*
|
||||
X10855357Y-11705357D01*
|
||||
X10855357Y-11448214D01*
|
||||
X11126786Y-11733929D02*
|
||||
X11098214Y-11748214D01*
|
||||
X11041071Y-11748214D01*
|
||||
X11012500Y-11733929D01*
|
||||
X10998214Y-11705357D01*
|
||||
X10998214Y-11591072D01*
|
||||
X11012500Y-11562500D01*
|
||||
X11041071Y-11548214D01*
|
||||
X11098214Y-11548214D01*
|
||||
X11126786Y-11562500D01*
|
||||
X11141071Y-11591072D01*
|
||||
X11141071Y-11619643D01*
|
||||
X10998214Y-11648214D01*
|
||||
X11255357Y-11733929D02*
|
||||
X11283928Y-11748214D01*
|
||||
X11341071Y-11748214D01*
|
||||
X11369643Y-11733929D01*
|
||||
X11383928Y-11705357D01*
|
||||
X11383928Y-11691072D01*
|
||||
X11369643Y-11662500D01*
|
||||
X11341071Y-11648214D01*
|
||||
X11298214Y-11648214D01*
|
||||
X11269643Y-11633929D01*
|
||||
X11255357Y-11605357D01*
|
||||
X11255357Y-11591072D01*
|
||||
X11269643Y-11562500D01*
|
||||
X11298214Y-11548214D01*
|
||||
X11341071Y-11548214D01*
|
||||
X11369643Y-11562500D01*
|
||||
X11483928Y-11862500D02*
|
||||
X11498214Y-11848214D01*
|
||||
X11526786Y-11805357D01*
|
||||
X11541071Y-11776786D01*
|
||||
X11555357Y-11733929D01*
|
||||
X11569643Y-11662500D01*
|
||||
X11569643Y-11605357D01*
|
||||
X11555357Y-11533929D01*
|
||||
X11541071Y-11491072D01*
|
||||
X11526786Y-11462500D01*
|
||||
X11498214Y-11419643D01*
|
||||
X11483928Y-11405357D01*
|
||||
X12026786Y-11862500D02*
|
||||
X12012500Y-11848214D01*
|
||||
X11983928Y-11805357D01*
|
||||
X11969643Y-11776786D01*
|
||||
X11955357Y-11733929D01*
|
||||
X11941071Y-11662500D01*
|
||||
X11941071Y-11605357D01*
|
||||
X11955357Y-11533929D01*
|
||||
X11969643Y-11491072D01*
|
||||
X11983928Y-11462500D01*
|
||||
X12012500Y-11419643D01*
|
||||
X12026786Y-11405357D01*
|
||||
X12141071Y-11548214D02*
|
||||
X12141071Y-11748214D01*
|
||||
X12141071Y-11576786D02*
|
||||
X12155357Y-11562500D01*
|
||||
X12183928Y-11548214D01*
|
||||
X12226786Y-11548214D01*
|
||||
X12255357Y-11562500D01*
|
||||
X12269643Y-11591072D01*
|
||||
X12269643Y-11748214D01*
|
||||
X12455357Y-11748214D02*
|
||||
X12426786Y-11733929D01*
|
||||
X12412500Y-11719643D01*
|
||||
X12398214Y-11691072D01*
|
||||
X12398214Y-11605357D01*
|
||||
X12412500Y-11576786D01*
|
||||
X12426786Y-11562500D01*
|
||||
X12455357Y-11548214D01*
|
||||
X12498214Y-11548214D01*
|
||||
X12526786Y-11562500D01*
|
||||
X12541071Y-11576786D01*
|
||||
X12555357Y-11605357D01*
|
||||
X12555357Y-11691072D01*
|
||||
X12541071Y-11719643D01*
|
||||
X12526786Y-11733929D01*
|
||||
X12498214Y-11748214D01*
|
||||
X12455357Y-11748214D01*
|
||||
X12641071Y-11548214D02*
|
||||
X12755357Y-11548214D01*
|
||||
X12683928Y-11448214D02*
|
||||
X12683928Y-11705357D01*
|
||||
X12698214Y-11733929D01*
|
||||
X12726786Y-11748214D01*
|
||||
X12755357Y-11748214D01*
|
||||
X13083928Y-11548214D02*
|
||||
X13083928Y-11848214D01*
|
||||
X13083928Y-11562500D02*
|
||||
X13112500Y-11548214D01*
|
||||
X13169643Y-11548214D01*
|
||||
X13198214Y-11562500D01*
|
||||
X13212500Y-11576786D01*
|
||||
X13226786Y-11605357D01*
|
||||
X13226786Y-11691072D01*
|
||||
X13212500Y-11719643D01*
|
||||
X13198214Y-11733929D01*
|
||||
X13169643Y-11748214D01*
|
||||
X13112500Y-11748214D01*
|
||||
X13083928Y-11733929D01*
|
||||
X13398214Y-11748214D02*
|
||||
X13369643Y-11733929D01*
|
||||
X13355357Y-11705357D01*
|
||||
X13355357Y-11448214D01*
|
||||
X13641071Y-11748214D02*
|
||||
X13641071Y-11591072D01*
|
||||
X13626786Y-11562500D01*
|
||||
X13598214Y-11548214D01*
|
||||
X13541071Y-11548214D01*
|
||||
X13512500Y-11562500D01*
|
||||
X13641071Y-11733929D02*
|
||||
X13612500Y-11748214D01*
|
||||
X13541071Y-11748214D01*
|
||||
X13512500Y-11733929D01*
|
||||
X13498214Y-11705357D01*
|
||||
X13498214Y-11676786D01*
|
||||
X13512500Y-11648214D01*
|
||||
X13541071Y-11633929D01*
|
||||
X13612500Y-11633929D01*
|
||||
X13641071Y-11619643D01*
|
||||
X13741071Y-11548214D02*
|
||||
X13855357Y-11548214D01*
|
||||
X13783928Y-11448214D02*
|
||||
X13783928Y-11705357D01*
|
||||
X13798214Y-11733929D01*
|
||||
X13826786Y-11748214D01*
|
||||
X13855357Y-11748214D01*
|
||||
X14069643Y-11733929D02*
|
||||
X14041071Y-11748214D01*
|
||||
X13983928Y-11748214D01*
|
||||
X13955357Y-11733929D01*
|
||||
X13941071Y-11705357D01*
|
||||
X13941071Y-11591072D01*
|
||||
X13955357Y-11562500D01*
|
||||
X13983928Y-11548214D01*
|
||||
X14041071Y-11548214D01*
|
||||
X14069643Y-11562500D01*
|
||||
X14083928Y-11591072D01*
|
||||
X14083928Y-11619643D01*
|
||||
X13941071Y-11648214D01*
|
||||
X14341071Y-11748214D02*
|
||||
X14341071Y-11448214D01*
|
||||
X14341071Y-11733929D02*
|
||||
X14312500Y-11748214D01*
|
||||
X14255357Y-11748214D01*
|
||||
X14226786Y-11733929D01*
|
||||
X14212500Y-11719643D01*
|
||||
X14198214Y-11691072D01*
|
||||
X14198214Y-11605357D01*
|
||||
X14212500Y-11576786D01*
|
||||
X14226786Y-11562500D01*
|
||||
X14255357Y-11548214D01*
|
||||
X14312500Y-11548214D01*
|
||||
X14341071Y-11562500D01*
|
||||
X14455357Y-11862500D02*
|
||||
X14469643Y-11848214D01*
|
||||
X14498214Y-11805357D01*
|
||||
X14512500Y-11776786D01*
|
||||
X14526786Y-11733929D01*
|
||||
X14541071Y-11662500D01*
|
||||
X14541071Y-11605357D01*
|
||||
X14526786Y-11533929D01*
|
||||
X14512500Y-11491072D01*
|
||||
X14498214Y-11462500D01*
|
||||
X14469643Y-11419643D01*
|
||||
X14455357Y-11405357D01*
|
||||
M02*
|
||||
17
kicad/Output/v1.2/mz25key-NPTH.drl
Normal file
17
kicad/Output/v1.2/mz25key-NPTH.drl
Normal file
@@ -0,0 +1,17 @@
|
||||
M48
|
||||
; DRILL file {KiCad (5.1.2-1)-1} date Wednesday, 26 January 2022 at 01:19:43
|
||||
; FORMAT={-:-/ absolute / metric / decimal}
|
||||
; #@! TF.CreationDate,2022-01-26T01:19:43+00:00
|
||||
; #@! TF.GenerationSoftware,Kicad,Pcbnew,(5.1.2-1)-1
|
||||
; #@! TF.FileFunction,NonPlated,1,2,NPTH
|
||||
FMAT,2
|
||||
METRIC
|
||||
T1C2.100
|
||||
%
|
||||
G90
|
||||
G05
|
||||
T1
|
||||
X91.0Y-83.5
|
||||
X59.2Y-102.7
|
||||
T0
|
||||
M30
|
||||
2643
kicad/Output/v1.2/mz25key-PTH-drl_map.gbr
Normal file
2643
kicad/Output/v1.2/mz25key-PTH-drl_map.gbr
Normal file
File diff suppressed because it is too large
Load Diff
123
kicad/Output/v1.2/mz25key-PTH.drl
Normal file
123
kicad/Output/v1.2/mz25key-PTH.drl
Normal file
@@ -0,0 +1,123 @@
|
||||
M48
|
||||
; DRILL file {KiCad (5.1.2-1)-1} date Wednesday, 26 January 2022 at 01:19:43
|
||||
; FORMAT={-:-/ absolute / metric / decimal}
|
||||
; #@! TF.CreationDate,2022-01-26T01:19:43+00:00
|
||||
; #@! TF.GenerationSoftware,Kicad,Pcbnew,(5.1.2-1)-1
|
||||
; #@! TF.FileFunction,Plated,1,2,PTH
|
||||
FMAT,2
|
||||
METRIC
|
||||
T1C0.300
|
||||
T2C0.400
|
||||
T3C0.500
|
||||
T4C0.650
|
||||
T5C0.800
|
||||
T6C0.900
|
||||
T7C2.000
|
||||
%
|
||||
G90
|
||||
G05
|
||||
T1
|
||||
X52.43Y-97.044
|
||||
X54.362Y-91.265
|
||||
X59.328Y-83.232
|
||||
X60.957Y-94.765
|
||||
X62.377Y-84.112
|
||||
X63.627Y-99.931
|
||||
X63.776Y-90.989
|
||||
X64.027Y-96.46
|
||||
X64.128Y-88.939
|
||||
X64.653Y-97.094
|
||||
X64.795Y-94.713
|
||||
X64.987Y-95.816
|
||||
X65.261Y-85.617
|
||||
X65.92Y-96.502
|
||||
X66.853Y-95.611
|
||||
X66.872Y-100.284
|
||||
X67.017Y-99.702
|
||||
X67.578Y-99.931
|
||||
X68.742Y-92.535
|
||||
X69.636Y-86.157
|
||||
X71.975Y-101.19
|
||||
X73.667Y-100.585
|
||||
X74.308Y-97.665
|
||||
X74.472Y-100.468
|
||||
X74.515Y-85.279
|
||||
X75.548Y-99.429
|
||||
X75.785Y-85.279
|
||||
X75.809Y-98.343
|
||||
X76.105Y-88.682
|
||||
X76.37Y-100.135
|
||||
X77.183Y-97.864
|
||||
X77.669Y-100.572
|
||||
X81.195Y-86.878
|
||||
X81.758Y-99.542
|
||||
X82.023Y-86.735
|
||||
X82.938Y-86.512
|
||||
X89.164Y-94.426
|
||||
X89.781Y-103.65
|
||||
X91.62Y-98.905
|
||||
T2
|
||||
X60.07Y-95.678
|
||||
X60.07Y-96.73
|
||||
X60.19Y-90.54
|
||||
X61.97Y-103.05
|
||||
X68.52Y-98.94
|
||||
X85.8Y-94.04
|
||||
T3
|
||||
X73.13Y-95.68
|
||||
X73.64Y-94.76
|
||||
X74.17Y-95.64
|
||||
X78.96Y-101.81
|
||||
X78.97Y-102.65
|
||||
X80.2Y-101.81
|
||||
X80.23Y-102.65
|
||||
T4
|
||||
X68.37Y-104.56
|
||||
X69.64Y-104.56
|
||||
X64.67Y-104.56
|
||||
X65.94Y-104.56
|
||||
T5
|
||||
X56.14Y-81.83
|
||||
X58.14Y-81.83
|
||||
X60.14Y-81.83
|
||||
X62.14Y-81.83
|
||||
X64.14Y-81.83
|
||||
X66.14Y-81.83
|
||||
X68.14Y-81.83
|
||||
X70.14Y-81.83
|
||||
X55.92Y-85.22
|
||||
X55.92Y-87.22
|
||||
X55.92Y-89.22
|
||||
X55.92Y-91.22
|
||||
X55.92Y-93.22
|
||||
X55.92Y-95.22
|
||||
X55.92Y-97.22
|
||||
X55.92Y-99.22
|
||||
X55.92Y-101.22
|
||||
T6
|
||||
X84.42Y-82.74
|
||||
X86.96Y-82.74
|
||||
X90.28Y-90.145
|
||||
X90.28Y-96.495
|
||||
X92.82Y-90.145
|
||||
X92.82Y-92.177
|
||||
X92.82Y-94.336
|
||||
X92.82Y-96.495
|
||||
T7
|
||||
G00X95.71Y-86.335
|
||||
M15
|
||||
G01X95.01Y-86.335
|
||||
M16
|
||||
G05
|
||||
G00X95.71Y-100.305
|
||||
M15
|
||||
G01X95.01Y-100.305
|
||||
M16
|
||||
G05
|
||||
G00X96.568Y-93.67
|
||||
M15
|
||||
G01X96.568Y-92.97
|
||||
M16
|
||||
G05
|
||||
T0
|
||||
M30
|
||||
17
kicad/Output/v1.2/mz25key-bottom.pos
Normal file
17
kicad/Output/v1.2/mz25key-bottom.pos
Normal file
@@ -0,0 +1,17 @@
|
||||
### Module positions - created on Tuesday, 22 February 2022 at 12:16:19 ###
|
||||
### Printed by Pcbnew version (6.0.1-0)
|
||||
## Unit = mm, Angle = deg.
|
||||
## Side : bottom
|
||||
# Ref Val Package PosX PosY Rot Side
|
||||
C4 100nF C_0805_2012Metric -91.6100 -105.0100 0.0000 bottom
|
||||
Q1 MMDT3904 SOT-363_SC-70-6 -87.7400 -104.5700 0.0000 bottom
|
||||
R8 2K R_0805_2012Metric -96.3200 -97.0800 0.0000 bottom
|
||||
R9 2K R_0805_2012Metric -91.6200 -98.8700 180.0000 bottom
|
||||
R10 10K R_0805_2012Metric -83.9400 -104.9800 0.0000 bottom
|
||||
R11 10K R_0805_2012Metric -91.6200 -100.9500 0.0000 bottom
|
||||
R12 100R R_0805_2012Metric -90.7400 -87.4300 180.0000 bottom
|
||||
R13 100R R_0805_2012Metric -90.5000 -93.6000 -90.0000 bottom
|
||||
R14 10K R_0805_2012Metric -59.2500 -84.5900 180.0000 bottom
|
||||
R15 10K R_0805_2012Metric -91.6200 -103.0200 180.0000 bottom
|
||||
U3 ESP32-S_AI_Thinker ESP32-S -74.9800 -93.2200 -90.0000 bottom
|
||||
## End
|
||||
33
kicad/Output/v1.2/mz25key-top.pos
Normal file
33
kicad/Output/v1.2/mz25key-top.pos
Normal file
@@ -0,0 +1,33 @@
|
||||
### Module positions - created on Tuesday, 22 February 2022 at 12:16:19 ###
|
||||
### Printed by Pcbnew version (6.0.1-0)
|
||||
## Unit = mm, Angle = deg.
|
||||
## Side : top
|
||||
# Ref Val Package PosX PosY Rot Side
|
||||
C1 100uF C_1210_3225Metric_Pad1.42x2.65mm_HandSolder 82.0700 -91.5500 0.0000 top
|
||||
C2 100uF C_1210_3225Metric_Pad1.42x2.65mm_HandSolder 82.0300 -95.6200 0.0000 top
|
||||
C3 100nF C_0805_2012Metric 60.0400 -90.5400 0.0000 top
|
||||
D1 1N4001 D_1206_3216Metric 60.6400 -88.3400 180.0000 top
|
||||
D2 1N4001 D_1206_3216Metric 60.6500 -85.9800 180.0000 top
|
||||
D3 Power LED_D3.0mm_Clear 84.4200 -82.7400 0.0000 top
|
||||
F1 500mA Fuse_1806_4516Metric 75.5100 -88.5400 0.0000 top
|
||||
J1 MZ2500_Keyboard PinHeader_1x09_P2.00mm_Vertical 55.9200 -85.2200 0.0000 top
|
||||
J2 PS/2_Keyboard Mini_din6_ps2 94.0900 -93.3200 90.0000 top
|
||||
J3 PGM/OLED PinHeader_1x08_P2.00mm_Vertical 56.1400 -81.8300 90.0000 top
|
||||
JP1 PGM PinHeader_1x02_P1.27mm_Vertical 69.6400 -104.5600 -90.0000 top
|
||||
JP2 ~{RESET} PinHeader_1x02_P1.27mm_Vertical 65.9400 -104.5600 -90.0000 top
|
||||
LG1 Argo_Logo Argo 75.3300 -85.2800 0.0000 top
|
||||
R1 100R R_0805_2012Metric 52.4500 -87.2400 180.0000 top
|
||||
R2 100R R_0805_2012Metric 52.4700 -89.2100 180.0000 top
|
||||
R3 100R R_0805_2012Metric 52.4700 -91.2000 0.0000 top
|
||||
R4 100R R_0805_2012Metric 52.4500 -93.1600 180.0000 top
|
||||
R5 100R R_0805_2012Metric 52.4500 -95.1400 180.0000 top
|
||||
R6 100R R_0805_2012Metric 52.4300 -97.1000 180.0000 top
|
||||
R7 100R R_0805_2012Metric 52.4500 -99.0600 180.0000 top
|
||||
R16 10K R_0805_2012Metric 75.0600 -102.2300 0.0000 top
|
||||
R17 1K R_0805_2012Metric 66.1600 -89.8700 0.0000 top
|
||||
R18 10K R_0805_2012Metric 69.6600 -86.7500 180.0000 top
|
||||
R19 10K R_0805_2012Metric 66.1400 -86.7500 0.0000 top
|
||||
SW1 WiFi_EN SW_SPST_B3S-1000 83.8700 -102.4400 180.0000 top
|
||||
U1 AMS1117-3.3 SOT-223-3_TabPin2 74.0800 -93.5700 180.0000 top
|
||||
U2 74LS257 SOIC-16_3.9x9.9mm_P1.27mm 63.5300 -95.9400 90.0000 top
|
||||
## End
|
||||
BIN
kicad/Output/v1.2/mz25key_50x26_26012022.zip
Normal file
BIN
kicad/Output/v1.2/mz25key_50x26_26012022.zip
Normal file
Binary file not shown.
4345
kicad/bom/ibom.html
Normal file
4345
kicad/bom/ibom.html
Normal file
File diff suppressed because one or more lines are too long
1
kicad/fp-info-cache
Normal file
1
kicad/fp-info-cache
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
6531
kicad/mz25key_v_1_2.kicad_pcb
Normal file
6531
kicad/mz25key_v_1_2.kicad_pcb
Normal file
File diff suppressed because it is too large
Load Diff
75
kicad/mz25key_v_1_2.kicad_prl
Normal file
75
kicad/mz25key_v_1_2.kicad_prl
Normal file
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"board": {
|
||||
"active_layer": 0,
|
||||
"active_layer_preset": "All Layers",
|
||||
"auto_track_width": true,
|
||||
"hidden_nets": [],
|
||||
"high_contrast_mode": 0,
|
||||
"net_color_mode": 1,
|
||||
"opacity": {
|
||||
"pads": 1.0,
|
||||
"tracks": 1.0,
|
||||
"vias": 1.0,
|
||||
"zones": 0.6
|
||||
},
|
||||
"ratsnest_display_mode": 0,
|
||||
"selection_filter": {
|
||||
"dimensions": true,
|
||||
"footprints": true,
|
||||
"graphics": true,
|
||||
"keepouts": true,
|
||||
"lockedItems": true,
|
||||
"otherItems": true,
|
||||
"pads": true,
|
||||
"text": true,
|
||||
"tracks": true,
|
||||
"vias": true,
|
||||
"zones": true
|
||||
},
|
||||
"visible_items": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36
|
||||
],
|
||||
"visible_layers": "fffffff_ffffffff",
|
||||
"zone_display_mode": 0
|
||||
},
|
||||
"meta": {
|
||||
"filename": "mz25key_v1_2.kicad_prl",
|
||||
"version": 3
|
||||
},
|
||||
"project": {
|
||||
"files": []
|
||||
}
|
||||
}
|
||||
472
kicad/mz25key_v_1_2.kicad_pro
Normal file
472
kicad/mz25key_v_1_2.kicad_pro
Normal file
@@ -0,0 +1,472 @@
|
||||
{
|
||||
"board": {
|
||||
"design_settings": {
|
||||
"defaults": {
|
||||
"board_outline_line_width": 0.049999999999999996,
|
||||
"copper_line_width": 0.19999999999999998,
|
||||
"copper_text_italic": false,
|
||||
"copper_text_size_h": 1.5,
|
||||
"copper_text_size_v": 1.5,
|
||||
"copper_text_thickness": 0.3,
|
||||
"copper_text_upright": false,
|
||||
"courtyard_line_width": 0.049999999999999996,
|
||||
"dimension_precision": 4,
|
||||
"dimension_units": 3,
|
||||
"dimensions": {
|
||||
"arrow_length": 1270000,
|
||||
"extension_offset": 500000,
|
||||
"keep_text_aligned": true,
|
||||
"suppress_zeroes": false,
|
||||
"text_position": 0,
|
||||
"units_format": 1
|
||||
},
|
||||
"fab_line_width": 0.09999999999999999,
|
||||
"fab_text_italic": false,
|
||||
"fab_text_size_h": 1.0,
|
||||
"fab_text_size_v": 1.0,
|
||||
"fab_text_thickness": 0.15,
|
||||
"fab_text_upright": false,
|
||||
"other_line_width": 0.09999999999999999,
|
||||
"other_text_italic": false,
|
||||
"other_text_size_h": 1.0,
|
||||
"other_text_size_v": 1.0,
|
||||
"other_text_thickness": 0.15,
|
||||
"other_text_upright": false,
|
||||
"pads": {
|
||||
"drill": 2.7,
|
||||
"height": 2.5,
|
||||
"width": 3.0
|
||||
},
|
||||
"silk_line_width": 0.12,
|
||||
"silk_text_italic": false,
|
||||
"silk_text_size_h": 1.0,
|
||||
"silk_text_size_v": 1.0,
|
||||
"silk_text_thickness": 0.15,
|
||||
"silk_text_upright": false,
|
||||
"zones": {
|
||||
"45_degree_only": false,
|
||||
"min_clearance": 0.254
|
||||
}
|
||||
},
|
||||
"diff_pair_dimensions": [],
|
||||
"drc_exclusions": [],
|
||||
"meta": {
|
||||
"filename": "board_design_settings.json",
|
||||
"version": 2
|
||||
},
|
||||
"rule_severities": {
|
||||
"annular_width": "error",
|
||||
"clearance": "error",
|
||||
"copper_edge_clearance": "error",
|
||||
"courtyards_overlap": "error",
|
||||
"diff_pair_gap_out_of_range": "error",
|
||||
"diff_pair_uncoupled_length_too_long": "error",
|
||||
"drill_out_of_range": "error",
|
||||
"duplicate_footprints": "warning",
|
||||
"extra_footprint": "warning",
|
||||
"footprint_type_mismatch": "error",
|
||||
"hole_clearance": "error",
|
||||
"hole_near_hole": "error",
|
||||
"invalid_outline": "error",
|
||||
"item_on_disabled_layer": "error",
|
||||
"items_not_allowed": "error",
|
||||
"length_out_of_range": "error",
|
||||
"malformed_courtyard": "error",
|
||||
"microvia_drill_out_of_range": "error",
|
||||
"missing_courtyard": "ignore",
|
||||
"missing_footprint": "warning",
|
||||
"net_conflict": "warning",
|
||||
"npth_inside_courtyard": "ignore",
|
||||
"padstack": "error",
|
||||
"pth_inside_courtyard": "ignore",
|
||||
"shorting_items": "error",
|
||||
"silk_over_copper": "warning",
|
||||
"silk_overlap": "warning",
|
||||
"skew_out_of_range": "error",
|
||||
"through_hole_pad_without_hole": "error",
|
||||
"too_many_vias": "error",
|
||||
"track_dangling": "warning",
|
||||
"track_width": "error",
|
||||
"tracks_crossing": "error",
|
||||
"unconnected_items": "error",
|
||||
"unresolved_variable": "error",
|
||||
"via_dangling": "warning",
|
||||
"zone_has_empty_net": "error",
|
||||
"zones_intersect": "error"
|
||||
},
|
||||
"rule_severitieslegacy_courtyards_overlap": true,
|
||||
"rule_severitieslegacy_no_courtyard_defined": false,
|
||||
"rules": {
|
||||
"allow_blind_buried_vias": false,
|
||||
"allow_microvias": false,
|
||||
"max_error": 0.005,
|
||||
"min_clearance": 0.0,
|
||||
"min_copper_edge_clearance": 0.024999999999999998,
|
||||
"min_hole_clearance": 0.25,
|
||||
"min_hole_to_hole": 0.25,
|
||||
"min_microvia_diameter": 0.19999999999999998,
|
||||
"min_microvia_drill": 0.09999999999999999,
|
||||
"min_silk_clearance": 0.0,
|
||||
"min_through_hole_diameter": 0.3,
|
||||
"min_track_width": 0.15239999999999998,
|
||||
"min_via_annular_width": 0.049999999999999996,
|
||||
"min_via_diameter": 0.39999999999999997,
|
||||
"use_height_for_length_calcs": true
|
||||
},
|
||||
"track_widths": [
|
||||
0.0,
|
||||
0.1524,
|
||||
0.254,
|
||||
0.381,
|
||||
0.508,
|
||||
0.8128
|
||||
],
|
||||
"via_dimensions": [
|
||||
{
|
||||
"diameter": 0.0,
|
||||
"drill": 0.0
|
||||
},
|
||||
{
|
||||
"diameter": 0.5,
|
||||
"drill": 0.3
|
||||
},
|
||||
{
|
||||
"diameter": 0.5,
|
||||
"drill": 0.35
|
||||
},
|
||||
{
|
||||
"diameter": 0.5,
|
||||
"drill": 0.4
|
||||
},
|
||||
{
|
||||
"diameter": 0.8,
|
||||
"drill": 0.5
|
||||
}
|
||||
],
|
||||
"zones_allow_external_fillets": false,
|
||||
"zones_use_no_outline": true
|
||||
},
|
||||
"layer_presets": []
|
||||
},
|
||||
"boards": [],
|
||||
"cvpcb": {
|
||||
"equivalence_files": []
|
||||
},
|
||||
"erc": {
|
||||
"erc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"pin_map": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
]
|
||||
],
|
||||
"rule_severities": {
|
||||
"bus_definition_conflict": "error",
|
||||
"bus_entry_needed": "error",
|
||||
"bus_label_syntax": "error",
|
||||
"bus_to_bus_conflict": "error",
|
||||
"bus_to_net_conflict": "error",
|
||||
"different_unit_footprint": "error",
|
||||
"different_unit_net": "error",
|
||||
"duplicate_reference": "error",
|
||||
"duplicate_sheet_names": "error",
|
||||
"extra_units": "error",
|
||||
"global_label_dangling": "warning",
|
||||
"hier_label_mismatch": "error",
|
||||
"label_dangling": "error",
|
||||
"lib_symbol_issues": "warning",
|
||||
"multiple_net_names": "warning",
|
||||
"net_not_bus_member": "warning",
|
||||
"no_connect_connected": "warning",
|
||||
"no_connect_dangling": "warning",
|
||||
"pin_not_connected": "error",
|
||||
"pin_not_driven": "error",
|
||||
"pin_to_pin": "warning",
|
||||
"power_pin_not_driven": "error",
|
||||
"similar_labels": "warning",
|
||||
"unannotated": "error",
|
||||
"unit_value_mismatch": "error",
|
||||
"unresolved_variable": "error",
|
||||
"wire_dangling": "error"
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"pinned_footprint_libs": [],
|
||||
"pinned_symbol_libs": []
|
||||
},
|
||||
"meta": {
|
||||
"filename": "mz25key_v1_2.kicad_pro",
|
||||
"version": 1
|
||||
},
|
||||
"net_settings": {
|
||||
"classes": [
|
||||
{
|
||||
"bus_width": 12.0,
|
||||
"clearance": 0.2,
|
||||
"diff_pair_gap": 0.25,
|
||||
"diff_pair_via_gap": 0.25,
|
||||
"diff_pair_width": 0.2,
|
||||
"line_style": 0,
|
||||
"microvia_diameter": 0.3,
|
||||
"microvia_drill": 0.1,
|
||||
"name": "Default",
|
||||
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||
"track_width": 0.1524,
|
||||
"via_diameter": 0.4,
|
||||
"via_drill": 0.3,
|
||||
"wire_width": 6.0
|
||||
},
|
||||
{
|
||||
"bus_width": 12.0,
|
||||
"clearance": 0.2,
|
||||
"diff_pair_gap": 0.25,
|
||||
"diff_pair_via_gap": 0.25,
|
||||
"diff_pair_width": 0.2,
|
||||
"line_style": 0,
|
||||
"microvia_diameter": 0.3,
|
||||
"microvia_drill": 0.1,
|
||||
"name": "Power",
|
||||
"nets": [
|
||||
"+5V",
|
||||
"/VCC",
|
||||
"/VCCMZ",
|
||||
"GNDPWR"
|
||||
],
|
||||
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||
"track_width": 0.381,
|
||||
"via_diameter": 0.8,
|
||||
"via_drill": 0.4,
|
||||
"wire_width": 6.0
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"version": 2
|
||||
},
|
||||
"net_colors": null
|
||||
},
|
||||
"pcbnew": {
|
||||
"last_paths": {
|
||||
"gencad": "",
|
||||
"idf": "",
|
||||
"netlist": "",
|
||||
"specctra_dsn": "",
|
||||
"step": "",
|
||||
"vrml": ""
|
||||
},
|
||||
"page_layout_descr_file": ""
|
||||
},
|
||||
"schematic": {
|
||||
"annotate_start_num": 0,
|
||||
"drawing": {
|
||||
"default_line_thickness": 6.0,
|
||||
"default_text_size": 39.0,
|
||||
"field_names": [],
|
||||
"intersheets_ref_own_page": false,
|
||||
"intersheets_ref_prefix": "",
|
||||
"intersheets_ref_short": false,
|
||||
"intersheets_ref_show": false,
|
||||
"intersheets_ref_suffix": "",
|
||||
"junction_size_choice": 3,
|
||||
"label_size_ratio": 0.25,
|
||||
"pin_symbol_size": 0.0,
|
||||
"text_offset_ratio": 0.08
|
||||
},
|
||||
"legacy_lib_dir": "",
|
||||
"legacy_lib_list": [],
|
||||
"meta": {
|
||||
"version": 1
|
||||
},
|
||||
"net_format_name": "",
|
||||
"ngspice": {
|
||||
"fix_include_paths": true,
|
||||
"fix_passive_vals": false,
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"model_mode": 0,
|
||||
"workbook_filename": ""
|
||||
},
|
||||
"page_layout_descr_file": "",
|
||||
"plot_directory": "",
|
||||
"spice_adjust_passive_values": false,
|
||||
"spice_external_command": "spice \"%I\"",
|
||||
"subpart_first_id": 65,
|
||||
"subpart_id_separator": 0
|
||||
},
|
||||
"sheets": [
|
||||
[
|
||||
"6aacdfdc-ee59-4331-8617-399c8000f015",
|
||||
""
|
||||
]
|
||||
],
|
||||
"text_variables": {}
|
||||
}
|
||||
4192
kicad/mz25key_v_1_2.kicad_sch
Normal file
4192
kicad/mz25key_v_1_2.kicad_sch
Normal file
File diff suppressed because it is too large
Load Diff
2558
kicad/mz25key_v_1_2.kicad_sym
Normal file
2558
kicad/mz25key_v_1_2.kicad_sym
Normal file
File diff suppressed because it is too large
Load Diff
3
kicad/sym-lib-table
Normal file
3
kicad/sym-lib-table
Normal file
@@ -0,0 +1,3 @@
|
||||
(sym_lib_table
|
||||
(lib (name "mz25key")(type "KiCad")(uri "${KIPRJMOD}/mz25key_v_1_2.kicad_sym")(options "")(descr ""))
|
||||
)
|
||||
674
license.txt
Normal file
674
license.txt
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
788
main/BT.cpp
Normal file
788
main/BT.cpp
Normal file
@@ -0,0 +1,788 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: BT.cpp
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Bluetooth base class.
|
||||
// This source file contains the class to encapsulate the Bluetooth ESP API. Both
|
||||
// BLE and BT Classic are supported. Allows for scanning, pairing and connection
|
||||
// to a peripheral device such as a Keyboard or Mouse.
|
||||
//
|
||||
// The application uses the Espressif Development environment with Arduino components.
|
||||
// This is necessary as the class uses the Arduino methods for GPIO manipulation. I
|
||||
// was considering using pure Espressif IDF methods but considered the potential
|
||||
// of also using this class on an Arduino project.
|
||||
//
|
||||
// Credits:
|
||||
// Copyright: (c) 2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_bt.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_gap_bt_api.h"
|
||||
#include "esp_bt_device.h"
|
||||
#include "esp_spp_api.h"
|
||||
#include "Arduino.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "BT.h"
|
||||
|
||||
#define SIZEOF_ARRAY(a) (sizeof(a) / sizeof(*a))
|
||||
|
||||
// Out of object pointer to a singleton class for use in the ESP IDF API callback routines which werent written for C++. Other methods can be used but this one is the simplest
|
||||
// to understand and the class can only ever be singleton.
|
||||
BT *pBTThis = NULL;
|
||||
|
||||
// Method to locate a valid scan entry in the results list.
|
||||
//
|
||||
BT::t_scanListItem* BT::findValidScannedDevice(esp_bd_addr_t bda, std::vector<t_scanListItem> &scanList)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
|
||||
// Loop through the scan results list looking for a valid entry, return entry if found.
|
||||
for(std::size_t idx = 0; idx < scanList.size(); idx++)
|
||||
{
|
||||
if (memcmp(bda, scanList[idx].bda, sizeof(esp_bd_addr_t)) == 0)
|
||||
{
|
||||
return &scanList[idx];
|
||||
}
|
||||
}
|
||||
return(nullptr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
// Method to add a valid BT Classic device onto the scan list.
|
||||
//
|
||||
void BT::addBTScanDevice(esp_bd_addr_t bda, esp_bt_cod_t *cod, esp_bt_uuid_t *uuid, uint8_t *name, uint8_t name_len, int rssi)
|
||||
{
|
||||
// Locals.
|
||||
t_scanListItem item;
|
||||
|
||||
// Find a valid device in the BT Classic scan results. If a device is found then this callback is with new data.
|
||||
t_scanListItem* result = findValidScannedDevice(bda, btCtrl.btScanList);
|
||||
if(result)
|
||||
{
|
||||
// Information can be updated through several calls.
|
||||
if(result->name.length() == 0 && name && name_len)
|
||||
{
|
||||
result->name.assign((char *)name, name_len);
|
||||
}
|
||||
if(result->bt.uuid.len == 0 && uuid->len)
|
||||
{
|
||||
memcpy(&result->bt.uuid, uuid, sizeof(esp_bt_uuid_t));
|
||||
}
|
||||
if(rssi != 0)
|
||||
{
|
||||
result->rssi = rssi;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Populate new list item with device results.
|
||||
item.transport = ESP_HID_TRANSPORT_BT;
|
||||
memcpy(item.bda, bda, sizeof(esp_bd_addr_t));
|
||||
memcpy(&item.bt.cod, cod, sizeof(esp_bt_cod_t));
|
||||
memcpy(&item.bt.uuid, uuid, sizeof(esp_bt_uuid_t));
|
||||
item.usage = esp_hid_usage_from_cod((uint32_t)cod);
|
||||
item.rssi = rssi;
|
||||
item.name = "";
|
||||
|
||||
// Store device name if present. This is possibly provided in a seperate callback.
|
||||
if(name_len && name)
|
||||
{
|
||||
item.name.assign((char *)name, name_len);
|
||||
}
|
||||
|
||||
// Add new item onto list.
|
||||
btCtrl.btScanList.push_back(item);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Method to add a valid BLE device to our scan list.
|
||||
//
|
||||
void BT::addBLEScanDevice(esp_bd_addr_t bda, esp_ble_addr_type_t addr_type, uint16_t appearance, uint8_t *name, uint8_t name_len, int rssi)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
t_scanListItem item;
|
||||
|
||||
// See if the device is already in the list, exit if found as data updates with seperate callbacks not normal under BLE.
|
||||
if(findValidScannedDevice(bda, btCtrl.bleScanList))
|
||||
{
|
||||
ESP_LOGW(TAG, "Result already exists!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Populate the item with data.
|
||||
item.transport = ESP_HID_TRANSPORT_BLE;
|
||||
memcpy(item.bda, bda, sizeof(esp_bd_addr_t));
|
||||
item.ble.appearance = appearance;
|
||||
item.ble.addr_type = addr_type;
|
||||
item.usage = esp_hid_usage_from_appearance(appearance);
|
||||
item.rssi = rssi;
|
||||
item.name = "";
|
||||
|
||||
// Store device name if present.
|
||||
if(name_len && name)
|
||||
{
|
||||
item.name.assign((char *)name, name_len);
|
||||
}
|
||||
|
||||
// Add new item onto list.
|
||||
btCtrl.bleScanList.push_back(item);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
// Method to process a device data resulting from a BT scan.
|
||||
//
|
||||
void BT::processBTDeviceScanResult(esp_bt_gap_cb_param_t * param)
|
||||
{
|
||||
// Locals
|
||||
//
|
||||
uint32_t codv = 0;
|
||||
esp_bt_cod_t *cod = (esp_bt_cod_t *)&codv;
|
||||
int8_t rssi = 0;
|
||||
uint8_t *name = nullptr;
|
||||
uint8_t name_len = 0;
|
||||
esp_bt_uuid_t uuid;
|
||||
uint8_t len = 0;
|
||||
uint8_t *data = 0;
|
||||
|
||||
uuid.len = ESP_UUID_LEN_16;
|
||||
uuid.uuid.uuid16 = 0;
|
||||
|
||||
for (int i = 0; i < param->disc_res.num_prop; i++)
|
||||
{
|
||||
esp_bt_gap_dev_prop_t * prop = ¶m->disc_res.prop[i];
|
||||
if(prop->type != ESP_BT_GAP_DEV_PROP_EIR)
|
||||
{
|
||||
}
|
||||
if(prop->type == ESP_BT_GAP_DEV_PROP_BDNAME)
|
||||
{
|
||||
name = (uint8_t *) prop->val;
|
||||
name_len = strlen((const char *)name);
|
||||
}
|
||||
else if(prop->type == ESP_BT_GAP_DEV_PROP_RSSI)
|
||||
{
|
||||
rssi = *((int8_t *) prop->val);
|
||||
}
|
||||
else if(prop->type == ESP_BT_GAP_DEV_PROP_COD)
|
||||
{
|
||||
memcpy(&codv, prop->val, sizeof(uint32_t));
|
||||
}
|
||||
else if(prop->type == ESP_BT_GAP_DEV_PROP_EIR)
|
||||
{
|
||||
data = esp_bt_gap_resolve_eir_data((uint8_t *) prop->val, ESP_BT_EIR_TYPE_CMPL_16BITS_UUID, &len);
|
||||
|
||||
if(data == nullptr)
|
||||
{
|
||||
data = esp_bt_gap_resolve_eir_data((uint8_t *) prop->val, ESP_BT_EIR_TYPE_INCMPL_16BITS_UUID, &len);
|
||||
}
|
||||
|
||||
if(data && len == ESP_UUID_LEN_16)
|
||||
{
|
||||
uuid.len = ESP_UUID_LEN_16;
|
||||
uuid.uuid.uuid16 = data[0] + (data[1] << 8);
|
||||
continue;
|
||||
}
|
||||
|
||||
data = esp_bt_gap_resolve_eir_data((uint8_t *) prop->val, ESP_BT_EIR_TYPE_CMPL_32BITS_UUID, &len);
|
||||
|
||||
if(data == nullptr)
|
||||
{
|
||||
data = esp_bt_gap_resolve_eir_data((uint8_t *) prop->val, ESP_BT_EIR_TYPE_INCMPL_32BITS_UUID, &len);
|
||||
}
|
||||
|
||||
if(data && len == ESP_UUID_LEN_32)
|
||||
{
|
||||
uuid.len = len;
|
||||
memcpy(&uuid.uuid.uuid32, data, sizeof(uint32_t));
|
||||
continue;
|
||||
}
|
||||
|
||||
data = esp_bt_gap_resolve_eir_data((uint8_t *) prop->val, ESP_BT_EIR_TYPE_CMPL_128BITS_UUID, &len);
|
||||
|
||||
if(data == nullptr)
|
||||
{
|
||||
data = esp_bt_gap_resolve_eir_data((uint8_t *) prop->val, ESP_BT_EIR_TYPE_INCMPL_128BITS_UUID, &len);
|
||||
}
|
||||
|
||||
if(data && len == ESP_UUID_LEN_128)
|
||||
{
|
||||
uuid.len = len;
|
||||
memcpy(uuid.uuid.uuid128, (uint8_t *)data, len);
|
||||
continue;
|
||||
}
|
||||
|
||||
//try to find a name
|
||||
if (name == nullptr)
|
||||
{
|
||||
data = esp_bt_gap_resolve_eir_data((uint8_t *) prop->val, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &len);
|
||||
|
||||
if (data == nullptr)
|
||||
{
|
||||
data = esp_bt_gap_resolve_eir_data((uint8_t *) prop->val, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &len);
|
||||
}
|
||||
|
||||
if (data && len)
|
||||
{
|
||||
name = data;
|
||||
name_len = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the found device is a peripheral or a second call on an existing device, add/update the device.
|
||||
if ((cod->major == ESP_BT_COD_MAJOR_DEV_PERIPHERAL) || (findValidScannedDevice(param->disc_res.bda, btCtrl.btScanList) != nullptr))
|
||||
{
|
||||
addBTScanDevice(param->disc_res.bda, cod, &uuid, name, name_len, rssi);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
// BT GAP Event Handler.
|
||||
//
|
||||
void BT::processBTGapEvent(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
|
||||
switch(event)
|
||||
{
|
||||
case ESP_BT_GAP_DISC_STATE_CHANGED_EVT:
|
||||
{
|
||||
ESP_LOGI(TAG, "BT GAP DISC_STATE %s", (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) ? "START" : "STOP");
|
||||
if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED)
|
||||
{
|
||||
// Release semaphore on which the initiator is waiting, this signals processing complete and results ready.
|
||||
xSemaphoreGive(pBTThis->btCtrl.bt_hidh_cb_semaphore);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_BT_GAP_DISC_RES_EVT:
|
||||
{
|
||||
pBTThis->processBTDeviceScanResult(param);
|
||||
break;
|
||||
}
|
||||
case ESP_BT_GAP_KEY_NOTIF_EVT:
|
||||
ESP_LOGI(TAG, "BT GAP KEY_NOTIF passkey:%d", param->key_notif.passkey);
|
||||
if(pBTThis->btCtrl.pairingHandler != nullptr) (*pBTThis->btCtrl.pairingHandler)(param->key_notif.passkey, 1);
|
||||
break;
|
||||
case ESP_BT_GAP_MODE_CHG_EVT:
|
||||
ESP_LOGI(TAG, "BT GAP MODE_CHG_EVT mode:%d", param->mode_chg.mode);
|
||||
break;
|
||||
case ESP_BT_GAP_AUTH_CMPL_EVT:
|
||||
ESP_LOGI(TAG, "BT GAP MODE AUTH_CMPL:%s (%d)", param->auth_cmpl.device_name, param->auth_cmpl.stat);
|
||||
if(pBTThis->btCtrl.pairingHandler != nullptr) (*pBTThis->btCtrl.pairingHandler)((uint32_t)param->auth_cmpl.stat, 2);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "BT GAP EVENT %s", pBTThis->bt_gap_evt_str(event));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Method to process a device data resulting from a BLE scan.
|
||||
//
|
||||
void BT::processBLEDeviceScanResult(esp_ble_gap_cb_param_t *param)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint16_t uuid = 0;
|
||||
uint16_t appearance = 0;
|
||||
char name[64] = "";
|
||||
uint8_t uuid_len = 0;
|
||||
uint8_t *uuid_d = esp_ble_resolve_adv_data(param->scan_rst.ble_adv, ESP_BLE_AD_TYPE_16SRV_CMPL, &uuid_len);
|
||||
uint8_t appearance_len = 0;
|
||||
uint8_t *appearance_d = esp_ble_resolve_adv_data(param->scan_rst.ble_adv, ESP_BLE_AD_TYPE_APPEARANCE, &appearance_len);
|
||||
uint8_t adv_name_len = 0;
|
||||
uint8_t *adv_name = esp_ble_resolve_adv_data(param->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len);
|
||||
|
||||
if (uuid_d != nullptr && uuid_len)
|
||||
{
|
||||
uuid = uuid_d[0] + (uuid_d[1] << 8);
|
||||
}
|
||||
|
||||
if (appearance_d != nullptr && appearance_len)
|
||||
{
|
||||
appearance = appearance_d[0] + (appearance_d[1] << 8);
|
||||
}
|
||||
|
||||
if (adv_name == nullptr)
|
||||
{
|
||||
adv_name = esp_ble_resolve_adv_data(param->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_SHORT, &adv_name_len);
|
||||
}
|
||||
|
||||
if (adv_name != nullptr && adv_name_len)
|
||||
{
|
||||
memcpy(name, adv_name, adv_name_len);
|
||||
name[adv_name_len] = 0;
|
||||
}
|
||||
|
||||
if (uuid == ESP_GATT_UUID_HID_SVC)
|
||||
{
|
||||
addBLEScanDevice(param->scan_rst.bda,
|
||||
param->scan_rst.ble_addr_type,
|
||||
appearance, adv_name, adv_name_len,
|
||||
param->scan_rst.rssi);
|
||||
}
|
||||
}
|
||||
|
||||
// BLE GAP Event Handler.
|
||||
//
|
||||
void BT::processBLEGapEvent(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t * param)
|
||||
{
|
||||
switch(event)
|
||||
{
|
||||
// SCAN
|
||||
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
|
||||
{
|
||||
ESP_LOGI(TAG, "BLE GAP EVENT SCAN_PARAM_SET_COMPLETE");
|
||||
|
||||
// Release semaphore, this releases the caller who initiated the scan as we are now complete.
|
||||
xSemaphoreGive(pBTThis->btCtrl.ble_hidh_cb_semaphore);
|
||||
break;
|
||||
}
|
||||
case ESP_GAP_BLE_SCAN_RESULT_EVT:
|
||||
{
|
||||
switch (param->scan_rst.search_evt)
|
||||
{
|
||||
case ESP_GAP_SEARCH_INQ_RES_EVT:
|
||||
{
|
||||
pBTThis->processBLEDeviceScanResult(param);
|
||||
break;
|
||||
}
|
||||
case ESP_GAP_SEARCH_INQ_CMPL_EVT:
|
||||
ESP_LOGI(TAG, "BLE GAP EVENT SCAN DONE: %d", param->scan_rst.num_resps);
|
||||
|
||||
// Release semaphore, this releases the caller who initiated the scan as we are now complete.
|
||||
xSemaphoreGive(pBTThis->btCtrl.ble_hidh_cb_semaphore);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
|
||||
{
|
||||
ESP_LOGI(TAG, "BLE GAP EVENT SCAN CANCELED");
|
||||
break;
|
||||
}
|
||||
|
||||
// ADVERTISEMENT
|
||||
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
|
||||
ESP_LOGI(TAG, "BLE GAP ADV_DATA_SET_COMPLETE");
|
||||
break;
|
||||
|
||||
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
|
||||
ESP_LOGI(TAG, "BLE GAP ADV_START_COMPLETE");
|
||||
break;
|
||||
|
||||
// AUTHENTICATION
|
||||
case ESP_GAP_BLE_AUTH_CMPL_EVT:
|
||||
if (!param->ble_security.auth_cmpl.success)
|
||||
{
|
||||
ESP_LOGE(TAG, "BLE GAP AUTH ERROR: 0x%x", param->ble_security.auth_cmpl.fail_reason);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "BLE GAP AUTH SUCCESS");
|
||||
}
|
||||
break;
|
||||
|
||||
case ESP_GAP_BLE_KEY_EVT: //shows the ble key info share with peer device to the user.
|
||||
ESP_LOGI(TAG, "BLE GAP KEY type = %s", pBTThis->ble_key_type_str(param->ble_security.ble_key.key_type));
|
||||
break;
|
||||
|
||||
case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: // ESP_IO_CAP_OUT
|
||||
// The app will receive this evt when the IO has Output capability and the peer device IO has Input capability.
|
||||
// Show the passkey number to the user to input it in the peer device.
|
||||
ESP_LOGI(TAG, "BLE GAP PASSKEY_NOTIF passkey:%d", param->ble_security.key_notif.passkey);
|
||||
if(pBTThis->btCtrl.pairingHandler != nullptr) (*pBTThis->btCtrl.pairingHandler)(param->ble_security.key_notif.passkey, 3);
|
||||
break;
|
||||
|
||||
case ESP_GAP_BLE_NC_REQ_EVT: // ESP_IO_CAP_IO
|
||||
// The app will receive this event when the IO has DisplayYesNO capability and the peer device IO also has DisplayYesNo capability.
|
||||
// show the passkey number to the user to confirm it with the number displayed by peer device.
|
||||
ESP_LOGI(TAG, "BLE GAP NC_REQ passkey:%d", param->ble_security.key_notif.passkey);
|
||||
esp_ble_confirm_reply(param->ble_security.key_notif.bd_addr, true);
|
||||
break;
|
||||
|
||||
case ESP_GAP_BLE_PASSKEY_REQ_EVT: // ESP_IO_CAP_IN
|
||||
// The app will receive this evt when the IO has Input capability and the peer device IO has Output capability.
|
||||
// See the passkey number on the peer device and send it back.
|
||||
ESP_LOGI(TAG, "BLE GAP PASSKEY_REQ");
|
||||
//esp_ble_passkey_reply(param->ble_security.ble_req.bd_addr, true, 1234);
|
||||
break;
|
||||
|
||||
case ESP_GAP_BLE_SEC_REQ_EVT:
|
||||
ESP_LOGI(TAG, "BLE GAP SEC_REQ");
|
||||
// Send the positive(true) security response to the peer device to accept the security request.
|
||||
// If not accept the security request, should send the security response with negative(false) accept value.
|
||||
esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true);
|
||||
break;
|
||||
|
||||
case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
|
||||
ESP_LOGI(TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d",
|
||||
param->update_conn_params.status,
|
||||
param->update_conn_params.min_int,
|
||||
param->update_conn_params.max_int,
|
||||
param->update_conn_params.conn_int,
|
||||
param->update_conn_params.latency,
|
||||
param->update_conn_params.timeout);
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "BLE GAP EVENT %s", pBTThis->ble_gap_evt_str(event));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
// Method to scan for BT Classic devices.
|
||||
//
|
||||
esp_err_t BT::scanForBTDevices(uint32_t timeout)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
esp_err_t result = ESP_OK;
|
||||
|
||||
// Start BT GAP Discovery, wait for 'timeout' seconds for a valid result.
|
||||
if((result = esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, (int)(timeout / 1.28), 0)) != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "esp_bt_gap_start_discovery failed: %d", result);
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Method to scan for BLE Devices.
|
||||
//
|
||||
esp_err_t BT::scanForBLEDevices(uint32_t timeout)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
esp_err_t result = ESP_OK;
|
||||
// Setup BLE scan parameters structure, defined in ESP IDF documentation.
|
||||
static esp_ble_scan_params_t hid_scan_params = {
|
||||
.scan_type = BLE_SCAN_TYPE_ACTIVE,
|
||||
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
|
||||
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
|
||||
.scan_interval = 0x50,
|
||||
.scan_window = 0x30,
|
||||
.scan_duplicate = BLE_SCAN_DUPLICATE_ENABLE,
|
||||
};
|
||||
|
||||
// Set scan parameters using populated structure.
|
||||
if((result = esp_ble_gap_set_scan_params(&hid_scan_params)) != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "esp_ble_gap_set_scan_params failed: %d", result);
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Wait for result, this is done by taking possession of a semaphore which is released in the callback when scan complete.
|
||||
xSemaphoreTake(btCtrl.ble_hidh_cb_semaphore, portMAX_DELAY);
|
||||
|
||||
if((result = esp_ble_gap_start_scanning(timeout)) != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "esp_ble_gap_start_scanning failed: %d", result);
|
||||
return(result);
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Method to scan for Bluetooth devices.
|
||||
//
|
||||
esp_err_t BT::scanForAllDevices(uint32_t timeout, size_t *noDevices, std::vector<t_scanListItem> &scanList)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
|
||||
// Clear previous lists.
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
btCtrl.btScanList.clear();
|
||||
#endif
|
||||
btCtrl.bleScanList.clear();
|
||||
|
||||
// Scan for BLE devices.
|
||||
if(scanForBLEDevices(timeout) == ESP_OK)
|
||||
{
|
||||
// Wait for result, this is done by taking possession of a semaphore which is released in the callback when scan complete.
|
||||
xSemaphoreTake(btCtrl.ble_hidh_cb_semaphore, portMAX_DELAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(ESP_FAIL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
// Scan for BT devices
|
||||
if(scanForBTDevices(timeout) == ESP_OK)
|
||||
{
|
||||
// Wait for result, this is done by taking possession of a semaphore which is released in the callback when scan complete.
|
||||
xSemaphoreTake(btCtrl.bt_hidh_cb_semaphore, portMAX_DELAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(ESP_FAIL);
|
||||
}
|
||||
#endif
|
||||
|
||||
//esp_bt_gap_cancel_discovery();
|
||||
//esp_ble_gap_stop_scanning();
|
||||
|
||||
// Process results into a merged list.
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
for(std::size_t idx = 0; idx < btCtrl.btScanList.size(); idx++)
|
||||
{
|
||||
scanList.push_back(btCtrl.btScanList[idx]);
|
||||
}
|
||||
#endif
|
||||
for(std::size_t idx = 0; idx < btCtrl.bleScanList.size(); idx++)
|
||||
{
|
||||
scanList.push_back(btCtrl.bleScanList[idx]);
|
||||
}
|
||||
|
||||
// Update the final list with display values.
|
||||
for(std::size_t idx = 0; idx < scanList.size(); idx++)
|
||||
{
|
||||
char buf[50];
|
||||
sprintf(buf, ESP_BD_ADDR_STR, ESP_BD_ADDR_HEX(scanList[idx].bda));
|
||||
scanList[idx].deviceAddr = buf;
|
||||
if(scanList[idx].transport == ESP_HID_TRANSPORT_BLE)
|
||||
{
|
||||
scanList[idx].deviceType = "BLE";
|
||||
}
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
if(scanList[idx].transport == ESP_HID_TRANSPORT_BT)
|
||||
{
|
||||
scanList[idx].deviceType = "BT";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Save number of entries.
|
||||
*noDevices = scanList.size();
|
||||
|
||||
// Clear BT/BLE lists as data no longer needed.
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
btCtrl.btScanList.clear();
|
||||
#endif
|
||||
btCtrl.bleScanList.clear();
|
||||
|
||||
return(ESP_OK);
|
||||
}
|
||||
|
||||
// Method to scan and build a list for all available devices.
|
||||
void BT::getDeviceList(std::vector<t_scanListItem> &scanList, int waitTime)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
size_t devicesFound = 0;
|
||||
|
||||
ESP_LOGD(TAG, "SCAN...");
|
||||
|
||||
// Clear previous entries.
|
||||
scanList.clear();
|
||||
|
||||
// Start scan for HID devices
|
||||
scanForAllDevices(waitTime, &devicesFound, scanList);
|
||||
|
||||
ESP_LOGD(TAG, "SCAN: %u results", devicesFound);
|
||||
}
|
||||
|
||||
// Method to configure Bluetooth and register required callbacks.
|
||||
bool BT::setup(t_pairingHandler *handler)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
esp_err_t result;
|
||||
const esp_bt_mode_t mode = HIDH_BTDM_MODE;
|
||||
uint8_t key_size = 16;
|
||||
uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
|
||||
uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
|
||||
uint32_t passkey = 123456;
|
||||
uint8_t auth_option = ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_DISABLE;
|
||||
uint8_t oob_support = ESP_BLE_OOB_DISABLE;
|
||||
|
||||
// Check for multiple instantiations, only one instance allowed.
|
||||
if(pBTThis != nullptr)
|
||||
{
|
||||
ESP_LOGE(TAG, "Setup called more than once. Only one instance of BT is allowed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store current object and handlers.
|
||||
pBTThis = this;
|
||||
btCtrl.pairingHandler = handler;
|
||||
|
||||
// Bluetooth not enabled, exit.
|
||||
if(mode == HIDH_IDLE_MODE)
|
||||
{
|
||||
ESP_LOGE(TAG, "Please turn on BT HID host or BLE!");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
// Create BT Classic semaphore, used to halt caller whilst underlying receives and proceses data.
|
||||
btCtrl.bt_hidh_cb_semaphore = xSemaphoreCreateBinary();
|
||||
if (btCtrl.bt_hidh_cb_semaphore == nullptr)
|
||||
{
|
||||
ESP_LOGE(TAG, "xSemaphoreCreateMutex BT failed!");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create BLE semaphore, used to halt caller whilst underlying receives and proceses data.
|
||||
btCtrl.ble_hidh_cb_semaphore = xSemaphoreCreateBinary();
|
||||
if(btCtrl.ble_hidh_cb_semaphore == nullptr)
|
||||
{
|
||||
ESP_LOGE(TAG, "xSemaphoreCreateMutex BLE failed!");
|
||||
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
// Delete BT semaphore as both BT and BLE need to be active, return fail to caller.
|
||||
vSemaphoreDelete(btCtrl.bt_hidh_cb_semaphore);
|
||||
btCtrl.bt_hidh_cb_semaphore = nullptr;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
// Setup default config for BT Classic.
|
||||
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
||||
bt_cfg.mode = mode;
|
||||
bt_cfg.bt_max_acl_conn = 3;
|
||||
bt_cfg.bt_max_sync_conn = 3;
|
||||
|
||||
// Configure Bluetooth controller for BT Classic operation.
|
||||
if((result = esp_bt_controller_init(&bt_cfg)))
|
||||
{
|
||||
ESP_LOGE(TAG, "esp_bt_controller_init failed: %d", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enable Bluetooth Classic mode.
|
||||
if((result = esp_bt_controller_enable(mode)))
|
||||
{
|
||||
ESP_LOGE(TAG, "esp_bt_controller_enable failed: %d", result);
|
||||
return false;
|
||||
}
|
||||
esp_bredr_tx_power_set(ESP_PWR_LVL_P9, ESP_PWR_LVL_P9);
|
||||
#endif
|
||||
|
||||
// Setup and initialise Bluetooth BLE mode.
|
||||
if((result = esp_bluedroid_init()))
|
||||
{
|
||||
ESP_LOGE(TAG, "esp_bluedroid_init failed: %d", result);
|
||||
return false;
|
||||
}
|
||||
if((result = esp_bluedroid_enable()))
|
||||
{
|
||||
ESP_LOGE(TAG, "esp_bluedroid_enable failed: %d", result);
|
||||
return false;
|
||||
}
|
||||
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, ESP_PWR_LVL_P9);
|
||||
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
// Classic Bluetooth GAP
|
||||
esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
|
||||
esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO;
|
||||
esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
|
||||
|
||||
// Set default parameters for Legacy Pairing
|
||||
// Use fixed pin code
|
||||
//
|
||||
esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED;
|
||||
esp_bt_pin_code_t pin_code;
|
||||
pin_code[0] = '1';
|
||||
pin_code[1] = '2';
|
||||
pin_code[2] = '3';
|
||||
pin_code[3] = '4';
|
||||
esp_bt_gap_set_pin(pin_type, 4, pin_code);
|
||||
|
||||
if((result = esp_bt_gap_register_callback(processBTGapEvent)))
|
||||
{
|
||||
ESP_LOGE(TAG, "esp_bt_gap_register_callback failed: %d", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allow BT devices to connect back to us
|
||||
if((result = esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_NON_DISCOVERABLE)))
|
||||
{
|
||||
ESP_LOGE(TAG, "esp_bt_gap_set_scan_mode failed: %d", result);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// BLE GAP
|
||||
if((result = esp_ble_gap_register_callback(processBLEGapEvent)))
|
||||
{
|
||||
ESP_LOGE(TAG, "esp_ble_gap_register_callback failed: %d", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Setup security, no password.
|
||||
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND; // Bonding with peer device after authentication
|
||||
esp_ble_io_cap_t iocapble = ESP_IO_CAP_NONE; // Set the IO capability to No output No input
|
||||
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));
|
||||
esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
|
||||
esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocapble, sizeof(uint8_t));
|
||||
esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
|
||||
esp_ble_gap_set_security_param(ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH, &auth_option, sizeof(uint8_t));
|
||||
esp_ble_gap_set_security_param(ESP_BLE_SM_OOB_SUPPORT, &oob_support, sizeof(uint8_t));
|
||||
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
|
||||
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t));
|
||||
|
||||
// Initialise parameters.
|
||||
btCtrl.batteryLevel = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Basic constructor, do nothing!
|
||||
BT::BT(void)
|
||||
{
|
||||
btCtrl.hidhDevHdl = NULL;
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
btCtrl.pairingHandler = nullptr;
|
||||
btCtrl.bt_hidh_cb_semaphore = nullptr;
|
||||
#endif
|
||||
btCtrl.ble_hidh_cb_semaphore = nullptr;
|
||||
pBTThis = NULL;
|
||||
//
|
||||
}
|
||||
|
||||
// Basic destructor, do nothing! Only ever called for instantiation of uninitialsed class to prove version data.Used for probing versions etc.
|
||||
BT::~BT(void)
|
||||
{
|
||||
//
|
||||
}
|
||||
1011
main/BTHID.cpp
Normal file
1011
main/BTHID.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
set(COMPONENT_SRCS main.cpp ssd1306.c ssd1306_i2c.c ssd1306_spi.c PS2KeyAdvanced.cpp)
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
set(COMPONENT_SRCS SharpKey.cpp NVS.cpp LED.cpp SWITCH.cpp KeyInterface.cpp MZ2528.cpp X1.cpp X68K.cpp Mouse.cpp MZ5665.cpp PC9801.cpp HID.cpp WiFi.cpp PS2KeyAdvanced.cpp PS2Mouse.cpp BT.cpp BTHID.cpp esp_efuse_custom_table.c)
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "." "include")
|
||||
|
||||
register_component()
|
||||
|
||||
1018
main/HID.cpp
Normal file
1018
main/HID.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,49 @@
|
||||
menu "MZ25Key Configuration"
|
||||
menu "SharpKey Configuration"
|
||||
|
||||
choice BUILD_TARGET
|
||||
prompt "Build target"
|
||||
default SHARPKEY
|
||||
help
|
||||
Choose the target of the next build, SHARPKEY for the multi-host SharpKey Interface, MZ25KEY_MZ2500 for the mz25key Interface which will be used
|
||||
with an MZ-2500 or MZ25KEY_MZ2800 for the mz25key Interface which will be used with an MZ-2800.
|
||||
|
||||
config SHARPKEY
|
||||
bool "SharpKey"
|
||||
help
|
||||
Target build for the SharpKey multi-host Interface.
|
||||
|
||||
config MZ25KEY_MZ2500
|
||||
bool "mz25key - MZ2500"
|
||||
help
|
||||
Target build for the mz25key Interface for use on an MZ-2500
|
||||
|
||||
config MZ25KEY_MZ2800
|
||||
bool "mz25key - MZ2800"
|
||||
help
|
||||
Target build for the mz25key Interface for use on an MZ-2800
|
||||
endchoice
|
||||
|
||||
choice FEATURE_SECURITY
|
||||
prompt "Runtime Feature Security"
|
||||
default DISABLE_FEATURE_SECURITY
|
||||
help
|
||||
Choose wether to enable features in the firmware based on fuse settings or to disable the feature.
|
||||
|
||||
config DISABLE_FEATURE_SECURITY
|
||||
bool "Disable feature security"
|
||||
help
|
||||
Disable the feature security, enabling all inbuilt modules of the SharpKey firmware.
|
||||
|
||||
config ENABLE_FEATURE_SECURITY
|
||||
bool "Enable feature security"
|
||||
help
|
||||
Enable feature security, modules will only be available if the corresponding eFuse is set.
|
||||
endchoice
|
||||
|
||||
menu "PS2 Keyboard"
|
||||
|
||||
config PS2_HW_DATAPIN
|
||||
int "GPIO pin number used for the PS/2 DATA line"
|
||||
int "GPIO pin number used for the PS/2 Keyboard DATA line"
|
||||
range 0 46
|
||||
default 14
|
||||
help
|
||||
@@ -12,7 +52,7 @@ menu "MZ25Key Configuration"
|
||||
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"
|
||||
int "GPIO pin number used for the PS/2 Keyboard CLK line"
|
||||
range 0 46
|
||||
default 13
|
||||
help
|
||||
@@ -21,137 +61,139 @@ menu "MZ25Key Configuration"
|
||||
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 "Host Interface"
|
||||
menu "4Bit Strobe Input"
|
||||
|
||||
config MZ_KDB0
|
||||
config HOST_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.
|
||||
GPIO number (IOxx) used to connect the 4bit bidirectional data bus Bit 0 with the ESP32. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDB1
|
||||
config HOST_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.
|
||||
GPIO number (IOxx) used to connect the 4bit bidirectional data bus Bit 1 with the ESP32. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDB2
|
||||
config HOST_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.
|
||||
GPIO number (IOxx) used to connect the 4bit bidirectional data bus Bit 2 with the ESP32. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDB3
|
||||
config HOST_KDB3
|
||||
int "KDB3 GPIO pin number"
|
||||
range 0 46
|
||||
default 27
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 4bit bidirectional data bus Bit 3 with the ESP32. See schematic for actual used value. May change with revisions.
|
||||
GPIO number (IOxx) used to connect the 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
|
||||
config HOST_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.
|
||||
GPIO number (IOxx) used to connect the 8bit scan data output Bit 0 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO1
|
||||
config HOST_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.
|
||||
GPIO number (IOxx) used to connect the 8bit scan data output Bit 1 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO2
|
||||
config HOST_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.
|
||||
GPIO number (IOxx) used to connect the 8bit scan data output Bit 2 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO3
|
||||
config HOST_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.
|
||||
GPIO number (IOxx) used to connect the 8bit scan data output Bit 3 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO4
|
||||
config HOST_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.
|
||||
GPIO number (IOxx) used to connect the 8bit scan data output Bit 4 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO5
|
||||
config HOST_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.
|
||||
GPIO number (IOxx) used to connect the 8bit scan data output Bit 5 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO6
|
||||
config HOST_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.
|
||||
GPIO number (IOxx) used to connect the 8bit scan data output Bit 6 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO7
|
||||
config HOST_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.
|
||||
GPIO number (IOxx) used to connect the 8bit scan data output Bit 7 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
endmenu
|
||||
|
||||
config MZ_RTSNI
|
||||
choice MOUSE_UART_CHOICE
|
||||
prompt "Mouse host side UART"
|
||||
default HOST_BITBANG_UART
|
||||
help
|
||||
Select the hardware method of sending mouse data to the host. The two possible methods are bitbang (software UART) and UART Hardware.
|
||||
config HOST_BITBANG_UART
|
||||
bool "Bitbang UART"
|
||||
help
|
||||
Use the Bitbang UART (software).
|
||||
config HOST_HW_UART
|
||||
bool "Hardware UART"
|
||||
help
|
||||
Use one of the ESP32 Hardware UART's.
|
||||
endchoice
|
||||
|
||||
config HOST_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.
|
||||
GPIO number (IOxx) used to connect the RTSN line with the ESP32. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDI4
|
||||
config HOST_MPXI
|
||||
int "MPXi GPIO pin number"
|
||||
range 0 46
|
||||
default 12
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MPX line with the ESP32. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config HOST_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.
|
||||
GPIO number (IOxx) used to connect the KDI4 line with the ESP32. See schematic for actual used value. May change with revisions.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "WiFi"
|
||||
|
||||
config MZ_WIFI_ENABLED
|
||||
config IF_WIFI_ENABLED
|
||||
bool "Enable WiFi connectivity"
|
||||
default false
|
||||
help
|
||||
@@ -159,57 +201,57 @@ menu "MZ25Key Configuration"
|
||||
key mapping changes.
|
||||
This is an experimental feature and under development.
|
||||
|
||||
config MZ_WIFI_EN_KEY
|
||||
config IF_WIFI_EN_KEY
|
||||
int "WiFi Enable GPIO pin number"
|
||||
range 0 46
|
||||
default 34
|
||||
depends on MZ_WIFI_ENABLED
|
||||
depends on IF_WIFI_ENABLED
|
||||
help
|
||||
GPIO number (IOxx) used by the WiFi En switch to enable wifi connectivity.
|
||||
|
||||
config MZ_SSID
|
||||
config IF_WIFI_SSID
|
||||
string "Default SSID in Access Point Mode"
|
||||
default "mz25key"
|
||||
depends on MZ_WIFI_ENABLED
|
||||
default "sharpkey"
|
||||
depends on IF_WIFI_ENABLED
|
||||
help
|
||||
The SSID broadcast whilst the mz25key module advertises wireless connectivity.
|
||||
The SSID broadcast whilst the sharpkey module advertises wireless connectivity.
|
||||
|
||||
config MZ_DEFAULT_SSID_PWD
|
||||
config IF_WIFI_DEFAULT_SSID_PWD
|
||||
string "Default password for initial connection to Access Point Mode"
|
||||
default "mz25key"
|
||||
depends on MZ_WIFI_ENABLED
|
||||
default "sharpkey"
|
||||
depends on IF_WIFI_ENABLED
|
||||
help
|
||||
The initial password needed to connect and logon to access point.
|
||||
|
||||
config MZ_WIFI_MAX_RETRIES
|
||||
config IF_WIFI_MAX_RETRIES
|
||||
int "Maximum number of connection retries."
|
||||
range 0 100
|
||||
default 10
|
||||
depends on MZ_WIFI_ENABLED
|
||||
depends on IF_WIFI_ENABLED
|
||||
help
|
||||
Number of retries allowed for making a wireless connection with a client.
|
||||
|
||||
config MZ_WIFI_AP_CHANNEL
|
||||
config IF_WIFI_AP_CHANNEL
|
||||
int "Channel of the Access Point."
|
||||
range 0 13
|
||||
default 7
|
||||
depends on MZ_WIFI_ENABLED
|
||||
depends on IF_WIFI_ENABLED
|
||||
help
|
||||
Channel use by the Access Point, default is 7.
|
||||
|
||||
config MZ_WIFI_SSID_HIDDEN
|
||||
config IF_WIFI_SSID_HIDDEN
|
||||
int "Broadcast SSID?"
|
||||
range 0 1
|
||||
default 0
|
||||
depends on MZ_WIFI_ENABLED
|
||||
depends on IF_WIFI_ENABLED
|
||||
help
|
||||
Broadcast the SSID (0) or hide it (1).
|
||||
|
||||
config MZ_WIFI_MAX_CONNECTIONS
|
||||
int "Maximum sinultaneous connections."
|
||||
config IF_WIFI_MAX_CONNECTIONS
|
||||
int "Maximum simultaneous connections."
|
||||
range 0 20
|
||||
default 5
|
||||
depends on MZ_WIFI_ENABLED
|
||||
depends on IF_WIFI_ENABLED
|
||||
help
|
||||
Maximum number of simultaneous open connections supported.
|
||||
|
||||
@@ -217,172 +259,41 @@ menu "MZ25Key Configuration"
|
||||
|
||||
menu "Debug Options"
|
||||
|
||||
menu "OLED"
|
||||
|
||||
choice INTERFACE
|
||||
prompt "OLED Interface Type"
|
||||
default OLED_DISABLED
|
||||
help
|
||||
Select Interface.
|
||||
config OLED_DISABLED
|
||||
bool "Interface disabled"
|
||||
help
|
||||
No OLED present or to be disabled.
|
||||
config I2C_INTERFACE
|
||||
bool "I2C Interface"
|
||||
help
|
||||
I2C Interface.
|
||||
config SPI_INTERFACE
|
||||
bool "SPI Interface"
|
||||
help
|
||||
SPI Interface.
|
||||
endchoice
|
||||
|
||||
choice PANEL
|
||||
prompt "OLED Panel Type"
|
||||
depends on I2C_INTERFACE || SPI_INTERFACE
|
||||
default SSD1306_128x64
|
||||
help
|
||||
Select Panel Type.
|
||||
config SSD1306_128x32
|
||||
bool "128x32 Panel"
|
||||
help
|
||||
Panel is 128x32.
|
||||
config SSD1306_128x64
|
||||
bool "128x64 Panel"
|
||||
help
|
||||
Panel is 128x64.
|
||||
endchoice
|
||||
|
||||
config OFFSETX
|
||||
int "GRAM X OFFSET"
|
||||
range 0 99
|
||||
default 0
|
||||
help
|
||||
When your TFT have offset(X), set it.
|
||||
|
||||
config FLIP
|
||||
bool "Flip upside down"
|
||||
default false
|
||||
help
|
||||
Flip upside down.
|
||||
|
||||
config SCL_GPIO
|
||||
depends on I2C_INTERFACE
|
||||
int "SCL GPIO number"
|
||||
range 0 46
|
||||
default 22 if IDF_TARGET_ESP32
|
||||
default 12 if IDF_TARGET_ESP32S2
|
||||
default 9 if IDF_TARGET_ESP32C3
|
||||
default 15 if IDF_TARGET_HELTEC32
|
||||
help
|
||||
GPIO number (IOxx) to I2C SCL.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
config SDA_GPIO
|
||||
depends on I2C_INTERFACE
|
||||
int "SDA GPIO number"
|
||||
range 0 46
|
||||
default 21 if IDF_TARGET_ESP32
|
||||
default 11 if IDF_TARGET_ESP32S2
|
||||
default 10 if IDF_TARGET_ESP32C3
|
||||
default 4 if IDF_TARGET_HELTEC32
|
||||
help
|
||||
GPIO number (IOxx) to I2C SDA.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
config RESET_GPIO
|
||||
int "RESET GPIO number"
|
||||
range -1 46
|
||||
default -1 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3
|
||||
default 16 if IDF_TARGET_HELTEC32
|
||||
help
|
||||
GPIO number (IOxx) to RESET.
|
||||
When it is -1, RESET isn't performed.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to Reset.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
config MOSI_GPIO
|
||||
depends on SPI_INTERFACE
|
||||
int "MOSI GPIO number"
|
||||
range 0 46
|
||||
default 23 if IDF_TARGET_ESP32
|
||||
default 35 if IDF_TARGET_ESP32S2
|
||||
default 0 if IDF_TARGET_ESP32C3
|
||||
help
|
||||
GPIO number (IOxx) to SPI MOSI.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to DC.
|
||||
On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs.
|
||||
|
||||
config SCLK_GPIO
|
||||
depends on SPI_INTERFACE
|
||||
int "SCLK GPIO number"
|
||||
range 0 46
|
||||
default 18 if IDF_TARGET_ESP32
|
||||
default 36 if IDF_TARGET_ESP32S2
|
||||
default 1 if IDF_TARGET_ESP32C3
|
||||
help
|
||||
GPIO number (IOxx) to SPI SCLK.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to DC.
|
||||
On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs.
|
||||
|
||||
config CS_GPIO
|
||||
depends on SPI_INTERFACE
|
||||
int "CS GPIO number"
|
||||
range 0 34
|
||||
default 5 if IDF_TARGET_ESP32
|
||||
default 34 if IDF_TARGET_ESP32S2
|
||||
default 10 if IDF_TARGET_ESP32C3
|
||||
help
|
||||
GPIO number (IOxx) to SPI CS.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to CS.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
config DC_GPIO
|
||||
depends on SPI_INTERFACE
|
||||
int "DC GPIO number"
|
||||
range 0 34
|
||||
default 2
|
||||
help
|
||||
GPIO number (IOxx) to SPI DC.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to DC.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
endmenu
|
||||
|
||||
config MZ_DEBUG_SERIAL
|
||||
config DEBUG_SERIAL
|
||||
bool "Serial debug output"
|
||||
default false
|
||||
help
|
||||
Enable debug output (non ESP logging) on the serial port.
|
||||
|
||||
config MZ_DISABLE_KDB
|
||||
config DEBUG_DISABLE_KDB
|
||||
bool "Disable input mode actuation of the KDB data bus"
|
||||
default false
|
||||
help
|
||||
Disable the MZ Interface KDB input configuration step, useful feature for debugging.
|
||||
Disable the Host KDB input configuration step, useful feature for debugging.
|
||||
|
||||
config MZ_DISABLE_KDO
|
||||
config DEBUG_DISABLE_KDO
|
||||
bool "Disable output mode actuation of the KDO strobe row"
|
||||
default false
|
||||
help
|
||||
Disable the MZ Interface KDO output configuration step, useful feature for debugging.
|
||||
Disable the Host KDO output configuration step, useful feature for debugging.
|
||||
|
||||
config MZ_DISABLE_RTSNI
|
||||
config DEBUG_DISABLE_RTSNI
|
||||
bool "Disable input mode actuation of the RTSNi signal"
|
||||
default false
|
||||
help
|
||||
Disable the MZ Interface RTSNi input configuration step, useful feature for debugging.
|
||||
Disable the Host RTSNi input configuration step, useful feature for debugging.
|
||||
|
||||
config MZ_DISABLE_KDI
|
||||
config DEBUG_DISABLE_MPXI
|
||||
bool "Disable input mode actuation of the MPXi signal"
|
||||
default false
|
||||
help
|
||||
Disable the Host MPXi input configuration step, useful feature for debugging.
|
||||
|
||||
config DEBUG_DISABLE_KDI
|
||||
bool "Disable input mode actuation of the KDI4 signal"
|
||||
default false
|
||||
help
|
||||
Disable the MZ Interface KDI input configuration step, useful feature for debugging.
|
||||
Disable the Host KDI input configuration step, useful feature for debugging.
|
||||
endmenu
|
||||
|
||||
config PWRLED
|
||||
|
||||
211
main/KeyInterface.cpp
Normal file
211
main/KeyInterface.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: KeyInterface.cpp
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Base class with virtual abstraction of key methods on which all host interfaces,
|
||||
// instantiated as a singleton, are based. This module comprises all common interface
|
||||
// code and the header contains the virtual abstraction methods overriden by the
|
||||
// sub-class which forms an actual interface.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// v1.01 May 2022 - Initial release version.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "driver/timer.h"
|
||||
#include "PS2KeyAdvanced.h"
|
||||
#include "PS2Mouse.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "KeyInterface.h"
|
||||
|
||||
|
||||
// Method to reconfigure the GPIO on ADC2. This is necessary due to an ESP32 issue regarding WiFi Client mode and ADC2. If the
|
||||
// pins are input and wrong value the WiFi Client mode wont connect, if they are output it will connect!! A few issues with the
|
||||
// ESP32 you have to work around, next design, try use ADC2 as outputs only!
|
||||
void KeyInterface::reconfigADC2Ports(bool setAsOutput)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
gpio_config_t io_conf;
|
||||
|
||||
// Configure 4 inputs to be the Strobe Row Number which is used to index the virtual key matrix and the strobe data returned.
|
||||
#if !defined(CONFIG_DEBUG_DISABLE_KDB)
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
io_conf.mode = (setAsOutput == true ? GPIO_MODE_OUTPUT : GPIO_MODE_INPUT);
|
||||
io_conf.pin_bit_mask = (1ULL<<CONFIG_HOST_KDB0);
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
io_conf.pull_up_en = (setAsOutput == true ? GPIO_PULLUP_DISABLE : GPIO_PULLUP_ENABLE);
|
||||
gpio_config(&io_conf);
|
||||
io_conf.pin_bit_mask = (1ULL<<CONFIG_HOST_KDB1);
|
||||
gpio_config(&io_conf);
|
||||
io_conf.pin_bit_mask = (1ULL<<CONFIG_HOST_KDB2);
|
||||
gpio_config(&io_conf);
|
||||
io_conf.pin_bit_mask = (1ULL<<CONFIG_HOST_KDB3);
|
||||
gpio_config(&io_conf);
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_DEBUG_DISABLE_KDI)
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
io_conf.mode = (setAsOutput == true ? GPIO_MODE_OUTPUT : GPIO_MODE_INPUT);
|
||||
io_conf.pin_bit_mask = (1ULL<<CONFIG_HOST_KDI4);
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
io_conf.pull_up_en = (setAsOutput == true ? GPIO_PULLUP_DISABLE : GPIO_PULLUP_ENABLE);
|
||||
gpio_config(&io_conf);
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_DEBUG_DISABLE_MPXI)
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
io_conf.mode = (setAsOutput == true ? GPIO_MODE_OUTPUT : GPIO_MODE_INPUT);
|
||||
io_conf.pin_bit_mask = (1ULL<<CONFIG_HOST_MPXI);
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
io_conf.pull_up_en = (setAsOutput == true ? GPIO_PULLUP_DISABLE : GPIO_PULLUP_ENABLE);
|
||||
gpio_config(&io_conf);
|
||||
#endif
|
||||
|
||||
// In output mode set the drive capability to weak so as not to adversely affect the 74LS257.
|
||||
if(setAsOutput == true)
|
||||
{
|
||||
#if !defined(CONFIG_DEBUG_DISABLE_KDB)
|
||||
gpio_set_drive_capability((gpio_num_t)CONFIG_HOST_KDB0, GPIO_DRIVE_CAP_0);
|
||||
gpio_set_drive_capability((gpio_num_t)CONFIG_HOST_KDB1, GPIO_DRIVE_CAP_0);
|
||||
gpio_set_drive_capability((gpio_num_t)CONFIG_HOST_KDB2, GPIO_DRIVE_CAP_0);
|
||||
gpio_set_drive_capability((gpio_num_t)CONFIG_HOST_KDB3, GPIO_DRIVE_CAP_0);
|
||||
#endif
|
||||
#if !defined(CONFIG_DEBUG_DISABLE_KDI)
|
||||
gpio_set_drive_capability((gpio_num_t)CONFIG_HOST_KDI4, GPIO_DRIVE_CAP_0);
|
||||
#endif
|
||||
#if !defined(CONFIG_DEBUG_DISABLE_MPXI)
|
||||
gpio_set_drive_capability((gpio_num_t)CONFIG_HOST_MPXI, GPIO_DRIVE_CAP_0);
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Method to set the suspend flag. This is needed as some sub-class logic (ie. the MZ sub-class) locks and dedicates a core to meet
|
||||
// required timing. Unfortunately if using some Espressif/Arduino/FreeRTOS API modules (such as WiFi) and a core is held in a spinlock
|
||||
// it appears the API code has been written to use or attach to a fixed core thus the spinlock blocks its operation. Thus this method is provided
|
||||
// so that external logic such as WiFi can disable the interface during these situations.
|
||||
//
|
||||
void KeyInterface::suspendInterface(bool suspendIf)
|
||||
{
|
||||
this->suspend = suspendIf;
|
||||
}
|
||||
|
||||
// Method to test to see if the interface has been suspended.
|
||||
// Two modes, one just tests and returns the state, the second waits in a loop until the interface suspends.
|
||||
//
|
||||
bool KeyInterface::isSuspended(bool waitForSuspend)
|
||||
{
|
||||
// If flag set, loop waiting for the suspended flag to be set.
|
||||
while(waitForSuspend == true && this->suspended == false)
|
||||
{
|
||||
vTaskDelay(1);
|
||||
}
|
||||
|
||||
// Return the suspended status.
|
||||
return(this->suspended);
|
||||
}
|
||||
|
||||
// Method to test to see if the interface is running and not suspended.
|
||||
// Two modes, one just tests and returns the state, the second waits in a loop until the interface runs.
|
||||
bool KeyInterface::isRunning(bool waitForRelease)
|
||||
{
|
||||
// If flag set, loop waiting for the suspended flag to be set.
|
||||
while(waitForRelease == true && this->suspended == true)
|
||||
{
|
||||
vTaskDelay(1);
|
||||
}
|
||||
|
||||
// Return the suspended status.
|
||||
return(this->suspended);
|
||||
}
|
||||
|
||||
// Base initialisation for generic hardware used by all sub-classes. The sub-class invokes the init
|
||||
// method manually from within it's init method.
|
||||
void KeyInterface::init(const char *subClassName, NVS *hdlNVS, LED *hdlLED, HID *hdlHID, uint32_t ifMode)
|
||||
{
|
||||
// Locals
|
||||
#define INITTAG "init"
|
||||
|
||||
// Store the NVS object.
|
||||
this->nvs = hdlNVS;
|
||||
|
||||
// Store the LED object.
|
||||
this->led = hdlLED;
|
||||
|
||||
// Store the HID object.
|
||||
this->hid = hdlHID;
|
||||
|
||||
// Store the sub-class name for later use, ie. NVS key access.
|
||||
this->subClassName = subClassName;
|
||||
|
||||
// Set LED to on.
|
||||
led->setLEDMode(LED::LED_MODE_ON, LED::LED_DUTY_CYCLE_OFF, 0, 0L, 0L);
|
||||
|
||||
// All done, no return code!
|
||||
return;
|
||||
}
|
||||
|
||||
// Base initialisation for generic hardware used by all sub-classes. The sub-class invokes the init
|
||||
// method manually from within it's init method.
|
||||
// This method doesnt initialise hardware, used for objects probing this object data.
|
||||
void KeyInterface::init(const char *subClassName, NVS *hdlNVS, HID *hdlHID)
|
||||
{
|
||||
// Locals
|
||||
#define INITTAG "init"
|
||||
|
||||
// Store the NVS object.
|
||||
this->nvs = hdlNVS;
|
||||
|
||||
// Store the HID object.
|
||||
this->hid = hdlHID;
|
||||
|
||||
// Store the sub-class name for later use, ie. NVS key access.
|
||||
this->subClassName = subClassName;
|
||||
|
||||
// All done, no return code!
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Constructor, basically initialise the Singleton interface and let the threads loose.
|
||||
//KeyInterface::KeyInterface(uint32_t ifMode)
|
||||
//{
|
||||
// // init(className(__PRETTY_FUNCTION__), ifMode);
|
||||
//}
|
||||
|
||||
// Basic constructor, do nothing!
|
||||
//KeyInterface::KeyInterface(void)
|
||||
//{
|
||||
// //
|
||||
//}
|
||||
341
main/LED.cpp
Normal file
341
main/LED.cpp
Normal file
@@ -0,0 +1,341 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: LED.cpp
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Base class for the encapsulation and control methods of an LED used primarily to
|
||||
// indicate to users the status of the application.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// v1.01 May 2022 - Initial release version.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "driver/timer.h"
|
||||
#include "PS2KeyAdvanced.h"
|
||||
#include "PS2Mouse.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "LED.h"
|
||||
|
||||
// Method to set the LED mode, duty cycle and duty period. Once the current LED cycle has come to an end, the control
|
||||
// thread will replace the working configuration with the new configuration set here.
|
||||
//
|
||||
bool LED::setLEDMode(enum LED_MODE mode, enum LED_DUTY_CYCLE dutyCycle, uint32_t maxBlinks, uint64_t usDutyPeriod, uint64_t msInterPeriod)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
bool result = true;
|
||||
|
||||
// If a setup is already waiting to be processed, exit with fail. This could be stacked into a vector but not really beneficial.
|
||||
if(ledCtrl.newConfig.updated == false)
|
||||
{
|
||||
// Ensure we have exclusive access, the LED can be controlled by numerous threads, so ensure only one can access and setup at a time.
|
||||
if(xSemaphoreTake(ledCtrl.mutexInternal, (TickType_t)1000) == pdTRUE)
|
||||
{
|
||||
ledCtrl.newConfig.mode = mode;
|
||||
ledCtrl.newConfig.dutyCycle = dutyCycle;
|
||||
ledCtrl.newConfig.maxBlinks = maxBlinks;
|
||||
ledCtrl.newConfig.dutyPeriod = usDutyPeriod;
|
||||
ledCtrl.newConfig.interPeriod = msInterPeriod;
|
||||
ledCtrl.newConfig.updated = true;
|
||||
|
||||
// Release mutex so other threads can set the LED.
|
||||
xSemaphoreGive(ledCtrl.mutexInternal);
|
||||
} else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
} else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Thread method to provide LED control.
|
||||
IRAM_ATTR void LED::ledInterface(void *pvParameters)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint32_t LED_MASK;
|
||||
uint64_t delayTimer = 0LL;
|
||||
uint64_t curTime = 0LL;
|
||||
enum LEDSTATE {
|
||||
LEDSTATE_IDLE = 0,
|
||||
LEDSTATE_BLINK_MARK = 1,
|
||||
LEDSTATE_BLINK_SPACE = 2,
|
||||
LEDSTATE_BLINK_INTER = 3,
|
||||
} fsmState = LEDSTATE_IDLE;
|
||||
#define LEDIFTAG "ledInterface"
|
||||
|
||||
// Map the instantiating object so we can access its methods and data.
|
||||
LED* pThis = (LED*)pvParameters;
|
||||
|
||||
// Set the LED GPIO mask according to the defined pin. This code needs updating if GPIO1 pins are used.
|
||||
LED_MASK = (1 << pThis->ledCtrl.ledPin);
|
||||
|
||||
// Sign on.
|
||||
ESP_LOGW("ledInterface", "Starting LED control thread.");
|
||||
|
||||
// Turn off LED.
|
||||
GPIO.out_w1tc = LED_MASK;
|
||||
|
||||
// Loops forever.
|
||||
for(;;)
|
||||
{
|
||||
// Check stack space, report if it is getting low.
|
||||
if(uxTaskGetStackHighWaterMark(NULL) < 1024)
|
||||
{
|
||||
ESP_LOGW(LEDIFTAG, "THREAD STACK SPACE(%d)\n",uxTaskGetStackHighWaterMark(NULL));
|
||||
}
|
||||
|
||||
// If a new configuration is set, then once the running FSM has returned to idle, update the configuration prior to the next FSM run.
|
||||
//
|
||||
if(pThis->ledCtrl.newConfig.updated)
|
||||
{
|
||||
// Take control of the Mutex so we are able to take on the data without a new setup clashing. If the Mutex is taken then continue on with the state machine logic till next loop.
|
||||
if(xSemaphoreTake(pThis->ledCtrl.mutexInternal, (TickType_t)1) == pdTRUE)
|
||||
{
|
||||
pThis->ledCtrl.currentConfig = pThis->ledCtrl.newConfig;
|
||||
pThis->ledCtrl.currentConfig.valid = true;
|
||||
pThis->ledCtrl.newConfig.updated = false;
|
||||
pThis->ledCtrl.blinkCnt = 0;
|
||||
|
||||
// Got new setup so release mutex.
|
||||
xSemaphoreGive(pThis->ledCtrl.mutexInternal);
|
||||
}
|
||||
}
|
||||
|
||||
// Only run if we have a valid configuration.
|
||||
if(pThis->ledCtrl.currentConfig.valid)
|
||||
{
|
||||
do {
|
||||
// Get the current timer value, only run the FSM when the timer is idle.
|
||||
timer_get_counter_value(TIMER_GROUP_0, TIMER_1, &curTime);
|
||||
if(curTime >= delayTimer)
|
||||
{
|
||||
// Ensure the timer is stopped.
|
||||
timer_pause(TIMER_GROUP_0, TIMER_1);
|
||||
delayTimer = 0LL;
|
||||
|
||||
// Mini finite state machine for LED control.
|
||||
switch(fsmState)
|
||||
{
|
||||
case LEDSTATE_IDLE:
|
||||
// For on/off, no need for the FSM, just apply setting to LED and loop.
|
||||
switch(pThis->ledCtrl.currentConfig.mode)
|
||||
{
|
||||
case LED_MODE_ON:
|
||||
// Turn on LED.
|
||||
GPIO.out_w1ts = LED_MASK;
|
||||
delayTimer = 1000UL;
|
||||
break;
|
||||
|
||||
case LED_MODE_BLINK_ONESHOT:
|
||||
// If the number of blinks is not 0 then on reaching the count, switch to LED off mode.
|
||||
if(pThis->ledCtrl.currentConfig.maxBlinks > 0 && pThis->ledCtrl.blinkCnt++ >= pThis->ledCtrl.currentConfig.maxBlinks)
|
||||
{
|
||||
pThis->ledCtrl.currentConfig.mode = LED_MODE_OFF;
|
||||
} else
|
||||
{
|
||||
fsmState = LEDSTATE_BLINK_MARK;
|
||||
}
|
||||
break;
|
||||
|
||||
case LED_MODE_BLINK:
|
||||
// Normal blink mode increments the count which is used for determining inter blink period.
|
||||
pThis->ledCtrl.blinkCnt++;
|
||||
fsmState = LEDSTATE_BLINK_MARK;
|
||||
break;
|
||||
|
||||
case LED_MODE_OFF:
|
||||
default:
|
||||
// Turn off LED.
|
||||
GPIO.out_w1tc = LED_MASK;
|
||||
delayTimer = 1000UL;
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case LEDSTATE_BLINK_MARK:
|
||||
// Turn on LED.
|
||||
GPIO.out_w1ts = LED_MASK;
|
||||
|
||||
// Next state, SPACE.
|
||||
fsmState = LEDSTATE_BLINK_SPACE;
|
||||
|
||||
// Calculate time to SPACE.
|
||||
switch(pThis->ledCtrl.currentConfig.dutyCycle)
|
||||
{
|
||||
case LED_DUTY_CYCLE_10:
|
||||
delayTimer = (pThis->ledCtrl.currentConfig.dutyPeriod / 10);
|
||||
break;
|
||||
case LED_DUTY_CYCLE_20:
|
||||
delayTimer = ((pThis->ledCtrl.currentConfig.dutyPeriod / 10) * 2);
|
||||
break;
|
||||
case LED_DUTY_CYCLE_30:
|
||||
delayTimer = ((pThis->ledCtrl.currentConfig.dutyPeriod / 10) * 3);
|
||||
break;
|
||||
case LED_DUTY_CYCLE_40:
|
||||
delayTimer = ((pThis->ledCtrl.currentConfig.dutyPeriod / 10) * 4);
|
||||
break;
|
||||
case LED_DUTY_CYCLE_50:
|
||||
delayTimer = ((pThis->ledCtrl.currentConfig.dutyPeriod / 10) * 5);
|
||||
break;
|
||||
case LED_DUTY_CYCLE_60:
|
||||
delayTimer = ((pThis->ledCtrl.currentConfig.dutyPeriod / 10) * 6);
|
||||
break;
|
||||
case LED_DUTY_CYCLE_70:
|
||||
delayTimer = ((pThis->ledCtrl.currentConfig.dutyPeriod / 10) * 7);
|
||||
break;
|
||||
case LED_DUTY_CYCLE_80:
|
||||
delayTimer = ((pThis->ledCtrl.currentConfig.dutyPeriod / 10) * 8);
|
||||
break;
|
||||
case LED_DUTY_CYCLE_90:
|
||||
delayTimer = ((pThis->ledCtrl.currentConfig.dutyPeriod / 10) * 9);
|
||||
break;
|
||||
// We shouldnt be here if duty cycle is off, so back to idle.
|
||||
case LED_DUTY_CYCLE_OFF:
|
||||
default:
|
||||
GPIO.out_w1tc = LED_MASK;
|
||||
delayTimer = 0;
|
||||
fsmState = LEDSTATE_IDLE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case LEDSTATE_BLINK_SPACE:
|
||||
// Turn off LED.
|
||||
GPIO.out_w1tc = LED_MASK;
|
||||
|
||||
// Calculate time to next MARK.
|
||||
delayTimer = pThis->ledCtrl.currentConfig.dutyPeriod - delayTimer;
|
||||
|
||||
// Now add an interblink delay prior to next blink.
|
||||
fsmState = LEDSTATE_BLINK_INTER;
|
||||
break;
|
||||
|
||||
case LEDSTATE_BLINK_INTER:
|
||||
// If we are in normal mode with a blink limit set and limit reached or in limited mode, then add an interblink delay as configured.
|
||||
if((pThis->ledCtrl.currentConfig.mode == LED_MODE_BLINK && pThis->ledCtrl.currentConfig.maxBlinks > 0 && pThis->ledCtrl.blinkCnt >= pThis->ledCtrl.currentConfig.maxBlinks) ||
|
||||
(pThis->ledCtrl.currentConfig.mode == LED_MODE_BLINK_ONESHOT))
|
||||
{
|
||||
// Interblink delay is given in milli-seconds, so multiply up and set delay.
|
||||
delayTimer = pThis->ledCtrl.currentConfig.interPeriod * 1000;
|
||||
|
||||
// Reset blink counter to trigger next interperiod delay.
|
||||
if(pThis->ledCtrl.currentConfig.mode == LED_MODE_BLINK)
|
||||
pThis->ledCtrl.blinkCnt = 0;
|
||||
}
|
||||
|
||||
// We return to IDLE to allow time for reconfiguration if requested.
|
||||
fsmState = LEDSTATE_IDLE;
|
||||
break;
|
||||
|
||||
// Unknown or not programmed state, return to IDLE.
|
||||
default:
|
||||
fsmState = LEDSTATE_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
// If a new delay is requested, reset the value in the timer and start.
|
||||
if(delayTimer > 0LL)
|
||||
{
|
||||
timer_set_counter_value(TIMER_GROUP_0, TIMER_1, 0LL);
|
||||
timer_start(TIMER_GROUP_0, TIMER_1);
|
||||
}
|
||||
}
|
||||
|
||||
// Give the OS some time...
|
||||
taskYIELD();
|
||||
} while(fsmState != LEDSTATE_IDLE);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method to set the GPIO pin to be used for LED output.
|
||||
void LED::ledInit(uint8_t ledPin)
|
||||
{
|
||||
// Initialise variables.
|
||||
this->ledCtrl.currentConfig.valid = false;
|
||||
this->ledCtrl.currentConfig.updated = false;
|
||||
this->ledCtrl.currentConfig.mode = LED_MODE_OFF;
|
||||
this->ledCtrl.currentConfig.dutyCycle = LED_DUTY_CYCLE_OFF;
|
||||
this->ledCtrl.currentConfig.dutyPeriod = 0LL;
|
||||
this->ledCtrl.currentConfig.interPeriod = 0LL;
|
||||
this->ledCtrl.newConfig = this->ledCtrl.currentConfig;
|
||||
|
||||
// Store GPIO pin to which LED is connected.
|
||||
this->ledCtrl.ledPin = ledPin;
|
||||
|
||||
// Configure a timer to be used for the LED blink rate.
|
||||
timer_config_t timerConfig = {
|
||||
.alarm_en = TIMER_ALARM_DIS, // No alarm, were not using interrupts as we are in a dedicated thread.
|
||||
.counter_en = TIMER_PAUSE, // Timer paused until required.
|
||||
.intr_type = TIMER_INTR_LEVEL, // No interrupts used.
|
||||
.counter_dir = TIMER_COUNT_UP, // Timing a fixed period.
|
||||
.auto_reload = TIMER_AUTORELOAD_DIS, // No need for auto reload, fixed time period.
|
||||
.divider = 80 // 1Mhz operation giving 1uS resolution.
|
||||
};
|
||||
ESP_ERROR_CHECK(timer_init(TIMER_GROUP_0, TIMER_1, &timerConfig));
|
||||
ESP_ERROR_CHECK(timer_set_counter_value(TIMER_GROUP_0, TIMER_1, 0));
|
||||
|
||||
// Setup mutex's.
|
||||
ledCtrl.mutexInternal = xSemaphoreCreateMutex();
|
||||
|
||||
// Core 0 - Application
|
||||
// LED control thread - dedicated thread to control the LED according to set mode.
|
||||
ESP_LOGW("ledInit", "Starting LEDif thread...");
|
||||
::xTaskCreatePinnedToCore(&this->ledInterface, "ledif", 4096, this, 0, &this->TaskLEDIF, 0);
|
||||
}
|
||||
|
||||
// Constructor, basically initialise the Singleton interface and let the control thread loose.
|
||||
LED::LED(uint32_t hwPin)
|
||||
{
|
||||
// Store the class name for later use, ie. NVS key access.
|
||||
this->className = getClassName(__PRETTY_FUNCTION__);
|
||||
|
||||
// Configure the Power LED used for activity and user interaction. Initial state is ON until a keyboard is detected when it turns off and only blinks on keyboard activity.
|
||||
ledInit(hwPin);
|
||||
|
||||
// Initial state, turn on LED to indicate LED control is working.
|
||||
setLEDMode(LED::LED_MODE_ON, LED::LED_DUTY_CYCLE_OFF, 0, 0L, 0L);
|
||||
}
|
||||
|
||||
// Basic constructor, do nothing!
|
||||
LED::LED(void)
|
||||
{
|
||||
// Store the class name for later use, ie. NVS key access.
|
||||
this->className = getClassName(__PRETTY_FUNCTION__);
|
||||
}
|
||||
1244
main/MZ2528.cpp
Normal file
1244
main/MZ2528.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1052
main/MZ5665.cpp
Normal file
1052
main/MZ5665.cpp
Normal file
File diff suppressed because it is too large
Load Diff
729
main/Mouse.cpp
Normal file
729
main/Mouse.cpp
Normal file
@@ -0,0 +1,729 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Mouse.cpp
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: PS/2 Mouse to Sharp Host Interface logic.
|
||||
// This source file contains the singleton class containing logic to obtain
|
||||
// PS/2 mouse data (position, keys etc), map them into Sharp compatible codes and
|
||||
// transmit the data to the connected host.
|
||||
//
|
||||
// The whole application of which this class is a member, uses the Espressif Development
|
||||
// environment with Arduino components.
|
||||
//
|
||||
// Credits:
|
||||
// Copyright: (c) 2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// v1.01 May 2022 - Initial release version.
|
||||
// v1.02 Jun 2022 - Updates to reflect changes realised in other modules due to addition of
|
||||
// bluetooth and suspend logic due to NVS issues using both cores.
|
||||
// Updates to reflect moving functionality into the HID and to support
|
||||
// Bluetooth as a primary mouse or secondary mouse.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <bitset>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <functional>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "driver/uart.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "Arduino.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "driver/timer.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "Mouse.h"
|
||||
|
||||
// Tag for ESP main application logging.
|
||||
#define MAINTAG "Mouse"
|
||||
|
||||
// Mouse Protocol
|
||||
// --------------
|
||||
//
|
||||
//
|
||||
// The Sharp (X68000/X1/MZ-2500/MZ-2800) mouse uses an asynchronous serial protocol over two wires (MSDATA/MSCTRL).
|
||||
// The MSCTRL signal is an enable signal, idle state = HIGH, it goes low prior to transmission of data by at least 1mS and goes high after
|
||||
// transmission of last bit by ~2.56mS.
|
||||
// The MSDATA signal is a standard asynchronous signal, idle = HIGH, 1 start bit, 8 data bits, 2 stop bits @ 4800baud.
|
||||
//
|
||||
// Protocol:
|
||||
// Idle State (MSDATA/MSCTRL) = High.
|
||||
// Transmission: MSCTRL -> LOW
|
||||
// 1ms delay
|
||||
// MSDATA -> low, first start bit.
|
||||
// 3 bytes transmitted in a <1xStart><8xdata><2xstop> format.
|
||||
// MSDATA -> high
|
||||
// 2.56ms delay.
|
||||
// MSCTRL -> HIGH
|
||||
// Data bytes: <CTRL><POS X><POS Y>
|
||||
// CTRL = [7] - Mouse rolling forward when high, backward when low.
|
||||
// [6]
|
||||
// [5] - Mouse rolling left, right when low.
|
||||
// [4]
|
||||
// [3]
|
||||
// [2]
|
||||
// [1] - Right button pressed = HIGH.
|
||||
// [0] - Left button pressed = HIGH.
|
||||
// POS X [7:0] - X Position data.
|
||||
// POS Y [7:0] - Y Position data.
|
||||
|
||||
|
||||
// Method to realise the Sharp host Mouse protocol.
|
||||
// This method uses Core 1 and it will hold it in a spinlock as necessary to ensure accurate timing.
|
||||
// Mouse data is passed into the method via a direct object, using the FreeRTOS Queue creates a time lag resulting in the mouse data being out of sync with hand movement.
|
||||
IRAM_ATTR void Mouse::hostInterface( void * pvParameters )
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
Mouse* pThis = (Mouse*)pvParameters; // Retrieve pointer to object in order to access data.
|
||||
bool msctrlEdge = false;
|
||||
uint8_t txBuf[4];
|
||||
uint32_t MSCTRL_MASK;
|
||||
uint32_t MSDATA_MASK;
|
||||
#ifdef CONFIG_HOST_BITBANG_UART
|
||||
int txPos;
|
||||
int txCnt;
|
||||
uint32_t shiftReg;
|
||||
uint64_t delayTimer = 0LL;
|
||||
uint64_t curTime = 0LL;
|
||||
uint32_t bitCount = 0;
|
||||
enum HOSTXMITSTATE {
|
||||
FSM_IDLE = 0,
|
||||
FSM_STARTXMIT = 1,
|
||||
FSM_STARTBIT = 2,
|
||||
FSM_DATA = 3,
|
||||
FSM_STOP = 4,
|
||||
FSM_ENDXMIT = 5
|
||||
} state = FSM_IDLE;
|
||||
#endif
|
||||
|
||||
// Initialise the MUTEX which prevents this core from being released to other tasks.
|
||||
pThis->x1Mutex = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
if(pThis->hostControl.secondaryIf == false)
|
||||
{
|
||||
MSCTRL_MASK = (1 << CONFIG_HOST_KDB0);
|
||||
MSDATA_MASK = (1 << CONFIG_HOST_KDB1);
|
||||
} else
|
||||
{
|
||||
MSCTRL_MASK = (1 << CONFIG_HOST_KDB0);
|
||||
MSDATA_MASK = (1 << CONFIG_HOST_KDI4);
|
||||
}
|
||||
|
||||
gpio_config_t ioConf;
|
||||
ioConf.intr_type = GPIO_INTR_DISABLE;
|
||||
ioConf.mode = GPIO_MODE_INPUT;
|
||||
ioConf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
ioConf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||
// Both Hardware UART and bitbang need MSCTRL setting as an input.
|
||||
if(pThis->hostControl.secondaryIf == false)
|
||||
{
|
||||
ioConf.pin_bit_mask = (1ULL<<CONFIG_HOST_KDB0);
|
||||
gpio_config(&ioConf);
|
||||
}
|
||||
// Bitbang mode also needs MSDATA setting as an output.
|
||||
#ifdef CONFIG_HOST_BITBANG_UART
|
||||
ioConf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
ioConf.mode = GPIO_MODE_OUTPUT;
|
||||
if(pThis->hostControl.secondaryIf == false)
|
||||
{
|
||||
ioConf.pin_bit_mask = (1ULL<<CONFIG_HOST_KDB1);
|
||||
} else
|
||||
{
|
||||
ioConf.pin_bit_mask = (1ULL<<CONFIG_HOST_KDI4);
|
||||
}
|
||||
gpio_config(&ioConf);
|
||||
|
||||
// Set MSDATA to default state which is high.
|
||||
GPIO.out_w1ts = MSDATA_MASK;
|
||||
#endif
|
||||
|
||||
// Configure a timer to be used for the host mouse asynchronous protocol spacing with 1uS resolution. The default clock source is the APB running at 80MHz.
|
||||
timer_config_t timerConfig = {
|
||||
.alarm_en = TIMER_ALARM_DIS, // No alarm, were not using interrupts as we are in a dedicated thread.
|
||||
.counter_en = TIMER_PAUSE, // Timer paused until required.
|
||||
.intr_type = TIMER_INTR_LEVEL, // No interrupts used.
|
||||
.counter_dir = TIMER_COUNT_UP, // Timing a fixed period.
|
||||
.auto_reload = TIMER_AUTORELOAD_DIS, // No need for auto reload, fixed time period.
|
||||
.divider = 80 // 1Mhz operation giving 1uS resolution.
|
||||
};
|
||||
ESP_ERROR_CHECK(timer_init(TIMER_GROUP_0, TIMER_0, &timerConfig));
|
||||
ESP_ERROR_CHECK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0));
|
||||
|
||||
// Sign on.
|
||||
ESP_LOGW(MAINTAG, "Starting Host side Mouse thread.");
|
||||
|
||||
// Permanent loop, wait for an incoming message on the key to send queue, read it then transmit to the host, repeat!
|
||||
for(;;)
|
||||
{
|
||||
#ifdef CONFIG_HOST_BITBANG_UART
|
||||
// Get the current timer value, only run the FSM when the timer is idle.
|
||||
timer_get_counter_value(TIMER_GROUP_0, TIMER_0, &curTime);
|
||||
if((state == FSM_IDLE && pThis->hostControl.secondaryIf == false) || curTime >= delayTimer)
|
||||
{
|
||||
// Ensure the timer is stopped.
|
||||
timer_pause(TIMER_GROUP_0, TIMER_0);
|
||||
delayTimer = 0LL;
|
||||
|
||||
// Finite state machine to retrieve a key for transmission then serialise it according to the X1 protocol.
|
||||
switch(state)
|
||||
{
|
||||
case FSM_IDLE:
|
||||
// Yield if the suspend flag is set.
|
||||
pThis->yield(0);
|
||||
|
||||
// Check stack space, report if it is getting low.
|
||||
if(uxTaskGetStackHighWaterMark(NULL) < 1024)
|
||||
{
|
||||
ESP_LOGW(MAINTAG, "THREAD STACK SPACE(%d)\n",uxTaskGetStackHighWaterMark(NULL));
|
||||
}
|
||||
|
||||
if(pThis->hostControl.secondaryIf == false)
|
||||
{
|
||||
// Detect high to low edge. On mouse primary mode the MSCTRL signal forces the tempo. On mouse secondary mode (operating in tandem to keyboard),
|
||||
// the timer forces the tempo.
|
||||
//
|
||||
msctrlEdge = (REG_READ(GPIO_IN_REG) & MSCTRL_MASK) != 0 ? true : msctrlEdge;
|
||||
}
|
||||
|
||||
// Wait for a window when MSCTRL goes low.
|
||||
if(pThis->hostControl.secondaryIf == true || (msctrlEdge == true && (REG_READ(GPIO_IN_REG) & MSCTRL_MASK) == 0))
|
||||
{
|
||||
// Wait for incoming mouse movement message.
|
||||
if(pThis->xmitMsg.valid)
|
||||
{
|
||||
txBuf[0] = (uint8_t)pThis->xmitMsg.status;
|
||||
txBuf[1] = (uint8_t)pThis->xmitMsg.xPos;
|
||||
txBuf[2] = (uint8_t)pThis->xmitMsg.yPos;
|
||||
pThis->xmitMsg.valid = false; // Shouldnt be a race state here but consider a mutex if mouse gets out of sync.
|
||||
txBuf[3] = 0x00;
|
||||
txPos = 0;
|
||||
txCnt = 3;
|
||||
} else
|
||||
{
|
||||
// Sharp host protocol requires us to send zero change messages on a regular period regardless of new data.
|
||||
txBuf[0] = 0x00;
|
||||
txBuf[1] = 0x00;
|
||||
txBuf[2] = 0x00;
|
||||
txBuf[3] = 0x00;
|
||||
txPos = 0;
|
||||
txCnt = 3;
|
||||
}
|
||||
|
||||
// Advance to first start bit.
|
||||
state = FSM_STARTXMIT;
|
||||
|
||||
// Clear edge detect for next loop.
|
||||
msctrlEdge = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSM_STARTXMIT:
|
||||
// Ensure all variables and states correct before entering serialisation.
|
||||
GPIO.out_w1ts = MSDATA_MASK;
|
||||
state = FSM_STARTBIT;
|
||||
bitCount = 8;
|
||||
shiftReg = txBuf[txPos++];
|
||||
txCnt--;
|
||||
|
||||
// Create, initialise and hold a spinlock so the current core is bound to this one method.
|
||||
portENTER_CRITICAL(&pThis->x1Mutex);
|
||||
|
||||
break;
|
||||
|
||||
case FSM_STARTBIT:
|
||||
// Send out the start bit by bringing MSDATA low for 208us (4800 baud 1bit time period).
|
||||
GPIO.out_w1tc = MSDATA_MASK;
|
||||
delayTimer = BITBANG_UART_BIT_TIME;
|
||||
state = FSM_DATA;
|
||||
break;
|
||||
|
||||
case FSM_DATA:
|
||||
if(bitCount > 0)
|
||||
{
|
||||
// Setup the bit on MSDATA
|
||||
if(shiftReg & 0x00000001)
|
||||
{
|
||||
GPIO.out_w1ts = MSDATA_MASK;
|
||||
} else
|
||||
{
|
||||
GPIO.out_w1tc = MSDATA_MASK;
|
||||
}
|
||||
|
||||
// Shift the data to the next bit for transmission.
|
||||
shiftReg = shiftReg >> 1;
|
||||
|
||||
// 1 bit period.
|
||||
delayTimer = BITBANG_UART_BIT_TIME;
|
||||
|
||||
// 1 Less bit in frame.
|
||||
bitCount--;
|
||||
} else
|
||||
{
|
||||
state = FSM_STOP;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSM_STOP:
|
||||
// Send out the stop bit, 2 are needed so just adjust the time delay.
|
||||
GPIO.out_w1ts = MSDATA_MASK;
|
||||
delayTimer = BITBANG_UART_BIT_TIME * 2;
|
||||
state = FSM_ENDXMIT;
|
||||
break;
|
||||
|
||||
case FSM_ENDXMIT:
|
||||
// End of critical timing loop, release the core so other tasks can run whilst we load up the next byte.
|
||||
portEXIT_CRITICAL(&pThis->x1Mutex);
|
||||
|
||||
// Any more bytes to transmit, loop and send if there are.
|
||||
if(txCnt > 0)
|
||||
{
|
||||
state = FSM_STARTXMIT;
|
||||
} else
|
||||
{
|
||||
// Reset timer for next loop.
|
||||
delayTimer = 20000UL;
|
||||
state = FSM_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// If a new delay is requested, set the value into the timer and start.
|
||||
if(delayTimer > 0LL)
|
||||
{
|
||||
timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0LL);
|
||||
timer_start(TIMER_GROUP_0, TIMER_0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HOST_HW_UART
|
||||
// Get the current timer value, we need to wait 20ms between transmissions.
|
||||
timer_get_counter_value(TIMER_GROUP_0, TIMER_0, &curTime);
|
||||
if(curTime >= delayTimer)
|
||||
{
|
||||
// Wait for a window when MSCTRL goes low.
|
||||
if(pThis->hostControl.secondaryIf == true || (REG_READ(GPIO_IN_REG) & MSCTRL_MASK) == 0)
|
||||
{
|
||||
// Ensure the timer is stopped, initialise to 0 and restart.
|
||||
timer_pause(TIMER_GROUP_0, TIMER_0);
|
||||
delayTimer = 20000LL;
|
||||
timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0LL);
|
||||
timer_start(TIMER_GROUP_0, TIMER_0);
|
||||
|
||||
// Wait for incoming mouse movement message.
|
||||
if(pThis->xmitMsg.valid)
|
||||
{
|
||||
txBuf[0] = (uint8_t)pThis->xmitMsg.status;
|
||||
txBuf[1] = (uint8_t)pThis->xmitMsg.xPos;
|
||||
txBuf[2] = (uint8_t)pThis->xmitMsg.yPos;
|
||||
pThis->xmitMsg.valid = false; // Shouldnt be a race state here but consider a mutex if mouse gets out of sync.
|
||||
txBuf[3] = 0x00;
|
||||
txPos = 0;
|
||||
txCnt = 3;
|
||||
} else
|
||||
{
|
||||
// Sharp host protocol requires us to send zero change messages on a regular period regardless of new data.
|
||||
txBuf[0] = 0x00;
|
||||
txBuf[1] = 0x00;
|
||||
txBuf[2] = 0x00;
|
||||
txBuf[3] = 0x00;
|
||||
txPos = 0;
|
||||
txCnt = 3;
|
||||
}
|
||||
|
||||
// Send the bytes and wait.
|
||||
uart_write_bytes(pThis->hostControl.uartNum, (const char *)txBuf, 3);
|
||||
|
||||
// This method doesnt actually return after the last byte is transmitted, it returns well before, so we tack on a 10ms delay which is the width for 3 bytes at 4800 baud.
|
||||
uart_wait_tx_done(pThis->hostControl.uartNum, 25000);
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
// Check stack space, report if it is getting low.
|
||||
if(uxTaskGetStackHighWaterMark(NULL) < 1024)
|
||||
{
|
||||
ESP_LOGW(MAPKEYTAG, "THREAD STACK SPACE(%d)\n",uxTaskGetStackHighWaterMark(NULL));
|
||||
}
|
||||
|
||||
// Yield if the suspend flag is set.
|
||||
pThis->yield(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Logic to feed the watchdog if needed. Watchdog disabled in menuconfig but if enabled this will need to be used.
|
||||
//TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable
|
||||
//TIMERG0.wdt_feed=1; // feed dog
|
||||
//TIMERG0.wdt_wprotect=0; // write protect
|
||||
//TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable
|
||||
//TIMERG1.wdt_feed=1; // feed dog
|
||||
//TIMERG1.wdt_wprotect=0; // write protect
|
||||
}
|
||||
}
|
||||
|
||||
// Primary HID routine.
|
||||
// This method is responsible for receiving HID (PS/2 or BT) mouse scan data and mapping it into Sharp compatible mouse data.
|
||||
// The HID mouse data once received is mapped and pushed onto a FIFO queue for transmission to the host.
|
||||
//
|
||||
void Mouse::mouseReceiveData(HID::t_mouseMessageElement mouseMessage)
|
||||
{
|
||||
// Locals.
|
||||
uint8_t status;
|
||||
|
||||
// Invert Y as the Sharp host is inverted compared to a PS/2 on the Y axis.
|
||||
mouseMessage.yPos = -mouseMessage.yPos;
|
||||
|
||||
// Initialise the status flag, on the Sharp host it is <Y Overflow><Y Underflow><X Overflow><X Underflow><1><0><Right Button><Left Button>
|
||||
status = (((mouseMessage.xPos >> 8) & 0x01) << 4) | (mouseMessage.status & 0x0F );
|
||||
|
||||
// Check bounds and set flags accordingly.
|
||||
if(mouseMessage.xPos > 127)
|
||||
{
|
||||
mouseMessage.xPos = 127; // Maximum resolution of Sharp host X movement.
|
||||
status |= (1UL << 4); // Set overflow bit.
|
||||
}
|
||||
if(mouseMessage.xPos < -128)
|
||||
{
|
||||
mouseMessage.xPos = -128; // Minimum resolution of Sharp host X movement.
|
||||
status |= (1UL << 5); // Set underflow bit.
|
||||
}
|
||||
if(mouseMessage.yPos > 127)
|
||||
{
|
||||
mouseMessage.yPos = 127; // Maximum resolution of Sharp host Y movement.
|
||||
status |= (1UL << 6); // Set overflow bit.
|
||||
}
|
||||
if(mouseMessage.yPos < -128)
|
||||
{
|
||||
mouseMessage.yPos = -128; // Minimum resolution of Sharp host Y movement.
|
||||
status |= (1UL << 7); // Set underflow bit.
|
||||
}
|
||||
|
||||
// Convert back to 8bit 2's compliment and store in the host message to the host thread.
|
||||
xmitMsg.xPos = (int8_t)mouseMessage.xPos;
|
||||
xmitMsg.yPos = (int8_t)mouseMessage.yPos;
|
||||
xmitMsg.status = status;
|
||||
xmitMsg.wheel = mouseMessage.wheel;
|
||||
xmitMsg.valid = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// A method to return the Type of data for a given column in the KeyMap table.
|
||||
//
|
||||
void Mouse::getMouseConfigTypes(std::vector<std::string>& typeList)
|
||||
{
|
||||
// Add the types.
|
||||
//
|
||||
typeList.push_back(HID_MOUSE_HOST_SCALING_TYPE);
|
||||
typeList.push_back(HID_MOUSE_SCALING_TYPE);
|
||||
typeList.push_back(HID_MOUSE_RESOLUTION_TYPE);
|
||||
typeList.push_back(HID_MOUSE_SAMPLING_TYPE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Method to return a list of key:value entries for a given config category. This represents the
|
||||
// feature which can be selected and the value it uses. Features can be combined by ORing the values
|
||||
// together.
|
||||
bool Mouse::getMouseSelectList(std::vector<std::pair<std::string, int>>& selectList, std::string option)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
bool result = true;
|
||||
|
||||
// Build up a map, depending on the list required, of name to value. This list can then be used
|
||||
// by a user front end to select an option based on a name and return its value.
|
||||
if(option.compare(HID_MOUSE_HOST_SCALING_TYPE) == 0)
|
||||
{
|
||||
selectList.push_back(std::make_pair("ACTIVE", mouseConfig.host.scaling));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_HOST_SCALING_1_1_NAME, HID::HID_MOUSE_HOST_SCALING_1_1));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_HOST_SCALING_1_2_NAME, HID::HID_MOUSE_HOST_SCALING_1_2));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_HOST_SCALING_1_3_NAME, HID::HID_MOUSE_HOST_SCALING_1_3));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_HOST_SCALING_1_4_NAME, HID::HID_MOUSE_HOST_SCALING_1_4));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_HOST_SCALING_1_5_NAME, HID::HID_MOUSE_HOST_SCALING_1_5));
|
||||
}
|
||||
else if(option.compare(HID_MOUSE_SCALING_TYPE) == 0)
|
||||
{
|
||||
selectList.push_back(std::make_pair("ACTIVE", mouseConfig.mouse.scaling));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_SCALING_1_1_NAME, HID::HID_MOUSE_SCALING_1_1));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_SCALING_2_1_NAME, HID::HID_MOUSE_SCALING_2_1));
|
||||
}
|
||||
else if(option.compare(HID_MOUSE_RESOLUTION_TYPE) == 0)
|
||||
{
|
||||
selectList.push_back(std::make_pair("ACTIVE", mouseConfig.mouse.resolution));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_RESOLUTION_1_1_NAME, HID::HID_MOUSE_RESOLUTION_1_1));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_RESOLUTION_1_2_NAME, HID::HID_MOUSE_RESOLUTION_1_2));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_RESOLUTION_1_4_NAME, HID::HID_MOUSE_RESOLUTION_1_4));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_RESOLUTION_1_8_NAME, HID::HID_MOUSE_RESOLUTION_1_8));
|
||||
}
|
||||
else if(option.compare(HID_MOUSE_SAMPLING_TYPE) == 0)
|
||||
{
|
||||
selectList.push_back(std::make_pair("ACTIVE", mouseConfig.mouse.sampleRate));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_SAMPLE_RATE_10_NAME, HID::HID_MOUSE_SAMPLE_RATE_10));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_SAMPLE_RATE_20_NAME, HID::HID_MOUSE_SAMPLE_RATE_20));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_SAMPLE_RATE_40_NAME, HID::HID_MOUSE_SAMPLE_RATE_40));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_SAMPLE_RATE_60_NAME, HID::HID_MOUSE_SAMPLE_RATE_60));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_SAMPLE_RATE_80_NAME, HID::HID_MOUSE_SAMPLE_RATE_80));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_SAMPLE_RATE_100_NAME, HID::HID_MOUSE_SAMPLE_RATE_100));
|
||||
selectList.push_back(std::make_pair(HID_MOUSE_SAMPLE_RATE_200_NAME, HID::HID_MOUSE_SAMPLE_RATE_200));
|
||||
} else
|
||||
{
|
||||
// Not found!
|
||||
result = false;
|
||||
}
|
||||
|
||||
// Return result, false if the option not found, true otherwise.
|
||||
//
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Public method to set the mouse configuration parameters.
|
||||
//
|
||||
bool Mouse::setMouseConfigValue(std::string paramName, std::string paramValue)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
bool dataError = false;
|
||||
int value(0);
|
||||
std::stringstream testVal(paramValue);
|
||||
|
||||
// Match the parameter name to a known mouse parameter, type and data check the parameter value and assign to the config accordingly.
|
||||
if(paramName.compare(HID_MOUSE_HOST_SCALING_TYPE) == 0)
|
||||
{
|
||||
// Exception handling is disabled, stringstream is used to catch bad input.
|
||||
dataError = (static_cast<bool>(testVal >> value) ? false : true);
|
||||
if(dataError == false)
|
||||
{
|
||||
if(value >= to_underlying(HID::HID_MOUSE_HOST_SCALING_1_1) && value <= to_underlying(HID::HID_MOUSE_HOST_SCALING_1_5))
|
||||
{
|
||||
mouseConfig.host.scaling = static_cast<HID::HID_MOUSE_HOST_SCALING>(value);
|
||||
hid->setMouseHostScaling(mouseConfig.host.scaling);
|
||||
} else
|
||||
{
|
||||
dataError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(paramName.compare(HID_MOUSE_SCALING_TYPE) == 0)
|
||||
{
|
||||
dataError = (static_cast<bool>(testVal >> value) ? false : true);
|
||||
if(dataError == false)
|
||||
{
|
||||
if(value >= to_underlying(HID::HID_MOUSE_SCALING_1_1) && value <= to_underlying(HID::HID_MOUSE_SCALING_2_1))
|
||||
{
|
||||
mouseConfig.mouse.scaling = static_cast<HID::HID_MOUSE_SCALING>(value);
|
||||
hid->setMouseScaling(mouseConfig.mouse.scaling);
|
||||
} else
|
||||
{
|
||||
dataError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(paramName.compare(HID_MOUSE_RESOLUTION_TYPE) == 0)
|
||||
{
|
||||
dataError = (static_cast<bool>(testVal >> value) ? false : true);
|
||||
if(dataError == false)
|
||||
{
|
||||
if(value >= to_underlying(HID::HID_MOUSE_RESOLUTION_1_1) && value <= to_underlying(HID::HID_MOUSE_RESOLUTION_1_8))
|
||||
{
|
||||
mouseConfig.mouse.resolution = static_cast<HID::HID_MOUSE_RESOLUTION>(value);
|
||||
hid->setMouseResolution(mouseConfig.mouse.resolution);
|
||||
} else
|
||||
{
|
||||
dataError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(paramName.compare(HID_MOUSE_SAMPLING_TYPE) == 0)
|
||||
{
|
||||
dataError = (static_cast<bool>(testVal >> value) ? false : true);
|
||||
if(dataError == false)
|
||||
{
|
||||
if(value >= to_underlying(HID::HID_MOUSE_SAMPLE_RATE_10) && value <= to_underlying(HID::HID_MOUSE_SAMPLE_RATE_200))
|
||||
{
|
||||
mouseConfig.mouse.sampleRate = static_cast<HID::HID_MOUSE_SAMPLING>(value);
|
||||
hid->setMouseSampleRate(mouseConfig.mouse.sampleRate);
|
||||
} else
|
||||
{
|
||||
dataError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Error = true, success = false.
|
||||
return(dataError);
|
||||
}
|
||||
|
||||
// Method to save (persist) the configuration into NVS RAM.
|
||||
bool Mouse::persistConfig(void)
|
||||
{
|
||||
// Locals.
|
||||
bool result = true;
|
||||
|
||||
// Persist the data for next time.
|
||||
if(nvs->persistData(getClassName(__PRETTY_FUNCTION__), &this->mouseConfig, sizeof(t_mouseConfig)) == false)
|
||||
{
|
||||
ESP_LOGW(MAINTAG, "Persisting Mouse configuration data failed, check NVS setup.\n");
|
||||
result = false;
|
||||
}
|
||||
// Few other updates so make a commit here to ensure data is flushed and written.
|
||||
else if(nvs->commitData() == false)
|
||||
{
|
||||
ESP_LOGW(MAINTAG, "NVS Commit writes operation failed, some previous writes may not persist in future power cycles.");
|
||||
}
|
||||
|
||||
// Request persistence in the HID module.
|
||||
result |= hid->persistConfig();
|
||||
|
||||
// Error = false, success = true.
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Initialisation routine. Start two threads, one to handle the incoming PS/2 mouse data and map it, the second to handle the host interface.
|
||||
void Mouse::init(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID)
|
||||
{
|
||||
// Initialise control variables.
|
||||
#ifdef CONFIG_HOST_HW_UART
|
||||
hostControl.uartNum = UART_NUM_2;
|
||||
hostControl.uartBufferSize = 256;
|
||||
hostControl.uartQueueSize = 10;
|
||||
#endif
|
||||
|
||||
// Initialise the basic components.
|
||||
init(hdlNVS, hdlHID);
|
||||
|
||||
// Invoke the prototype init which initialises common variables and devices shared by all subclass.
|
||||
KeyInterface::init(getClassName(__PRETTY_FUNCTION__), hdlNVS, hdlLED, hdlHID, ifMode);
|
||||
|
||||
// There are two build possibilities, hardware UART and BITBANG. I initially coded using hardware but whilst trying to find a bug, wrote a bitbang
|
||||
// technique and both are fit for purpose, so enabling either yields the same result.
|
||||
#ifdef CONFIG_HOST_HW_UART
|
||||
// Prepare the UART to be used for communications with the Sharp host.
|
||||
// The Sharp host Mouse uses an Asynchronous protocol with 2 stop bits no parity 4800 baud.
|
||||
//
|
||||
uart_config_t uartConfig = {
|
||||
.baud_rate = 4800,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_2,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 122,
|
||||
.source_clk = UART_SCLK_APB,
|
||||
};
|
||||
|
||||
// Configure UART parameters and pin assignments, software flow control, not RTS/CTS.
|
||||
// The mouse only uses a Tx line, the MSCTRL line is used as a gate signal, so assign the Rx line to an unused pin.
|
||||
ESP_ERROR_CHECK(uart_param_config(hostControl.uartNum, &uartConfig));
|
||||
ESP_ERROR_CHECK(uart_set_pin(hostControl.uartNum, CONFIG_HOST_KDB1, CONFIG_HOST_KDB2, -1, -1));
|
||||
// Install UART driver. Use RX/TX buffers without event queue.
|
||||
ESP_ERROR_CHECK(uart_driver_install(hostControl.uartNum, hostControl.uartBufferSize, hostControl.uartBufferSize, 0, NULL, 0));
|
||||
#endif
|
||||
|
||||
// Register the streaming callback for the mouse, this will receive data, process it and send to the hostInterface for transmission to the host.
|
||||
hid->setDataCallback(&Mouse::mouseReceiveData, this);
|
||||
|
||||
// Create a task pinned to core 1 which will fulfill the Sharp Mouse host interface. This task has the highest priority
|
||||
// and it will also hold spinlock and manipulate the watchdog to ensure a scan cycle timing can be met. This means
|
||||
// all other tasks running on Core 1 will suspend as needed. The HID mouse controller will be serviced with core 0.
|
||||
//
|
||||
// Core 1 - Sharp Mouse Host Interface
|
||||
ESP_LOGW(MAINTAG, "Starting mouseIf thread...");
|
||||
::xTaskCreatePinnedToCore(&this->hostInterface, "mouseIf", 4096, this, 25, &this->TaskHostIF, 1);
|
||||
vTaskDelay(500);
|
||||
}
|
||||
|
||||
// Initialisation routine without hardware.
|
||||
void Mouse::init(NVS *hdlNVS, HID *hdlHID)
|
||||
{
|
||||
// Invoke the prototype init which initialises common variables and devices shared by all subclass.
|
||||
KeyInterface::init(getClassName(__PRETTY_FUNCTION__), hdlNVS, hdlHID);
|
||||
|
||||
// Retrieve configuration, if it doesnt exist, set defaults.
|
||||
//
|
||||
if(nvs->retrieveData(getClassName(__PRETTY_FUNCTION__), &this->mouseConfig, sizeof(t_mouseConfig)) == false)
|
||||
{
|
||||
ESP_LOGW(MAINTAG, "Mouse configuration set to default, no valid config in NVS found.");
|
||||
mouseConfig.mouse.resolution= HID::HID_MOUSE_RESOLUTION_1_8;
|
||||
mouseConfig.mouse.scaling = HID::HID_MOUSE_SCALING_1_1;
|
||||
mouseConfig.mouse.sampleRate= HID::HID_MOUSE_SAMPLE_RATE_60;
|
||||
mouseConfig.host.scaling = HID::HID_MOUSE_HOST_SCALING_1_2;
|
||||
|
||||
// Persist the data for next time.
|
||||
if(nvs->persistData(getClassName(__PRETTY_FUNCTION__), &this->mouseConfig, sizeof(t_mouseConfig)) == false)
|
||||
{
|
||||
ESP_LOGW(MAINTAG, "Persisting Default Mouse configuration data failed, check NVS setup.\n");
|
||||
}
|
||||
// Few other updates so make a commit here to ensure data is flushed and written.
|
||||
else if(nvs->commitData() == false)
|
||||
{
|
||||
ESP_LOGW(MAINTAG, "NVS Commit writes operation failed, some previous writes may not persist in future power cycles.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Constructor, basically initialise the Singleton interface and let the threads loose.
|
||||
Mouse::Mouse(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID)
|
||||
{
|
||||
// Operating in uni-mode.
|
||||
hostControl.secondaryIf = false;
|
||||
|
||||
// Initialise the interface
|
||||
init(ifMode, hdlNVS, hdlLED, hdlHID);
|
||||
}
|
||||
|
||||
// Constructor, basic initialisation without hardware.
|
||||
Mouse::Mouse(NVS *hdlNVS, HID *hdlHID)
|
||||
{
|
||||
// Operating in uni-mode.
|
||||
hostControl.secondaryIf = false;
|
||||
|
||||
// Initialise the interface
|
||||
init(hdlNVS, hdlHID);
|
||||
}
|
||||
|
||||
// Constructor for use when mouse operates in tandem with a keyboard.
|
||||
Mouse::Mouse(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID, bool secondaryIf)
|
||||
{
|
||||
// The interface can act in primary mode, ie. sole interface or secondary mode where it acts in tandem to a keyboard host. Slight processing differences occur
|
||||
// in secondary mode, for example, the pin used to output mouse data differs.
|
||||
hostControl.secondaryIf = secondaryIf;
|
||||
|
||||
// Initialise the interface
|
||||
init(ifMode, hdlNVS, hdlLED, hdlHID);
|
||||
}
|
||||
|
||||
// Constructor, used for version reporting so no hardware is initialised.
|
||||
Mouse::Mouse(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Destructor - only ever called when the class is used for version reporting.
|
||||
Mouse::~Mouse(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
293
main/NVS.cpp
Normal file
293
main/NVS.cpp
Normal file
@@ -0,0 +1,293 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: NVS.cpp
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Base class for encapsulating the Espressif C API for the Non Volatile Storage.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// v1.01 May 2022 - Initial release version.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "nvs.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "driver/timer.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "NVS.h"
|
||||
|
||||
// Method to externally take the NVS mutex for situations where another IDF module requires access to the NVS subsystem.
|
||||
//
|
||||
bool NVS::takeMutex(void)
|
||||
{
|
||||
// Locals.
|
||||
bool result = false;
|
||||
|
||||
// Ensure a handle has been opened to the NVS.
|
||||
if(nvsCtrl.nvsHandle != (nvs_handle_t)0)
|
||||
{
|
||||
// Request exclusive access.
|
||||
if(xSemaphoreTake(nvsCtrl.mutexInternal, (TickType_t)1000) == pdTRUE)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Method to release the NVS mutex previously taken.
|
||||
void NVS::giveMutex(void)
|
||||
{
|
||||
// Locals.
|
||||
|
||||
// Release mutex, external access now possible to the input devices.
|
||||
xSemaphoreGive(nvsCtrl.mutexInternal);
|
||||
}
|
||||
|
||||
// Method to persist data into the NVS RAM. This method takes a pointer to any memory object and writes it into the NVS using the handle opened at initialisation time.
|
||||
//
|
||||
bool NVS::persistData(const char *key, void *pData, uint32_t size)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
esp_err_t nvsStatus;
|
||||
bool result = true;
|
||||
#define NVSPERSISTTAG "persistData"
|
||||
|
||||
// Ensure a handle has been opened to the NVS.
|
||||
if(nvsCtrl.nvsHandle != (nvs_handle_t)0)
|
||||
{
|
||||
// Ensure we have exclusive access before accessing NVS.
|
||||
if(xSemaphoreTake(nvsCtrl.mutexInternal, (TickType_t)1000) == pdTRUE)
|
||||
{
|
||||
// Write a binary blob of data straight from memory pointed to by pData for readSize bytes into the NVS. This allows for individual variables or entire structures.
|
||||
nvsStatus = nvs_set_blob(this->nvsCtrl.nvsHandle, key, pData, size);
|
||||
if(nvsStatus != ESP_OK)
|
||||
{
|
||||
ESP_LOGW(NVSPERSISTTAG, "Failed to persist NVS data, key:%s, size:%d, nvsStatus:%d", key, size, nvsStatus);
|
||||
result = false;
|
||||
}
|
||||
} else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
} else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
// NB: Mutex only released in COMMIT.
|
||||
|
||||
// Return result code.
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Method to retrieve persisted data from the NVS RAM. This method takes a pointer to a pre-allocated memoery block along with size and retrieves a data block from NVS upto size bytes.
|
||||
//
|
||||
bool NVS::retrieveData(const char *key, void *pData, uint32_t size)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
esp_err_t nvsStatus;
|
||||
size_t readSize = size;
|
||||
bool result = true;
|
||||
#define NVSRTRVTAG "retrieveData"
|
||||
|
||||
// Ensure a handle has been opened to the NVS.
|
||||
if(nvsCtrl.nvsHandle != (nvs_handle_t)0)
|
||||
{
|
||||
// Ensure we have exclusive access before accessing NVS.
|
||||
if(xSemaphoreTake(nvsCtrl.mutexInternal, (TickType_t)1000) == pdTRUE)
|
||||
{
|
||||
// Get a binary blob of data straight into the memory pointed to by pData for readSize. This allows for individual variables or entire structures.
|
||||
nvsStatus = nvs_get_blob(this->nvsCtrl.nvsHandle, key, pData, &readSize);
|
||||
if(nvsStatus != ESP_OK || readSize != size)
|
||||
{
|
||||
ESP_LOGW(NVSRTRVTAG, "Failed to retrieve NVS data, key:%s, size:%d, requested size:%d, nvsStatus:%d", key, readSize, size, nvsStatus);
|
||||
result = false;
|
||||
}
|
||||
|
||||
// Release mutex, external access now possible to the input devices.
|
||||
xSemaphoreGive(nvsCtrl.mutexInternal);
|
||||
} else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
} else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
// Return result code.
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Method to ensure all data written to NVS is flushed and committed. This step is necessary as a write may be buffered and requires flushing to ensure persistence.
|
||||
//
|
||||
bool NVS::commitData(void)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
esp_err_t nvsStatus;
|
||||
bool result = true;
|
||||
#define NVSCOMMITTAG "commitData"
|
||||
|
||||
// Ensure a handle has been opened to the NVS.
|
||||
if(nvsCtrl.nvsHandle != (nvs_handle_t)0)
|
||||
{
|
||||
|
||||
// Check that the Mutex has been taken, if we grab it then it hasnt been taken in the persistData method, so exit as a call to persistData is mandatory.
|
||||
if(xSemaphoreTake(nvsCtrl.mutexInternal, (TickType_t)0) == pdTRUE)
|
||||
{
|
||||
xSemaphoreGive(nvsCtrl.mutexInternal);
|
||||
} else
|
||||
{
|
||||
// Request a commit transaction and return response accordingly.
|
||||
nvsStatus = nvs_commit(this->nvsCtrl.nvsHandle);
|
||||
if(nvsStatus != ESP_OK)
|
||||
{
|
||||
ESP_LOGW(NVSCOMMITTAG, "Failed to commit pending NVS data.");
|
||||
result = false;
|
||||
}
|
||||
|
||||
// Release mutex, external access now possible to the input devices.
|
||||
xSemaphoreGive(nvsCtrl.mutexInternal);
|
||||
}
|
||||
} else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
// Return result code.
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Method to erase all the NVS and return to factory default state. The method closes any open handle,
|
||||
// de-initialises the NVS then performs a flash erase.
|
||||
//
|
||||
void NVS::eraseAll(void)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
#define NVSERATAG "eraseAll"
|
||||
|
||||
// Ensure we have exclusive access before accessing NVS.
|
||||
while(xSemaphoreTake(nvsCtrl.mutexInternal, (TickType_t)1000) != pdTRUE);
|
||||
|
||||
// Ensure a handle has been opened to the NVS.
|
||||
if(nvsCtrl.nvsHandle != (nvs_handle_t)0)
|
||||
{
|
||||
// Close open handle.
|
||||
nvs_close(nvsCtrl.nvsHandle);
|
||||
nvsCtrl.nvsHandle = NULL;
|
||||
}
|
||||
|
||||
// Stop the flash driver.
|
||||
nvs_flash_deinit();
|
||||
|
||||
ESP_LOGW(NVSERATAG, "Erasing flash, disable for production!\n");
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
|
||||
// Release mutex, external access now possible to the input devices.
|
||||
xSemaphoreGive(nvsCtrl.mutexInternal);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Method to initialise the NVS subsystem.
|
||||
void NVS::init(void)
|
||||
{
|
||||
// Locals.
|
||||
esp_err_t nvsStatus;
|
||||
#define NVSINITTAG "nvsInit"
|
||||
|
||||
// Initialise variables.
|
||||
nvsCtrl.nvsHandle = (nvs_handle_t)0;
|
||||
|
||||
//ESP_LOGW(NVSINITTAG, "Erasing flash, disable for production!\n");
|
||||
//ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
|
||||
// Initialize NVS
|
||||
ESP_LOGW(NVSINITTAG, "Initialising NVS.");
|
||||
nvsStatus = nvs_flash_init();
|
||||
if(nvsStatus == ESP_ERR_NVS_NO_FREE_PAGES || nvsStatus == ESP_ERR_NVS_NEW_VERSION_FOUND)
|
||||
{
|
||||
// NVS partition was truncated and needs to be erased
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
|
||||
// Retry nvs_flash_init
|
||||
nvsStatus = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK(nvsStatus);
|
||||
|
||||
// Setup mutex's.
|
||||
nvsCtrl.mutexInternal = xSemaphoreCreateMutex();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Method to open a namespace on the NVS given a key.
|
||||
//
|
||||
bool NVS::open(std::string keyName)
|
||||
{
|
||||
// Locals.
|
||||
bool result = true;
|
||||
#define NVSOPENTAG "nvsOpen"
|
||||
|
||||
// Only process if no handle has been opened. Currently only coded for one session at a time.
|
||||
if(nvsCtrl.nvsHandle == (nvs_handle_t)0)
|
||||
{
|
||||
// Store the key name under which all data is stored.
|
||||
this->nvsCtrl.nvsKeyName = keyName;
|
||||
|
||||
// Open handle to persistence using the base-class name as the key which represents the global namespace. Sub-classes and objects accessing the public methods will
|
||||
// use there own class name as a sub-key which represents the class namespace within NVS. Data is then stored within the class namespace using a key:value pair.
|
||||
esp_err_t nvsStatus = nvs_open(nvsCtrl.nvsKeyName.c_str(), NVS_READWRITE, &this->nvsCtrl.nvsHandle);
|
||||
if (nvsStatus != ESP_OK)
|
||||
{
|
||||
ESP_LOGW(NVSOPENTAG, "Error (%s) opening NVS handle!\n", esp_err_to_name(nvsStatus));
|
||||
result = false;
|
||||
}
|
||||
} else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Basic constructor, init variables!
|
||||
NVS::NVS(void)
|
||||
{
|
||||
// Store the class name for later use, ie. NVS key access.
|
||||
this->nvsCtrl.nvsClassName = getClassName(__PRETTY_FUNCTION__);
|
||||
}
|
||||
1054
main/PC9801.cpp
Normal file
1054
main/PC9801.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -214,7 +214,7 @@ uint8_t PS2_keystatus; // current CAPS etc status for top byte
|
||||
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 )
|
||||
IRAM_ATTR void ps2interrupt( void )
|
||||
{
|
||||
// Workaround for ESP32 SILICON error see extra/Porting.md
|
||||
#ifdef PS2_ONLY_CHANGE_IRQ
|
||||
@@ -755,7 +755,6 @@ uint16_t translate( void )
|
||||
|
||||
if( PS2_lockstate[ retdata ] == 1 )
|
||||
{
|
||||
printf("PLEASE REMOVE ME translate: %04x, %d\n", retdata, PS2_lockstate[ retdata ]);
|
||||
retdata = PS2_KEY_IGNORE; // ignore key if make and not received break
|
||||
// As per above, MZ-2500 needs both events, so this code changed from original authors.
|
||||
} else
|
||||
@@ -843,7 +842,7 @@ printf("PLEASE REMOVE ME translate: %04x, %d\n", retdata, PS2_lockstate[ retdata
|
||||
}
|
||||
|
||||
// Assign Function keys _mode
|
||||
if( ( retdata <= PS2_KEY_SPACE || retdata >= PS2_KEY_F1 ) && retdata != PS2_KEY_EUROPE2 )
|
||||
if( ( retdata <= PS2_KEY_SPACE || retdata >= PS2_KEY_F1) && retdata != PS2_KEY_BTICK && retdata != PS2_KEY_HASH && retdata != PS2_KEY_EUROPE2 )
|
||||
{
|
||||
PS2_keystatus |= _FUNCTION;
|
||||
} else
|
||||
@@ -1068,12 +1067,33 @@ while( ( result = available( ) ) )
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method to suspend the keyboard handler and disable the interrupts whilst other non-mutually inclusive tasks make
|
||||
// use of system resources.
|
||||
//
|
||||
void PS2KeyAdvanced::suspend(bool suspend)
|
||||
{
|
||||
// Suspend detaches the interrupt, ie. this module becomes inactive, attach re-enables the interrupt.
|
||||
if(suspend)
|
||||
{
|
||||
detachInterrupt( digitalPinToInterrupt( PS2_IrqPin ) );
|
||||
} else
|
||||
{
|
||||
attachInterrupt( digitalPinToInterrupt( PS2_IrqPin ), ps2interrupt, FALLING );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
PS2KeyAdvanced::PS2KeyAdvanced( )
|
||||
{
|
||||
// nothing to do here, begin( ) does it all
|
||||
}
|
||||
|
||||
// Destructor - detach interrupts and free up resources.
|
||||
PS2KeyAdvanced::~PS2KeyAdvanced(void)
|
||||
{
|
||||
// Detach interrupts.
|
||||
detachInterrupt( digitalPinToInterrupt( PS2_IrqPin ) );
|
||||
}
|
||||
|
||||
/* instantiate class for keyboard */
|
||||
void PS2KeyAdvanced::begin( uint8_t data_pin, uint8_t irq_pin )
|
||||
|
||||
682
main/PS2Mouse.cpp
Normal file
682
main/PS2Mouse.cpp
Normal file
@@ -0,0 +1,682 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: PS2Mouse.cpp
|
||||
// Created: Jan 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: PS/2 Mouse Class.
|
||||
// This source file contains the class to encapsulate a PS/2 mouse. Given two GPIO
|
||||
// pins, datapin and clkpin, it is able to communicate, configure and return mouse
|
||||
// data via a rich set of methods.
|
||||
//
|
||||
// This class borrows ideas from the interrupt concept of the PS2KeyAdvanced class
|
||||
// for communicating via the PS/2 protocol.
|
||||
// https://github.com/techpaul/PS2KeyAdvanced class from Paul Carpenter.
|
||||
//
|
||||
// The application uses the Espressif Development environment with Arduino components.
|
||||
// This is necessary as the class uses the Arduino methods for GPIO manipulation. I
|
||||
// was considering using pure Espressif IDF methods but considered the potential
|
||||
// of also using this class on an Arduino project.
|
||||
//
|
||||
// Credits:
|
||||
// Copyright: (c) 2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "PS2Mouse.h"
|
||||
|
||||
// Global handle to allow the static interrupt routine to access the instantiated object. This does limit this class to being Singleton
|
||||
// but it is unusual to have more than 1 PS/2 mouse on a project so less of a problem.
|
||||
PS2Mouse *pThis;
|
||||
|
||||
// Constructor. Simple assign the hardware data and clock pins to internal variables and setup
|
||||
// variables. Actual real initialisation is performed by a public method so re-initialisation can
|
||||
// be made if required.
|
||||
//
|
||||
PS2Mouse::PS2Mouse(int clockPin, int dataPin)
|
||||
{
|
||||
ps2Ctrl.clkPin = clockPin;
|
||||
ps2Ctrl.dataPin = dataPin;
|
||||
ps2Ctrl.supportsIntelliMouseExtensions = false;
|
||||
ps2Ctrl.mouseDataCallback = NULL;
|
||||
}
|
||||
|
||||
// Destructor - Detach interrupts and free resources.
|
||||
//
|
||||
PS2Mouse::~PS2Mouse()
|
||||
{
|
||||
// Disable interrupts.
|
||||
detachInterrupt( digitalPinToInterrupt( ps2Ctrl.clkPin ) );
|
||||
}
|
||||
|
||||
// The interrupt handler triggered on each falling edge of the clock pin.
|
||||
// Rx Mode: 11 bits - <start><8 data bits><ODD parity bit><stop bit>
|
||||
// Tx Mode: 11 bits - <start><8 data bits><ODD parity bit><stop bit>
|
||||
IRAM_ATTR void PS2Mouse::ps2interrupt( void )
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
static uint32_t timeLast = 0;
|
||||
uint32_t timeCurrent;
|
||||
uint8_t dataBit;
|
||||
|
||||
// Workaround for ESP32 SILICON error see extra/Porting.md
|
||||
#ifdef PS2_ONLY_CHANGE_IRQ
|
||||
if( digitalRead( ps2Ctrl.clkPin ) )
|
||||
return;
|
||||
#endif
|
||||
|
||||
// TRANSMIT MODE.
|
||||
if( pThis->ps2Ctrl.mode & _TX_MODE )
|
||||
{
|
||||
// Received data not valid when transmitting.
|
||||
pThis->ps2Ctrl.rxPos = 0;
|
||||
|
||||
// Now point to next bit
|
||||
pThis->ps2Ctrl.bitCount++;
|
||||
|
||||
// BIT 1 - START BIT
|
||||
if(pThis->ps2Ctrl.bitCount == 1)
|
||||
{
|
||||
#if defined( PS2_CLEAR_PENDING_IRQ )
|
||||
// Start bit due to Arduino bug
|
||||
digitalWrite(pThis->ps2Ctrl.dataPin, LOW);
|
||||
break;
|
||||
#endif
|
||||
} else
|
||||
// BIT 2->9 - DATA BIT MSB->LSB
|
||||
if(pThis->ps2Ctrl.bitCount >= 2 && pThis->ps2Ctrl.bitCount <= 9)
|
||||
{
|
||||
// Data bits
|
||||
dataBit = pThis->ps2Ctrl.shiftReg & 0x01; // get LSB
|
||||
digitalWrite(pThis->ps2Ctrl.dataPin, dataBit); // send start bit
|
||||
pThis->ps2Ctrl.parity += dataBit; // another one received ?
|
||||
pThis->ps2Ctrl.shiftReg >>= 1; // right _SHIFT one place for next bit
|
||||
} else
|
||||
// BIT 10 - PARITY BIT
|
||||
if(pThis->ps2Ctrl.bitCount == 10)
|
||||
{
|
||||
// Parity - Send LSB if 1 = odd number of 1's so ps2Ctrl.parity should be 0
|
||||
digitalWrite( pThis->ps2Ctrl.dataPin, ( ~pThis->ps2Ctrl.parity & 1 ) );
|
||||
} else
|
||||
// BIT 11 - STOP BIT
|
||||
if(pThis->ps2Ctrl.bitCount == 11)
|
||||
{
|
||||
// Stop bit write change to input pull up for high stop bit
|
||||
digitalWrite( pThis->ps2Ctrl.dataPin, HIGH );
|
||||
pinMode( pThis->ps2Ctrl.dataPin, INPUT );
|
||||
} else
|
||||
// BIT 12 - ACK BIT
|
||||
if(pThis->ps2Ctrl.bitCount == 12)
|
||||
{
|
||||
// Acknowledge bit low we cannot do anything if high instead of low
|
||||
// clear modes to receive again
|
||||
pThis->ps2Ctrl.mode &= ~_TX_MODE;
|
||||
pThis->ps2Ctrl.bitCount = 0; // end of byte
|
||||
} else
|
||||
{
|
||||
// in case of weird error and end of byte reception re-sync
|
||||
pThis->ps2Ctrl.bitCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// RECEIVE MODE.
|
||||
else
|
||||
{
|
||||
// Read latest bit.
|
||||
dataBit = digitalRead( pThis->ps2Ctrl.dataPin );
|
||||
|
||||
// Get current time.
|
||||
timeCurrent = millis( );
|
||||
|
||||
// Reset the receive byte buffer pointer if the gap from the last received byte to the current time is greater than a packet interbyte delay.
|
||||
if(timeCurrent - timeLast > 100)
|
||||
{
|
||||
pThis->ps2Ctrl.rxPos = 0;
|
||||
}
|
||||
|
||||
// Catch glitches, any clock taking longer than 250ms is either a glitch, an error or start of a new packet.
|
||||
if( timeCurrent - timeLast > 250 )
|
||||
{
|
||||
pThis->ps2Ctrl.bitCount = 0;
|
||||
pThis->ps2Ctrl.shiftReg = 0;
|
||||
}
|
||||
|
||||
// Store current time for next loop to detect timing issues.
|
||||
timeLast = timeCurrent;
|
||||
|
||||
// Now point to next bit
|
||||
pThis->ps2Ctrl.bitCount++;
|
||||
|
||||
// BIT 1 - START BIT
|
||||
if(pThis->ps2Ctrl.bitCount == 1)
|
||||
{
|
||||
// Start bit
|
||||
pThis->ps2Ctrl.parity = 0;
|
||||
pThis->ps2Ctrl.mode |= _PS2_BUSY; // set busy
|
||||
} else
|
||||
// BIT 2->9 - DATA BIT MSB->LSB
|
||||
if(pThis->ps2Ctrl.bitCount >= 2 && pThis->ps2Ctrl.bitCount <= 9)
|
||||
{
|
||||
// Data bits
|
||||
pThis->ps2Ctrl.parity += dataBit; // another one received ?
|
||||
pThis->ps2Ctrl.shiftReg >>= 1; // right _SHIFT one place for next bit
|
||||
pThis->ps2Ctrl.shiftReg |= ( dataBit ) ? 0x80 : 0; // or in MSbit
|
||||
} else
|
||||
// BIT 10 - PARITY BIT
|
||||
if(pThis->ps2Ctrl.bitCount == 10)
|
||||
{
|
||||
// Parity check
|
||||
pThis->ps2Ctrl.parity &= 1; // Get LSB if 1 = odd number of 1's so ps2Ctrl.parity bit should be 0
|
||||
if( pThis->ps2Ctrl.parity == dataBit ) // Both same ps2Ctrl.parity error
|
||||
pThis->ps2Ctrl.parity = 0xFD; // To ensure at next bit count clear and discard
|
||||
} else
|
||||
// BIT 11 - STOP BIT
|
||||
if(pThis->ps2Ctrl.bitCount == 11)
|
||||
{
|
||||
// Streaming mode, assemble the data into the buffer.
|
||||
if(pThis->ps2Ctrl.streamingEnabled)
|
||||
{
|
||||
if(pThis->ps2Ctrl.rxPos == 0 && pThis->streaming.newData == true) pThis->streaming.overrun = true;
|
||||
if(pThis->ps2Ctrl.rxPos == 0) pThis->streaming.mouseData.status = pThis->ps2Ctrl.shiftReg;
|
||||
if(pThis->ps2Ctrl.rxPos == 1) pThis->streaming.mouseData.position.x = pThis->ps2Ctrl.shiftReg;
|
||||
if(pThis->ps2Ctrl.rxPos == 2) pThis->streaming.mouseData.position.y = pThis->ps2Ctrl.shiftReg;
|
||||
if(pThis->ps2Ctrl.rxPos == 3) pThis->streaming.mouseData.wheel = pThis->ps2Ctrl.shiftReg;
|
||||
if( (pThis->ps2Ctrl.supportsIntelliMouseExtensions == false && pThis->ps2Ctrl.rxPos == 2) || (pThis->ps2Ctrl.supportsIntelliMouseExtensions == true && pThis->ps2Ctrl.rxPos == 3))
|
||||
{
|
||||
pThis->streaming.newData = true;
|
||||
pThis->streaming.overrun = false;
|
||||
pThis->ps2Ctrl.rxPos = 0;
|
||||
} else
|
||||
{
|
||||
pThis->ps2Ctrl.rxPos++;
|
||||
}
|
||||
} else
|
||||
{
|
||||
// Save the received byte and parity, let consumer decide on it's validity.
|
||||
pThis->ps2Ctrl.rxBuf[pThis->ps2Ctrl.rxPos++] = (pThis->ps2Ctrl.parity << 8 | pThis->ps2Ctrl.shiftReg);
|
||||
}
|
||||
// Set mode and status for next receive byte
|
||||
pThis->ps2Ctrl.mode &= ~( _WAIT_RESPONSE );
|
||||
pThis->ps2Ctrl.mode &= ~_PS2_BUSY;
|
||||
pThis->ps2Ctrl.bitCount = 0; // end of byte
|
||||
} else
|
||||
{
|
||||
// in case of weird error and end of byte reception re-sync
|
||||
pThis->ps2Ctrl.bitCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method to write a byte (control or parameter) to the Mouse. This method encapsulates the protocol necessary
|
||||
// to invoke Host -> PS/2 Mouse transmission and the interrupts, on falling clock edge, process the byte to send
|
||||
// and bitbang accordingly.
|
||||
//
|
||||
void PS2Mouse::writeByte(uint8_t command)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint32_t currentTime = millis();
|
||||
|
||||
// Test to see if a transmission is underway, block until the xmit buffer becomes available or timeout expires (no mouse).
|
||||
//
|
||||
while((ps2Ctrl.mode & _TX_MODE) && currentTime+100 > millis());
|
||||
|
||||
// If TX_MODE has been reset, interrupt processing has occurred so line up next byte,
|
||||
//
|
||||
if((ps2Ctrl.mode & _TX_MODE) == 0)
|
||||
{
|
||||
// Initialise the ps2 control variables.
|
||||
ps2Ctrl.shiftReg = command;
|
||||
ps2Ctrl.bitCount = 1;
|
||||
ps2Ctrl.parity = 0;
|
||||
ps2Ctrl.mode |= _TX_MODE + _PS2_BUSY;
|
||||
ps2Ctrl.rxPos = 0;
|
||||
|
||||
// Initialise the streaming buffer.
|
||||
streaming.mouseData.valid = false;
|
||||
streaming.mouseData.status = 0;
|
||||
streaming.mouseData.position.x = 0;
|
||||
streaming.mouseData.position.y = 0;
|
||||
streaming.mouseData.wheel = 0;
|
||||
streaming.newData = false;
|
||||
streaming.overrun = false;
|
||||
|
||||
// STOP the interrupt handler - Setting pin output low will cause interrupt before ready
|
||||
detachInterrupt( digitalPinToInterrupt( ps2Ctrl.clkPin ) );
|
||||
|
||||
// Set data and clock pins to output and high
|
||||
digitalWrite(ps2Ctrl.dataPin, HIGH);
|
||||
pinMode(ps2Ctrl.dataPin, OUTPUT);
|
||||
digitalWrite(ps2Ctrl.clkPin, HIGH);
|
||||
pinMode(ps2Ctrl.clkPin, OUTPUT);
|
||||
|
||||
// Essential for PS2 spec compliance
|
||||
delayMicroseconds(10);
|
||||
|
||||
// Set Clock LOW - trigger Host -> Mouse transmission. Mouse controls the clock but dragging clock low is used by the mouse to detect a host write and clock
|
||||
// data in accordingly.
|
||||
digitalWrite( ps2Ctrl.clkPin, LOW );
|
||||
|
||||
// Essential for PS2 spec compliance, set clock low for 60us
|
||||
delayMicroseconds(60);
|
||||
|
||||
// Set data low - Start bit
|
||||
digitalWrite( ps2Ctrl.dataPin, LOW );
|
||||
|
||||
// Set clock to input_pullup data stays output while writing to keyboard
|
||||
digitalWrite(ps2Ctrl.clkPin, HIGH);
|
||||
pinMode(ps2Ctrl.clkPin, INPUT);
|
||||
|
||||
// Restart interrupt handler
|
||||
attachInterrupt( digitalPinToInterrupt( ps2Ctrl.clkPin ), ps2interrupt, FALLING );
|
||||
}
|
||||
|
||||
// Everything is now processed in the interrupt handler.
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup and initialise the running object and Mouse hardware. This method must be called at startup and anytime a full reset is required.
|
||||
//
|
||||
void PS2Mouse::initialize()
|
||||
{
|
||||
// Setup variables.
|
||||
ps2Ctrl.mode = 0;
|
||||
ps2Ctrl.supportsIntelliMouseExtensions = false;
|
||||
ps2Ctrl.streamingEnabled = false;
|
||||
ps2Ctrl.bitCount = 0;
|
||||
ps2Ctrl.shiftReg = 0;
|
||||
ps2Ctrl.parity = 0;
|
||||
ps2Ctrl.rxPos = 0;
|
||||
// Clear the receive buffer.
|
||||
for(int idx=0; idx < 16; idx++) ps2Ctrl.rxBuf[idx] = 0x00;
|
||||
|
||||
// Set data and clock pins to input.
|
||||
digitalWrite(ps2Ctrl.dataPin, HIGH);
|
||||
pinMode(ps2Ctrl.dataPin, INPUT);
|
||||
digitalWrite(ps2Ctrl.clkPin, HIGH);
|
||||
pinMode(ps2Ctrl.clkPin, INPUT);
|
||||
|
||||
// Initialise the control structure.
|
||||
ps2Ctrl.bitCount = 0;
|
||||
ps2Ctrl.mode = 0;
|
||||
ps2Ctrl.rxPos = 0;
|
||||
|
||||
// As the interrupt handler is static it wont have reference to the instantiated object methods so we need to store the object in a pointer
|
||||
// which is then used by the interrupt handler.
|
||||
pThis = this;
|
||||
|
||||
// Attach the clock line to a falling low interrupt trigger and handler. The Mouse toggles the clock line for each bit to be sent/received
|
||||
// so we interrupt on each falling clock edge.
|
||||
attachInterrupt( digitalPinToInterrupt( ps2Ctrl.clkPin ), ps2interrupt, FALLING );
|
||||
|
||||
// Setup the mouse, make a reset, check and set Intellimouse extensions, set the resolution, scaling, sample rate to defaults and switch to remote (polled) mode.
|
||||
reset();
|
||||
checkIntelliMouseExtensions();
|
||||
setResolution(PS2_MOUSE_RESOLUTION_1_8);
|
||||
setScaling(PS2_MOUSE_SCALING_1_1);
|
||||
setSampleRate(PS2_MOUSE_SAMPLE_RATE_40);
|
||||
setRemoteMode();
|
||||
|
||||
// All done.
|
||||
return;
|
||||
}
|
||||
|
||||
// Public method to force a mouse reset. Used on startup and anytime the client believes the mouse has hungup.
|
||||
//
|
||||
bool PS2Mouse::reset(void)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint8_t respBuf[5];
|
||||
bool result = false;
|
||||
|
||||
// Send command to reset the mouse, if it returns an ACK then reset succeeded.
|
||||
//
|
||||
if(sendCmd(MOUSE_CMD_RESET, 0, respBuf, DEFAULT_MOUSE_TIMEOUT))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
// Return result.
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Private method to check and see if the mouse suports Microsoft Intellimouse extensions. It sets an internal state flag accordingly.
|
||||
//
|
||||
bool PS2Mouse::checkIntelliMouseExtensions(void)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
char deviceId;
|
||||
|
||||
// IntelliMouse detection sequence, error checking isnt used.
|
||||
setSampleRate(PS2_MOUSE_SAMPLE_RATE_200);
|
||||
setSampleRate(PS2_MOUSE_SAMPLE_RATE_100);
|
||||
setSampleRate(PS2_MOUSE_SAMPLE_RATE_80);
|
||||
|
||||
// Get device Id and if the mouse supports Intellimouse extensions, it will reveal itself as an INTELLI_MOUSE.
|
||||
deviceId = getDeviceId();
|
||||
ps2Ctrl.supportsIntelliMouseExtensions = (deviceId == INTELLI_MOUSE);
|
||||
|
||||
// Return flag to indicate support (true) or no support (false).
|
||||
return(ps2Ctrl.supportsIntelliMouseExtensions);
|
||||
}
|
||||
|
||||
// Public method to set the automatic sample rate.
|
||||
//
|
||||
bool PS2Mouse::setSampleRate(enum PS2_SAMPLING rate)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint8_t respBuf[5];
|
||||
bool result = false;
|
||||
|
||||
// Sanity check.
|
||||
if(rate == PS2_MOUSE_SAMPLE_RATE_10 || rate == PS2_MOUSE_SAMPLE_RATE_20 || rate == PS2_MOUSE_SAMPLE_RATE_40 || rate == PS2_MOUSE_SAMPLE_RATE_60 || rate == PS2_MOUSE_SAMPLE_RATE_80 || rate == PS2_MOUSE_SAMPLE_RATE_100 || rate == PS2_MOUSE_SAMPLE_RATE_200)
|
||||
{
|
||||
// Send command to set the mouse resolution.
|
||||
//
|
||||
if(sendCmd(MOUSE_CMD_SET_SAMPLE_RATE, 0, respBuf, DEFAULT_MOUSE_TIMEOUT))
|
||||
{
|
||||
// Send the rate, if ACK is returned, then resolution set otherwise error.
|
||||
if(sendCmd((uint8_t)rate, 0, respBuf, DEFAULT_MOUSE_TIMEOUT))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return result.
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Public method to request the mouse Id which can be used to identify the mouse capabilities.
|
||||
//
|
||||
char PS2Mouse::getDeviceId(void)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint8_t respBuf[5];
|
||||
|
||||
// Send command to set the mouse scaling, either 2:1 or 1:1.
|
||||
//
|
||||
if(sendCmd(MOUSE_CMD_GET_DEVICE_ID, 1, respBuf, DEFAULT_MOUSE_TIMEOUT) == false)
|
||||
{
|
||||
respBuf[0] = 0xFF;
|
||||
}
|
||||
|
||||
// Return result.
|
||||
return(respBuf[0]);
|
||||
}
|
||||
|
||||
// Public method to set the mouse scaling, either Normal 1:1 (scaling = 0) or non-linear 2:1 (scaling = 1).
|
||||
//
|
||||
bool PS2Mouse::setScaling(enum PS2_SCALING scaling)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint8_t respBuf[5];
|
||||
bool result = false;
|
||||
|
||||
// Sanity check.
|
||||
if(scaling >= PS2_MOUSE_SCALING_1_1 && scaling < PS2_MOUSE_SCALING_2_1)
|
||||
{
|
||||
// Send command to set the mouse scaling, either 2:1 or 1:1.
|
||||
//
|
||||
if(sendCmd((uint8_t)scaling, 0, respBuf, DEFAULT_MOUSE_TIMEOUT))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Return result.
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Public method to request the mouse enters remote mode.
|
||||
//
|
||||
bool PS2Mouse::setRemoteMode(void)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint8_t respBuf[5];
|
||||
|
||||
// Simply pass on the request to the mouse to enter remote mode.
|
||||
return(sendCmd(MOUSE_CMD_SET_REMOTE_MODE, 1, respBuf, DEFAULT_MOUSE_TIMEOUT));
|
||||
}
|
||||
|
||||
// Public method to request the mouse enters stream mode. This mode reports mouse movements as they change, albeit the streaming must also be enabled
|
||||
// once set to Stream Mode via the enableStreaming method.
|
||||
//
|
||||
bool PS2Mouse::setStreamMode(void)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint8_t respBuf[5];
|
||||
|
||||
// Simply pass on the request to the mouse to enter stream mode.
|
||||
return(sendCmd(MOUSE_CMD_SET_STREAM_MODE, 1, respBuf, DEFAULT_MOUSE_TIMEOUT));
|
||||
}
|
||||
|
||||
// Public methods to enable and disable streaming (constant rate packet transmission from mouse to host).
|
||||
// This module accepts the data and updates an in object set which the caller queries. No buffering takes place
|
||||
// so should the caller fail to read the data then the arrival of the next packet from the mouse will override
|
||||
// the in object values.
|
||||
//
|
||||
bool PS2Mouse::enableStreaming(void)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint8_t respBuf[5];
|
||||
|
||||
// Sanity check.
|
||||
if(ps2Ctrl.streamingEnabled == false)
|
||||
{
|
||||
if(sendCmd(MOUSE_CMD_ENABLE_STREAMING, 0, respBuf, DEFAULT_MOUSE_TIMEOUT))
|
||||
{
|
||||
// Initialise the streaming buffer.
|
||||
streaming.mouseData.valid = false;
|
||||
streaming.mouseData.status = 0;
|
||||
streaming.mouseData.position.x = 0;
|
||||
streaming.mouseData.position.y = 0;
|
||||
streaming.mouseData.wheel = 0;
|
||||
streaming.newData = false;
|
||||
streaming.overrun = false;
|
||||
ps2Ctrl.streamingEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the enabled flag to indicate success.
|
||||
return(ps2Ctrl.streamingEnabled);
|
||||
}
|
||||
bool PS2Mouse::disableStreaming(void)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint8_t respBuf[5];
|
||||
|
||||
// Sanity check.
|
||||
if(ps2Ctrl.streamingEnabled == true)
|
||||
{
|
||||
if(sendCmd(MOUSE_CMD_DISABLE_STREAMING, 0, respBuf, DEFAULT_MOUSE_TIMEOUT))
|
||||
{
|
||||
ps2Ctrl.streamingEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the enabled flag to indicate success.
|
||||
return(ps2Ctrl.streamingEnabled);
|
||||
}
|
||||
|
||||
// Public method to set the mouse resolution in pixels per millimeter, valid values are o..3.
|
||||
//
|
||||
bool PS2Mouse::setResolution(enum PS2_RESOLUTION resolution)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint8_t respBuf[5];
|
||||
bool result = false;
|
||||
|
||||
// Sanity check.
|
||||
if(resolution >= PS2_MOUSE_RESOLUTION_1_1 && resolution < PS2_MOUSE_RESOLUTION_1_8)
|
||||
{
|
||||
// Send command to set the mouse resolution.
|
||||
//
|
||||
if(sendCmd(MOUSE_CMD_SET_RESOLUTION, 0, respBuf, DEFAULT_MOUSE_TIMEOUT))
|
||||
{
|
||||
// Send the resolution, if ACK is returned, then resolution set otherwise error.
|
||||
if(sendCmd((uint8_t)resolution, 0, respBuf, DEFAULT_MOUSE_TIMEOUT))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return result.
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Public method to get the current mouse status. The status code is 3 bytes wide and has the following format:
|
||||
//
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// Byte 1: 0 mode enable scaling 0 left btn middle right btn
|
||||
// Byte 2: resolution
|
||||
// Byte 3: sample rate
|
||||
//
|
||||
bool PS2Mouse::getStatus(uint8_t *respBuf)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
// Sanity check.
|
||||
if(respBuf != NULL)
|
||||
{
|
||||
// Send command to set the mouse resolution.
|
||||
//
|
||||
if(sendCmd(MOUSE_CMD_GET_STATUS, 3, respBuf, DEFAULT_MOUSE_TIMEOUT))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Return result.
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Public method to obtain current mouse state data.
|
||||
//
|
||||
PS2Mouse::MouseData PS2Mouse::readData(void)
|
||||
{
|
||||
// Locals.
|
||||
MouseData data;
|
||||
uint8_t dataBuf[8] = {0,0,0,0,0,0,0,0};
|
||||
|
||||
// If streaming mode enabled then set values according to data state. Data only valid if a new update has occurred since last call otherwise old data is returned and valid flag
|
||||
// is cleared.
|
||||
if(ps2Ctrl.streamingEnabled)
|
||||
{
|
||||
data.valid = streaming.newData;
|
||||
data.overrun = streaming.overrun;
|
||||
data.status = streaming.mouseData.status;
|
||||
data.position.x = streaming.mouseData.position.x;
|
||||
data.position.y = streaming.mouseData.position.y;
|
||||
data.wheel = ps2Ctrl.supportsIntelliMouseExtensions ? streaming.mouseData.wheel : 0;
|
||||
streaming.newData = false;
|
||||
streaming.overrun = false;
|
||||
|
||||
// If a data callback has been setup execute it otherwise data is read by caller.
|
||||
//
|
||||
if(ps2Ctrl.mouseDataCallback != NULL && data.valid)
|
||||
ps2Ctrl.mouseDataCallback(data);
|
||||
} else
|
||||
// Single on-request data set from mouse.
|
||||
{
|
||||
// Request data from mouse via issuing get single data packet command.
|
||||
if(requestData(ps2Ctrl.supportsIntelliMouseExtensions ? 3 : 3, dataBuf, DEFAULT_MOUSE_TIMEOUT))
|
||||
{
|
||||
data.valid = true;
|
||||
data.overrun = false;
|
||||
data.status = dataBuf[0];
|
||||
data.position.x = dataBuf[1];
|
||||
data.position.y = dataBuf[2];
|
||||
data.wheel = ps2Ctrl.supportsIntelliMouseExtensions ? dataBuf[3] : 0;
|
||||
} else
|
||||
{
|
||||
data.valid = false;
|
||||
data.overrun = false;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
// Method to request the latest mouse movement, wheel and key data. The method blocks until data is available or the timeout is reached. A timeout of 0
|
||||
// will only return when the data has been received.
|
||||
bool PS2Mouse::requestData(uint8_t expectedBytes, uint8_t *respBuf, uint32_t timeout)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
|
||||
// Simply pass on the request for the mouse to send data and await reply.
|
||||
return(sendCmd(MOUSE_CMD_REQUEST_DATA, expectedBytes, respBuf, timeout));
|
||||
}
|
||||
|
||||
// Method to send a command to the Mouse and await it's reply. If an ACK isnt returned then a resend request is made otherwise wait until all bytes
|
||||
// arrive or we timeout.
|
||||
//
|
||||
bool PS2Mouse::sendCmd(uint8_t cmd, uint8_t expectedBytes, uint8_t *respBuf, uint32_t timeout)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint32_t currentTime = millis();
|
||||
uint32_t endTime = millis() + timeout;
|
||||
uint8_t *pBuf = respBuf;
|
||||
bool result = false;
|
||||
|
||||
// Send command.
|
||||
writeByte(cmd);
|
||||
|
||||
// Wait for the expected number of bytes to arrive.
|
||||
while(((timeout == 0) || (currentTime < endTime)) && ps2Ctrl.rxPos <= expectedBytes)
|
||||
{
|
||||
// If an ACK isnt received, request a resend.
|
||||
if(ps2Ctrl.rxPos >= 1 && ps2Ctrl.rxBuf[0] != MOUSE_RESP_ACK) { writeByte(MOUSE_CMD_RESEND); }
|
||||
|
||||
// Get latest time.
|
||||
currentTime = millis();
|
||||
}
|
||||
|
||||
// Store the response in callers buffer.
|
||||
for(int idx=0; idx < expectedBytes; idx++)
|
||||
{
|
||||
(*pBuf) = ps2Ctrl.rxBuf[idx+1];
|
||||
pBuf++;
|
||||
}
|
||||
|
||||
// Set return code, true if a valid packet was received.
|
||||
if(((timeout == 0) || (currentTime < endTime)) && ps2Ctrl.rxPos >= expectedBytes && ps2Ctrl.rxBuf[0] == MOUSE_RESP_ACK) result = true;
|
||||
|
||||
// Debug print.
|
||||
//printf("%d:%d:%02x,%02x,%02x,%02x, %02x, %d, result=%d, %d, %d, %d\n", result, ps2Ctrl.rxPos, ps2Ctrl.rxBuf[0], ps2Ctrl.rxBuf[1], ps2Ctrl.rxBuf[2], ps2Ctrl.rxBuf[3],ps2Ctrl.rxBuf[4], ps2Ctrl.bitCount, result, timeout, currentTime, endTime);
|
||||
|
||||
// And complete with result!
|
||||
return(result);
|
||||
}
|
||||
216
main/SWITCH.cpp
Normal file
216
main/SWITCH.cpp
Normal file
@@ -0,0 +1,216 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: SWITCH.cpp
|
||||
// Created: May 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Base class for encapsulating the SharpKey WiFi/Config switch.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: May 2022 - Initial write.
|
||||
// v1.00 Jun 2022 - Updates to add additional callbacks for RESET and CLEARNVS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "nvs.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "driver/timer.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "SWITCH.h"
|
||||
|
||||
// Primary SWITCH thread, running on Core 0.
|
||||
// This thread is responsible for scanning the config/WiFi key on the SharpKey and generating callbacks according to state.
|
||||
//
|
||||
IRAM_ATTR void SWITCH::swInterface( void * pvParameters )
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint32_t keyDebCtr = 0;
|
||||
uint32_t WIFIEN_MASK = (1 << (CONFIG_IF_WIFI_EN_KEY - 32));
|
||||
uint32_t resetTimer = 0;
|
||||
#define WIFIIFTAG "swInterface"
|
||||
|
||||
// Map the instantiating object so we can access its methods and data.
|
||||
SWITCH* pThis = (SWITCH*)pvParameters;
|
||||
|
||||
// Loop indefinitely.
|
||||
while(true)
|
||||
{
|
||||
// Check the switch, has it gone to zero, ie. pressed?
|
||||
//
|
||||
if((REG_READ(GPIO_IN1_REG) & WIFIEN_MASK) == 0)
|
||||
{
|
||||
// First press detection turn LED off.
|
||||
if(keyDebCtr == 0)
|
||||
{
|
||||
pThis->led->setLEDMode(LED::LED_MODE_OFF, LED::LED_DUTY_CYCLE_OFF, 0, 0L, 0L);
|
||||
}
|
||||
// Entering WiFi enable mode, blink LED
|
||||
if(keyDebCtr == 10)
|
||||
{
|
||||
pThis->led->setLEDMode(LED::LED_MODE_BLINK, LED::LED_DUTY_CYCLE_50, 1, 50000L, 500L);
|
||||
}
|
||||
// Enter default AP mode.
|
||||
if(keyDebCtr == 50)
|
||||
{
|
||||
pThis->led->setLEDMode(LED::LED_MODE_BLINK, LED::LED_DUTY_CYCLE_30, 1, 25000L, 250L);
|
||||
}
|
||||
// Enter BT pairing mode.
|
||||
if(keyDebCtr == 100)
|
||||
{
|
||||
pThis->led->setLEDMode(LED::LED_MODE_BLINK, LED::LED_DUTY_CYCLE_10, 1, 10000L, 100L);
|
||||
}
|
||||
// Enter Clear NVS settings mode.
|
||||
if(keyDebCtr == 150)
|
||||
{
|
||||
pThis->led->setLEDMode(LED::LED_MODE_BLINK, LED::LED_DUTY_CYCLE_80, 5, 10000L, 1000L);
|
||||
}
|
||||
// Increment counter so we know how long it has been held.
|
||||
keyDebCtr++;
|
||||
} else
|
||||
if((REG_READ(GPIO_IN1_REG) & WIFIEN_MASK) != 0 && keyDebCtr > 1)
|
||||
{
|
||||
// On first 1/2 second press, if WiFi active, disable and reboot.
|
||||
if(keyDebCtr > 1 && keyDebCtr < 10)
|
||||
{
|
||||
// If a cancel callback has been setup, invoke it.
|
||||
//
|
||||
if(pThis->swCtrl.cancelEventCallback != NULL)
|
||||
pThis->swCtrl.cancelEventCallback();
|
||||
|
||||
// If the reset timer is running then a previous button press occurred. If it is less than 1 second then a RESET event
|
||||
// is required.
|
||||
if(resetTimer != 0 && (pThis->milliSeconds() - resetTimer) < 1000L)
|
||||
{
|
||||
// If a handler is installed call it. If the return value is true then a restart is possible. No handler then we just restart.
|
||||
if(pThis->swCtrl.resetEventCallback != NULL)
|
||||
{
|
||||
if(pThis->swCtrl.resetEventCallback())
|
||||
esp_restart();
|
||||
} else
|
||||
esp_restart();
|
||||
} else
|
||||
{
|
||||
resetTimer = pThis->milliSeconds();
|
||||
}
|
||||
}
|
||||
// If counter is in range 1 to 4 seconds then assume a WiFi on (so long as the client parameters have been configured).
|
||||
else if(keyDebCtr > 10 && keyDebCtr < 40)
|
||||
{
|
||||
// If a wifi enable callback has been setup, invoke it.
|
||||
//
|
||||
if(pThis->swCtrl.wifiEnEventCallback != NULL)
|
||||
pThis->swCtrl.wifiEnEventCallback();
|
||||
}
|
||||
// If the key is held for 5 or more seconds, then enter Wifi Config Default AP mode.
|
||||
else if(keyDebCtr > 50 && keyDebCtr < 100)
|
||||
{
|
||||
// If a wifi default enable callback has been setup, invoke it.
|
||||
//
|
||||
if(pThis->swCtrl.wifiDefEventCallback != NULL)
|
||||
pThis->swCtrl.wifiDefEventCallback();
|
||||
}
|
||||
// If the key is held for 10 seconds or more, invoke Bluetooth pairing mode.
|
||||
else if(keyDebCtr >= 100 && keyDebCtr < 150)
|
||||
{
|
||||
// If a bluetooth start pairing callback has been setup, invoke it.
|
||||
//
|
||||
if(pThis->swCtrl.btPairingEventCallback != NULL)
|
||||
pThis->swCtrl.btPairingEventCallback();
|
||||
}
|
||||
// If the key is held for 15 seconds or more, invoke the clear NVS settings (factory) mode.
|
||||
else if(keyDebCtr >= 150)
|
||||
{
|
||||
// If a clear NVS handler has been installed, call it.
|
||||
//
|
||||
if(pThis->swCtrl.clearNVSEventCallback != NULL)
|
||||
pThis->swCtrl.clearNVSEventCallback();
|
||||
}
|
||||
|
||||
// LED off, no longer needed.
|
||||
pThis->led->setLEDMode(LED::LED_MODE_OFF, LED::LED_DUTY_CYCLE_OFF, 0, 0L, 0L);
|
||||
|
||||
// Re-init switch variables for next activation.
|
||||
keyDebCtr = 0;
|
||||
}
|
||||
|
||||
// Reset the reset timer if not activated.
|
||||
if(resetTimer != 0 && (pThis->milliSeconds() - resetTimer) > 2000L) { resetTimer = 0; }
|
||||
|
||||
// Let other tasks run. NB. This value affects the debounce counter, update as necessary.
|
||||
vTaskDelay(100);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialisation routine. Setup variables and spawn a task to monitor the config switch.
|
||||
//
|
||||
void SWITCH::init(void)
|
||||
{
|
||||
// Initialise control variables.
|
||||
#define SWINITTAG "SWINIT"
|
||||
|
||||
// Core 0 - Application
|
||||
// SWITCH handler thread.
|
||||
ESP_LOGW(SWINITTAG, "Starting SWITCH thread...");
|
||||
::xTaskCreatePinnedToCore(&this->swInterface, "switch", 4096, this, 0, &this->swCtrl.TaskSWIF, 0);
|
||||
vTaskDelay(1500);
|
||||
}
|
||||
|
||||
// Basic constructor, init variables!
|
||||
SWITCH::SWITCH(LED *hdlLED)
|
||||
{
|
||||
swCtrl.cancelEventCallback = NULL;
|
||||
swCtrl.wifiEnEventCallback = NULL;
|
||||
swCtrl.wifiDefEventCallback = NULL;
|
||||
swCtrl.btPairingEventCallback = NULL;
|
||||
|
||||
// Store the class name for later use.
|
||||
this->swCtrl.swClassName = getClassName(__PRETTY_FUNCTION__);
|
||||
|
||||
// Save the LED object so it can be used to warn the user.
|
||||
this->led = hdlLED;
|
||||
|
||||
// Initialse the SWITCH object.
|
||||
init();
|
||||
}
|
||||
|
||||
// Basic consructor, do nothing!
|
||||
SWITCH::SWITCH(void)
|
||||
{
|
||||
// Store the class name for later use.
|
||||
this->swCtrl.swClassName = getClassName(__PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
// Basic destructor.
|
||||
SWITCH::~SWITCH(void)
|
||||
{
|
||||
}
|
||||
1074
main/SharpKey.cpp
Normal file
1074
main/SharpKey.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2872
main/WiFi.cpp
Normal file
2872
main/WiFi.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1124
main/X1.cpp
Normal file
1124
main/X1.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1067
main/X68K.cpp
Normal file
1067
main/X68K.cpp
Normal file
File diff suppressed because it is too large
Load Diff
222
main/include/BT.h
Normal file
222
main/include/BT.h
Normal file
@@ -0,0 +1,222 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: BT.h
|
||||
// Created: Jan 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Header file for the Bluetooth Class.
|
||||
//
|
||||
// Credits:
|
||||
// Copyright: (c) 2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BT_H_
|
||||
#define BT_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_bt.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_hidh.h"
|
||||
#include "esp_hid_common.h"
|
||||
#include "esp_gap_bt_api.h"
|
||||
#include "esp_gap_ble_api.h"
|
||||
|
||||
// Bluetooth interface class. Provides Mouse and Keyboard functionality via the Bluetooth wireless interface.
|
||||
class BT {
|
||||
#define SIZEOF_ARRAY(a) (sizeof(a) / sizeof(*a))
|
||||
|
||||
public:
|
||||
typedef void t_pairingHandler(uint32_t code, uint8_t trigger);
|
||||
|
||||
// Structure to contain details of a single device forming a scanned device list.
|
||||
//
|
||||
typedef struct {
|
||||
esp_bd_addr_t bda;
|
||||
std::string name;
|
||||
int8_t rssi;
|
||||
esp_hid_usage_t usage;
|
||||
esp_hid_transport_t transport; //BT, BLE or USB
|
||||
|
||||
union {
|
||||
struct {
|
||||
esp_bt_cod_t cod;
|
||||
esp_bt_uuid_t uuid;
|
||||
} bt;
|
||||
struct {
|
||||
esp_ble_addr_type_t addr_type;
|
||||
uint16_t appearance;
|
||||
} ble;
|
||||
};
|
||||
|
||||
// Display format values.
|
||||
std::string deviceAddr; // MAC address of the Bluetooth device.
|
||||
std::string deviceType; // BT, BLE or USB
|
||||
} t_scanListItem;
|
||||
|
||||
|
||||
// Prototypes.
|
||||
BT(void);
|
||||
virtual ~BT(void);
|
||||
void getDeviceList(std::vector<t_scanListItem> &scanList, int waitTime);
|
||||
bool setup(t_pairingHandler *handler = nullptr);
|
||||
|
||||
inline uint8_t getBatteryLevel() { return btCtrl.batteryLevel; }
|
||||
inline void setBatteryLevel(uint8_t level) { btCtrl.batteryLevel = level; }
|
||||
|
||||
private:
|
||||
static constexpr char const *TAG = "BT";
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
const char *gap_bt_prop_type_names[5] = { "", "BDNAME", "COD", "RSSI", "EIR" };
|
||||
const char *bt_gap_evt_names[10] = { "DISC_RES", "DISC_STATE_CHANGED", "RMT_SRVCS", "RMT_SRVC_REC", "AUTH_CMPL", "PIN_REQ", "CFM_REQ", "KEY_NOTIF", "KEY_REQ", "READ_RSSI_DELTA" };
|
||||
#endif
|
||||
const char *ble_gap_evt_names[28] = { "ADV_DATA_SET_COMPLETE", "SCAN_RSP_DATA_SET_COMPLETE", "SCAN_PARAM_SET_COMPLETE", "SCAN_RESULT", "ADV_DATA_RAW_SET_COMPLETE",
|
||||
"SCAN_RSP_DATA_RAW_SET_COMPLETE", "ADV_START_COMPLETE", "SCAN_START_COMPLETE", "AUTH_CMPL", "KEY",
|
||||
"SEC_REQ", "PASSKEY_NOTIF", "PASSKEY_REQ", "OOB_REQ", "LOCAL_IR",
|
||||
"LOCAL_ER", "NC_REQ", "ADV_STOP_COMPLETE", "SCAN_STOP_COMPLETE", "SET_STATIC_RAND_ADDR",
|
||||
"UPDATE_CONN_PARAMS", "SET_PKT_LENGTH_COMPLETE", "SET_LOCAL_PRIVACY_COMPLETE", "REMOVE_BOND_DEV_COMPLETE", "CLEAR_BOND_DEV_COMPLETE",
|
||||
"GET_BOND_DEV_COMPLETE", "READ_RSSI_COMPLETE", "UPDATE_WHITELIST_COMPLETE" };
|
||||
const char *ble_addr_type_names[4] = { "PUBLIC", "RANDOM", "RPA_PUBLIC", "RPA_RANDOM" };
|
||||
|
||||
// Define possible HIDH host modes.
|
||||
static const esp_bt_mode_t HIDH_IDLE_MODE = (esp_bt_mode_t) 0x00;
|
||||
static const esp_bt_mode_t HIDH_BLE_MODE = (esp_bt_mode_t) 0x01;
|
||||
static const esp_bt_mode_t HIDH_BT_MODE = (esp_bt_mode_t) 0x02;
|
||||
static const esp_bt_mode_t HIDH_BTDM_MODE = (esp_bt_mode_t) 0x03;
|
||||
|
||||
// Structure to maintain control variables.
|
||||
typedef struct {
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
std::vector<t_scanListItem> btScanList;
|
||||
#endif
|
||||
std::vector<t_scanListItem> bleScanList;
|
||||
|
||||
t_pairingHandler *pairingHandler;
|
||||
esp_hidh_dev_t *hidhDevHdl;
|
||||
|
||||
int8_t batteryLevel;
|
||||
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
xSemaphoreHandle bt_hidh_cb_semaphore;
|
||||
#endif
|
||||
xSemaphoreHandle ble_hidh_cb_semaphore;
|
||||
|
||||
BT *pThis;
|
||||
} t_btCtrl;
|
||||
|
||||
// All control variables are stored in a struct for ease of reference.
|
||||
t_btCtrl btCtrl;
|
||||
|
||||
|
||||
// Prototypes.
|
||||
static void processBTGapEvent(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t * param);
|
||||
static void processBLEGapEvent(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t * param);
|
||||
t_scanListItem* findValidScannedDevice(esp_bd_addr_t bda, std::vector<t_scanListItem> &scanList);
|
||||
void processBLEDeviceScanResult(esp_ble_gap_cb_param_t * scan_rst);
|
||||
void addBLEScanDevice(esp_bd_addr_t bda, esp_ble_addr_type_t addr_type, uint16_t appearance, uint8_t *name, uint8_t name_len, int rssi);
|
||||
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
void processBTDeviceScanResult(esp_bt_gap_cb_param_t * param);
|
||||
void addBTScanDevice(esp_bd_addr_t bda, esp_bt_cod_t *cod, esp_bt_uuid_t *uuid, uint8_t *name, uint8_t name_len, int rssi);
|
||||
#endif
|
||||
esp_err_t scanForBLEDevices(uint32_t timeout);
|
||||
esp_err_t scanForBTDevices(uint32_t timeout);
|
||||
esp_err_t scanForAllDevices(uint32_t timeout, size_t *noDevices, std::vector<t_scanListItem> &scanList);
|
||||
void printUUID(esp_bt_uuid_t * uuid);
|
||||
|
||||
const char *ble_addr_type_str(esp_ble_addr_type_t ble_addr_type)
|
||||
{
|
||||
if (ble_addr_type > BLE_ADDR_TYPE_RPA_RANDOM)
|
||||
{
|
||||
return "UNKNOWN";
|
||||
}
|
||||
return ble_addr_type_names[ble_addr_type];
|
||||
}
|
||||
|
||||
const char *ble_gap_evt_str(uint8_t event)
|
||||
{
|
||||
if (event >= SIZEOF_ARRAY(ble_gap_evt_names))
|
||||
{
|
||||
return "UNKNOWN";
|
||||
}
|
||||
return ble_gap_evt_names[event];
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
const char *bt_gap_evt_str(uint8_t event)
|
||||
{
|
||||
if (event >= SIZEOF_ARRAY(bt_gap_evt_names))
|
||||
{
|
||||
return "UNKNOWN";
|
||||
}
|
||||
return bt_gap_evt_names[event];
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *ble_key_type_str(esp_ble_key_type_t key_type)
|
||||
{
|
||||
const char *key_str = nullptr;
|
||||
switch (key_type)
|
||||
{
|
||||
case ESP_LE_KEY_NONE:
|
||||
key_str = "ESP_LE_KEY_NONE";
|
||||
break;
|
||||
case ESP_LE_KEY_PENC:
|
||||
key_str = "ESP_LE_KEY_PENC";
|
||||
break;
|
||||
case ESP_LE_KEY_PID:
|
||||
key_str = "ESP_LE_KEY_PID";
|
||||
break;
|
||||
case ESP_LE_KEY_PCSRK:
|
||||
key_str = "ESP_LE_KEY_PCSRK";
|
||||
break;
|
||||
case ESP_LE_KEY_PLK:
|
||||
key_str = "ESP_LE_KEY_PLK";
|
||||
break;
|
||||
case ESP_LE_KEY_LLK:
|
||||
key_str = "ESP_LE_KEY_LLK";
|
||||
break;
|
||||
case ESP_LE_KEY_LENC:
|
||||
key_str = "ESP_LE_KEY_LENC";
|
||||
break;
|
||||
case ESP_LE_KEY_LID:
|
||||
key_str = "ESP_LE_KEY_LID";
|
||||
break;
|
||||
case ESP_LE_KEY_LCSRK:
|
||||
key_str = "ESP_LE_KEY_LCSRK";
|
||||
break;
|
||||
default:
|
||||
key_str = "INVALID BLE KEY TYPE";
|
||||
break;
|
||||
}
|
||||
|
||||
return key_str;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BT_H_
|
||||
701
main/include/BTHID.h
Normal file
701
main/include/BTHID.h
Normal file
@@ -0,0 +1,701 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: BTHID.h
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Header file for the Bluetooth Keyboard Class.
|
||||
//
|
||||
// Credits:
|
||||
// Copyright: (c) 2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// Jun 2022 - Updated with latest findings. Now checks the bonded list and opens
|
||||
// connections or scans for new devices if no connections exist.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BT_KEYBOARD_H_
|
||||
#define BT_KEYBOARD_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_bt.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_hidh.h"
|
||||
#include "esp_hid_common.h"
|
||||
#include "esp_gap_bt_api.h"
|
||||
#include "esp_gap_ble_api.h"
|
||||
#include "PS2KeyAdvanced.h"
|
||||
#include "PS2Mouse.h"
|
||||
#include "BT.h"
|
||||
|
||||
// Keyboard is a sub-class of BT which provides methods to setup BT for use by a keyboard.
|
||||
class BTHID : public BT {
|
||||
// Macros.
|
||||
//
|
||||
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
// Global constants
|
||||
#define MAX_KEYBOARD_DATA_BYTES 8
|
||||
#define MAX_CCONTROL_DATA_BYTES 3
|
||||
#define MAX_MOUSE_DATA_BYTES 7
|
||||
#define MAX_BT2PS2_MAP_ENTRIES 179
|
||||
#define MAX_BTMEDIA2PS2_MAP_ENTRIES 8
|
||||
|
||||
// LED's
|
||||
#define BT_LED_NUMLOCK 0x01
|
||||
#define BT_LED_CAPSLOCK 0x02
|
||||
#define BT_LED_SCROLLLOCK 0x04
|
||||
|
||||
// Control keys.
|
||||
#define BT_NONE 0x0000
|
||||
#define BT_CTRL_LEFT 0x0001
|
||||
#define BT_SHIFT_LEFT 0x0002
|
||||
#define BT_ALT_LEFT 0x0004
|
||||
#define BT_GUI_LEFT 0x0008
|
||||
#define BT_CTRL_RIGHT 0x0010
|
||||
#define BT_SHIFT_RIGHT 0x0020
|
||||
#define BT_ALT_RIGHT 0x0040
|
||||
#define BT_GUI_RIGHT 0x0080
|
||||
#define BT_CAPS_LOCK 0x0100
|
||||
#define BT_NUM_LOCK 0x0200
|
||||
#define BT_SCROLL_LOCK 0x0400
|
||||
#define BT_DUPLICATE 0xFFFF // Duplicate BT flags onto PS/2 flags.
|
||||
|
||||
#define BT_PS2_FUNCTION 0x01
|
||||
#define BT_PS2_GUI 0x02
|
||||
#define BT_PS2_ALT_GR 0x04
|
||||
#define BT_PS2_ALT 0x08
|
||||
#define BT_PS2_CAPS 0x10
|
||||
#define BT_PS2_CTRL 0x20
|
||||
#define BT_PS2_SHIFT 0x40
|
||||
#define BT_PS2_BREAK 0x80
|
||||
|
||||
#define BT_KEY_NONE 0x00 // No key pressed
|
||||
#define BT_KEY_ERR_OVF 0x01 // Keyboard Error Roll Over
|
||||
// 0x02 // Keyboard POST Fail
|
||||
// 0x03 // Keyboard Error Undefined
|
||||
#define BT_KEY_A 0x04 // Keyboard a and A
|
||||
#define BT_KEY_B 0x05 // Keyboard b and B
|
||||
#define BT_KEY_C 0x06 // Keyboard c and C
|
||||
#define BT_KEY_D 0x07 // Keyboard d and D
|
||||
#define BT_KEY_E 0x08 // Keyboard e and E
|
||||
#define BT_KEY_F 0x09 // Keyboard f and F
|
||||
#define BT_KEY_G 0x0a // Keyboard g and G
|
||||
#define BT_KEY_H 0x0b // Keyboard h and H
|
||||
#define BT_KEY_I 0x0c // Keyboard i and I
|
||||
#define BT_KEY_J 0x0d // Keyboard j and J
|
||||
#define BT_KEY_K 0x0e // Keyboard k and K
|
||||
#define BT_KEY_L 0x0f // Keyboard l and L
|
||||
#define BT_KEY_M 0x10 // Keyboard m and M
|
||||
#define BT_KEY_N 0x11 // Keyboard n and N
|
||||
#define BT_KEY_O 0x12 // Keyboard o and O
|
||||
#define BT_KEY_P 0x13 // Keyboard p and P
|
||||
#define BT_KEY_Q 0x14 // Keyboard q and Q
|
||||
#define BT_KEY_R 0x15 // Keyboard r and R
|
||||
#define BT_KEY_S 0x16 // Keyboard s and S
|
||||
#define BT_KEY_T 0x17 // Keyboard t and T
|
||||
#define BT_KEY_U 0x18 // Keyboard u and U
|
||||
#define BT_KEY_V 0x19 // Keyboard v and V
|
||||
#define BT_KEY_W 0x1a // Keyboard w and W
|
||||
#define BT_KEY_X 0x1b // Keyboard x and X
|
||||
#define BT_KEY_Y 0x1c // Keyboard y and Y
|
||||
#define BT_KEY_Z 0x1d // Keyboard z and Z
|
||||
|
||||
#define BT_KEY_1 0x1e // Keyboard 1 and !
|
||||
#define BT_KEY_2 0x1f // Keyboard 2 and @
|
||||
#define BT_KEY_3 0x20 // Keyboard 3 and #
|
||||
#define BT_KEY_4 0x21 // Keyboard 4 and $
|
||||
#define BT_KEY_5 0x22 // Keyboard 5 and %
|
||||
#define BT_KEY_6 0x23 // Keyboard 6 and ^
|
||||
#define BT_KEY_7 0x24 // Keyboard 7 and &
|
||||
#define BT_KEY_8 0x25 // Keyboard 8 and *
|
||||
#define BT_KEY_9 0x26 // Keyboard 9 and (
|
||||
#define BT_KEY_0 0x27 // Keyboard 0 and )
|
||||
|
||||
#define BT_KEY_ENTER 0x28 // Keyboard Return (ENTER)
|
||||
#define BT_KEY_ESC 0x29 // Keyboard ESCAPE
|
||||
#define BT_KEY_BACKSPACE 0x2a // Keyboard DELETE (Backspace)
|
||||
#define BT_KEY_TAB 0x2b // Keyboard Tab
|
||||
#define BT_KEY_SPACE 0x2c // Keyboard Spacebar
|
||||
#define BT_KEY_MINUS 0x2d // Keyboard - and _
|
||||
#define BT_KEY_EQUAL 0x2e // Keyboard = and +
|
||||
#define BT_KEY_LEFTBRACE 0x2f // Keyboard [ and {
|
||||
#define BT_KEY_RIGHTBRACE 0x30 // Keyboard ] and }
|
||||
#define BT_KEY_BACKSLASH 0x31 // Keyboard \ and |
|
||||
#define BT_KEY_HASHTILDE 0x32 // Keyboard Non-US # and ~
|
||||
#define BT_KEY_SEMICOLON 0x33 // Keyboard ; and :
|
||||
#define BT_KEY_APOSTROPHE 0x34 // Keyboard ' and "
|
||||
#define BT_KEY_GRAVE 0x35 // Keyboard ` and ~
|
||||
#define BT_KEY_COMMA 0x36 // Keyboard , and <
|
||||
#define BT_KEY_DOT 0x37 // Keyboard . and >
|
||||
#define BT_KEY_SLASH 0x38 // Keyboard / and ?
|
||||
#define BT_KEY_CAPSLOCK 0x39 // Keyboard Caps Lock
|
||||
|
||||
#define BT_KEY_F1 0x3a // Keyboard F1
|
||||
#define BT_KEY_F2 0x3b // Keyboard F2
|
||||
#define BT_KEY_F3 0x3c // Keyboard F3
|
||||
#define BT_KEY_F4 0x3d // Keyboard F4
|
||||
#define BT_KEY_F5 0x3e // Keyboard F5
|
||||
#define BT_KEY_F6 0x3f // Keyboard F6
|
||||
#define BT_KEY_F7 0x40 // Keyboard F7
|
||||
#define BT_KEY_F8 0x41 // Keyboard F8
|
||||
#define BT_KEY_F9 0x42 // Keyboard F9
|
||||
#define BT_KEY_F10 0x43 // Keyboard F10
|
||||
#define BT_KEY_F11 0x44 // Keyboard F11
|
||||
#define BT_KEY_F12 0x45 // Keyboard F12
|
||||
|
||||
#define BT_KEY_SYSRQ 0x46 // Keyboard Print Screen
|
||||
#define BT_KEY_SCROLLLOCK 0x47 // Keyboard Scroll Lock
|
||||
#define BT_KEY_PAUSE 0x48 // Keyboard Pause
|
||||
#define BT_KEY_INSERT 0x49 // Keyboard Insert
|
||||
#define BT_KEY_HOME 0x4a // Keyboard Home
|
||||
#define BT_KEY_PAGEUP 0x4b // Keyboard Page Up
|
||||
#define BT_KEY_DELETE 0x4c // Keyboard Delete Forward
|
||||
#define BT_KEY_END 0x4d // Keyboard End
|
||||
#define BT_KEY_PAGEDOWN 0x4e // Keyboard Page Down
|
||||
#define BT_KEY_RIGHT 0x4f // Keyboard Right Arrow
|
||||
#define BT_KEY_LEFT 0x50 // Keyboard Left Arrow
|
||||
#define BT_KEY_DOWN 0x51 // Keyboard Down Arrow
|
||||
#define BT_KEY_UP 0x52 // Keyboard Up Arrow
|
||||
|
||||
#define BT_KEY_NUMLOCK 0x53 // Keyboard Num Lock and Clear
|
||||
#define BT_KEY_KPSLASH 0x54 // Keypad /
|
||||
#define BT_KEY_KPASTERISK 0x55 // Keypad *
|
||||
#define BT_KEY_KPMINUS 0x56 // Keypad -
|
||||
#define BT_KEY_KPPLUS 0x57 // Keypad +
|
||||
#define BT_KEY_KPENTER 0x58 // Keypad ENTER
|
||||
#define BT_KEY_KP1 0x59 // Keypad 1 and End
|
||||
#define BT_KEY_KP2 0x5a // Keypad 2 and Down Arrow
|
||||
#define BT_KEY_KP3 0x5b // Keypad 3 and PageDn
|
||||
#define BT_KEY_KP4 0x5c // Keypad 4 and Left Arrow
|
||||
#define BT_KEY_KP5 0x5d // Keypad 5
|
||||
#define BT_KEY_KP6 0x5e // Keypad 6 and Right Arrow
|
||||
#define BT_KEY_KP7 0x5f // Keypad 7 and Home
|
||||
#define BT_KEY_KP8 0x60 // Keypad 8 and Up Arrow
|
||||
#define BT_KEY_KP9 0x61 // Keypad 9 and Page Up
|
||||
#define BT_KEY_KP0 0x62 // Keypad 0 and Insert
|
||||
#define BT_KEY_KPDOT 0x63 // Keypad . and Delete
|
||||
|
||||
#define BT_KEY_102ND 0x64 // Keyboard Non-US \ and |
|
||||
#define BT_KEY_COMPOSE 0x65 // Keyboard Application
|
||||
#define BT_KEY_POWER 0x66 // Keyboard Power
|
||||
#define BT_KEY_KPEQUAL 0x67 // Keypad =
|
||||
|
||||
#define BT_KEY_F13 0x68 // Keyboard F13
|
||||
#define BT_KEY_F14 0x69 // Keyboard F14
|
||||
#define BT_KEY_F15 0x6a // Keyboard F15
|
||||
#define BT_KEY_F16 0x6b // Keyboard F16
|
||||
#define BT_KEY_F17 0x6c // Keyboard F17
|
||||
#define BT_KEY_F18 0x6d // Keyboard F18
|
||||
#define BT_KEY_F19 0x6e // Keyboard F19
|
||||
#define BT_KEY_F20 0x6f // Keyboard F20
|
||||
#define BT_KEY_F21 0x70 // Keyboard F21
|
||||
#define BT_KEY_F22 0x71 // Keyboard F22
|
||||
#define BT_KEY_F23 0x72 // Keyboard F23
|
||||
#define BT_KEY_F24 0x73 // Keyboard F24
|
||||
|
||||
#define BT_KEY_OPEN 0x74 // Keyboard Execute
|
||||
#define BT_KEY_HELP 0x75 // Keyboard Help
|
||||
#define BT_KEY_PROPS 0x76 // Keyboard Menu
|
||||
#define BT_KEY_FRONT 0x77 // Keyboard Select
|
||||
#define BT_KEY_STOP 0x78 // Keyboard Stop
|
||||
#define BT_KEY_AGAIN 0x79 // Keyboard Again
|
||||
#define BT_KEY_UNDO 0x7a // Keyboard Undo
|
||||
#define BT_KEY_CUT 0x7b // Keyboard Cut
|
||||
#define BT_KEY_COPY 0x7c // Keyboard Copy
|
||||
#define BT_KEY_PASTE 0x7d // Keyboard Paste
|
||||
#define BT_KEY_FIND 0x7e // Keyboard Find
|
||||
#define BT_KEY_MUTE 0x7f // Keyboard Mute
|
||||
#define BT_KEY_VOLUMEUP 0x80 // Keyboard Volume Up
|
||||
#define BT_KEY_VOLUMEDOWN 0x81 // Keyboard Volume Down
|
||||
// 0x82 Keyboard Locking Caps Lock
|
||||
// 0x83 Keyboard Locking Num Lock
|
||||
// 0x84 Keyboard Locking Scroll Lock
|
||||
#define BT_KEY_KPCOMMA 0x85 // Keypad Comma
|
||||
// 0x86 Keypad Equal Sign
|
||||
#define BT_KEY_RO 0x87 // Keyboard International1
|
||||
#define BT_KEY_KATAKANAHIRAGANA 0x88 // Keyboard International2
|
||||
#define BT_KEY_YEN 0x89 // Keyboard International3
|
||||
#define BT_KEY_HENKAN 0x8a // Keyboard International4
|
||||
#define BT_KEY_MUHENKAN 0x8b // Keyboard International5
|
||||
#define BT_KEY_KPJPCOMMA 0x8c // Keyboard International6
|
||||
// 0x8d Keyboard International7
|
||||
// 0x8e Keyboard International8
|
||||
// 0x8f Keyboard International9
|
||||
#define BT_KEY_HANGEUL 0x90 // Keyboard LANG1
|
||||
#define BT_KEY_HANJA 0x91 // Keyboard LANG2
|
||||
#define BT_KEY_KATAKANA 0x92 // Keyboard LANG3
|
||||
#define BT_KEY_HIRAGANA 0x93 // Keyboard LANG4
|
||||
#define BT_KEY_ZENKAKUHANKAKU 0x94 // Keyboard LANG5
|
||||
// 0x95 Keyboard LANG6
|
||||
// 0x96 Keyboard LANG7
|
||||
// 0x97 Keyboard LANG8
|
||||
// 0x98 Keyboard LANG9
|
||||
// 0x99 Keyboard Alternate Erase
|
||||
// 0x9a Keyboard SysReq/Attention
|
||||
// 0x9b Keyboard Cancel
|
||||
// 0x9c Keyboard Clear
|
||||
// 0x9d Keyboard Prior
|
||||
// 0x9e Keyboard Return
|
||||
// 0x9f Keyboard Separator
|
||||
// 0xa0 Keyboard Out
|
||||
// 0xa1 Keyboard Oper
|
||||
// 0xa2 Keyboard Clear/Again
|
||||
// 0xa3 Keyboard CrSel/Props
|
||||
// 0xa4 Keyboard ExSel
|
||||
|
||||
// 0xb0 Keypad 00
|
||||
// 0xb1 Keypad 000
|
||||
// 0xb2 Thousands Separator
|
||||
// 0xb3 Decimal Separator
|
||||
// 0xb4 Currency Unit
|
||||
// 0xb5 Currency Sub-unit
|
||||
#define BT_KEY_KPLEFTPAREN 0xb6 // Keypad (
|
||||
#define BT_KEY_KPRIGHTPAREN 0xb7 // Keypad )
|
||||
// 0xb8 Keypad {
|
||||
// 0xb9 Keypad }
|
||||
// 0xba Keypad Tab
|
||||
// 0xbb Keypad Backspace
|
||||
// 0xbc Keypad A
|
||||
// 0xbd Keypad B
|
||||
// 0xbe Keypad C
|
||||
// 0xbf Keypad D
|
||||
// 0xc0 Keypad E
|
||||
// 0xc1 Keypad F
|
||||
// 0xc2 Keypad XOR
|
||||
// 0xc3 Keypad ^
|
||||
// 0xc4 Keypad %
|
||||
// 0xc5 Keypad <
|
||||
// 0xc6 Keypad >
|
||||
// 0xc7 Keypad &
|
||||
// 0xc8 Keypad &&
|
||||
// 0xc9 Keypad |
|
||||
// 0xca Keypad ||
|
||||
// 0xcb Keypad :
|
||||
// 0xcc Keypad #
|
||||
// 0xcd Keypad Space
|
||||
// 0xce Keypad @
|
||||
// 0xcf Keypad !
|
||||
// 0xd0 Keypad Memory Store
|
||||
// 0xd1 Keypad Memory Recall
|
||||
// 0xd2 Keypad Memory Clear
|
||||
// 0xd3 Keypad Memory Add
|
||||
// 0xd4 Keypad Memory Subtract
|
||||
// 0xd5 Keypad Memory Multiply
|
||||
// 0xd6 Keypad Memory Divide
|
||||
// 0xd7 Keypad +/-
|
||||
// 0xd8 Keypad Clear
|
||||
// 0xd9 Keypad Clear Entry
|
||||
// 0xda Keypad Binary
|
||||
// 0xdb Keypad Octal
|
||||
// 0xdc Keypad Decimal
|
||||
// 0xdd Keypad Hexadecimal
|
||||
|
||||
#define BT_KEY_LEFTCTRL 0xe0 // Keyboard Left Control
|
||||
#define BT_KEY_LEFTSHIFT 0xe1 // Keyboard Left Shift
|
||||
#define BT_KEY_LEFTALT 0xe2 // Keyboard Left Alt
|
||||
#define BT_KEY_LEFTMETA 0xe3 // Keyboard Left GUI
|
||||
#define BT_KEY_RIGHTCTRL 0xe4 // Keyboard Right Control
|
||||
#define BT_KEY_RIGHTSHIFT 0xe5 // Keyboard Right Shift
|
||||
#define BT_KEY_RIGHTALT 0xe6 // Keyboard Right Alt
|
||||
#define BT_KEY_RIGHTMETA 0xe7 // Keyboard Right GUI
|
||||
|
||||
#define BT_KEY_MEDIA_PLAYPAUSE 0xe8
|
||||
#define BT_KEY_MEDIA_STOPCD 0xe9
|
||||
#define BT_KEY_MEDIA_PREVIOUSSONG 0xea
|
||||
#define BT_KEY_MEDIA_NEXTSONG 0xeb
|
||||
#define BT_KEY_MEDIA_EJECTCD 0xec
|
||||
#define BT_KEY_MEDIA_VOLUMEUP 0xed
|
||||
#define BT_KEY_MEDIA_VOLUMEDOWN 0xee
|
||||
#define BT_KEY_MEDIA_MUTE 0xef
|
||||
#define BT_KEY_MEDIA_WWW 0xf0
|
||||
#define BT_KEY_MEDIA_BACK 0xf1
|
||||
#define BT_KEY_MEDIA_FORWARD 0xf2
|
||||
#define BT_KEY_MEDIA_STOP 0xf3
|
||||
#define BT_KEY_MEDIA_FIND 0xf4
|
||||
#define BT_KEY_MEDIA_SCROLLUP 0xf5
|
||||
#define BT_KEY_MEDIA_SCROLLDOWN 0xf6
|
||||
#define BT_KEY_MEDIA_EDIT 0xf7
|
||||
#define BT_KEY_MEDIA_SLEEP 0xf8
|
||||
#define BT_KEY_MEDIA_COFFEE 0xf9
|
||||
#define BT_KEY_MEDIA_REFRESH 0xfa
|
||||
#define BT_KEY_MEDIA_CALC 0xfb
|
||||
|
||||
// Media key definition. On the ESP module a seperate usage type, CCONTROL is created for media keys and it delivers a 24bit word, each bit signifying a key.
|
||||
#define BT_MEDIA_SEARCH 0x00200000
|
||||
#define BT_MEDIA_HOME 0x00080000
|
||||
#define BT_MEDIA_BRIGHTNESS_UP 0x00004000
|
||||
#define BT_MEDIA_BRIGHTNESS_DOWN 0x00008000
|
||||
#define BT_MEDIA_MUTE 0x00000040
|
||||
#define BT_MEDIA_VOL_DOWN 0x00000020
|
||||
#define BT_MEDIA_VOL_UP 0x00000010
|
||||
#define BT_MEDIA_TRACK_PREV 0x00000001
|
||||
|
||||
// PS2 Flag definitions.
|
||||
#define PS2_FLG_NONE 0x00 // No keys active = 0
|
||||
#define PS2_FLG_SHIFT PS2_SHIFT >> 8 // Shift Key active = 1
|
||||
#define PS2_FLG_CTRL PS2_CTRL >> 8 // Ctrl Key active = 1
|
||||
#define PS2_FLG_CAPS PS2_CAPS >> 8 // CAPS active = 1
|
||||
#define PS2_FLG_ALT PS2_ALT >> 8 // ALT flag used as Right CTRL flag, active = 1
|
||||
#define PS2_FLG_ALTGR PS2_ALT_GR >> 8 // ALTGR active = 1
|
||||
#define PS2_FLG_GUI PS2_GUI >> 8 // GUI Key active = 1
|
||||
#define PS2_FLG_FUNC PS2_FUNCTION >> 8 // Special Function Keys active = 1
|
||||
#define PS2_FLG_BREAK PS2_BREAL >> 8 // BREAK Key active = 1
|
||||
|
||||
|
||||
public:
|
||||
|
||||
struct KeyInfo {
|
||||
uint8_t keys[MAX_KEYBOARD_DATA_BYTES];
|
||||
uint8_t length;
|
||||
bool cControl;
|
||||
esp_hidh_dev_t *hdlDev;
|
||||
};
|
||||
|
||||
// Prototypes.
|
||||
BTHID(void);
|
||||
virtual ~BTHID(void);
|
||||
bool setup(t_pairingHandler *handler);
|
||||
bool openDevice(esp_bd_addr_t bda, esp_hid_transport_t transport, esp_ble_addr_type_t addrType);
|
||||
bool closeDevice(esp_bd_addr_t bda);
|
||||
void checkBTDevices(void);
|
||||
bool setResolution(enum PS2Mouse::PS2_RESOLUTION resolution);
|
||||
bool setScaling(enum PS2Mouse::PS2_SCALING scaling);
|
||||
bool setSampleRate(enum PS2Mouse::PS2_SAMPLING rate);
|
||||
void processBTKeys(void);
|
||||
uint16_t getKey(uint32_t timeout = 0);
|
||||
|
||||
// Method to register an object method for callback with context.
|
||||
template<typename A, typename B>
|
||||
void setMouseDataCallback(A func_ptr, B obj_ptr)
|
||||
{
|
||||
btHIDCtrl.ms.mouseDataCallback = bind(func_ptr, obj_ptr, 1, std::placeholders::_1);
|
||||
}
|
||||
|
||||
// Template to aid in conversion of an enum to integer.
|
||||
template <typename E> constexpr typename std::underlying_type<E>::type to_underlying(E e) noexcept
|
||||
{
|
||||
return static_cast<typename std::underlying_type<E>::type>(e);
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr char const * TAG = "BTHID";
|
||||
|
||||
// Structure to hold details of an active or post-active connection.
|
||||
typedef struct {
|
||||
esp_bd_addr_t bda;
|
||||
esp_hid_transport_t transport;
|
||||
esp_ble_addr_type_t addrType;
|
||||
esp_hid_usage_t usage;
|
||||
esp_hidh_dev_t *hidhDevHdl;
|
||||
uint32_t nextCheckTime;
|
||||
bool open;
|
||||
} t_activeDev;
|
||||
|
||||
// Structure to encapsulate a single key map from Bluetooth to PS/2.
|
||||
typedef struct {
|
||||
uint8_t btKeyCode;
|
||||
uint16_t btCtrl;
|
||||
uint8_t ps2KeyCode;
|
||||
uint16_t ps2Ctrl;
|
||||
} t_keyMapEntry;
|
||||
|
||||
// Structure to encapsulate the entire static keyboard mapping table.
|
||||
typedef struct {
|
||||
t_keyMapEntry kme[MAX_BT2PS2_MAP_ENTRIES];
|
||||
} t_keyMap;
|
||||
|
||||
// Structure to contain a media key map.
|
||||
typedef struct {
|
||||
uint32_t mediaKey; // 24bit Media key value.
|
||||
uint8_t ps2Key; // Equivalent PS/2 key for media key.
|
||||
uint16_t ps2Ctrl; // PS/2 translated control flags.
|
||||
} t_mediaMapEntry;
|
||||
|
||||
// Structure to encapsulate Media key mappings.
|
||||
typedef struct {
|
||||
t_mediaMapEntry kme[MAX_BTMEDIA2PS2_MAP_ENTRIES];
|
||||
} t_mediaKeyMap;
|
||||
|
||||
// Structure to maintain control variables.
|
||||
typedef struct {
|
||||
// Array of active devices which connect with the SharpKey.
|
||||
std::vector<t_activeDev> devices;
|
||||
|
||||
// Keyboard handling.
|
||||
struct {
|
||||
// Queues for storing data in the 2 processing stages.
|
||||
xQueueHandle rawKeyQueue;
|
||||
xQueueHandle keyQueue;
|
||||
|
||||
uint8_t lastKeys[MAX_KEYBOARD_DATA_BYTES]; // Required to generate a PS/2 break event when a key is released.
|
||||
uint32_t lastMediaKey; // Required to detect changes in the media control keys, ie. release.
|
||||
uint16_t btFlags; // Bluetooth control flags.
|
||||
uint16_t ps2Flags; // PS/2 translated control flags.
|
||||
uint8_t statusLED; // Keyboard LED state.
|
||||
t_keyMapEntry *kme; // Pointer to the mapping array.
|
||||
t_mediaMapEntry *kmeMedia; // Pointer to the media key mapping array.
|
||||
int kmeRows; // Number of entries in the BT to PS/2 mapping table.
|
||||
int kmeMediaRows; // Number of entries in the BT to PS/2 media key mapping table.
|
||||
} kbd;
|
||||
|
||||
// Mouse handling.
|
||||
struct {
|
||||
int resolution; // PS/2 compatible resolution (pixels per mm) setting.
|
||||
int scaling; // PS/2 compatible scaling (1:1 or 2:1).
|
||||
int sampleRate; // PS/2 compatible sample rate (10 .. 200).
|
||||
int xDivisor; // Divisor on the X plane to scale down the 12bit BT resolution.
|
||||
int yDivisor; // Divisor on the Y plane to scale down the 12bit BT resolution.
|
||||
|
||||
// Callback for streaming processed mouse data to HID handler.
|
||||
std::function<void(PS2Mouse::MouseData)> mouseDataCallback;
|
||||
} ms;
|
||||
|
||||
BTHID *pThis;
|
||||
} t_btHIDCtrl;
|
||||
|
||||
// All control variables are stored in a struct for ease of reference.
|
||||
t_btHIDCtrl btHIDCtrl;
|
||||
|
||||
// Prototypes.
|
||||
static void hidh_callback(void * handler_args, esp_event_base_t base, int32_t id, void * event_data);
|
||||
void pushKeyToFIFO(esp_hid_usage_t src, esp_hidh_dev_t *hdlDev, uint8_t *keys, uint8_t size);
|
||||
void setStatusLED(esp_hidh_dev_t *dev, uint8_t led);
|
||||
void clearStatusLED(esp_hidh_dev_t *dev, uint8_t led);
|
||||
uint16_t mapBTMediaToPS2(uint32_t key);
|
||||
uint16_t mapBTtoPS2(uint8_t key);
|
||||
inline uint32_t milliSeconds(void)
|
||||
{
|
||||
return( (uint32_t) (clock() ) );
|
||||
}
|
||||
|
||||
// Mapping for Media keys. ESP module seperates them but not properly, some media keys are sent as normal key scancodes others as control key bit maps.
|
||||
// Hence two mapping tables, one for normal scancodes and one for media codes.
|
||||
t_mediaKeyMap MediaKeyToPS2 = {
|
||||
{
|
||||
{ BT_MEDIA_SEARCH, PS2_KEY_WEB_SEARCH, PS2_FLG_NONE, },
|
||||
{ BT_MEDIA_HOME, PS2_KEY_WEB_HOME, PS2_FLG_NONE, },
|
||||
{ BT_MEDIA_BRIGHTNESS_UP, PS2_KEY_WEB_FORWARD, PS2_FLG_NONE, },
|
||||
{ BT_MEDIA_BRIGHTNESS_DOWN, PS2_KEY_WEB_BACK, PS2_FLG_NONE, },
|
||||
{ BT_MEDIA_MUTE, PS2_KEY_MUTE, PS2_FLG_NONE, },
|
||||
{ BT_MEDIA_VOL_DOWN, PS2_KEY_VOL_DN, PS2_FLG_NONE, },
|
||||
{ BT_MEDIA_VOL_UP, PS2_KEY_VOL_UP, PS2_FLG_NONE, },
|
||||
{ BT_MEDIA_TRACK_PREV, PS2_KEY_PREV_TR, PS2_FLG_NONE, },
|
||||
}};
|
||||
|
||||
// Mapping table between BT Keyboard Scan Codes and PS/2 Keyboard Scan Codes.
|
||||
//
|
||||
t_keyMap BTKeyToPS2 = {
|
||||
{
|
||||
// Bluetooth Key Bluetooth Control, PS/2 Key PS/2 Control,
|
||||
{ BT_KEY_A, BT_NONE, PS2_KEY_A, PS2_FLG_NONE, },
|
||||
{ BT_KEY_B, BT_NONE, PS2_KEY_B, PS2_FLG_NONE, },
|
||||
{ BT_KEY_C, BT_NONE, PS2_KEY_C, PS2_FLG_NONE, },
|
||||
{ BT_KEY_D, BT_NONE, PS2_KEY_D, PS2_FLG_NONE, },
|
||||
{ BT_KEY_E, BT_NONE, PS2_KEY_E, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F, BT_NONE, PS2_KEY_F, PS2_FLG_NONE, },
|
||||
{ BT_KEY_G, BT_NONE, PS2_KEY_G, PS2_FLG_NONE, },
|
||||
{ BT_KEY_H, BT_NONE, PS2_KEY_H, PS2_FLG_NONE, },
|
||||
{ BT_KEY_I, BT_NONE, PS2_KEY_I, PS2_FLG_NONE, },
|
||||
{ BT_KEY_J, BT_NONE, PS2_KEY_J, PS2_FLG_NONE, },
|
||||
{ BT_KEY_K, BT_NONE, PS2_KEY_K, PS2_FLG_NONE, },
|
||||
{ BT_KEY_L, BT_NONE, PS2_KEY_L, PS2_FLG_NONE, },
|
||||
{ BT_KEY_M, BT_NONE, PS2_KEY_M, PS2_FLG_NONE, },
|
||||
{ BT_KEY_N, BT_NONE, PS2_KEY_N, PS2_FLG_NONE, },
|
||||
{ BT_KEY_O, BT_NONE, PS2_KEY_O, PS2_FLG_NONE, },
|
||||
{ BT_KEY_P, BT_NONE, PS2_KEY_P, PS2_FLG_NONE, },
|
||||
{ BT_KEY_Q, BT_NONE, PS2_KEY_Q, PS2_FLG_NONE, },
|
||||
{ BT_KEY_R, BT_NONE, PS2_KEY_R, PS2_FLG_NONE, },
|
||||
{ BT_KEY_S, BT_NONE, PS2_KEY_S, PS2_FLG_NONE, },
|
||||
{ BT_KEY_T, BT_NONE, PS2_KEY_T, PS2_FLG_NONE, },
|
||||
{ BT_KEY_U, BT_NONE, PS2_KEY_U, PS2_FLG_NONE, },
|
||||
{ BT_KEY_V, BT_NONE, PS2_KEY_V, PS2_FLG_NONE, },
|
||||
{ BT_KEY_W, BT_NONE, PS2_KEY_W, PS2_FLG_NONE, },
|
||||
{ BT_KEY_X, BT_NONE, PS2_KEY_X, PS2_FLG_NONE, },
|
||||
{ BT_KEY_Y, BT_NONE, PS2_KEY_Y, PS2_FLG_NONE, },
|
||||
{ BT_KEY_Z, BT_NONE, PS2_KEY_Z, PS2_FLG_NONE, },
|
||||
{ BT_KEY_1, BT_NONE, PS2_KEY_1, PS2_FLG_NONE, },
|
||||
{ BT_KEY_2, BT_NONE, PS2_KEY_2, PS2_FLG_NONE, },
|
||||
{ BT_KEY_3, BT_NONE, PS2_KEY_3, PS2_FLG_NONE, },
|
||||
{ BT_KEY_4, BT_NONE, PS2_KEY_4, PS2_FLG_NONE, },
|
||||
{ BT_KEY_5, BT_NONE, PS2_KEY_5, PS2_FLG_NONE, },
|
||||
{ BT_KEY_6, BT_NONE, PS2_KEY_6, PS2_FLG_NONE, },
|
||||
{ BT_KEY_7, BT_NONE, PS2_KEY_7, PS2_FLG_NONE, },
|
||||
{ BT_KEY_8, BT_NONE, PS2_KEY_8, PS2_FLG_NONE, },
|
||||
{ BT_KEY_9, BT_NONE, PS2_KEY_9, PS2_FLG_NONE, },
|
||||
{ BT_KEY_0, BT_NONE, PS2_KEY_0, PS2_FLG_NONE, },
|
||||
{ BT_KEY_ENTER, BT_NONE, PS2_KEY_ENTER, PS2_FLG_NONE, },
|
||||
{ BT_KEY_ESC, BT_NONE, PS2_KEY_ESC, PS2_FLG_NONE, },
|
||||
{ BT_KEY_BACKSPACE, BT_NONE, PS2_KEY_BS, PS2_FLG_NONE, },
|
||||
{ BT_KEY_TAB, BT_NONE, PS2_KEY_TAB, PS2_FLG_NONE, },
|
||||
{ BT_KEY_SPACE, BT_NONE, PS2_KEY_SPACE, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MINUS, BT_NONE, PS2_KEY_MINUS, PS2_FLG_NONE, },
|
||||
{ BT_KEY_EQUAL, BT_NONE, PS2_KEY_EQUAL, PS2_FLG_NONE, },
|
||||
{ BT_KEY_LEFTBRACE, BT_NONE, PS2_KEY_OPEN_SQ, PS2_FLG_NONE, },
|
||||
{ BT_KEY_RIGHTBRACE, BT_NONE, PS2_KEY_CLOSE_SQ, PS2_FLG_NONE, },
|
||||
{ BT_KEY_BACKSLASH, BT_NONE, PS2_KEY_BACK, PS2_FLG_NONE, },
|
||||
{ BT_KEY_HASHTILDE, BT_NONE, PS2_KEY_HASH, PS2_FLG_NONE, },
|
||||
{ BT_KEY_SEMICOLON, BT_NONE, PS2_KEY_SEMI, PS2_FLG_NONE, },
|
||||
{ BT_KEY_APOSTROPHE, BT_NONE, PS2_KEY_APOS, PS2_FLG_NONE, },
|
||||
{ BT_KEY_GRAVE, BT_NONE, PS2_KEY_BTICK, PS2_FLG_NONE, },
|
||||
{ BT_KEY_COMMA, BT_NONE, PS2_KEY_COMMA, PS2_FLG_NONE, },
|
||||
{ BT_KEY_DOT, BT_NONE, PS2_KEY_DOT, PS2_FLG_NONE, },
|
||||
{ BT_KEY_SLASH, BT_NONE, PS2_KEY_DIV, PS2_FLG_NONE, },
|
||||
{ BT_KEY_CAPSLOCK, BT_NONE, PS2_KEY_CAPS, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F1, BT_NONE, PS2_KEY_F1, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F2, BT_NONE, PS2_KEY_F2, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F3, BT_NONE, PS2_KEY_F3, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F4, BT_NONE, PS2_KEY_F4, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F5, BT_NONE, PS2_KEY_F5, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F6, BT_NONE, PS2_KEY_F6, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F7, BT_NONE, PS2_KEY_F7, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F8, BT_NONE, PS2_KEY_F8, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F9, BT_NONE, PS2_KEY_F9, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F10, BT_NONE, PS2_KEY_F10, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F11, BT_NONE, PS2_KEY_F11, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F12, BT_NONE, PS2_KEY_F12, PS2_FLG_NONE, },
|
||||
{ BT_KEY_SYSRQ, BT_NONE, PS2_KEY_PRTSCR, PS2_FLG_NONE, },
|
||||
{ BT_KEY_SCROLLLOCK, BT_NONE, PS2_KEY_SCROLL, PS2_FLG_NONE, },
|
||||
{ BT_KEY_PAUSE, BT_NONE, PS2_KEY_PAUSE, PS2_FLG_NONE, },
|
||||
{ BT_KEY_INSERT, BT_NONE, PS2_KEY_INSERT, PS2_FLG_NONE, },
|
||||
{ BT_KEY_HOME, BT_NONE, PS2_KEY_HOME, PS2_FLG_NONE, },
|
||||
{ BT_KEY_PAGEUP, BT_NONE, PS2_KEY_PGUP, PS2_FLG_NONE, },
|
||||
{ BT_KEY_DELETE, BT_NONE, PS2_KEY_DELETE, PS2_FLG_NONE, },
|
||||
{ BT_KEY_END, BT_NONE, PS2_KEY_END, PS2_FLG_NONE, },
|
||||
{ BT_KEY_PAGEDOWN, BT_NONE, PS2_KEY_PGDN, PS2_FLG_NONE, },
|
||||
{ BT_KEY_RIGHT, BT_NONE, PS2_KEY_R_ARROW, PS2_FLG_NONE, },
|
||||
{ BT_KEY_LEFT, BT_NONE, PS2_KEY_L_ARROW, PS2_FLG_NONE, },
|
||||
{ BT_KEY_DOWN, BT_NONE, PS2_KEY_DN_ARROW, PS2_FLG_NONE, },
|
||||
{ BT_KEY_UP, BT_NONE, PS2_KEY_UP_ARROW, PS2_FLG_NONE, },
|
||||
{ BT_KEY_NUMLOCK, BT_NONE, PS2_KEY_NUM, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KPSLASH, BT_NONE, PS2_KEY_KP_DIV, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KPASTERISK, BT_NONE, PS2_KEY_KP_TIMES, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KPMINUS, BT_NONE, PS2_KEY_KP_MINUS, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KPPLUS, BT_NONE, PS2_KEY_KP_PLUS, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KPENTER, BT_NONE, PS2_KEY_KP_ENTER, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP1, BT_NUM_LOCK, PS2_KEY_KP1, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP2, BT_NUM_LOCK, PS2_KEY_KP2, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP3, BT_NUM_LOCK, PS2_KEY_KP3, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP4, BT_NUM_LOCK, PS2_KEY_KP4, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP5, BT_NUM_LOCK, PS2_KEY_KP5, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP6, BT_NUM_LOCK, PS2_KEY_KP6, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP7, BT_NUM_LOCK, PS2_KEY_KP7, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP8, BT_NUM_LOCK, PS2_KEY_KP8, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP9, BT_NUM_LOCK, PS2_KEY_KP9, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP0, BT_NUM_LOCK, PS2_KEY_KP0, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KPDOT, BT_NUM_LOCK, PS2_KEY_KP_DOT, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP1, BT_NONE, PS2_KEY_END, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP2, BT_NONE, PS2_KEY_DN_ARROW, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP3, BT_NONE, PS2_KEY_PGDN, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP4, BT_NONE, PS2_KEY_L_ARROW, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP5, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP6, BT_NONE, PS2_KEY_R_ARROW, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP7, BT_NONE, PS2_KEY_HOME, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP8, BT_NONE, PS2_KEY_UP_ARROW, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP9, BT_NONE, PS2_KEY_PGUP, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KP0, BT_NONE, PS2_KEY_INSERT, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KPDOT, BT_NONE, PS2_KEY_DELETE, PS2_FLG_NONE, },
|
||||
{ BT_KEY_102ND, BT_NONE, PS2_KEY_BACK, PS2_FLG_NONE, },
|
||||
{ BT_KEY_COMPOSE, BT_NONE, PS2_KEY_MENU, PS2_FLG_NONE, },
|
||||
{ BT_KEY_POWER, BT_NONE, PS2_KEY_POWER, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KPEQUAL, BT_NONE, PS2_KEY_KP_EQUAL, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F13, BT_NONE, PS2_KEY_F13, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F14, BT_NONE, PS2_KEY_F14, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F15, BT_NONE, PS2_KEY_F15, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F16, BT_NONE, PS2_KEY_F16, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F17, BT_NONE, PS2_KEY_F17, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F18, BT_NONE, PS2_KEY_F18, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F19, BT_NONE, PS2_KEY_F19, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F20, BT_NONE, PS2_KEY_F20, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F21, BT_NONE, PS2_KEY_F21, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F22, BT_NONE, PS2_KEY_F22, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F23, BT_NONE, PS2_KEY_F23, PS2_FLG_NONE, },
|
||||
{ BT_KEY_F24, BT_NONE, PS2_KEY_F24, PS2_FLG_NONE, },
|
||||
{ BT_KEY_OPEN, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_HELP, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_PROPS, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_FRONT, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_STOP, BT_NONE, PS2_KEY_STOP, PS2_FLG_NONE, },
|
||||
{ BT_KEY_AGAIN, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_UNDO, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_CUT, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_COPY, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_PASTE, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_FIND, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MUTE, BT_NONE, PS2_KEY_MUTE, PS2_FLG_NONE, },
|
||||
{ BT_KEY_VOLUMEUP, BT_NONE, PS2_KEY_VOL_UP, PS2_FLG_NONE, },
|
||||
{ BT_KEY_VOLUMEDOWN, BT_NONE, PS2_KEY_VOL_DN, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KPCOMMA, BT_NONE, PS2_KEY_KP_COMMA, PS2_FLG_NONE, },
|
||||
{ BT_KEY_RO, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KATAKANAHIRAGANA, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_YEN, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_HENKAN, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MUHENKAN, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KPJPCOMMA, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_HANGEUL, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_HANJA, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KATAKANA, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_HIRAGANA, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_ZENKAKUHANKAKU, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KPLEFTPAREN, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_KPRIGHTPAREN, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
// Control keys.
|
||||
{ BT_KEY_LEFTCTRL, BT_NONE, PS2_KEY_L_CTRL, PS2_FLG_FUNC | PS2_FLG_CTRL, },
|
||||
{ BT_KEY_LEFTSHIFT, BT_NONE, PS2_KEY_L_SHIFT, PS2_FLG_FUNC | PS2_FLG_SHIFT, },
|
||||
{ BT_KEY_LEFTALT, BT_NONE, PS2_KEY_L_ALT, PS2_FLG_FUNC | PS2_FLG_ALT, },
|
||||
{ BT_KEY_LEFTMETA, BT_NONE, PS2_KEY_L_GUI, PS2_FLG_FUNC | PS2_FLG_GUI, },
|
||||
{ BT_KEY_RIGHTCTRL, BT_NONE, PS2_KEY_R_CTRL, PS2_FLG_FUNC | PS2_FLG_CTRL, },
|
||||
{ BT_KEY_RIGHTSHIFT, BT_NONE, PS2_KEY_R_SHIFT, PS2_FLG_FUNC | PS2_FLG_SHIFT, },
|
||||
{ BT_KEY_RIGHTALT, BT_NONE, PS2_KEY_R_ALT, PS2_FLG_FUNC | PS2_FLG_ALTGR, },
|
||||
{ BT_KEY_RIGHTMETA, BT_NONE, PS2_KEY_R_GUI, PS2_FLG_FUNC | PS2_FLG_NONE, },
|
||||
// Media keys
|
||||
{ BT_KEY_MEDIA_PLAYPAUSE, BT_NONE, PS2_KEY_PLAY, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_STOPCD, BT_NONE, PS2_KEY_STOP, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_PREVIOUSSONG, BT_NONE, PS2_KEY_PREV_TR, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_NEXTSONG, BT_NONE, PS2_KEY_NEXT_TR, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_EJECTCD, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_VOLUMEUP, BT_NONE, PS2_KEY_VOL_UP, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_VOLUMEDOWN, BT_NONE, PS2_KEY_VOL_DN, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_MUTE, BT_NONE, PS2_KEY_MUTE, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_WWW, BT_NONE, PS2_KEY_WEB_SEARCH, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_BACK, BT_NONE, PS2_KEY_WEB_BACK, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_FORWARD, BT_NONE, PS2_KEY_WEB_FORWARD, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_STOP, BT_NONE, PS2_KEY_WEB_STOP, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_FIND, BT_NONE, PS2_KEY_WEB_SEARCH, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_SCROLLUP, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_SCROLLDOWN, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_EDIT, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_SLEEP, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_COFFEE, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_REFRESH, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
{ BT_KEY_MEDIA_CALC, BT_NONE, 0x00, PS2_FLG_NONE, },
|
||||
}};
|
||||
};
|
||||
|
||||
#endif // BT_KEYBOARD_H_
|
||||
385
main/include/HID.h
Normal file
385
main/include/HID.h
Normal file
@@ -0,0 +1,385 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: HID.h
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: A HID Class definition, used to instantiate differing input device classes and
|
||||
// present a standard API.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// v1.01 May 2022 - Initial release version.
|
||||
// v1.02 Jun 2022 - Updates to support Bluetooth keyboard and mouse. The mouse can be
|
||||
// a primary device or a secondary device for hosts which support
|
||||
// keyboard and mouse over one physical port.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef HID_H
|
||||
#define HID_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "nvs.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "driver/timer.h"
|
||||
#include "PS2KeyAdvanced.h"
|
||||
#include "PS2Mouse.h"
|
||||
#include "BTHID.h"
|
||||
#include "LED.h"
|
||||
#include "SWITCH.h"
|
||||
|
||||
// NB: Macros definitions put inside class for clarity, they are still global scope.
|
||||
|
||||
// Define a class which acts as the encapsulation object of many base classes which provide input device functionality.
|
||||
class HID {
|
||||
|
||||
// Macros.
|
||||
//
|
||||
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
// Constants.
|
||||
#define HID_VERSION 1.02
|
||||
#define HID_MOUSE_DATA_POLL_DELAY 10
|
||||
#define MAX_MOUSE_INACTIVITY_TIME 500 * HID_MOUSE_DATA_POLL_DELAY
|
||||
|
||||
// Categories of configuration possible with the mouse. These are used primarily with the web based UI for rendering selection choices.
|
||||
#define HID_MOUSE_HOST_SCALING_TYPE "host_scaling"
|
||||
#define HID_MOUSE_SCALING_TYPE "mouse_scaling"
|
||||
#define HID_MOUSE_RESOLUTION_TYPE "mouse_resolution"
|
||||
#define HID_MOUSE_SAMPLING_TYPE "mouse_sampling"
|
||||
|
||||
#define HID_MOUSE_HOST_SCALING_1_1_NAME "1:1"
|
||||
#define HID_MOUSE_HOST_SCALING_1_2_NAME "1:2"
|
||||
#define HID_MOUSE_HOST_SCALING_1_3_NAME "1:3"
|
||||
#define HID_MOUSE_HOST_SCALING_1_4_NAME "1:4"
|
||||
#define HID_MOUSE_HOST_SCALING_1_5_NAME "1:5"
|
||||
|
||||
// Names for the configuration value settings.
|
||||
#define HID_MOUSE_RESOLUTION_1_1_NAME "1 c/mm"
|
||||
#define HID_MOUSE_RESOLUTION_1_2_NAME "2 c/mm"
|
||||
#define HID_MOUSE_RESOLUTION_1_4_NAME "4 c/mm"
|
||||
#define HID_MOUSE_RESOLUTION_1_8_NAME "8 c/mm"
|
||||
#define HID_MOUSE_SCALING_1_1_NAME "1:1"
|
||||
#define HID_MOUSE_SCALING_2_1_NAME "2:1"
|
||||
#define HID_MOUSE_SAMPLE_RATE_10_NAME "10 S/s"
|
||||
#define HID_MOUSE_SAMPLE_RATE_20_NAME "20 S/s"
|
||||
#define HID_MOUSE_SAMPLE_RATE_40_NAME "40 S/s"
|
||||
#define HID_MOUSE_SAMPLE_RATE_60_NAME "60 S/s"
|
||||
#define HID_MOUSE_SAMPLE_RATE_80_NAME "80 S/s"
|
||||
#define HID_MOUSE_SAMPLE_RATE_100_NAME "100 S/s"
|
||||
#define HID_MOUSE_SAMPLE_RATE_200_NAME "200 S/s"
|
||||
|
||||
public:
|
||||
// Types of devices the HID class can support.
|
||||
enum HID_DEVICE_TYPES {
|
||||
HID_DEVICE_TYPE_KEYBOARD = 0x00,
|
||||
HID_DEVICE_TYPE_MOUSE = 0x01,
|
||||
HID_DEVICE_TYPE_BLUETOOTH = 0x02,
|
||||
};
|
||||
|
||||
// HID class can encapsulate many input device objects, only one at a time though. On startup the device is enumerated and then all
|
||||
// functionality serves the device object.
|
||||
enum HID_INPUT_DEVICE {
|
||||
HID_DEVICE_PS2_KEYBOARD = 0x00,
|
||||
HID_DEVICE_PS2_MOUSE = 0x01,
|
||||
HID_DEVICE_BLUETOOTH = 0x02,
|
||||
HID_DEVICE_BT_KEYBOARD = 0x03,
|
||||
HID_DEVICE_BT_MOUSE = 0x04
|
||||
};
|
||||
|
||||
// Scaling - The host receiving mouse data may have a different resolution to that of the mouse, so we use configurable host side scaling to compensate. The mouse data received
|
||||
// is scaled according to the enum setting.
|
||||
enum HID_MOUSE_HOST_SCALING {
|
||||
HID_MOUSE_HOST_SCALING_1_1 = 0x00,
|
||||
HID_MOUSE_HOST_SCALING_1_2 = 0x01,
|
||||
HID_MOUSE_HOST_SCALING_1_3 = 0x02,
|
||||
HID_MOUSE_HOST_SCALING_1_4 = 0x03,
|
||||
HID_MOUSE_HOST_SCALING_1_5 = 0x04,
|
||||
};
|
||||
|
||||
// Resolution - the mouse can digitize movement from 1mm to 1/8mm, the default being 1/4 (ie. 1mm = 4 counts). This allows configuration for a finer or rougher
|
||||
// tracking digitisation.
|
||||
enum HID_MOUSE_RESOLUTION {
|
||||
HID_MOUSE_RESOLUTION_1_1 = PS2Mouse::PS2_MOUSE_RESOLUTION_1_1,
|
||||
HID_MOUSE_RESOLUTION_1_2 = PS2Mouse::PS2_MOUSE_RESOLUTION_1_2,
|
||||
HID_MOUSE_RESOLUTION_1_4 = PS2Mouse::PS2_MOUSE_RESOLUTION_1_4,
|
||||
HID_MOUSE_RESOLUTION_1_8 = PS2Mouse::PS2_MOUSE_RESOLUTION_1_8,
|
||||
};
|
||||
|
||||
// Scaling - the mouse can provide linear (1:1 no scaling) or non liner (2:1 scaling) adaptation of the digitised data. This allows configuration for amplification of movements.
|
||||
enum HID_MOUSE_SCALING {
|
||||
HID_MOUSE_SCALING_1_1 = PS2Mouse::PS2_MOUSE_SCALING_1_1,
|
||||
HID_MOUSE_SCALING_2_1 = PS2Mouse::PS2_MOUSE_SCALING_2_1,
|
||||
};
|
||||
|
||||
// Sampling rate - the mouse, in streaming mode, the mouse sends with movement updates. This allows for finer or rougher digitisation of movements. The default is 100 samples per
|
||||
// second and the X68000 is fixed at 100 samples per second.
|
||||
enum HID_MOUSE_SAMPLING {
|
||||
HID_MOUSE_SAMPLE_RATE_10 = PS2Mouse::PS2_MOUSE_SAMPLE_RATE_10,
|
||||
HID_MOUSE_SAMPLE_RATE_20 = PS2Mouse::PS2_MOUSE_SAMPLE_RATE_20,
|
||||
HID_MOUSE_SAMPLE_RATE_40 = PS2Mouse::PS2_MOUSE_SAMPLE_RATE_40,
|
||||
HID_MOUSE_SAMPLE_RATE_60 = PS2Mouse::PS2_MOUSE_SAMPLE_RATE_60,
|
||||
HID_MOUSE_SAMPLE_RATE_80 = PS2Mouse::PS2_MOUSE_SAMPLE_RATE_80,
|
||||
HID_MOUSE_SAMPLE_RATE_100 = PS2Mouse::PS2_MOUSE_SAMPLE_RATE_100,
|
||||
HID_MOUSE_SAMPLE_RATE_200 = PS2Mouse::PS2_MOUSE_SAMPLE_RATE_200,
|
||||
};
|
||||
|
||||
// Suspend flag. When active, the interface components enter an idle state after completing there latest cycle.
|
||||
bool suspend = false;
|
||||
bool suspended = true;
|
||||
|
||||
// Element to store mouse data in a queue. The data is actual mouse movements, any control data and private data for the actual mouse is stripped.
|
||||
typedef struct {
|
||||
int16_t xPos;
|
||||
int16_t yPos;
|
||||
uint8_t status;
|
||||
uint8_t wheel;
|
||||
} t_mouseMessageElement;
|
||||
|
||||
// Prototypes.
|
||||
HID(enum HID_DEVICE_TYPES, NVS *hdlNVS, LED *hdlLED, SWITCH *hdlSWITCH);
|
||||
HID(NVS *hdlNVS);
|
||||
HID(void);
|
||||
virtual ~HID(void);
|
||||
bool isBluetooth(void);
|
||||
void enableBluetooth(void);
|
||||
void disableBluetooth(void);
|
||||
bool isSuspended(bool waitForSuspend);
|
||||
void suspendInterface(bool suspendIf);
|
||||
bool persistConfig(void);
|
||||
uint16_t read(void);
|
||||
void setMouseResolution(enum HID_MOUSE_RESOLUTION resolution);
|
||||
void setMouseHostScaling(enum HID_MOUSE_HOST_SCALING scaling);
|
||||
void setMouseScaling(enum HID_MOUSE_SCALING scaling);
|
||||
void setMouseSampleRate(enum HID_MOUSE_SAMPLING sampleRate);
|
||||
void btStartPairing(void);
|
||||
void btCancelPairing(void);
|
||||
|
||||
|
||||
// Method to register an object method for callback with context.
|
||||
template<typename A, typename B>
|
||||
void setDataCallback(A func_ptr, B obj_ptr)
|
||||
{
|
||||
hidCtrl.dataCallback = bind(func_ptr, obj_ptr, std::placeholders::_1);
|
||||
}
|
||||
|
||||
// Method to suspend input device activity, yielding to the OS until suspend is cleared.
|
||||
inline virtual void yield(uint32_t delay)
|
||||
{
|
||||
// If suspended, go into a permanent loop until the suspend flag is reset.
|
||||
if(this->suspend)
|
||||
{
|
||||
// Suspend the keyboard interface.
|
||||
if(hidCtrl.deviceType == HID_DEVICE_TYPE_KEYBOARD) { printf("SUSPEND\n"); ps2Keyboard->suspend(true); }
|
||||
this->suspended = true;
|
||||
|
||||
// Sleep while suspended.
|
||||
while(this->suspend)
|
||||
{
|
||||
vTaskDelay(100);
|
||||
}
|
||||
|
||||
// Release the keyboard interface.
|
||||
if(hidCtrl.deviceType == HID_DEVICE_TYPE_KEYBOARD) ps2Keyboard->suspend(false);
|
||||
this->suspended = false;
|
||||
} else
|
||||
// Otherwise just delay by the required amount for timing and to give other threads a time slice.
|
||||
{
|
||||
vTaskDelay(delay);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Method to see if the interface must enter suspend mode.
|
||||
//
|
||||
inline virtual bool suspendRequested(void)
|
||||
{
|
||||
return(this->suspend);
|
||||
}
|
||||
|
||||
// Helper method to identify the sub class, this is used in non volatile key management.
|
||||
// Warning: This method wont work if optimisation for size is enabled on the compiler.
|
||||
const char *getClassName(const std::string& prettyFunction)
|
||||
{
|
||||
// First find the CLASS :: METHOD seperation.
|
||||
size_t colons = prettyFunction.find("::");
|
||||
|
||||
// None, then this is not a class.
|
||||
if (colons == std::string::npos)
|
||||
return "::";
|
||||
|
||||
// Split out the class name.
|
||||
size_t begin = prettyFunction.substr(0,colons).rfind(" ") + 1;
|
||||
size_t end = colons - begin;
|
||||
|
||||
// Return the name.
|
||||
return(prettyFunction.substr(begin,end).c_str());
|
||||
}
|
||||
|
||||
// Template to aid in conversion of an enum to integer.
|
||||
template <typename E> constexpr typename std::underlying_type<E>::type to_underlying(E e) noexcept
|
||||
{
|
||||
return static_cast<typename std::underlying_type<E>::type>(e);
|
||||
}
|
||||
|
||||
// Method to return the class version number.
|
||||
virtual float version(void)
|
||||
{
|
||||
return(HID_VERSION);
|
||||
}
|
||||
|
||||
// Method to return the name of this class.
|
||||
virtual std::string ifName(void)
|
||||
{
|
||||
return(className);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
// Prototypes.
|
||||
void init(const char *className, enum HID_DEVICE_TYPES deviceTypes);
|
||||
bool nvsPersistData(const char *key, void *pData, uint32_t size);
|
||||
bool nvsRetrieveData(const char *key, void *pData, uint32_t size);
|
||||
bool nvsCommitData(void);
|
||||
void checkKeyboard( void );
|
||||
bool checkPS2Keyboard( void );
|
||||
bool checkPS2Mouse( void );
|
||||
void checkMouse( void );
|
||||
void processPS2Mouse( void );
|
||||
void checkBTMouse( void );
|
||||
void mouseReceiveData(uint8_t src, PS2Mouse::MouseData mouseData);
|
||||
IRAM_ATTR static void hidControl( void * pvParameters );
|
||||
static void btPairingHandler(uint32_t pid, uint8_t trigger);
|
||||
inline uint32_t milliSeconds(void)
|
||||
{
|
||||
return( (uint32_t) (clock() ) );
|
||||
}
|
||||
|
||||
|
||||
enum HOST_CONFIG_MODES {
|
||||
HOST_CONFIG_OFF = 0x00,
|
||||
HOST_CONFIG_SCALING = 0x01,
|
||||
HOST_CONFIG_RESOLUTION = 0x02,
|
||||
};
|
||||
|
||||
// Structure to maintain configuration for the HID.
|
||||
//
|
||||
typedef struct {
|
||||
|
||||
struct {
|
||||
// Mouse data Adjustment and filtering options.
|
||||
//
|
||||
enum HID_MOUSE_RESOLUTION resolution;
|
||||
enum HID_MOUSE_SCALING scaling;
|
||||
enum HID_MOUSE_SAMPLING sampleRate;
|
||||
} mouse;
|
||||
|
||||
struct {
|
||||
// Host data for adjustment and configuration.
|
||||
enum HID_MOUSE_HOST_SCALING scaling;
|
||||
} host;
|
||||
|
||||
struct {
|
||||
// Configuration mode time period used to select configuration option. Once the middle key is held, the configuration option starts at 1, after this number of seconds
|
||||
// the configuration option advances to the next configuration item, and so on...
|
||||
uint16_t optionAdvanceDelay;
|
||||
} params;
|
||||
|
||||
} t_hidConfig;
|
||||
|
||||
// Structure to maintain an active settings for HID devices.
|
||||
typedef struct {
|
||||
enum HID_INPUT_DEVICE hidDevice; // Active HID device, only one can be active.
|
||||
enum HID_DEVICE_TYPES deviceType; // Type of device which is active.
|
||||
bool ps2Active; // Flag to indicate PS/2 device is online and active.
|
||||
uint32_t noEchoCount = 0L; // Echo back counter, used for testing if a keyboard is online.
|
||||
TickType_t ps2CheckTimer = 0; // Check timer, used for timing periodic keyboard checks.
|
||||
|
||||
// Mouse control variables.
|
||||
uint32_t noValidMouseMessage = 0;
|
||||
int wheelCnt = 0;
|
||||
uint32_t loopTimer = 0;
|
||||
bool middleKeyPressed = false;
|
||||
PS2Mouse::MouseData mouseData;
|
||||
|
||||
// Flag to indicate the mouse is active and online.
|
||||
bool active;
|
||||
|
||||
// Flag to indicate the configuration data has been updated.
|
||||
bool updated;
|
||||
|
||||
// Configuration mode selected when middle button pressed.
|
||||
enum HOST_CONFIG_MODES configMode;
|
||||
|
||||
// Mutex to block access during maintenance tasks.
|
||||
SemaphoreHandle_t mutexInternal;
|
||||
|
||||
// Callback for streaming input devices with data to be processed.
|
||||
std::function<void(t_mouseMessageElement)> dataCallback;
|
||||
} t_hidControl;
|
||||
|
||||
// Current configuration of the HID.
|
||||
t_hidConfig hidConfig;
|
||||
|
||||
// Variables to control the HID.
|
||||
t_hidControl hidCtrl;
|
||||
|
||||
// Handle to the persistent storage api.
|
||||
nvs_handle_t nvsHandle;
|
||||
|
||||
// Name of this class, used for NVS access.
|
||||
std::string className;
|
||||
|
||||
// NVS persistence object.
|
||||
NVS *nvs;
|
||||
|
||||
// LED activity object handle.
|
||||
LED *led;
|
||||
|
||||
// SWITCH object handle.
|
||||
SWITCH *sw;
|
||||
|
||||
// Keyboard object for PS/2 data retrieval and management.
|
||||
PS2KeyAdvanced *ps2Keyboard;
|
||||
|
||||
// Keyboard object for Bluetooth data retrieval and management.
|
||||
BTHID *btHID;
|
||||
|
||||
// Mouse object for PS/2 data retrieval and management.
|
||||
PS2Mouse *ps2Mouse;
|
||||
|
||||
// Thread handle for the HID control thread.
|
||||
TaskHandle_t TaskHID = NULL;
|
||||
};
|
||||
#endif // HID_H
|
||||
203
main/include/KeyInterface.h
Normal file
203
main/include/KeyInterface.h
Normal file
@@ -0,0 +1,203 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: KeyInterface.h
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Virtual class definition on which all host interfaces, instantiated as a singleton,
|
||||
// are based.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// v1.01 May 2022 - Initial release version.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef KEYINTERFACE_H
|
||||
#define KEYINTERFACE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "driver/timer.h"
|
||||
#include "PS2KeyAdvanced.h"
|
||||
#include "PS2Mouse.h"
|
||||
#include "NVS.h"
|
||||
#include "LED.h"
|
||||
#include "HID.h"
|
||||
|
||||
|
||||
// NB: Macros definitions put inside class for clarity, they are still global scope.
|
||||
|
||||
// Define a virtual class which acts as the base and specification of all super classes forming host
|
||||
// interface objects.
|
||||
class KeyInterface {
|
||||
|
||||
// Macros.
|
||||
//
|
||||
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
// Constants.
|
||||
#define KEYIF_VERSION 1.01
|
||||
|
||||
public:
|
||||
// Suspend flag. When active, the interface components enter an idle state after completing there latest cycle.
|
||||
bool suspend = false;
|
||||
bool suspended = true;
|
||||
|
||||
// NVS object.
|
||||
NVS *nvs;
|
||||
|
||||
// LED object.
|
||||
LED *led;
|
||||
|
||||
// HID object, used for keyboard input.
|
||||
HID *hid;
|
||||
|
||||
// Prototypes.
|
||||
KeyInterface(void) {};
|
||||
virtual ~KeyInterface(void) {};
|
||||
KeyInterface(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID) { init(getClassName(__PRETTY_FUNCTION__), hdlNVS, hdlLED, hdlHID, ifMode); };
|
||||
KeyInterface(NVS *hdlNVS, HID *hdlHID) { init(getClassName(__PRETTY_FUNCTION__), hdlNVS, hdlHID); };
|
||||
void reconfigADC2Ports(bool setAsOutput);
|
||||
void suspendInterface(bool suspendIf);
|
||||
virtual bool isSuspended(bool waitForSuspend);
|
||||
virtual bool isRunning(bool waitForRelease);
|
||||
virtual void identify(void) { };
|
||||
virtual void init(const char * subClassName, NVS *hdlNVS, LED *hdlLED, HID *hdlHID, uint32_t ifMode);
|
||||
virtual void init(const char * subClassName, NVS *hdlNVS, HID *hdlHID);
|
||||
// Persistence.
|
||||
virtual bool persistConfig(void) { return(true); }
|
||||
|
||||
// Key mapping.
|
||||
virtual IRAM_ATTR uint32_t mapKey(uint16_t scanCode) { return(0); };
|
||||
virtual bool createKeyMapFile(std::fstream &outFile) { return(false); };
|
||||
virtual bool storeDataToKeyMapFile(std::fstream &outFile, char *data, int size) { return(false); };
|
||||
virtual bool storeDataToKeyMapFile(std::fstream & outFile, std::vector<uint32_t>& dataArray) { return(false); }
|
||||
virtual bool closeAndCommitKeyMapFile(std::fstream &outFile, bool cleanupOnly) { return(false); };
|
||||
virtual std::string getKeyMapFileName(void) { return("nokeymap.bin"); };
|
||||
virtual void getKeyMapHeaders(std::vector<std::string>& headerList) { };
|
||||
virtual void getKeyMapTypes(std::vector<std::string>& typeList) { };
|
||||
virtual bool getKeyMapSelectList(std::vector<std::pair<std::string, int>>& selectList, std::string option) { return(true); }
|
||||
virtual bool getKeyMapData(std::vector<uint32_t>& dataArray, int *row, bool start) { return(true); };
|
||||
// Mouse config.
|
||||
virtual void getMouseConfigTypes(std::vector<std::string>& typeList) { };
|
||||
virtual bool getMouseSelectList(std::vector<std::pair<std::string, int>>& selectList, std::string option) { return(true); }
|
||||
virtual bool setMouseConfigValue(std::string paramName, std::string paramValue) { return(true); }
|
||||
|
||||
// Method to suspend an active interface thread by holding in a tight loop, yielding to the OS. This method was chosen rather than the more conventional
|
||||
// vTaskSuspend as it allows multiple threads, without giving a handle, to yield if required for a fixed period or indefinitely until the suspend mode is de-activated.
|
||||
// The method is inline to avoid a call overhead as it is generally used in time sensitive interface timing.
|
||||
inline virtual void yield(uint32_t delay)
|
||||
{
|
||||
// If suspended, go into a permanent loop until the suspend flag is reset.
|
||||
if(this->suspend)
|
||||
{
|
||||
this->suspended = true;
|
||||
while(this->suspend)
|
||||
{
|
||||
vTaskDelay(100);
|
||||
}
|
||||
this->suspended = false;
|
||||
} else
|
||||
// Otherwise just delay by the required amount for timing and to give other threads a time slice.
|
||||
{
|
||||
vTaskDelay(delay);
|
||||
}
|
||||
}
|
||||
|
||||
// Method to see if the interface must enter suspend mode.
|
||||
//
|
||||
inline virtual bool suspendRequested(void)
|
||||
{
|
||||
return(this->suspend);
|
||||
}
|
||||
|
||||
// Helper method to identify the sub class, this is used in non volatile key management.
|
||||
// Warning: This method wont work if optimisation for size is enabled on the compiler.
|
||||
const char *getClassName(const std::string& prettyFunction)
|
||||
{
|
||||
// First find the CLASS :: METHOD seperation.
|
||||
size_t colons = prettyFunction.find("::");
|
||||
|
||||
// None, then this is not a class.
|
||||
if (colons == std::string::npos)
|
||||
return "::";
|
||||
|
||||
// Split out the class name.
|
||||
size_t begin = prettyFunction.substr(0,colons).rfind(" ") + 1;
|
||||
size_t end = colons - begin;
|
||||
|
||||
// Return the name.
|
||||
return(prettyFunction.substr(begin,end).c_str());
|
||||
}
|
||||
|
||||
// Helper method to change a file extension.
|
||||
void replaceExt(std::string& fileName, const std::string& newExt)
|
||||
{
|
||||
// Locals.
|
||||
std::string::size_type extPos = fileName.rfind('.', fileName.length());
|
||||
|
||||
if(extPos != std::string::npos)
|
||||
{
|
||||
fileName.replace(extPos+1, newExt.length(), newExt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Template to aid in conversion of an enum to integer.
|
||||
template <typename E> constexpr typename std::underlying_type<E>::type to_underlying(E e) noexcept
|
||||
{
|
||||
return static_cast<typename std::underlying_type<E>::type>(e);
|
||||
}
|
||||
|
||||
// Method to return the class version number.
|
||||
virtual float version(void)
|
||||
{
|
||||
return(KEYIF_VERSION);
|
||||
}
|
||||
|
||||
// Method to return the name of the inferface class.
|
||||
virtual std::string ifName(void)
|
||||
{
|
||||
return(subClassName);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
// Prototypes.
|
||||
virtual IRAM_ATTR void selectOption(uint8_t optionCode) {};
|
||||
|
||||
// Name of the sub-class for this instantiation.
|
||||
std::string subClassName;
|
||||
|
||||
// Thread handle for the LED control thread.
|
||||
TaskHandle_t TaskLEDIF = NULL;
|
||||
};
|
||||
#endif // KEYINTERFACE_H
|
||||
181
main/include/LED.h
Normal file
181
main/include/LED.h
Normal file
@@ -0,0 +1,181 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: LED.h
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Class definition for the control of a single LED. The LED is used to indicate to a
|
||||
// user a desired status. This class is normally instantiated as a singleton and
|
||||
// manipulated by public methods.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// v1.01 May 2022 - Initial release version.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LED_H
|
||||
#define LED_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "driver/timer.h"
|
||||
#include "PS2KeyAdvanced.h"
|
||||
#include "PS2Mouse.h"
|
||||
#include "NVS.h"
|
||||
|
||||
// NB: Macros definitions put inside class for clarity, they are still global scope.
|
||||
|
||||
// Define a class to encapsulate a LED and required control mechanisms,
|
||||
class LED {
|
||||
|
||||
// Macros.
|
||||
//
|
||||
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
// Constants.
|
||||
#define LED_VERSION 1.01
|
||||
|
||||
public:
|
||||
// Interface LED activity modes.
|
||||
enum LED_MODE {
|
||||
LED_MODE_OFF = 0x00,
|
||||
LED_MODE_ON = 0x01,
|
||||
LED_MODE_BLINK_ONESHOT = 0x02,
|
||||
LED_MODE_BLINK = 0x03,
|
||||
};
|
||||
|
||||
// Interface LED duty cycle.
|
||||
enum LED_DUTY_CYCLE {
|
||||
LED_DUTY_CYCLE_OFF = 0x00,
|
||||
LED_DUTY_CYCLE_10 = 0x01,
|
||||
LED_DUTY_CYCLE_20 = 0x02,
|
||||
LED_DUTY_CYCLE_30 = 0x03,
|
||||
LED_DUTY_CYCLE_40 = 0x04,
|
||||
LED_DUTY_CYCLE_50 = 0x05,
|
||||
LED_DUTY_CYCLE_60 = 0x06,
|
||||
LED_DUTY_CYCLE_70 = 0x07,
|
||||
LED_DUTY_CYCLE_80 = 0x08,
|
||||
LED_DUTY_CYCLE_90 = 0x09,
|
||||
};
|
||||
|
||||
// Prototypes.
|
||||
LED(uint32_t hwPin);
|
||||
LED(void);
|
||||
virtual ~LED(void) {};
|
||||
void identify(void) { };
|
||||
|
||||
// LED Control.
|
||||
bool setLEDMode(enum LED_MODE mode, enum LED_DUTY_CYCLE dutyCycle, uint32_t maxBlinks, uint64_t usDutyPeriod, uint64_t msInterPeriod);
|
||||
IRAM_ATTR static void ledInterface(void *pvParameters);
|
||||
void ledInit(uint8_t ledPin);
|
||||
|
||||
// Helper method to identify the sub class, this is used in non volatile key management.
|
||||
// Warning: This method wont work if optimisation for size is enabled on the compiler.
|
||||
const char *getClassName(const std::string& prettyFunction)
|
||||
{
|
||||
// First find the CLASS :: METHOD seperation.
|
||||
size_t colons = prettyFunction.find("::");
|
||||
|
||||
// None, then this is not a class.
|
||||
if (colons == std::string::npos)
|
||||
return "::";
|
||||
|
||||
// Split out the class name.
|
||||
size_t begin = prettyFunction.substr(0,colons).rfind(" ") + 1;
|
||||
size_t end = colons - begin;
|
||||
|
||||
// Return the name.
|
||||
return(prettyFunction.substr(begin,end).c_str());
|
||||
}
|
||||
|
||||
// Template to aid in conversion of an enum to integer.
|
||||
template <typename E> constexpr typename std::underlying_type<E>::type to_underlying(E e) noexcept
|
||||
{
|
||||
return static_cast<typename std::underlying_type<E>::type>(e);
|
||||
}
|
||||
|
||||
// Method to return the class version number.
|
||||
virtual float version(void)
|
||||
{
|
||||
return(LED_VERSION);
|
||||
}
|
||||
|
||||
// Method to return the name of the inferface class.
|
||||
virtual std::string ifName(void)
|
||||
{
|
||||
return(className);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
// Prototypes.
|
||||
|
||||
// Structure to maintain configuration for the LED.
|
||||
//
|
||||
typedef struct {
|
||||
bool valid; // The configuration is valid and should be processed.
|
||||
bool updated; // This configuration is an update to override current configuration.
|
||||
|
||||
enum LED_MODE mode; // Mode of LED activity.
|
||||
enum LED_DUTY_CYCLE dutyCycle; // Duty cycle of the BLINK LED period.
|
||||
uint32_t maxBlinks; // Maximum number of blinks before switching to LED off mode.
|
||||
uint64_t dutyPeriod; // Period, is micro-seconds of the full duty cycle.
|
||||
uint64_t interPeriod; // Period, is milli-seconds between LED activity.
|
||||
} t_ledConfig;
|
||||
|
||||
// Structure to maintain an active setting for the LED. The LED control thread uses these values to effect the required lighting of the LED.
|
||||
typedef struct {
|
||||
// Current, ie. working LED config acted upon by the LED thread.
|
||||
t_ledConfig currentConfig;
|
||||
// New config to replace current on next state.
|
||||
t_ledConfig newConfig;
|
||||
|
||||
// Led GPIO pin.
|
||||
uint8_t ledPin;
|
||||
|
||||
// Runtime parameters for state machine and control.
|
||||
uint32_t blinkCnt; // count of blink on periods.
|
||||
|
||||
// Mutex to block access to limit one thread at a time.
|
||||
SemaphoreHandle_t mutexInternal;
|
||||
} t_ledControl;
|
||||
|
||||
// Variables to control the LED.
|
||||
t_ledControl ledCtrl;
|
||||
|
||||
// Name of the class for this instantiation.
|
||||
std::string className;
|
||||
|
||||
// Thread handle for the LED control thread.
|
||||
TaskHandle_t TaskLEDIF = NULL;
|
||||
};
|
||||
#endif // LED_H
|
||||
534
main/include/MZ2528.h
Normal file
534
main/include/MZ2528.h
Normal file
@@ -0,0 +1,534 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: MZ2528.h
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Header for the MZ-2500/MZ-2800 PS/2 logic.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// v1.01 May 2022 - Initial release version.
|
||||
// v1.02 Jun 2022 - Updates to reflect bluetooth.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef MZ2528_H
|
||||
#define MZ2528_H
|
||||
|
||||
// Include the specification class.
|
||||
#include "KeyInterface.h"
|
||||
#include "NVS.h"
|
||||
#include "LED.h"
|
||||
#include "HID.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
// NB: Macros definitions put inside class for clarity, they are still global scope.
|
||||
|
||||
// Encapsulate the MZ-2500/MZ-2800 interface.
|
||||
class MZ2528 : public KeyInterface {
|
||||
// Macros.
|
||||
//
|
||||
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
// Constants.
|
||||
#define MZ2528IF_VERSION 1.02
|
||||
#define MZ2528IF_KEYMAP_FILE "MZ2528_KeyMap.BIN"
|
||||
#define PS2TBL_MZ_MAXROWS 165
|
||||
#define PS2TBL_MZ_MAX_MKROW 3
|
||||
#define PS2TBL_MZ_MAX_BRKROW 2
|
||||
|
||||
// PS2 Flag definitions.
|
||||
#define PS2CTRL_NONE 0x00 // No keys active = 0
|
||||
#define PS2CTRL_SHIFT 0x01 // Shfit Key active = 1
|
||||
#define PS2CTRL_CTRL 0x02 // Ctrl Key active = 1
|
||||
#define PS2CTRL_CAPS 0x04 // CAPS active = 1
|
||||
#define PS2CTRL_ALT 0x08 // ALT active = 1
|
||||
#define PS2CTRL_ALTGR 0x10 // ALTGR active = 1
|
||||
#define PS2CTRL_GUI 0x20 // GUI Key active = 1
|
||||
#define PS2CTRL_FUNC 0x40 // Special Function Keys active = 1
|
||||
#define PS2CTRL_BREAK 0x80 // BREAK Key active = 1
|
||||
#define PS2CTRL_EXACT 0x80 // EXACT Match active = 1
|
||||
|
||||
// The MZ-2500 machine can emulate 3 models, the MZ-80B, MZ-2000 and the MZ-2500. The MZ-2800 provides a new mode as well as the MZ-2500 mode and each has slight
|
||||
// keyboard differences. This requires tagging of machine specific mappings. Normally a mapping would be MZ_ALL, ie. applied to all models, but if a machine specific
|
||||
// mapping appears and it matches the current machine mode, this mapping is chosen.
|
||||
#define MZ_ALL 0xFF
|
||||
#define MZ_80B 0x01
|
||||
#define MZ_2000 0x02
|
||||
#define MZ_2500 0x04
|
||||
#define MZ_2800 0x08
|
||||
|
||||
// Keyboard mapping table select list for target machine.
|
||||
#define MZ2528_SEL_ALL "ALL"
|
||||
#define MZ2528_SEL_MZ_80B "MZ80B"
|
||||
#define MZ2528_SEL_MZ_2000 "MZ2000"
|
||||
#define MZ2528_SEL_MZ_2500 "MZ2500"
|
||||
#define MZ2528_SEL_MZ_2800 "MZ2800"
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
// Keyboard mapping table column names.
|
||||
#define PS2TBL_PS2KEYCODE_NAME "PS/2 KeyCode"
|
||||
#define PS2TBL_PS2CTRL_NAME "PS/2 Control Key"
|
||||
#define PS2TBL_KEYBOARDMODEL_NAME "For Keyboard"
|
||||
#define PS2TBL_MACHINE_NAME "For Host Model"
|
||||
#define PS2TBL_MZ_MK_ROW1_NAME "Make Row 1"
|
||||
#define PS2TBL_MZ_MK_KEY1_NAME "Key 1"
|
||||
#define PS2TBL_MZ_MK_ROW2_NAME "Row 2"
|
||||
#define PS2TBL_MZ_MK_KEY2_NAME "Key 2"
|
||||
#define PS2TBL_MZ_MK_ROW3_NAME "Row 3"
|
||||
#define PS2TBL_MZ_MK_KEY3_NAME "Key 3"
|
||||
#define PS2TBL_MZ_BRK_ROW1_NAME "Break Row 1"
|
||||
#define PS2TBL_MZ_BRK_KEY1_NAME "Key 1"
|
||||
#define PS2TBL_MZ_BRK_ROW2_NAME "Row 2"
|
||||
#define PS2TBL_MZ_BRK_KEY2_NAME "Key 2"
|
||||
|
||||
// Keyboard mapping table column types.
|
||||
#define PS2TBL_PS2KEYCODE_TYPE "hex"
|
||||
#define PS2TBL_PS2CTRL_TYPE "custom_cbp_ps2ctrl"
|
||||
#define PS2TBL_KEYBOARDMODEL_TYPE "custom_cbp_keybmodel"
|
||||
#define PS2TBL_MACHINE_TYPE "custom_cbp_machine"
|
||||
#define PS2TBL_MZ_MK_ROW1_TYPE "custom_rdp_mzrow"
|
||||
#define PS2TBL_MZ_MK_KEY1_TYPE "hex"
|
||||
#define PS2TBL_MZ_MK_ROW2_TYPE "custom_rdp_mzrow"
|
||||
#define PS2TBL_MZ_MK_KEY2_TYPE "hex"
|
||||
#define PS2TBL_MZ_MK_ROW3_TYPE "custom_rdp_mzrow"
|
||||
#define PS2TBL_MZ_MK_KEY3_TYPE "hex"
|
||||
#define PS2TBL_MZ_BRK_ROW1_TYPE "custom_rdp_mzrow"
|
||||
#define PS2TBL_MZ_BRK_KEY1_TYPE "hex"
|
||||
#define PS2TBL_MZ_BRK_ROW2_TYPE "custom_rdp_mzrow"
|
||||
#define PS2TBL_MZ_BRK_KEY2_TYPE "hex"
|
||||
|
||||
// Keyboard mapping table select list for PS2CTRL.
|
||||
#define PS2TBL_PS2CTRL_SEL_NONE "NONE"
|
||||
#define PS2TBL_PS2CTRL_SEL_SHIFT "SHIFT"
|
||||
#define PS2TBL_PS2CTRL_SEL_CTRL "CTRL"
|
||||
#define PS2TBL_PS2CTRL_SEL_CAPS "CAPS"
|
||||
#define PS2TBL_PS2CTRL_SEL_ALT "ALT"
|
||||
#define PS2TBL_PS2CTRL_SEL_ALTGR "ALTGR"
|
||||
#define PS2TBL_PS2CTRL_SEL_GUI "GUI"
|
||||
#define PS2TBL_PS2CTRL_SEL_FUNC "FUNC"
|
||||
#define PS2TBL_PS2CTRL_SEL_EXACT "EXACT"
|
||||
|
||||
// Keyboard mapping table select list for Model of keyboard.
|
||||
#define KEYMAP_SEL_STANDARD "ALL"
|
||||
#define KEYMAP_SEL_UK_WYSE_KB3926 "UK_WYSE_KB3926"
|
||||
#define KEYMAP_SEL_JAPAN_OADG109 "JAPAN_OADG109"
|
||||
#define KEYMAP_SEL_JAPAN_SANWA_SKBL1 "JAPAN_SANWA_SKBL1"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_4 "KEYBOARD_4"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_5 "KEYBOARD_5"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_6 "KEYBOARD_6"
|
||||
#define KEYMAP_SEL_UK_PERIBOARD_810 "UK_PERIBOARD_810"
|
||||
#define KEYMAP_SEL_UK_OMOTON_K8508 "UK_OMOTON_K8508"
|
||||
|
||||
// Keyboard models. The base on which this interface was created was a Wyse KB3926 PS/2 Keyboard and this is deemed STANDARD. Other models need to insert difference maps
|
||||
// prior to the STANDARD entry along with the keyboard model so that it is processed first thus allowing differing keyboards with different maps.
|
||||
#define KEYMAP_STANDARD 0xFF
|
||||
#define KEYMAP_UK_WYSE_KB3926 0x01
|
||||
#define KEYMAP_JAPAN_OADG109 0x02
|
||||
#define KEYMAP_JAPAN_SANWA_SKBL1 0x04
|
||||
#define KEYMAP_NOT_ASSIGNED_4 0x08
|
||||
#define KEYMAP_NOT_ASSIGNED_5 0x10
|
||||
#define KEYMAP_NOT_ASSIGNED_6 0x20
|
||||
#define KEYMAP_UK_PERIBOARD_810 0x40
|
||||
#define KEYMAP_UK_OMOTON_K8508 0x80
|
||||
|
||||
public:
|
||||
// Prototypes.
|
||||
MZ2528(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID, const char *fsPath);
|
||||
MZ2528(NVS *hdlNVS, HID *hdlHID, const char *fsPath);
|
||||
MZ2528(void);
|
||||
~MZ2528(void);
|
||||
bool createKeyMapFile(std::fstream &outFile);
|
||||
bool storeDataToKeyMapFile(std::fstream &outFile, char *data, int size);
|
||||
bool storeDataToKeyMapFile(std::fstream & outFile, std::vector<uint32_t>& dataArray);
|
||||
bool closeAndCommitKeyMapFile(std::fstream &outFile, bool cleanupOnly);
|
||||
std::string getKeyMapFileName(void) { return(MZ2528IF_KEYMAP_FILE); };
|
||||
void getKeyMapHeaders(std::vector<std::string>& headerList);
|
||||
void getKeyMapTypes(std::vector<std::string>& typeList);
|
||||
bool getKeyMapSelectList(std::vector<std::pair<std::string, int>>& selectList, std::string option);
|
||||
bool getKeyMapData(std::vector<uint32_t>& dataArray, int *row, bool start);
|
||||
|
||||
// Overloaded method to see if the interface must enter suspend mode, either triggered by an external event or internal.
|
||||
//
|
||||
inline bool suspendRequested(void)
|
||||
{
|
||||
return(this->suspend);
|
||||
}
|
||||
|
||||
// // Method to overload the suspend mechanism and include the core release mechanism. Core release is needed in order to use ESP32 API's such as NVS.
|
||||
// // The method is inline to avoid a call overhead as it is generally used in time sensitive interface timing.
|
||||
// inline void yield(uint32_t delay)
|
||||
// {
|
||||
// // If suspended, go into a permanent loop until the suspend flag is reset.
|
||||
// if(this->suspend)
|
||||
// {
|
||||
// this->suspended = true;
|
||||
// while(this->suspend)
|
||||
// {
|
||||
// vTaskDelay(100);
|
||||
// }
|
||||
// this->suspended = false;
|
||||
// } else
|
||||
// // Otherwise just delay by the required amount for timing and to give other threads a time slice.
|
||||
// {
|
||||
// vTaskDelay(delay);
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Method to return the class version number.
|
||||
float version(void)
|
||||
{
|
||||
return(MZ2528IF_VERSION);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
// Prototypes.
|
||||
void updateMirrorMatrix(void);
|
||||
uint32_t mapKey(uint16_t scanCode);
|
||||
IRAM_ATTR static void mz25Interface(void *pvParameters );
|
||||
IRAM_ATTR static void mz28Interface(void *pvParameters );
|
||||
IRAM_ATTR static void hidInterface(void *pvParameters );
|
||||
void selectOption(uint8_t optionCode);
|
||||
bool loadKeyMap();
|
||||
bool saveKeyMap(void);
|
||||
void init(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID);
|
||||
void init(NVS *hdlNVS, HID *hdlHID);
|
||||
|
||||
// Overload the base yield method to include suspension of the PS/2 Keyboard interface. This interface uses interrupts which are not mutex protected and clash with the
|
||||
// WiFi API methods.
|
||||
// inline void yield(uint32_t delay)
|
||||
// {
|
||||
// // If suspended, go into a permanent loop until the suspend flag is reset.
|
||||
// if(this->suspend)
|
||||
// {
|
||||
// // Suspend the keyboard interface.
|
||||
// Keyboard->suspend(true);
|
||||
//
|
||||
// // Use the base method logic.
|
||||
// KeyInterface::yield(delay);
|
||||
//
|
||||
// // Release the keyboard interface.
|
||||
// Keyboard->suspend(false);
|
||||
// } else
|
||||
// // Otherwise just delay by the required amount for timing and to give other threads a time slice.
|
||||
// {
|
||||
// KeyInterface::yield(delay);
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Structure to encapsulate a single key map from PS/2 to MZ-2500/MZ-2800.
|
||||
typedef struct {
|
||||
uint8_t ps2KeyCode;
|
||||
uint8_t ps2Ctrl;
|
||||
uint8_t keyboardModel;
|
||||
uint8_t machine;
|
||||
uint8_t mkRow[PS2TBL_MZ_MAX_MKROW];
|
||||
uint8_t mkKey[PS2TBL_MZ_MAX_MKROW];
|
||||
uint8_t brkRow[PS2TBL_MZ_MAX_BRKROW];
|
||||
uint8_t brkKey[PS2TBL_MZ_MAX_BRKROW];
|
||||
} t_keyMapEntry;
|
||||
|
||||
// Structure to encapsulate the entire static keyboard mapping table.
|
||||
typedef struct {
|
||||
t_keyMapEntry kme[PS2TBL_MZ_MAXROWS];
|
||||
} t_keyMap;
|
||||
|
||||
// Structure to maintain the MZ2528 interface configuration data. This data is persisted through powercycles as needed.
|
||||
typedef struct {
|
||||
struct {
|
||||
uint8_t activeKeyboardMap; // Model of keyboard a keymap entry is applicable to.
|
||||
uint8_t activeMachineModel; // Machine model a keymap entry is applicable to.
|
||||
} params;
|
||||
} t_mzConfig;
|
||||
|
||||
// Configuration data.
|
||||
t_mzConfig mzConfig;
|
||||
|
||||
// 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; // Strobe All flag, 16 possible rows have the same column AND'd together to create this 8bit map. It is used to see if any key has been pressed.
|
||||
uint32_t strobeAllAsGPIO; // Strobe All signal but as a GPIO bit map to save time in the interface thread.
|
||||
uint8_t keyMatrix[16]; // Key matrix as a 16x8 matrix.
|
||||
uint32_t keyMatrixAsGPIO[16]; // Key matrix mapped as GPIO bits to save time in the interface thread.
|
||||
bool mode2500;
|
||||
bool optionSelect; // Flag to indicate a user requested keyboard configuration option is being selected.
|
||||
std::string fsPath; // Path on the underlying filesystem where storage is mounted and accessible.
|
||||
t_keyMapEntry *kme; // Pointer to an array in memory to contain PS2 to MZ-2500/MZ-2800 mapping values.
|
||||
int kmeRows; // Number of rows in the kme table.
|
||||
std::string keyMapFileName; // Name of file where extension or replacement key map entries are stored.
|
||||
bool noKeyPressed; // Flag to indicate no key has been pressed.
|
||||
bool persistConfig; // Flag to request saving of the config into NVS storage.
|
||||
} t_mzControl;
|
||||
|
||||
// Thread handles - one per function, ie. HID interface and host target interface.
|
||||
TaskHandle_t TaskHostIF = NULL;
|
||||
TaskHandle_t TaskHIDIF = NULL;
|
||||
|
||||
// Control structure to control interaction and mapping of keys for the host.
|
||||
t_mzControl mzControl;
|
||||
|
||||
// Spin lock mutex to hold a coresied to an uninterruptable method. This only works on dual core ESP32's.
|
||||
portMUX_TYPE mzMutex;
|
||||
|
||||
// Flag to indicate host interface should yield the CPU.
|
||||
volatile bool yieldHostInterface;
|
||||
|
||||
// // Keyboard object for PS/2 data retrieval and management.
|
||||
// PS2KeyAdvanced *Keyboard;
|
||||
|
||||
// HID object, used for keyboard input.
|
||||
// HID *hid;
|
||||
|
||||
// Lookup table to matrix row/column co-ordinates.
|
||||
//
|
||||
// Given that the MZ-2500 can emulate 3 machines and each machine has it's own mapping, differences are tagged by machine name, ie. ALL, MZ80B, MZ2000, MZ2500
|
||||
//
|
||||
// If a PS2 key is matched, then the Matrix is updated using MK_ROW to point into the array with MK_KEY being the column value, equivalent of strobe line and
|
||||
// the required KEY bits to be set. Upto 3 matrix bits can be set (3 key presses on the MZ-2500 keyboard) per PS/2 key. Upto 2 matrix releases can be set per
|
||||
// PS/2 key. A key release is used when a modifier may already have been pressed, ie. SHIFT and it needs to be released to set the required key into the matrix.
|
||||
// A set bit = 1, reset bits = 0 but is inverted in the actual matrix (1 = inactive, 0 = active), this applies for releases two, if bit = 1 then that key will be released.
|
||||
// The table is scanned for a match from top to bottom. The first match is used so order is important. Japanese characters are being added as I gleam more information.
|
||||
|
||||
///////////////////////////
|
||||
// MZ-2500 Keyboard Map. //
|
||||
///////////////////////////
|
||||
//
|
||||
// Row D7 D6 D5 D4 D3 D2 D1 D0
|
||||
//----------------------------------------------------------------------------------
|
||||
// 0 F8 F7 F6 F5 F4 F3 F2 F1
|
||||
// 1 KP - KP + KP . KP , KP 9 KP 8 F1O F9
|
||||
// 2 KP 7 KP 6 KP 5 KP 4 KP 3 KP 2 KP 1 KP 0
|
||||
// 3 BREAK RIGHT LEFT DOWN UP RETURN SPACE TAB
|
||||
// 4 G F E D C B A / ?
|
||||
// 5 O N M L K J I H
|
||||
// 6 W V U T S R Q P
|
||||
// 7 , < . > _ YEN | ^ '¿ Z ¿ Y X ¿
|
||||
// 8 7 ' 6 & 5 % 4 $ 3 # 2 " 1 ! 0
|
||||
// 9 [ { @ ` - = ; + : * 9 ) 8 (
|
||||
// 10 KP / KP * ESC BACKSPACE INST/DEL CLR/HOME COPY ] }
|
||||
// 11 CTRL KANA SHIFT LOCK GRAPH
|
||||
// 12 KJ2 KJ1
|
||||
// 13 HELP ARGO
|
||||
//
|
||||
// Col 0 1 2 3 4 5 6 7 8 9 10 11 12 13
|
||||
// --------------------------------------------------------------------------------------------------------------------------------------
|
||||
// D0 F1 F9 KP 0 TAB / ? H P X 0 8 ( ] } GRAPH KJ1 ARGO
|
||||
// D1 F2 F10 KP 1 SPACE A I Q Y 1 ! 9 ) COPY LOCK KJ2 HELP
|
||||
// D2 F3 KP 8 KP 2 RETURN B J R Z 2 " : * CLR/HOME SHIFT
|
||||
// D3 F4 KP 9 KP 3 UP C K S ^ '¿ 3 # ; + INST/DEL KANA
|
||||
// D4 F5 KP , KP 4 DOWN D L T YEN | 4 $ - = BACKSPACE CTRL
|
||||
// D5 F6 KP . KP 5 LEFT E M U _ 5 % @ ` ESC
|
||||
// D6 F7 KP + KP 6 RIGHT F N V . > 6 & [ { KP *
|
||||
// D7 F8 KP - KP 7 BREAK G O W , < 7 ' KP /
|
||||
//
|
||||
// This initial mapping is for the UK Wyse KB-3926 PS/2 keyboard and his equates to KEYMAP_STANDARD.
|
||||
//
|
||||
t_keyMap PS2toMZ = {
|
||||
{
|
||||
// < Keys to be applied on match > < Keys to be reset on match >
|
||||
// PS2 Code PS2 Ctrl (Flags to Match) Keyboard Model Machine MK_ROW1 MK_ROW2 MK_ROW3 MK_KEY1 MK_KEY2 MK_KEY3 BRK_ROW1 BRK_ROW2 BRK_KEY1 BRK_KEY2
|
||||
{ PS2_KEY_F1, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x00, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // F1
|
||||
{ PS2_KEY_F2, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x00, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // F2
|
||||
{ PS2_KEY_F3, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x00, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // F3
|
||||
{ PS2_KEY_F4, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x00, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // F4
|
||||
{ PS2_KEY_F5, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x00, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // F5
|
||||
{ PS2_KEY_F6, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x00, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // F6
|
||||
{ PS2_KEY_F7, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x00, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // F7
|
||||
{ PS2_KEY_F8, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x00, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // F8
|
||||
{ PS2_KEY_F9, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // F9
|
||||
{ PS2_KEY_F10, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x01, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // F10
|
||||
{ PS2_KEY_F11, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x0D, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // HELP
|
||||
{ PS2_KEY_F12, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x0A, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // COPY
|
||||
{ PS2_KEY_TAB, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x03, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // TAB
|
||||
{ PS2_KEY_0, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x09, 0x0B, 0xFF, 0x02, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Close Right Bracket )
|
||||
{ PS2_KEY_0, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x08, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // 0
|
||||
{ PS2_KEY_1, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x08, 0x0B, 0xFF, 0x02, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Exclamation
|
||||
{ PS2_KEY_1, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x08, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // 1
|
||||
{ PS2_KEY_2, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x08, 0x0B, 0xFF, 0x04, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Double quote.
|
||||
{ PS2_KEY_2, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x08, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // 2
|
||||
{ PS2_KEY_3, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x08, 0x0B, 0xFF, 0x08, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Pound Sign -> Hash
|
||||
{ PS2_KEY_3, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x08, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // 3
|
||||
{ PS2_KEY_4, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x08, 0x0B, 0xFF, 0x10, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Dollar
|
||||
{ PS2_KEY_4, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x08, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // 4
|
||||
{ PS2_KEY_5, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x08, 0x0B, 0xFF, 0x20, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Percent
|
||||
{ PS2_KEY_5, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x08, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // 5
|
||||
{ PS2_KEY_6, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x07, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0x0B, 0xFF, 0x04, 0xFF, }, // Kappa
|
||||
{ PS2_KEY_6, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x08, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // 6
|
||||
{ PS2_KEY_7, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x08, 0x0B, 0xFF, 0x40, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Ampersand
|
||||
{ PS2_KEY_7, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x08, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // 7
|
||||
{ PS2_KEY_8, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x09, 0x0B, 0xFF, 0x04, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Star
|
||||
{ PS2_KEY_8, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x09, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // 8
|
||||
{ PS2_KEY_9, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x09, 0x0B, 0xFF, 0x01, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Open Left Bracket (
|
||||
{ PS2_KEY_9, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x09, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // 9
|
||||
{ PS2_KEY_A, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // a
|
||||
{ PS2_KEY_A, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // A
|
||||
{ PS2_KEY_B, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // b
|
||||
{ PS2_KEY_B, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // B
|
||||
{ PS2_KEY_C, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // c
|
||||
{ PS2_KEY_C, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // C
|
||||
{ PS2_KEY_D, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // d
|
||||
{ PS2_KEY_D, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // D
|
||||
{ PS2_KEY_E, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // e
|
||||
{ PS2_KEY_E, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // E
|
||||
{ PS2_KEY_F, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // f
|
||||
{ PS2_KEY_F, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // F
|
||||
{ PS2_KEY_G, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // g
|
||||
{ PS2_KEY_G, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // G
|
||||
{ PS2_KEY_H, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // h
|
||||
{ PS2_KEY_H, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // H
|
||||
{ PS2_KEY_I, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // i
|
||||
{ PS2_KEY_I, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // I
|
||||
{ PS2_KEY_J, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // j
|
||||
{ PS2_KEY_J, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // J
|
||||
{ PS2_KEY_K, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // k
|
||||
{ PS2_KEY_K, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // K
|
||||
{ PS2_KEY_L, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // l
|
||||
{ PS2_KEY_L, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // L
|
||||
{ PS2_KEY_M, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // m
|
||||
{ PS2_KEY_M, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // M
|
||||
{ PS2_KEY_N, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // n
|
||||
{ PS2_KEY_N, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // N
|
||||
{ PS2_KEY_O, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // o
|
||||
{ PS2_KEY_O, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x05, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // O
|
||||
{ PS2_KEY_P, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // p
|
||||
{ PS2_KEY_P, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // P
|
||||
{ PS2_KEY_Q, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // q
|
||||
{ PS2_KEY_Q, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Q
|
||||
{ PS2_KEY_R, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // r
|
||||
{ PS2_KEY_R, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // R
|
||||
{ PS2_KEY_S, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // s
|
||||
{ PS2_KEY_S, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // S
|
||||
{ PS2_KEY_T, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // t
|
||||
{ PS2_KEY_T, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // T
|
||||
{ PS2_KEY_U, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // u
|
||||
{ PS2_KEY_U, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // U
|
||||
{ PS2_KEY_V, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // v
|
||||
{ PS2_KEY_V, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // V
|
||||
{ PS2_KEY_W, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // w
|
||||
{ PS2_KEY_W, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x06, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // W
|
||||
{ PS2_KEY_X, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x07, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // x
|
||||
{ PS2_KEY_X, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x07, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // X
|
||||
{ PS2_KEY_Y, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x07, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // y
|
||||
{ PS2_KEY_Y, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x07, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Y
|
||||
{ PS2_KEY_Z, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x07, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // z
|
||||
{ PS2_KEY_Z, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x07, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Z
|
||||
// PS2 Code PS2 Ctrl (Flags to Match) Keyboard Model Machine MK_ROW1 MK_ROW2 MK_ROW3 MK_KEY1 MK_KEY2 MK_KEY3 BRK_ROW1 BRK_ROW2 BRK_KEY1 BRK_KEY2
|
||||
{ PS2_KEY_SPACE, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x03, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Space
|
||||
{ PS2_KEY_COMMA, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x07, 0x0B, 0xFF, 0x80, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Less Than <
|
||||
{ PS2_KEY_COMMA, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x07, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Comma ,
|
||||
{ PS2_KEY_SEMI, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x09, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0x0B, 0xFF, 0x04, 0xFF, }, // Colon :
|
||||
{ PS2_KEY_SEMI, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x09, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Semi-Colon ;
|
||||
{ PS2_KEY_DOT, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x07, 0x0B, 0xFF, 0x40, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Greater Than >
|
||||
{ PS2_KEY_DOT, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x07, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Full stop .
|
||||
{ PS2_KEY_DIV, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_2000, 0x07, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0x0B, 0xFF, 0x04, 0xFF, }, // Question ?
|
||||
{ PS2_KEY_DIV, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_80B, 0x07, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0x0B, 0xFF, 0x04, 0xFF, }, // Question ?
|
||||
{ PS2_KEY_DIV, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x04, 0x0B, 0xFF, 0x01, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Question ?
|
||||
{ PS2_KEY_DIV, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x04, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Divide /
|
||||
{ PS2_KEY_MINUS, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_2000, 0x08, 0x0B, 0xFF, 0x01, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Upper bar
|
||||
{ PS2_KEY_MINUS, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_80B, 0x08, 0x0B, 0xFF, 0x01, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Upper bar
|
||||
{ PS2_KEY_MINUS, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x07, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0x0B, 0xFF, 0x04, 0xFF, }, // Underscore
|
||||
{ PS2_KEY_MINUS, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x09, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, //
|
||||
|
||||
{ PS2_KEY_APOS, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_80B, 0x09, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0x0B, 0xFF, 0x04, 0xFF, }, // At @
|
||||
{ PS2_KEY_APOS, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x09, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0x0B, 0xFF, 0x04, 0xFF, }, // At @
|
||||
{ PS2_KEY_APOS, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x08, 0x0B, 0xFF, 0x80, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Single quote '
|
||||
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x09, 0x0B, 0xFF, 0x40, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Open Left Brace {
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x09, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Open Left Square Bracket [
|
||||
{ PS2_KEY_EQUAL, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x09, 0x0B, 0xFF, 0x08, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Plus +
|
||||
{ PS2_KEY_EQUAL, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x09, 0x0B, 0xFF, 0x10, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Equal =
|
||||
{ PS2_KEY_CAPS, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x0B, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // LOCK
|
||||
{ PS2_KEY_ENTER, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x03, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // ENTER/RETURN
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x0A, 0x0B, 0xFF, 0x01, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Close Right Brace }
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x0A, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Close Right Square Bracket ]
|
||||
{ PS2_KEY_BACK, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x07, 0x0B, 0xFF, 0x10, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, //
|
||||
{ PS2_KEY_BACK, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x07, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Back slash maps to Yen
|
||||
{ PS2_KEY_BTICK, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0x07, 0x0B, 0xFF, 0x10, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Pipe
|
||||
{ PS2_KEY_BTICK, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x09, 0x0B, 0xFF, 0x20, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Back tick `
|
||||
{ PS2_KEY_HASH, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_2000, 0x07, 0x0B, 0xFF, 0x08, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Tilde
|
||||
{ PS2_KEY_HASH, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_80B, 0x07, 0x0B, 0xFF, 0x08, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Tilde
|
||||
{ PS2_KEY_HASH, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ_ALL, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Tilde has no mapping.
|
||||
{ PS2_KEY_HASH, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x08, 0x0B, 0xFF, 0x08, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Hash
|
||||
{ PS2_KEY_BS, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x0A, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Backspace
|
||||
{ PS2_KEY_ESC, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x0A, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // ESCape
|
||||
{ PS2_KEY_SCROLL, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Not assigned.
|
||||
{ PS2_KEY_INSERT, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x0A, 0x0B, 0xFF, 0x08, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // INSERT
|
||||
{ PS2_KEY_HOME, PS2CTRL_FUNC | PS2CTRL_SHIFT | PS2CTRL_EXACT, KEYMAP_STANDARD, MZ_ALL, 0x0A, 0x0B, 0xFF, 0x04, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // CLR
|
||||
{ PS2_KEY_HOME, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x0A, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // HOME
|
||||
{ PS2_KEY_PGUP, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Not assigned.
|
||||
{ PS2_KEY_DELETE, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x0A, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // DELETE
|
||||
{ PS2_KEY_END, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Not assigned.
|
||||
{ PS2_KEY_PGDN, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_80B|MZ_2000|MZ_2500, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Not mapped
|
||||
{ PS2_KEY_PGDN, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_2800, 0x0C, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Japanese Key - Previous
|
||||
{ PS2_KEY_UP_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x03, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Up Arrow
|
||||
{ PS2_KEY_L_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x03, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Left Arrow
|
||||
{ PS2_KEY_DN_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x03, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Down Arrow
|
||||
{ PS2_KEY_R_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x03, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Right Arrow
|
||||
{ PS2_KEY_NUM, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Not assigned.
|
||||
|
||||
// Keypad.
|
||||
{ PS2_KEY_KP0, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x02, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad 0
|
||||
{ PS2_KEY_KP1, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x02, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad 1
|
||||
{ PS2_KEY_KP2, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x02, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad 2
|
||||
{ PS2_KEY_KP3, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x02, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad 3
|
||||
{ PS2_KEY_KP4, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x02, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad 4
|
||||
{ PS2_KEY_KP5, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x02, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad 5
|
||||
{ PS2_KEY_KP6, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x02, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad 6
|
||||
{ PS2_KEY_KP7, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x02, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad 7
|
||||
{ PS2_KEY_KP8, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x01, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad 8
|
||||
{ PS2_KEY_KP9, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x01, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad 9
|
||||
{ PS2_KEY_KP_COMMA, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x01, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad Comma ,
|
||||
{ PS2_KEY_KP_DOT, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x01, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad Full stop .
|
||||
{ PS2_KEY_KP_PLUS, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x01, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad Plus +
|
||||
{ PS2_KEY_KP_MINUS, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x01, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad Minus -
|
||||
{ PS2_KEY_KP_TIMES, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x0A, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad Times *
|
||||
{ PS2_KEY_KP_DIV, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x0A, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad Divide /
|
||||
{ PS2_KEY_KP_ENTER, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0x03, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Keypad Ebter /
|
||||
|
||||
// PS2 Code PS2 Ctrl (Flags to Match) Keyboard Model Machine MK_ROW1 MK_ROW2 MK_ROW3 MK_KEY1 MK_KEY2 MK_KEY3 BRK_ROW1 BRK_ROW2 BRK_KEY1 BRK_KEY2
|
||||
// Special keys.
|
||||
{ PS2_KEY_PRTSCR, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x0D, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // ARGO KEY
|
||||
{ PS2_KEY_PAUSE, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x03, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // BREAK KEY
|
||||
{ PS2_KEY_L_GUI, PS2CTRL_FUNC | PS2CTRL_GUI, KEYMAP_STANDARD, MZ_ALL, 0x0B, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // GRAPH KEY
|
||||
{ PS2_KEY_L_ALT, PS2CTRL_FUNC | PS2CTRL_ALT, KEYMAP_STANDARD, MZ_ALL, 0x0C, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // KJ1 Sentence
|
||||
{ PS2_KEY_R_ALT, PS2CTRL_FUNC | PS2CTRL_ALTGR, KEYMAP_STANDARD, MZ_ALL, 0x0C, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // KJ2 Transform
|
||||
{ PS2_KEY_R_GUI, PS2CTRL_FUNC | PS2CTRL_GUI, KEYMAP_STANDARD, MZ_ALL, 0x0B, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // KANA KEY
|
||||
{ PS2_KEY_MENU, PS2CTRL_FUNC | PS2CTRL_GUI, KEYMAP_STANDARD, MZ_ALL, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Not assigned.
|
||||
// Modifiers are last, only being selected if an earlier match isnt made.
|
||||
{ PS2_KEY_L_SHIFT, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x0B, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },
|
||||
{ PS2_KEY_R_SHIFT, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x0B, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },
|
||||
{ PS2_KEY_L_CTRL, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_ALL, 0x0B, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },
|
||||
{ PS2_KEY_R_CTRL, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_80B|MZ_2000|MZ_2500, 0x0B, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Map to Control
|
||||
{ PS2_KEY_R_CTRL, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ_2800, 0x0C, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, // Japanese Key - Cancel
|
||||
{ 0, PS2CTRL_NONE, KEYMAP_STANDARD, MZ_ALL, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },
|
||||
}};
|
||||
};
|
||||
|
||||
#endif // MZ2528_H
|
||||
574
main/include/MZ5665.h
Normal file
574
main/include/MZ5665.h
Normal file
@@ -0,0 +1,574 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: MZ5665.h
|
||||
// Created: Apr 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Header for the Sharp MZ-6500 to HID (PS/2, Bluetooth) interface logic.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Apr 2022 - Initial write.
|
||||
// v1.01 Jun 2022 - Updates to reflect changes realised in other modules due to addition of
|
||||
// bluetooth and suspend logic due to NVS issues using both cores.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef MZ5665_H
|
||||
#define MZ5665_H
|
||||
|
||||
// Include the specification class.
|
||||
#include "KeyInterface.h"
|
||||
#include "NVS.h"
|
||||
#include "LED.h"
|
||||
#include "HID.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
// NB: Macros definitions put inside class for clarity, they are still global scope.
|
||||
|
||||
// Encapsulate the Sharp MZ-6500 interface.
|
||||
class MZ5665 : public KeyInterface {
|
||||
// Macros.
|
||||
//
|
||||
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
// Constants.
|
||||
#define MZ5665IF_VERSION 1.01
|
||||
#define MZ5665IF_KEYMAP_FILE "MZ5665_KeyMap.BIN"
|
||||
#define MAX_MZ5665_XMIT_KEY_BUF 16
|
||||
#define PS2TBL_MZ5665_MAXROWS 349
|
||||
|
||||
// MZ-6500 Key control bit mask.
|
||||
#define MZ5665_CTRL_GRAPH ((unsigned char) (1 << 4))
|
||||
#define MZ5665_CTRL_CAPS ((unsigned char) (1 << 3))
|
||||
#define MZ5665_CTRL_KANA ((unsigned char) (1 << 2))
|
||||
#define MZ5665_CTRL_SHIFT ((unsigned char) (1 << 1))
|
||||
#define MZ5665_CTRL_CTRL ((unsigned char) (1 << 0))
|
||||
|
||||
// Special key definition.
|
||||
#define MZ5665_KEY_UP 0x1E // ↑
|
||||
#define MZ5665_KEY_DOWN 0x1F // ↓
|
||||
#define MZ5665_KEY_LEFT 0x1D // ←
|
||||
#define MZ5665_KEY_RIGHT 0x1C // → →
|
||||
#define MZ5665_KEY_INS 0x12 // INS
|
||||
#define MZ5665_KEY_DEL 0x08 // DEL
|
||||
#define MZ5665_KEY_CLR 0x0C // CLR
|
||||
#define MZ5665_KEY_HOME 0x0B // HOME
|
||||
|
||||
// PS2 Flag definitions.
|
||||
#define PS2CTRL_NONE 0x00 // No keys active = 0
|
||||
#define PS2CTRL_SHIFT 0x01 // Shfit Key active = 1
|
||||
#define PS2CTRL_CTRL 0x02 // Ctrl Key active = 1
|
||||
#define PS2CTRL_CAPS 0x04 // CAPS active = 1
|
||||
#define PS2CTRL_KANA 0x08 // KANA active = 1
|
||||
#define PS2CTRL_GRAPH 0x10 // GRAPH active = 1
|
||||
#define PS2CTRL_GUI 0x20 // GUI Key active = 1
|
||||
#define PS2CTRL_FUNC 0x40 // Special Function Keys active = 1
|
||||
#define PS2CTRL_BREAK 0x80 // BREAK Key active = 1
|
||||
#define PS2CTRL_EXACT 0x80 // EXACT Match active = 1
|
||||
|
||||
// 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 extract the MZ-6500 key code and control data.
|
||||
// ie. PS/2 Scan Code -> ASCII + Flags -> MZ-6500 Key Code + Ctrl Data
|
||||
|
||||
// Keyboard mapping table column names.
|
||||
#define PS2TBL_PS2KEYCODE_NAME "PS/2 KeyCode"
|
||||
#define PS2TBL_PS2CTRL_NAME "PS/2 Control Key"
|
||||
#define PS2TBL_KEYBOARDMODEL_NAME "For Keyboard"
|
||||
#define PS2TBL_MACHINE_NAME "For Host Model"
|
||||
#define PS2TBL_MZ5665_KEYCODE_NAME "MZ5665 KeyCode"
|
||||
#define PS2TBL_MZ5665__CTRL_NAME "MZ5665 Control Key"
|
||||
|
||||
// Keyboard mapping table column types.
|
||||
#define PS2TBL_PS2KEYCODE_TYPE "hex"
|
||||
#define PS2TBL_PS2CTRL_TYPE "custom_cbp_ps2ctrl"
|
||||
#define PS2TBL_KEYBOARDMODEL_TYPE "custom_cbp_keybmodel"
|
||||
#define PS2TBL_MACHINE_TYPE "custom_cbp_machine"
|
||||
#define PS2TBL_MZ5665_KEYCODE_TYPE "hex"
|
||||
#define PS2TBL_MZ5665_CTRL_TYPE "custom_cbn_x1ctrl"
|
||||
|
||||
// Keyboard mapping table select list for PS2CTRL.
|
||||
#define PS2TBL_PS2CTRL_SEL_NONE "NONE"
|
||||
#define PS2TBL_PS2CTRL_SEL_SHIFT "SHIFT"
|
||||
#define PS2TBL_PS2CTRL_SEL_CTRL "CTRL"
|
||||
#define PS2TBL_PS2CTRL_SEL_CAPS "CAPS"
|
||||
#define PS2TBL_PS2CTRL_SEL_KANA "KANA"
|
||||
#define PS2TBL_PS2CTRL_SEL_GRAPH "GRAPH"
|
||||
#define PS2TBL_PS2CTRL_SEL_GUI "GUI"
|
||||
#define PS2TBL_PS2CTRL_SEL_FUNC "FUNC"
|
||||
#define PS2TBL_PS2CTRL_SEL_EXACT "EXACT"
|
||||
|
||||
// Keyboard mapping table select list for Model of keyboard.
|
||||
#define KEYMAP_SEL_STANDARD "ALL"
|
||||
#define KEYMAP_SEL_UK_WYSE_KB3926 "UK_WYSE_KB3926"
|
||||
#define KEYMAP_SEL_JAPAN_OADG109 "JAPAN_OADG109"
|
||||
#define KEYMAP_SEL_JAPAN_SANWA_SKBL1 "JAPAN_SANWA_SKBL1"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_4 "KEYBOARD_4"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_5 "KEYBOARD_5"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_6 "KEYBOARD_6"
|
||||
#define KEYMAP_SEL_UK_PERIBOARD_810 "UK_PERIBOARD_810"
|
||||
#define KEYMAP_SEL_UK_OMOTON_K8508 "UK_OMOTON_K8508"
|
||||
|
||||
// Keyboard mapping table select list for target machine.
|
||||
#define MZ5665_SEL_ALL "ALL"
|
||||
|
||||
// Keyboard mapping table select list for MZ5665 Control codes.
|
||||
#define MZ5665_CTRL_SEL_GRAPH "GRAPH"
|
||||
#define MZ5665_CTRL_SEL_CAPS "CAPS"
|
||||
#define MZ5665_CTRL_SEL_KANA "KANA"
|
||||
#define MZ5665_CTRL_SEL_SHIFT "SHIFT"
|
||||
#define MZ5665_CTRL_SEL_CTRL "CTRL"
|
||||
|
||||
// The Sharp MZ-6500 Series was released over a number of years and each iteration added changes/updates. In order to cater for differences, it is possible to assign a key mapping
|
||||
// to a specific machine type(s) or all of the series by adding the flags below into the mapping table.
|
||||
#define MZ5665_ALL 0xFF
|
||||
|
||||
// Keyboard models. The base on which this interface was created was a Wyse KB3926 PS/2 Keyboard and this is deemed STANDARD. Other models need to insert difference maps
|
||||
// prior to the STANDARD entry along with the keyboard model so that it is processed first thus allowing differing keyboards with different maps.
|
||||
#define KEYMAP_STANDARD 0xFF
|
||||
#define KEYMAP_UK_WYSE_KB3926 0x01
|
||||
#define KEYMAP_JAPAN_OADG109 0x02
|
||||
#define KEYMAP_JAPAN_SANWA_SKBL1 0x04
|
||||
#define KEYMAP_NOT_ASSIGNED_4 0x08
|
||||
#define KEYMAP_NOT_ASSIGNED_5 0x10
|
||||
#define KEYMAP_NOT_ASSIGNED_6 0x20
|
||||
#define KEYMAP_UK_PERIBOARD_810 0x40
|
||||
#define KEYMAP_UK_OMOTON_K8508 0x80
|
||||
|
||||
public:
|
||||
// Prototypes.
|
||||
MZ5665(void);
|
||||
MZ5665(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID, const char *fsPath);
|
||||
MZ5665(NVS *hdlNVS, HID *hdlHID, const char *fsPath);
|
||||
~MZ5665(void);
|
||||
bool createKeyMapFile(std::fstream &outFile);
|
||||
bool storeDataToKeyMapFile(std::fstream &outFile, char *data, int size);
|
||||
bool storeDataToKeyMapFile(std::fstream & outFile, std::vector<uint32_t>& dataArray);
|
||||
bool closeAndCommitKeyMapFile(std::fstream &outFile, bool cleanupOnly);
|
||||
std::string getKeyMapFileName(void) { return(MZ5665IF_KEYMAP_FILE); };
|
||||
void getKeyMapHeaders(std::vector<std::string>& headerList);
|
||||
void getKeyMapTypes(std::vector<std::string>& typeList);
|
||||
bool getKeyMapSelectList(std::vector<std::pair<std::string, int>>& selectList, std::string option);
|
||||
bool getKeyMapData(std::vector<uint32_t>& dataArray, int *row, bool start);
|
||||
|
||||
// Method to return the class version number.
|
||||
float version(void)
|
||||
{
|
||||
return(MZ5665IF_VERSION);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
// Prototypes.
|
||||
void pushKeyToQueue(uint32_t key);
|
||||
IRAM_ATTR static void mzInterface( void * pvParameters );
|
||||
IRAM_ATTR static void hidInterface( void * pvParameters );
|
||||
void selectOption(uint8_t optionCode);
|
||||
uint32_t mapKey(uint16_t scanCode);
|
||||
bool loadKeyMap();
|
||||
bool saveKeyMap(void);
|
||||
void init(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID);
|
||||
void init(NVS *hdlNVS, HID *hdlHID);
|
||||
|
||||
// // Overload the base yield method to include suspension of the PS/2 Keyboard interface. This interface uses interrupts which are not mutex protected and clash with the
|
||||
// // WiFi API methods.
|
||||
// inline void yield(uint32_t delay)
|
||||
// {
|
||||
// // If suspended, go into a permanent loop until the suspend flag is reset.
|
||||
// if(this->suspend)
|
||||
// {
|
||||
// // Suspend the keyboard interface.
|
||||
// Keyboard->suspend(true);
|
||||
//
|
||||
// // Use the base method logic.
|
||||
// KeyInterface::yield(delay);
|
||||
//
|
||||
// // Release the keyboard interface.
|
||||
// Keyboard->suspend(false);
|
||||
// } else
|
||||
// // Otherwise just delay by the required amount for timing and to give other threads a time slice.
|
||||
// {
|
||||
// KeyInterface::yield(delay);
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Structure to encapsulate a single key map from PS/2 to MZ-5600/MZ-6500.
|
||||
typedef struct {
|
||||
uint8_t ps2KeyCode;
|
||||
uint8_t ps2Ctrl;
|
||||
uint8_t keyboardModel;
|
||||
uint8_t machine;
|
||||
uint8_t mzKey;
|
||||
uint8_t mzCtrl;
|
||||
} t_keyMapEntry;
|
||||
|
||||
// Structure to encapsulate the entire static keyboard mapping table.
|
||||
typedef struct {
|
||||
t_keyMapEntry kme[PS2TBL_MZ5665_MAXROWS];
|
||||
} t_keyMap;
|
||||
|
||||
// Structure to maintain the MZ-5600/MZ-6500 interface configuration data. This data is persisted through powercycles as needed.
|
||||
typedef struct {
|
||||
struct {
|
||||
uint8_t activeKeyboardMap; // Model of keyboard a keymap entry is applicable to.
|
||||
uint8_t activeMachineModel; // Machine model a keymap entry is applicable to.
|
||||
} params;
|
||||
} t_mzConfig;
|
||||
|
||||
// Configuration data.
|
||||
t_mzConfig mzConfig;
|
||||
|
||||
// Structure to manage the control signals signifying the state of the MZ-6500 keyboard.
|
||||
typedef struct {
|
||||
bool optionSelect; // Flag to indicate a user requested keyboard configuration option is being selected.
|
||||
uint8_t keyCtrl; // Keyboard state flag control.
|
||||
|
||||
std::string fsPath; // Path on the underlying filesystem where storage is mounted and accessible.
|
||||
t_keyMapEntry *kme; // Pointer to an array in memory to contain PS2 to MZ-6500 mapping values.
|
||||
int kmeRows; // Number of rows in the kme table.
|
||||
std::string keyMapFileName; // Name of file where extension or replacement key map entries are stored.
|
||||
} t_mzControl;
|
||||
|
||||
// Transmit buffer queue item.
|
||||
typedef struct {
|
||||
uint32_t keyCode; // 16bit, bits 8:0 represent the key, 9 if CTRL to be sent, 10 if ALT to be sent.
|
||||
} t_xmitQueueMessage;
|
||||
|
||||
// Thread handles - one per function, ie. HID interface and host target interface.
|
||||
TaskHandle_t TaskHostIF = NULL;
|
||||
TaskHandle_t TaskHIDIF = NULL;
|
||||
|
||||
// Control structure to control interaction and mapping of keys for the host.
|
||||
t_mzControl mzCtrl;
|
||||
|
||||
// Spin lock mutex to hold a coresied to an uninterruptable method. This only works on dual core ESP32's.
|
||||
portMUX_TYPE mzMutex;
|
||||
|
||||
//
|
||||
// This mapping is for the UK Wyse KB-3926 PS/2 keyboard
|
||||
//
|
||||
t_keyMap PS2toMZ5665 = {
|
||||
{
|
||||
// HELP
|
||||
// COPY
|
||||
////PS2 Code PS2 Ctrl (Flags to Match) Keyboard Model Machine MZ5665 Data MZ5665 Ctrl (Flags to Set).
|
||||
//{ PS2_KEY_F1, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 'v', 0x00, }, // SHIFT+F1
|
||||
//{ PS2_KEY_F2, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 'w', 0x00, }, // SHIFT+F2
|
||||
//{ PS2_KEY_F3, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 'x', 0x00, }, // SHIFT+F3
|
||||
//{ PS2_KEY_F4, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 'y', 0x00, }, // SHIFT+F4
|
||||
//{ PS2_KEY_F5, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 'z', 0x00, }, // SHIFT+F5
|
||||
//{ PS2_KEY_F1, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 'q', 0x00, }, // F1
|
||||
//{ PS2_KEY_F2, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 'r', 0x00, }, // F2
|
||||
//{ PS2_KEY_F3, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 's', 0x00, }, // F3
|
||||
//{ PS2_KEY_F4, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 't', 0x00, }, // F4
|
||||
//{ PS2_KEY_F5, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 'u', 0x00, }, // F5
|
||||
//{ PS2_KEY_F6, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0xEC, 0x00, }, // F6
|
||||
//{ PS2_KEY_F7, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0xEB, 0x00, }, // F7
|
||||
//{ PS2_KEY_F8, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0xE2, 0x00, }, // F8
|
||||
//{ PS2_KEY_F9, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0xE1, 0x00, }, // F9
|
||||
//{ PS2_KEY_F10, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, }, // XFER
|
||||
//{ PS2_KEY_F11, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0xFE, 0x00, }, // HELP
|
||||
//{ PS2_KEY_F12, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, }, // COPY
|
||||
//{ PS2_KEY_TAB, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, 0x09, 0x00, }, // TAB
|
||||
// Numeric keys.
|
||||
{ PS2_KEY_0, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '0', 0x00, }, // 0
|
||||
{ PS2_KEY_1, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '1', 0x00, }, // 1
|
||||
{ PS2_KEY_2, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '2', 0x00, }, // 2
|
||||
{ PS2_KEY_3, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '3', 0x00, }, // 3
|
||||
{ PS2_KEY_4, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '4', 0x00, }, // 4
|
||||
{ PS2_KEY_5, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '5', 0x00, }, // 5
|
||||
{ PS2_KEY_6, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '6', 0x00, }, // 6
|
||||
{ PS2_KEY_7, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '7', 0x00, }, // 7
|
||||
{ PS2_KEY_8, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '8', 0x00, }, // 8
|
||||
{ PS2_KEY_9, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '9', 0x00, }, // 9
|
||||
// Punctuation keys.
|
||||
{ PS2_KEY_0, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, ')', 0x00, }, // Close Right Bracket )
|
||||
{ PS2_KEY_1, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '!', 0x00, }, // Exclamation
|
||||
{ PS2_KEY_2, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '"', 0x00, }, // Double quote.
|
||||
{ PS2_KEY_3, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0x23, 0x00, }, // Pound Sign -> Hash
|
||||
{ PS2_KEY_4, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '$', 0x00, }, // Dollar
|
||||
{ PS2_KEY_5, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '%', 0x00, }, // Percent
|
||||
{ PS2_KEY_6, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '^', 0x00, }, // Kappa
|
||||
{ PS2_KEY_7, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '&', 0x00, }, // Ampersand
|
||||
{ PS2_KEY_8, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '*', 0x00, }, // Star
|
||||
{ PS2_KEY_9, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '(', 0x00, }, // Open Left Bracket (
|
||||
// ALPHA keys, lower and uppercase.
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Keyboard Model Machine MZ5665 Data MZ5665 Ctrl (Flags to Set).
|
||||
{ PS2_KEY_A, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'a', 0x00, }, // a
|
||||
{ PS2_KEY_A, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'A', 0x00, }, // A
|
||||
{ PS2_KEY_B, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'b', 0x00, }, // b
|
||||
{ PS2_KEY_B, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'B', 0x00, }, // B
|
||||
{ PS2_KEY_C, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'c', 0x00, }, // c
|
||||
{ PS2_KEY_C, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'C', 0x00, }, // C
|
||||
{ PS2_KEY_D, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'd', 0x00, }, // d
|
||||
{ PS2_KEY_D, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'D', 0x00, }, // D
|
||||
{ PS2_KEY_E, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'e', 0x00, }, // e
|
||||
{ PS2_KEY_E, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'E', 0x00, }, // E
|
||||
{ PS2_KEY_F, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'f', 0x00, }, // f
|
||||
{ PS2_KEY_F, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'F', 0x00, }, // F
|
||||
{ PS2_KEY_G, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'g', 0x00, }, // g
|
||||
{ PS2_KEY_G, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'G', 0x00, }, // G
|
||||
{ PS2_KEY_H, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'h', 0x00, }, // h
|
||||
{ PS2_KEY_H, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'H', 0x00, }, // H
|
||||
{ PS2_KEY_I, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'i', 0x00, }, // i
|
||||
{ PS2_KEY_I, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'I', 0x00, }, // I
|
||||
{ PS2_KEY_J, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'j', 0x00, }, // j
|
||||
{ PS2_KEY_J, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'J', 0x00, }, // J
|
||||
{ PS2_KEY_K, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'k', 0x00, }, // k
|
||||
{ PS2_KEY_K, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'K', 0x00, }, // K
|
||||
{ PS2_KEY_L, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'l', 0x00, }, // l
|
||||
{ PS2_KEY_L, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'L', 0x00, }, // L
|
||||
{ PS2_KEY_M, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'm', 0x00, }, // m
|
||||
{ PS2_KEY_M, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'M', 0x00, }, // M
|
||||
{ PS2_KEY_N, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'n', 0x00, }, // n
|
||||
{ PS2_KEY_N, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'N', 0x00, }, // N
|
||||
{ PS2_KEY_O, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'o', 0x00, }, // o
|
||||
{ PS2_KEY_O, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'O', 0x00, }, // O
|
||||
{ PS2_KEY_P, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'p', 0x00, }, // p
|
||||
{ PS2_KEY_P, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'P', 0x00, }, // P
|
||||
{ PS2_KEY_Q, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'q', 0x00, }, // q
|
||||
{ PS2_KEY_Q, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'Q', 0x00, }, // Q
|
||||
{ PS2_KEY_R, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'r', 0x00, }, // r
|
||||
{ PS2_KEY_R, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'R', 0x00, }, // R
|
||||
{ PS2_KEY_S, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 's', 0x00, }, // s
|
||||
{ PS2_KEY_S, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'S', 0x00, }, // S
|
||||
{ PS2_KEY_T, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 't', 0x00, }, // t
|
||||
{ PS2_KEY_T, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'T', 0x00, }, // T
|
||||
{ PS2_KEY_U, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'u', 0x00, }, // u
|
||||
{ PS2_KEY_U, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'U', 0x00, }, // U
|
||||
{ PS2_KEY_V, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'v', 0x00, }, // v
|
||||
{ PS2_KEY_V, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'V', 0x00, }, // V
|
||||
{ PS2_KEY_W, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'w', 0x00, }, // w
|
||||
{ PS2_KEY_W, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'W', 0x00, }, // W
|
||||
{ PS2_KEY_X, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'x', 0x00, }, // x
|
||||
{ PS2_KEY_X, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'X', 0x00, }, // X
|
||||
{ PS2_KEY_Y, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'y', 0x00, }, // y
|
||||
{ PS2_KEY_Y, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'Y', 0x00, }, // Y
|
||||
{ PS2_KEY_Z, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'z', 0x00, }, // z
|
||||
{ PS2_KEY_Z, PS2CTRL_CAPS, KEYMAP_STANDARD, MZ5665_ALL, 'Z', 0x00, }, // Z
|
||||
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Keyboard Model Machine MZ5665 Data MZ5665 Ctrl (Flags to Set).
|
||||
{ PS2_KEY_SPACE, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, ' ', 0x00, }, // Space
|
||||
{ PS2_KEY_COMMA, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '<', 0x00, }, // Less Than <
|
||||
{ PS2_KEY_COMMA, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, ',', 0x00, }, // Comma ,
|
||||
{ PS2_KEY_SEMI, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, ':', 0x00, }, // Colon :
|
||||
{ PS2_KEY_SEMI, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, ';', 0x00, }, // Semi-Colon ;
|
||||
{ PS2_KEY_DOT, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '>', 0x00, }, // Greater Than >
|
||||
{ PS2_KEY_DOT, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '.', 0x00, }, // Full stop .
|
||||
{ PS2_KEY_DIV, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '?', 0x00, }, // Question ?
|
||||
{ PS2_KEY_DIV, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '/', 0x00, }, // Divide /
|
||||
{ PS2_KEY_MINUS, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '_', 0x00, }, // Underscore
|
||||
{ PS2_KEY_MINUS, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '-', 0x00, },
|
||||
{ PS2_KEY_APOS, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '@', 0x00, }, // At @
|
||||
{ PS2_KEY_APOS, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '\'', 0x00, }, // Single quote '
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '{', 0x00, }, // Open Left Brace {
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '[', 0x00, }, // Open Left Square Bracket [
|
||||
{ PS2_KEY_EQUAL, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '+', 0x00, }, // Plus +
|
||||
{ PS2_KEY_EQUAL, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '=', 0x00, }, // Equal =
|
||||
{ PS2_KEY_CAPS, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, ' ', 0x00, }, // LOCK
|
||||
{ PS2_KEY_ENTER, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, 0x0D, 0x00, }, // ENTER/RETURN
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '}', 0x00, }, // Close Right Brace }
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, ']', 0x00, }, // Close Right Square Bracket ]
|
||||
{ PS2_KEY_BACK, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '|', 0x00, }, //
|
||||
{ PS2_KEY_BACK, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '\\', 0x00, }, // Back slash maps to Yen
|
||||
{ PS2_KEY_BTICK, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '`', 0x00, }, // Pipe
|
||||
{ PS2_KEY_BTICK, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '|', 0x00, }, // Back tick `
|
||||
{ PS2_KEY_HASH, PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, '~', 0x00, }, // Tilde has no mapping.
|
||||
{ PS2_KEY_HASH, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '#', 0x00, }, // Hash
|
||||
{ PS2_KEY_BS, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0x08, 0x00, }, // Backspace
|
||||
{ PS2_KEY_ESC, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0x1B, 0x00, }, // ESCape
|
||||
{ PS2_KEY_SCROLL, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, ' ', 0x00, }, // Not assigned.
|
||||
{ PS2_KEY_INSERT, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, MZ5665_KEY_INS, 0x00, }, // INSERT
|
||||
{ PS2_KEY_HOME, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, MZ5665_KEY_CLR, 0x00, }, // CLR
|
||||
{ PS2_KEY_HOME, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, MZ5665_KEY_HOME, 0x00, }, // HOME
|
||||
{ PS2_KEY_DELETE, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, MZ5665_KEY_DEL, 0x00, }, // DELETE
|
||||
{ PS2_KEY_END, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0x11, 0x00, }, // END
|
||||
{ PS2_KEY_PGUP, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0x0E, 0x00, }, // Roll Up.
|
||||
{ PS2_KEY_PGDN, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0x0F, 0x00, }, // Roll Down
|
||||
{ PS2_KEY_UP_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, MZ5665_KEY_UP, 0x00, }, // Up Arrow
|
||||
{ PS2_KEY_L_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, MZ5665_KEY_LEFT, 0x00, }, // Left Arrow
|
||||
{ PS2_KEY_DN_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, MZ5665_KEY_DOWN, 0x00, }, // Down Arrow
|
||||
{ PS2_KEY_R_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, MZ5665_KEY_RIGHT, 0x00, }, // Right Arrow
|
||||
{ PS2_KEY_NUM, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, }, // Not assigned.
|
||||
// GRPH (Alt Gr)
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Keyboard Model Machine MZ5665 Data MZ5665 Ctrl (Flags to Set).
|
||||
{ PS2_KEY_0, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xFA, 0x00, }, // GRPH+0
|
||||
{ PS2_KEY_1, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xF1, 0x00, }, // GRPH+1
|
||||
{ PS2_KEY_2, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xF2, 0x00, }, // GRPH+2
|
||||
{ PS2_KEY_3, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xF3, 0x00, }, // GRPH+3
|
||||
{ PS2_KEY_4, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xF4, 0x00, }, // GRPH+4
|
||||
{ PS2_KEY_5, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xF5, 0x00, }, // GRPH+5
|
||||
{ PS2_KEY_6, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xF6, 0x00, }, // GRPH+6
|
||||
{ PS2_KEY_7, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xF7, 0x00, }, // GRPH+7
|
||||
{ PS2_KEY_8, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xF8, 0x00, }, // GRPH+8
|
||||
{ PS2_KEY_9, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xF9, 0x00, }, // GRPH+9
|
||||
{ PS2_KEY_A, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x7F, 0x00, }, // GRPH+A
|
||||
{ PS2_KEY_B, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x84, 0x00, }, // GRPH+B
|
||||
{ PS2_KEY_C, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x82, 0x00, }, // GRPH+C
|
||||
{ PS2_KEY_D, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xEA, 0x00, }, // GRPH+D
|
||||
{ PS2_KEY_E, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xE2, 0x00, }, // GRPH+E
|
||||
{ PS2_KEY_F, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xEB, 0x00, }, // GRPH+F
|
||||
{ PS2_KEY_G, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xEC, 0x00, }, // GRPH+G
|
||||
{ PS2_KEY_H, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xED, 0x00, }, // GRPH+H
|
||||
{ PS2_KEY_I, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xE7, 0x00, }, // GRPH+I
|
||||
{ PS2_KEY_J, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xEE, 0x00, }, // GRPH+J
|
||||
{ PS2_KEY_K, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xEF, 0x00, }, // GRPH+K
|
||||
{ PS2_KEY_L, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x8E, 0x00, }, // GRPH+L
|
||||
{ PS2_KEY_M, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x86, 0x00, }, // GRPH+M
|
||||
{ PS2_KEY_N, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x85, 0x00, }, // GRPH+N
|
||||
{ PS2_KEY_O, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xF0, 0x00, }, // GRPH+O
|
||||
{ PS2_KEY_P, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x8D, 0x00, }, // GRPH+P
|
||||
{ PS2_KEY_Q, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xE0, 0x00, }, // GRPH+Q
|
||||
{ PS2_KEY_R, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xE3, 0x00, }, // GRPH+R
|
||||
{ PS2_KEY_S, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xE9, 0x00, }, // GRPH+S
|
||||
{ PS2_KEY_T, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xE4, 0x00, }, // GRPH+T
|
||||
{ PS2_KEY_U, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xE6, 0x00, }, // GRPH+U
|
||||
{ PS2_KEY_V, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x83, 0x00, }, // GRPH+V
|
||||
{ PS2_KEY_W, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xE1, 0x00, }, // GRPH+W
|
||||
{ PS2_KEY_X, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x81, 0x00, }, // GRPH+X
|
||||
{ PS2_KEY_Y, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xE5, 0x00, }, // GRPH+Y
|
||||
{ PS2_KEY_Z, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x80, 0x00, }, // GRPH+Z
|
||||
{ PS2_KEY_COMMA, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x87, 0x00, }, // GRPH+,
|
||||
{ PS2_KEY_SEMI, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x89, 0x00, }, // GRPH+;
|
||||
{ PS2_KEY_DOT, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x88, 0x00, }, // GRPH+.
|
||||
{ PS2_KEY_DIV, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xFE, 0x00, }, // GRPH+/
|
||||
{ PS2_KEY_MINUS, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x8C, 0x00, }, // GRPH+-
|
||||
{ PS2_KEY_APOS, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x8A, 0x00, }, // GRPH+'
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xFC, 0x00, }, // GRPH+[
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0xE8, 0x00, }, // GRPH+]
|
||||
{ PS2_KEY_BACK, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x90, 0x00, }, // GRPH+Backslash
|
||||
{ PS2_KEY_KP0, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x8F, 0x00, }, // GRPH+Keypad 0
|
||||
{ PS2_KEY_KP1, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x99, 0x00, }, // GRPH+Keypad 1
|
||||
{ PS2_KEY_KP2, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x92, 0x00, }, // GRPH+Keypad 2
|
||||
{ PS2_KEY_KP3, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x98, 0x00, }, // GRPH+Keypad 3
|
||||
{ PS2_KEY_KP4, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x95, 0x00, }, // GRPH+Keypad 4
|
||||
{ PS2_KEY_KP5, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x96, 0x00, }, // GRPH+Keypad 5
|
||||
{ PS2_KEY_KP6, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x94, 0x00, }, // GRPH+Keypad 6
|
||||
{ PS2_KEY_KP7, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x9A, 0x00, }, // GRPH+Keypad 7
|
||||
{ PS2_KEY_KP8, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x93, 0x00, }, // GRPH+Keypad 8
|
||||
{ PS2_KEY_KP9, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x97, 0x00, }, // GRPH+Keypad 9
|
||||
{ PS2_KEY_KP_DOT, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x91, 0x00, }, // GRPH+Keypad Full stop .
|
||||
{ PS2_KEY_KP_PLUS, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x9D, 0x00, }, // GRPH+Keypad Plus +
|
||||
{ PS2_KEY_KP_MINUS, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x9C, 0x00, }, // GRPH+Keypad Minus -
|
||||
{ PS2_KEY_KP_TIMES, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x9B, 0x00, }, // GRPH+Keypad Times *
|
||||
{ PS2_KEY_KP_DIV, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x9E, 0x00, }, // GRPH+Keypad Divide /
|
||||
{ PS2_KEY_KP_ENTER, PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x90, 0x00, }, // GRPH+Keypad Ebter /
|
||||
// KANA (Alt)
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Keyboard Model Machine MZ5665 Data MZ5665 Ctrl (Flags to Set).
|
||||
{ PS2_KEY_0, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xA6, 0x00, }, // KANA+SHIFT+0
|
||||
{ PS2_KEY_0, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xDC, 0x00, }, // KANA+0
|
||||
{ PS2_KEY_1, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xC7, 0x00, }, // KANA+1
|
||||
{ PS2_KEY_2, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xCC, 0x00, }, // KANA+2
|
||||
{ PS2_KEY_3, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xA7, 0x00, }, // KANA+SHIFT+3
|
||||
{ PS2_KEY_3, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xB1, 0x00, }, // KANA+3
|
||||
{ PS2_KEY_4, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xA9, 0x00, }, // KANA+SHIFT+4
|
||||
{ PS2_KEY_4, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xB3, 0x00, }, // KANA+4
|
||||
{ PS2_KEY_5, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xAA, 0x00, }, // KANA+SHIFT+5
|
||||
{ PS2_KEY_5, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xB4, 0x00, }, // KANA+5
|
||||
{ PS2_KEY_6, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xAB, 0x00, }, // KANA+SHIFT+6
|
||||
{ PS2_KEY_6, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xB5, 0x00, }, // KANA+6
|
||||
{ PS2_KEY_7, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xAC, 0x00, }, // KANA+SHIFT+7
|
||||
{ PS2_KEY_7, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xD4, 0x00, }, // KANA+7
|
||||
{ PS2_KEY_8, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xAD, 0x00, }, // KANA+SHIFT+8
|
||||
{ PS2_KEY_8, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xD5, 0x00, }, // KANA+8
|
||||
{ PS2_KEY_9, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xAE, 0x00, }, // KANA+SHIFT+9
|
||||
{ PS2_KEY_9, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xD6, 0x00, }, // KANA+9
|
||||
{ PS2_KEY_A, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xC1, 0x00, }, // KANA+A
|
||||
{ PS2_KEY_B, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xBA, 0x00, }, // KANA+B
|
||||
{ PS2_KEY_C, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xBF, 0x00, }, // KANA+C
|
||||
{ PS2_KEY_D, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xBC, 0x00, }, // KANA+D
|
||||
{ PS2_KEY_E, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xA8, 0x00, }, // KANA+SHIFT+E
|
||||
{ PS2_KEY_E, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xB2, 0x00, }, // KANA+E
|
||||
{ PS2_KEY_F, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xCA, 0x00, }, // KANA+F
|
||||
{ PS2_KEY_G, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xB7, 0x00, }, // KANA+G
|
||||
{ PS2_KEY_H, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xB8, 0x00, }, // KANA+H
|
||||
{ PS2_KEY_I, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xC6, 0x00, }, // KANA+I
|
||||
{ PS2_KEY_J, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xCF, 0x00, }, // KANA+J
|
||||
{ PS2_KEY_K, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xC9, 0x00, }, // KANA+K
|
||||
{ PS2_KEY_L, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xD8, 0x00, }, // KANA+L
|
||||
{ PS2_KEY_M, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xD3, 0x00, }, // KANA+M
|
||||
{ PS2_KEY_N, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xD0, 0x00, }, // KANA+N
|
||||
{ PS2_KEY_O, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xD7, 0x00, }, // KANA+O
|
||||
{ PS2_KEY_P, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xBE, 0x00, }, // KANA+P
|
||||
{ PS2_KEY_Q, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xC0, 0x00, }, // KANA+Q
|
||||
{ PS2_KEY_R, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xBD, 0x00, }, // KANA+R
|
||||
{ PS2_KEY_S, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xC4, 0x00, }, // KANA+S
|
||||
{ PS2_KEY_T, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xB6, 0x00, }, // KANA+T
|
||||
{ PS2_KEY_U, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xC5, 0x00, }, // KANA+U
|
||||
{ PS2_KEY_V, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xCB, 0x00, }, // KANA+V
|
||||
{ PS2_KEY_W, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xC3, 0x00, }, // KANA+W
|
||||
{ PS2_KEY_X, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xBB, 0x00, }, // KANA+X
|
||||
{ PS2_KEY_Y, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xDD, 0x00, }, // KANA+Y
|
||||
{ PS2_KEY_Z, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xAF, 0x00, }, // KANA+SHIFT+Z
|
||||
{ PS2_KEY_Z, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xC2, 0x00, }, // KANA+Z
|
||||
{ PS2_KEY_COMMA, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xA4, 0x00, }, // KANA+SHIFT+,
|
||||
{ PS2_KEY_COMMA, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xC8, 0x00, }, // KANA+,
|
||||
{ PS2_KEY_SEMI, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xDA, 0x00, }, // KANA+;
|
||||
{ PS2_KEY_DOT, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xA1, 0x00, }, // KANA+SHIFT+.
|
||||
{ PS2_KEY_DOT, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xD9, 0x00, }, // KANA+.
|
||||
{ PS2_KEY_DIV, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xA5, 0x00, }, // KANA+SHIFT+/
|
||||
{ PS2_KEY_DIV, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xD2, 0x00, }, // KANA+/
|
||||
{ PS2_KEY_MINUS, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xCE, 0x00, }, // KANA+-
|
||||
{ PS2_KEY_APOS, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xDE, 0x00, }, // KANA+'
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xA2, 0x00, }, // KANA+SHIFT+[
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xDF, 0x00, }, // KANA+[
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0xA3, 0x00, }, // KANA+SHIFT+]
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xD1, 0x00, }, // KANA+]
|
||||
{ PS2_KEY_BACK, PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0xDB, 0x00, }, // KANA+Backslash
|
||||
{ PS2_KEY_BS, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, MZ5665_ALL, 0x12, 0x00, }, // KANA+SHIFT+Backspace
|
||||
// Keypad.
|
||||
{ PS2_KEY_KP0, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '0', 0x00, }, // Keypad 0
|
||||
{ PS2_KEY_KP1, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '1', 0x00, }, // Keypad 1
|
||||
{ PS2_KEY_KP2, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '2', 0x00, }, // Keypad 2
|
||||
{ PS2_KEY_KP3, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '3', 0x00, }, // Keypad 3
|
||||
{ PS2_KEY_KP4, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '4', 0x00, }, // Keypad 4
|
||||
{ PS2_KEY_KP5, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '5', 0x00, }, // Keypad 5
|
||||
{ PS2_KEY_KP6, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '6', 0x00, }, // Keypad 6
|
||||
{ PS2_KEY_KP7, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '7', 0x00, }, // Keypad 7
|
||||
{ PS2_KEY_KP8, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '8', 0x00, }, // Keypad 8
|
||||
{ PS2_KEY_KP9, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '9', 0x00, }, // Keypad 9
|
||||
{ PS2_KEY_KP_COMMA, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, ',', 0x00, }, // Keypad Comma ,
|
||||
{ PS2_KEY_KP_DOT, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '.', 0x00, }, // Keypad Full stop .
|
||||
{ PS2_KEY_KP_PLUS, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '+', 0x00, }, // Keypad Plus +
|
||||
{ PS2_KEY_KP_MINUS, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '-', 0x00, }, // Keypad Minus -
|
||||
{ PS2_KEY_KP_TIMES, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '*', 0x00, }, // Keypad Times *
|
||||
{ PS2_KEY_KP_DIV, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, '/', 0x00, }, // Keypad Divide /
|
||||
{ PS2_KEY_KP_ENTER, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, 0x0D, 0x00, }, // Keypad Ebter /
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Keyboard Model Machine MZ5665 Data MZ5665 Ctrl (Flags to Set).
|
||||
// Special keys.
|
||||
{ PS2_KEY_PRTSCR, PS2CTRL_FUNC, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, }, // ARGO KEY
|
||||
{ PS2_KEY_PAUSE, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, 0x03, 0x00, }, // BREAK KEY
|
||||
{ PS2_KEY_L_GUI, PS2CTRL_FUNC | PS2CTRL_GUI, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, }, // GRAPH KEY
|
||||
//{ PS2_KEY_L_ALT, PS2CTRL_FUNC | PS2CTRL_KANA, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, }, // KJ1 Sentence
|
||||
//{ PS2_KEY_R_ALT, PS2CTRL_FUNC | PS2CTRL_GRAPH, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, }, // KJ2 Transform
|
||||
{ PS2_KEY_R_GUI, PS2CTRL_FUNC | PS2CTRL_GUI, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, }, // KANA KEY
|
||||
{ PS2_KEY_MENU, PS2CTRL_FUNC | PS2CTRL_GUI, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, }, // Not assigned.
|
||||
// Modifiers are last, only being selected if an earlier match isnt made.
|
||||
{ PS2_KEY_L_SHIFT, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, },
|
||||
{ PS2_KEY_R_SHIFT, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, },
|
||||
{ PS2_KEY_L_CTRL, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, },
|
||||
{ PS2_KEY_R_CTRL, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, }, // Map to Control
|
||||
{ 0, PS2CTRL_NONE, KEYMAP_STANDARD, MZ5665_ALL, 0x00, 0x00, },
|
||||
}};
|
||||
};
|
||||
|
||||
#endif // MZ5665_H
|
||||
151
main/include/Mouse.h
Normal file
151
main/include/Mouse.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Mouse.h
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Header for the PS/2 Mouse to Sharp Host interface logic.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// v1.01 May 2022 - Initial release version.
|
||||
// v1.02 Jun 2022 - Updates to reflect changes realised in other modules due to addition of
|
||||
// bluetooth and suspend logic due to NVS issues using both cores.
|
||||
// Updates to reflect moving functionality into the HID and to support
|
||||
// Bluetooth as a primary mouse or secondary mouse.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef MOUSE_H
|
||||
#define MOUSE_H
|
||||
|
||||
// Include the specification class.
|
||||
#include "KeyInterface.h"
|
||||
#include "NVS.h"
|
||||
#include "HID.h"
|
||||
|
||||
// NB: Macros definitions put inside class for clarity, they are still global scope.
|
||||
|
||||
// Encapsulate the Mouse interface.
|
||||
class Mouse : public KeyInterface {
|
||||
|
||||
// Macros.
|
||||
//
|
||||
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
// Constants.
|
||||
#define MOUSEIF_VERSION 1.02
|
||||
#define MAX_MOUSE_XMIT_KEY_BUF 128
|
||||
#define BITBANG_UART_BIT_TIME 208UL
|
||||
|
||||
public:
|
||||
|
||||
// Prototypes.
|
||||
Mouse(void);
|
||||
Mouse(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID);
|
||||
Mouse(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID, bool secondaryIf);
|
||||
Mouse(NVS *hdlNVShdlHID, HID *hdlHID);
|
||||
~Mouse(void);
|
||||
void getMouseConfigTypes(std::vector<std::string>& typeList);
|
||||
bool getMouseSelectList(std::vector<std::pair<std::string, int>>& selectList, std::string option);
|
||||
bool setMouseConfigValue(std::string paramName, std::string paramValue);
|
||||
void mouseReceiveData(HID::t_mouseMessageElement mouseMessage);
|
||||
bool persistConfig(void);
|
||||
|
||||
// Method to return the class version number.
|
||||
float version(void)
|
||||
{
|
||||
return(MOUSEIF_VERSION);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
// Prototypes.
|
||||
IRAM_ATTR static void hostInterface( void * pvParameters );
|
||||
void init(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID);
|
||||
void init(NVS *hdlNVS, HID *hdlHID);
|
||||
|
||||
// Structure to maintain mouse interface configuration data. This data is persisted through powercycles as needed.
|
||||
typedef struct {
|
||||
struct {
|
||||
// PS/2 Mouse data Adjustment and filtering options.
|
||||
//
|
||||
enum HID::HID_MOUSE_RESOLUTION resolution;
|
||||
enum HID::HID_MOUSE_SCALING scaling;
|
||||
enum HID::HID_MOUSE_SAMPLING sampleRate;
|
||||
} mouse;
|
||||
|
||||
struct {
|
||||
// Host data for adjustment and configuration.
|
||||
enum HID::HID_MOUSE_HOST_SCALING scaling;
|
||||
} host;
|
||||
|
||||
struct {
|
||||
} params;
|
||||
} t_mouseConfig;
|
||||
|
||||
// Configuration data.
|
||||
t_mouseConfig mouseConfig;
|
||||
|
||||
// Structure to manage the Mouse control variables signifying the state of the Mouse.
|
||||
typedef struct {
|
||||
} t_msControl;
|
||||
|
||||
// Mouse Control variables.
|
||||
volatile t_msControl msCtrl;
|
||||
|
||||
// Structure to manage the Sharp host control variables which define control and data mapping of the host interface and data sent.
|
||||
//
|
||||
typedef struct {
|
||||
#ifdef CONFIG_HOST_HW_UART
|
||||
int uartNum;
|
||||
int uartBufferSize;
|
||||
int uartQueueSize;
|
||||
#endif
|
||||
bool secondaryIf; // Mouse runs in tandem with a keyboard interface.
|
||||
|
||||
// Data adjustment and processing options applied to the PS/2 data.
|
||||
bool updated;
|
||||
} t_hostControl;
|
||||
|
||||
// Host Control variables.
|
||||
volatile t_hostControl hostControl;
|
||||
|
||||
// PS/2 to HOST serialiser buffer item.
|
||||
typedef struct {
|
||||
uint8_t xPos;
|
||||
uint8_t yPos;
|
||||
uint8_t status;
|
||||
uint8_t wheel;
|
||||
bool valid;
|
||||
} t_xmitMessage;
|
||||
|
||||
// Create an object for storing the data to be sent to the Host. This data has already been converted and adjusted from the incoming PS/2 message.
|
||||
t_xmitMessage xmitMsg;
|
||||
|
||||
// Thread handles - one per function, ie. ps/2 interface, host target interface, wifi interface.
|
||||
TaskHandle_t TaskHostIF = NULL;
|
||||
TaskHandle_t TaskHIDIF = NULL;
|
||||
|
||||
// Spin lock mutex to hold a coresied to an uninterruptable method. This only works on dual core ESP32's.
|
||||
portMUX_TYPE x1Mutex;
|
||||
};
|
||||
|
||||
#endif // MOUSE_H
|
||||
162
main/include/NVS.h
Normal file
162
main/include/NVS.h
Normal file
@@ -0,0 +1,162 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: NVS.h
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Class definition to encapsulate the Espressif Non Volatile Storage into a thread safe
|
||||
// object, The underlying API is supposed to be thread safe but experience has shown
|
||||
// that two threads, each with there own handle can cause a lockup.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// v1.01 May 2022 - Initial release version.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef NVS_H
|
||||
#define NVS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "nvs.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "driver/timer.h"
|
||||
|
||||
|
||||
// NB: Macros definitions put inside class for clarity, they are still global scope.
|
||||
|
||||
// Define a virtual class which acts as the base and specification of all super classes forming host
|
||||
// interface objects.
|
||||
class NVS {
|
||||
|
||||
// Macros.
|
||||
//
|
||||
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
// Constants.
|
||||
#define NVS_VERSION 1.01
|
||||
|
||||
public:
|
||||
|
||||
// Prototypes.
|
||||
NVS(void);
|
||||
NVS(std::string keyName);
|
||||
virtual ~NVS(void) {};
|
||||
void eraseAll(void);
|
||||
void init(void);
|
||||
bool takeMutex(void);
|
||||
void giveMutex(void);
|
||||
// Persistence.
|
||||
bool open(std::string keyName);
|
||||
bool persistData(const char *key, void *pData, uint32_t size);
|
||||
bool retrieveData(const char *key, void *pData, uint32_t size);
|
||||
bool commitData(void);
|
||||
|
||||
// Helper method to identify the sub class, this is used in non volatile key management.
|
||||
// Warning: This method wont work if optimisation for size is enabled on the compiler.
|
||||
const char *getClassName(const std::string& prettyFunction)
|
||||
{
|
||||
// First find the CLASS :: METHOD seperation.
|
||||
size_t colons = prettyFunction.find("::");
|
||||
|
||||
// None, then this is not a class.
|
||||
if (colons == std::string::npos)
|
||||
return "::";
|
||||
|
||||
// Split out the class name.
|
||||
size_t begin = prettyFunction.substr(0,colons).rfind(" ") + 1;
|
||||
size_t end = colons - begin;
|
||||
|
||||
// Return the name.
|
||||
return(prettyFunction.substr(begin,end).c_str());
|
||||
}
|
||||
|
||||
// Helper method to change a file extension.
|
||||
void replaceExt(std::string& fileName, const std::string& newExt)
|
||||
{
|
||||
// Locals.
|
||||
std::string::size_type extPos = fileName.rfind('.', fileName.length());
|
||||
|
||||
if(extPos != std::string::npos)
|
||||
{
|
||||
fileName.replace(extPos+1, newExt.length(), newExt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Template to aid in conversion of an enum to integer.
|
||||
template <typename E> constexpr typename std::underlying_type<E>::type to_underlying(E e) noexcept
|
||||
{
|
||||
return static_cast<typename std::underlying_type<E>::type>(e);
|
||||
}
|
||||
|
||||
// Method to return the class version number.
|
||||
virtual float version(void)
|
||||
{
|
||||
return(NVS_VERSION);
|
||||
}
|
||||
|
||||
// Method to return the name of the class.
|
||||
virtual std::string ifName(void)
|
||||
{
|
||||
return(nvsCtrl.nvsClassName);
|
||||
}
|
||||
|
||||
// Method to return the name of the nvs key.
|
||||
virtual std::string keyName(void)
|
||||
{
|
||||
return(nvsCtrl.nvsKeyName);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
// Structure to maintain an active setting for the LED. The LED control thread uses these values to effect the required lighting of the LED.
|
||||
typedef struct {
|
||||
// Handle to the persistent storage api.
|
||||
nvs_handle_t nvsHandle;
|
||||
|
||||
// Name of the class for this instantiation.
|
||||
std::string nvsClassName;
|
||||
|
||||
// Name of the key under which NVS was opened.
|
||||
std::string nvsKeyName;
|
||||
|
||||
// Mutex to block access to limit one thread at a time.
|
||||
SemaphoreHandle_t mutexInternal;
|
||||
} t_nvsControl;
|
||||
|
||||
// Var to store all NVS control variables.
|
||||
t_nvsControl nvsCtrl;
|
||||
|
||||
};
|
||||
#endif // NVS_H
|
||||
529
main/include/PC9801.h
Normal file
529
main/include/PC9801.h
Normal file
@@ -0,0 +1,529 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: PC9801.h
|
||||
// Created: Apr 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Header for the NEC PC-9801 to HID (PS/2, Bluetooth) interface logic.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Apr 2022 - Initial write.
|
||||
// v1.01 Jun 2022 - Updates to reflect changes realised in other modules due to addition of
|
||||
// bluetooth and suspend logic due to NVS issues using both cores.
|
||||
//
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PC9801_H
|
||||
#define PC9801_H
|
||||
|
||||
// Include the specification class.
|
||||
#include "KeyInterface.h"
|
||||
#include "NVS.h"
|
||||
#include "LED.h"
|
||||
#include "HID.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
// NB: Macros definitions put inside class for clarity, they are still global scope.
|
||||
|
||||
// Encapsulate the NEC PC-9801 interface.
|
||||
class PC9801 : public KeyInterface {
|
||||
// Macros.
|
||||
//
|
||||
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
// Constants.
|
||||
#define PC9801IF_VERSION 1.00
|
||||
#define PC9801IF_KEYMAP_FILE "PC9801_KeyMap.BIN"
|
||||
#define MAX_PC9801_XMIT_KEY_BUF 16
|
||||
#define MAX_PC9801_RCV_KEY_BUF 16
|
||||
|
||||
// NEC PC-9801 Key control bit mask.
|
||||
#define PC9801_CTRL_SHIFT ((unsigned char) (1 << 5))
|
||||
#define PC9801_CTRL_RELEASESHIFT ((unsigned char) (1 << 4))
|
||||
#define PC9801_CTRL_CTRL ((unsigned char) (1 << 3))
|
||||
#define PC9801_CTRL_GRAPH ((unsigned char) (1 << 2))
|
||||
#define PC9801_CTRL_CAPS ((unsigned char) (1 << 1))
|
||||
#define PC9801_CTRL_KANA ((unsigned char) (1 << 0))
|
||||
#define PC9801_CTRL_NONE 0x00
|
||||
|
||||
// Special key definition.
|
||||
// #define PC9801_KEY_UP 0x1E // ↑
|
||||
// #define PC9801_KEY_DOWN 0x1F // ↓
|
||||
// #define PC9801_KEY_LEFT 0x1D // ←
|
||||
// #define PC9801_KEY_RIGHT 0x1C // → →
|
||||
// #define PC9801_KEY_INS 0x12 // INS
|
||||
// #define PC9801_KEY_DEL 0x08 // DEL
|
||||
// #define PC9801_KEY_CLR 0x0C // CLR
|
||||
// #define PC9801_KEY_HOME 0x0B // HOME
|
||||
|
||||
// PS2 Flag definitions.
|
||||
#define PS2CTRL_NONE 0x00 // No keys active = 0
|
||||
#define PS2CTRL_SHIFT 0x01 // Shfit Key active = 1
|
||||
#define PS2CTRL_CTRL 0x02 // Ctrl Key active = 1
|
||||
#define PS2CTRL_CAPS 0x04 // CAPS active = 1
|
||||
#define PS2CTRL_KANA 0x08 // KANA active = 1
|
||||
#define PS2CTRL_GRAPH 0x10 // GRAPH active = 1
|
||||
#define PS2CTRL_GUI 0x20 // GUI Key active = 1
|
||||
#define PS2CTRL_FUNC 0x40 // Special Function Keys active = 1
|
||||
#define PS2CTRL_BREAK 0x80 // BREAK Key active = 1
|
||||
#define PS2CTRL_EXACT 0x80 // EXACT Match active = 1
|
||||
|
||||
// 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 extract the PC-9801 key code and control data.
|
||||
// ie. PS/2 Scan Code -> ASCII + Flags -> PC-9801 Key Code + Ctrl Data
|
||||
#define PS2TBL_PC9801_MAXCOLS 6
|
||||
#define PS2TBL_PC9801_MAXROWS 131
|
||||
|
||||
// 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 extract the NEC PC-9801 key code and control data.
|
||||
// ie. PS/2 Scan Code -> ASCII + Flags -> NEC PC-9801 Key Code + Ctrl Data
|
||||
|
||||
// Keyboard mapping table column names.
|
||||
#define PS2TBL_PS2KEYCODE_NAME "PS/2 KeyCode"
|
||||
#define PS2TBL_PS2CTRL_NAME "PS/2 Control Key"
|
||||
#define PS2TBL_KEYBOARDMODEL_NAME "For Keyboard"
|
||||
#define PS2TBL_MACHINE_NAME "For Host Model"
|
||||
#define PS2TBL_PC9801_KEYCODE_NAME "PC9801 KeyCode"
|
||||
#define PS2TBL_PC9801__CTRL_NAME "PC9801 Control Key"
|
||||
|
||||
// Keyboard mapping table column types.
|
||||
#define PS2TBL_PS2KEYCODE_TYPE "hex"
|
||||
#define PS2TBL_PS2CTRL_TYPE "custom_cbp_ps2ctrl"
|
||||
#define PS2TBL_KEYBOARDMODEL_TYPE "custom_cbp_keybmodel"
|
||||
#define PS2TBL_MACHINE_TYPE "custom_cbp_machine"
|
||||
#define PS2TBL_PC9801_KEYCODE_TYPE "hex"
|
||||
#define PS2TBL_PC9801_CTRL_TYPE "custom_cbn_x1ctrl"
|
||||
|
||||
// Keyboard mapping table select list for PS2CTRL.
|
||||
#define PS2TBL_PS2CTRL_SEL_NONE "NONE"
|
||||
#define PS2TBL_PS2CTRL_SEL_SHIFT "SHIFT"
|
||||
#define PS2TBL_PS2CTRL_SEL_CTRL "CTRL"
|
||||
#define PS2TBL_PS2CTRL_SEL_CAPS "CAPS"
|
||||
#define PS2TBL_PS2CTRL_SEL_KANA "KANA"
|
||||
#define PS2TBL_PS2CTRL_SEL_GRAPH "GRAPH"
|
||||
#define PS2TBL_PS2CTRL_SEL_GUI "GUI"
|
||||
#define PS2TBL_PS2CTRL_SEL_FUNC "FUNC"
|
||||
#define PS2TBL_PS2CTRL_SEL_EXACT "EXACT"
|
||||
|
||||
// Keyboard mapping table select list for target machine.
|
||||
#define PC9801_SEL_ALL "ALL"
|
||||
#define PC9801_SEL_ORIG "ORIGINAL"
|
||||
|
||||
// Keyboard mapping table select list for Model of keyboard.
|
||||
#define KEYMAP_SEL_STANDARD "ALL"
|
||||
#define KEYMAP_SEL_UK_WYSE_KB3926 "UK_WYSE_KB3926"
|
||||
#define KEYMAP_SEL_JAPAN_OADG109 "JAPAN_OADG109"
|
||||
#define KEYMAP_SEL_JAPAN_SANWA_SKBL1 "JAPAN_SANWA_SKBL1"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_4 "KEYBOARD_4"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_5 "KEYBOARD_5"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_6 "KEYBOARD_6"
|
||||
#define KEYMAP_SEL_UK_PERIBOARD_810 "UK_PERIBOARD_810"
|
||||
#define KEYMAP_SEL_UK_OMOTON_K8508 "UK_OMOTON_K8508"
|
||||
|
||||
// Keyboard mapping table select list for PC9801 Control codes.
|
||||
#define PC9801_CTRL_SEL_GRAPH "GRAPH"
|
||||
#define PC9801_CTRL_SEL_CAPS "CAPS"
|
||||
#define PC9801_CTRL_SEL_KANA "KANA"
|
||||
#define PC9801_CTRL_SEL_SHIFT "SHIFT"
|
||||
#define PC9801_CTRL_SEL_CTRL "CTRL"
|
||||
|
||||
// The NEC PC-9801 Series was released over a number of years and each iteration added changes/updates. In order to cater for differences, it is possible to assign a key mapping
|
||||
// to a specific machine type(s) or all of the series by adding the flags below into the mapping table.
|
||||
#define PC9801_ALL 0xFF
|
||||
|
||||
// Keyboard models. The base on which this interface was created was a Wyse KB3926 PS/2 Keyboard and this is deemed STANDARD. Other models need to insert difference maps
|
||||
// prior to the STANDARD entry along with the keyboard model so that it is processed first thus allowing differing keyboards with different maps.
|
||||
#define KEYMAP_STANDARD 0xFF
|
||||
#define KEYMAP_UK_WYSE_KB3926 0x01
|
||||
#define KEYMAP_JAPAN_OADG109 0x02
|
||||
#define KEYMAP_JAPAN_SANWA_SKBL1 0x04
|
||||
#define KEYMAP_NOT_ASSIGNED_4 0x08
|
||||
#define KEYMAP_NOT_ASSIGNED_5 0x10
|
||||
#define KEYMAP_NOT_ASSIGNED_6 0x20
|
||||
#define KEYMAP_UK_PERIBOARD_810 0x40
|
||||
#define KEYMAP_UK_OMOTON_K8508 0x80
|
||||
|
||||
// PC-9801 Scan codes - PS2 codes along with function keys (SHIFT, CTRL etc) are mapped to the X68000 scan codes below.
|
||||
#define PC9801_KEY_ESC 0x00
|
||||
#define PC9801_KEY_0 0x0A
|
||||
#define PC9801_KEY_1 0x01
|
||||
#define PC9801_KEY_2 0x02
|
||||
#define PC9801_KEY_3 0x03
|
||||
#define PC9801_KEY_4 0x04
|
||||
#define PC9801_KEY_5 0x05
|
||||
#define PC9801_KEY_6 0x06
|
||||
#define PC9801_KEY_7 0x07
|
||||
#define PC9801_KEY_8 0x08
|
||||
#define PC9801_KEY_9 0x09
|
||||
#define PC9801_KEY_A 0x1D
|
||||
#define PC9801_KEY_B 0x2D
|
||||
#define PC9801_KEY_C 0x2B
|
||||
#define PC9801_KEY_D 0x1F
|
||||
#define PC9801_KEY_E 0x12
|
||||
#define PC9801_KEY_F 0x20
|
||||
#define PC9801_KEY_G 0x21
|
||||
#define PC9801_KEY_H 0x22
|
||||
#define PC9801_KEY_I 0x17
|
||||
#define PC9801_KEY_J 0x23
|
||||
#define PC9801_KEY_K 0x24
|
||||
#define PC9801_KEY_L 0x25
|
||||
#define PC9801_KEY_M 0x2F
|
||||
#define PC9801_KEY_N 0x2E
|
||||
#define PC9801_KEY_O 0x18
|
||||
#define PC9801_KEY_P 0x19
|
||||
#define PC9801_KEY_Q 0x10
|
||||
#define PC9801_KEY_R 0x13
|
||||
#define PC9801_KEY_S 0x1E
|
||||
#define PC9801_KEY_T 0x14
|
||||
#define PC9801_KEY_U 0x16
|
||||
#define PC9801_KEY_V 0x2C
|
||||
#define PC9801_KEY_W 0x11
|
||||
#define PC9801_KEY_X 0x2A
|
||||
#define PC9801_KEY_Y 0x15
|
||||
#define PC9801_KEY_Z 0x29
|
||||
#define PC9801_KEY_AT 0x1A // Requires SHIFT
|
||||
#define PC9801_KEY_MINUS 0x0B
|
||||
#define PC9801_KEY_CIRCUMFLEX 0x0C
|
||||
#define PC9801_KEY_YEN 0x0D
|
||||
#define PC9801_KEY_BS 0x0E
|
||||
#define PC9801_KEY_TAB 0x0F
|
||||
#define PC9801_KEY_OPEN_SQ 0x1A
|
||||
#define PC9801_KEY_CLOSE_SQ 0x1B
|
||||
#define PC9801_KEY_RETURN 0x1C
|
||||
#define PC9801_KEY_SEMI 0x26
|
||||
#define PC9801_KEY_COLON 0x27
|
||||
#define PC9801_KEY_COMMA 0x30
|
||||
#define PC9801_KEY_DOT 0x31
|
||||
#define PC9801_KEY_DIV 0x32
|
||||
#define PC9801_KEY_UNDERLINE 0x0D // Requires SHIFT
|
||||
#define PC9801_KEY_SPACE 0x34
|
||||
#define PC9801_KEY_HOME 0x3E
|
||||
#define PC9801_KEY_ROLLUP 0x36
|
||||
#define PC9801_KEY_ROLLDN 0x37
|
||||
#define PC9801_KEY_UNDO 0x3 // Not known3
|
||||
#define PC9801_KEY_L_ARROW 0x3B
|
||||
#define PC9801_KEY_UP_ARROW 0x3A
|
||||
#define PC9801_KEY_R_ARROW 0x3C
|
||||
#define PC9801_KEY_DN_ARROW 0x3D
|
||||
#define PC9801_KEY_CLR 0x3F // Not known
|
||||
#define PC9801_KEY_KP0 0x4E
|
||||
#define PC9801_KEY_KP1 0x4A
|
||||
#define PC9801_KEY_KP2 0x4B
|
||||
#define PC9801_KEY_KP3 0x4C
|
||||
#define PC9801_KEY_KP4 0x46
|
||||
#define PC9801_KEY_KP5 0x47
|
||||
#define PC9801_KEY_KP6 0x48
|
||||
#define PC9801_KEY_KP7 0x42
|
||||
#define PC9801_KEY_KP8 0x43
|
||||
#define PC9801_KEY_KP9 0x44
|
||||
#define PC9801_KEY_KP_DIV 0x41
|
||||
#define PC9801_KEY_KP_TIMES 0x45
|
||||
#define PC9801_KEY_KP_MINUS 0x4D
|
||||
#define PC9801_KEY_KP_PLUS 0x49
|
||||
#define PC9801_KEY_KP_EQUAL 0x4D
|
||||
#define PC9801_KEY_KP_ENTER 0x1C
|
||||
#define PC9801_KEY_KP_COMMA 0x4F
|
||||
#define PC9801_KEY_KP_DOT 0x50
|
||||
#define PC9801_KEY_SYMBOL 0x52 // Not known
|
||||
#define PC9801_KEY_HELP 0x3F
|
||||
#define PC9801_KEY_CAPS 0x71
|
||||
#define PC9801_KEY_INS 0x38
|
||||
#define PC9801_KEY_DEL 0x39
|
||||
#define PC9801_KEY_BREAK 0x60 // Stop
|
||||
#define PC9801_KEY_COPY 0x61
|
||||
#define PC9801_KEY_SHIFT 0x70
|
||||
#define PC9801_KEY_R_SHIFT 0x7D
|
||||
#define PC9801_KEY_CTRL 0x74
|
||||
#define PC9801_KEY_GRAPH 0x73
|
||||
#define PC9801_KEY_XFER 0x35
|
||||
#define PC9801_KEY_NFER 0x51
|
||||
#define PC9801_KEY_KATAKANA 0x72
|
||||
#define PC9801_KEY_ROMAJI 0x33
|
||||
#define PC9801_KEY_F1 0x62
|
||||
#define PC9801_KEY_F2 0x63
|
||||
#define PC9801_KEY_F3 0x64
|
||||
#define PC9801_KEY_F4 0x65
|
||||
#define PC9801_KEY_F5 0x66
|
||||
#define PC9801_KEY_F6 0x67
|
||||
#define PC9801_KEY_F7 0x68
|
||||
#define PC9801_KEY_F8 0x69
|
||||
#define PC9801_KEY_F9 0x6A
|
||||
#define PC9801_KEY_F10 0x6B
|
||||
#define PC9801_KEY_F11 0x52
|
||||
#define PC9801_KEY_F12 0x53
|
||||
#define PC9801_KEY_F13 0x54
|
||||
#define PC9801_KEY_F14 0x55
|
||||
#define PC9801_KEY_F15 0x56
|
||||
#define PC9801_KEY_NULL 0xFF
|
||||
|
||||
public:
|
||||
// Prototypes.
|
||||
PC9801(void);
|
||||
PC9801(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID, const char *fsPath);
|
||||
PC9801(NVS *hdlNVS, HID *hdlHID, const char *fsPath);
|
||||
~PC9801(void);
|
||||
bool createKeyMapFile(std::fstream &outFile);
|
||||
bool storeDataToKeyMapFile(std::fstream &outFile, char *data, int size);
|
||||
bool storeDataToKeyMapFile(std::fstream & outFile, std::vector<uint32_t>& dataArray);
|
||||
bool closeAndCommitKeyMapFile(std::fstream &outFile, bool cleanupOnly);
|
||||
std::string getKeyMapFileName(void) { return(PC9801IF_KEYMAP_FILE); };
|
||||
void getKeyMapHeaders(std::vector<std::string>& headerList);
|
||||
void getKeyMapTypes(std::vector<std::string>& typeList);
|
||||
bool getKeyMapSelectList(std::vector<std::pair<std::string, int>>& selectList, std::string option);
|
||||
bool getKeyMapData(std::vector<uint32_t>& dataArray, int *row, bool start);
|
||||
|
||||
// Method to return the class version number.
|
||||
float version(void)
|
||||
{
|
||||
return(PC9801IF_VERSION);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
// Prototypes.
|
||||
IRAM_ATTR void pushKeyToQueue(uint32_t key);
|
||||
IRAM_ATTR void pushHostCmdToQueue(uint8_t cmd);
|
||||
IRAM_ATTR static void pcInterface( void * pvParameters );
|
||||
IRAM_ATTR static void hidInterface( void * pvParameters );
|
||||
void selectOption(uint8_t optionCode);
|
||||
uint32_t mapKey(uint16_t scanCode);
|
||||
bool loadKeyMap();
|
||||
bool saveKeyMap(void);
|
||||
void init(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID);
|
||||
void init(NVS *hdlNVS, HID *hdlHID);
|
||||
|
||||
// Structure to encapsulate a single key map from PS/2 to NEC PC-9801
|
||||
typedef struct {
|
||||
uint8_t ps2KeyCode;
|
||||
uint8_t ps2Ctrl;
|
||||
uint8_t keyboardModel;
|
||||
uint8_t machine;
|
||||
uint8_t pcKey;
|
||||
uint8_t pcCtrl;
|
||||
} t_keyMapEntry;
|
||||
|
||||
// Structure to encapsulate the entire static keyboard mapping table.
|
||||
typedef struct {
|
||||
t_keyMapEntry kme[PS2TBL_PC9801_MAXROWS];
|
||||
} t_keyMap;
|
||||
|
||||
// Structure to maintain the NEC PC-9801 interface configuration data. This data is persisted through powercycles as needed.
|
||||
typedef struct {
|
||||
struct {
|
||||
uint8_t activeKeyboardMap; // Model of keyboard a keymap entry is applicable to.
|
||||
uint8_t activeMachineModel; // Machine model a keymap entry is applicable to.
|
||||
bool useOnlyPersisted; // Flag to indicate wether the inbuilt keymap array should be combined with persisted values or the inbuilt array is ignored and only persisted values used.
|
||||
} params;
|
||||
} t_pcConfig;
|
||||
|
||||
// Configuration data.
|
||||
t_pcConfig pcConfig;
|
||||
|
||||
// Structure to manage the control signals signifying the state of the NEC PC-9801 keyboard.
|
||||
typedef struct {
|
||||
uint8_t keyCtrl; // Keyboard state flag control.
|
||||
bool optionSelect; // Flag to indicate a user requested keyboard configuration option is being selected.
|
||||
int uartNum;
|
||||
int uartBufferSize;
|
||||
int uartQueueSize;
|
||||
|
||||
std::string fsPath; // Path on the underlying filesystem where storage is mounted and accessible.
|
||||
t_keyMapEntry *kme; // Pointer to an array in memory to contain PS2 to NEC PC-9801 mapping values.
|
||||
int kmeRows; // Number of rows in the kme table.
|
||||
std::string keyMapFileName; // Name of file where extension or replacement key map entries are stored.
|
||||
bool persistConfig; // Flag to request saving of the config into NVS storage.
|
||||
} t_pcControl;
|
||||
|
||||
// Transmit buffer queue item.
|
||||
typedef struct {
|
||||
uint32_t keyCode; // Key data to be sent to PC-9801, 4 bytes to allow for extended sequences..
|
||||
} t_xmitQueueMessage;
|
||||
|
||||
// Receive buffer queue item.
|
||||
typedef struct {
|
||||
uint8_t hostCmd; // Keyboard configuration command received from X68000.
|
||||
} t_rcvQueueMessage;
|
||||
|
||||
// Thread handles - one per function, ie. HID interface and host target interface.
|
||||
TaskHandle_t TaskHostIF = NULL;
|
||||
TaskHandle_t TaskHIDIF = NULL;
|
||||
|
||||
// Control structure to control interaction and mapping of keys for the host.
|
||||
t_pcControl pcCtrl;
|
||||
|
||||
// Spin lock mutex to hold a coresied to an uninterruptable method. This only works on dual core ESP32's.
|
||||
portMUX_TYPE pcMutex;
|
||||
|
||||
//
|
||||
// This mapping is for the UK Wyse KB-3926 PS/2 keyboard
|
||||
//
|
||||
t_keyMap PS2toPC9801 = {
|
||||
{
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Keyboard Model Machine PC-9801 Data PC-9801 Ctrl (Flags to Set).
|
||||
// Function keys
|
||||
// { PS2_KEY_F1, PS2CTRL_FUNC | PS2CTRL_CTRL, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_HIRAGANA, PC9801_CTRL_NONE, }, // CTRL + F1 = Hiragana
|
||||
// { PS2_KEY_F2, PS2CTRL_FUNC | PS2CTRL_CTRL, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_FULLWIDTH, PC9801_CTRL_NONE, }, // CTRL + F2 = Full Width
|
||||
// { PS2_KEY_F3, PS2CTRL_FUNC | PS2CTRL_CTRL, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KATAKANA, PC9801_CTRL_NONE, }, // CTRL + F3 = Katakana
|
||||
// { PS2_KEY_F4, PS2CTRL_FUNC | PS2CTRL_CTRL, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_ROMAJI, PC9801_CTRL_NONE, }, // CTRL + F4 = Romaji
|
||||
// { PS2_KEY_F5, PS2CTRL_FUNC | PS2CTRL_CTRL, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_TRANSPOSE, PC9801_CTRL_NONE, }, // CTRL + F5 = Tranpose
|
||||
// { PS2_KEY_F6, PS2CTRL_FUNC | PS2CTRL_CTRL, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_SYMBOL, PC9801_CTRL_NONE, }, // CTRL + F6 = Symbol
|
||||
// { PS2_KEY_F7, PS2CTRL_FUNC | PS2CTRL_CTRL, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_REGISTRATION, PC9801_CTRL_NONE, }, // CTRL + F7 = Registration - maybe a poor translation, needs better one!
|
||||
// { PS2_KEY_F9, PS2CTRL_FUNC | PS2CTRL_CTRL, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_COPY, PC9801_CTRL_NONE, }, // CTRL + F9 = Copy
|
||||
// { PS2_KEY_F10, PS2CTRL_FUNC | PS2CTRL_CTRL, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_HELP, PC9801_CTRL_NONE, }, // CTRL + F10 = Help
|
||||
{ PS2_KEY_F1, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_F1, PC9801_CTRL_NONE, }, // F1
|
||||
{ PS2_KEY_F2, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_F2, PC9801_CTRL_NONE, }, // F2
|
||||
{ PS2_KEY_F3, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_F3, PC9801_CTRL_NONE, }, // F3
|
||||
{ PS2_KEY_F4, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_F4, PC9801_CTRL_NONE, }, // F4
|
||||
{ PS2_KEY_F5, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_F5, PC9801_CTRL_NONE, }, // F5
|
||||
{ PS2_KEY_F6, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_F6, PC9801_CTRL_NONE, }, // F6
|
||||
{ PS2_KEY_F7, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_F7, PC9801_CTRL_NONE, }, // F7
|
||||
{ PS2_KEY_F8, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_F8, PC9801_CTRL_NONE, }, // F8
|
||||
{ PS2_KEY_F9, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_F9, PC9801_CTRL_NONE, }, // F9
|
||||
{ PS2_KEY_F10, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_F10, PC9801_CTRL_NONE, }, // F10
|
||||
// { PS2_KEY_F11, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_OPT_1, PC9801_CTRL_NONE, }, // F11 - OPT.1
|
||||
// { PS2_KEY_F12, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_OPT_2, PC9801_CTRL_NONE, }, // F12 - OPT.2
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Machine PC-9801 Data PC-9801 Ctrl (Flags to Set).
|
||||
// ALPHA keys, case is maaped in the PC-9801 via the SHIFT key event or CAPS key.
|
||||
{ PS2_KEY_A, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_A, PC9801_CTRL_NONE, }, // A
|
||||
{ PS2_KEY_B, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_B, PC9801_CTRL_NONE, }, // B
|
||||
{ PS2_KEY_C, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_C, PC9801_CTRL_NONE, }, // C
|
||||
{ PS2_KEY_D, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_D, PC9801_CTRL_NONE, }, // D
|
||||
{ PS2_KEY_E, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_E, PC9801_CTRL_NONE, }, // E
|
||||
{ PS2_KEY_F, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_F, PC9801_CTRL_NONE, }, // F
|
||||
{ PS2_KEY_G, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_G, PC9801_CTRL_NONE, }, // G
|
||||
{ PS2_KEY_H, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_H, PC9801_CTRL_NONE, }, // H
|
||||
{ PS2_KEY_I, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_I, PC9801_CTRL_NONE, }, // I
|
||||
{ PS2_KEY_J, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_J, PC9801_CTRL_NONE, }, // J
|
||||
{ PS2_KEY_K, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_K, PC9801_CTRL_NONE, }, // K
|
||||
{ PS2_KEY_L, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_L, PC9801_CTRL_NONE, }, // L
|
||||
{ PS2_KEY_M, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_M, PC9801_CTRL_NONE, }, // M
|
||||
{ PS2_KEY_N, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_N, PC9801_CTRL_NONE, }, // N
|
||||
{ PS2_KEY_O, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_O, PC9801_CTRL_NONE, }, // O
|
||||
{ PS2_KEY_P, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_P, PC9801_CTRL_NONE, }, // P
|
||||
{ PS2_KEY_Q, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_Q, PC9801_CTRL_NONE, }, // Q
|
||||
{ PS2_KEY_R, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_R, PC9801_CTRL_NONE, }, // R
|
||||
{ PS2_KEY_S, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_S, PC9801_CTRL_NONE, }, // S
|
||||
{ PS2_KEY_T, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_T, PC9801_CTRL_NONE, }, // T
|
||||
{ PS2_KEY_U, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_U, PC9801_CTRL_NONE, }, // U
|
||||
{ PS2_KEY_V, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_V, PC9801_CTRL_NONE, }, // V
|
||||
{ PS2_KEY_W, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_W, PC9801_CTRL_NONE, }, // W
|
||||
{ PS2_KEY_X, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_X, PC9801_CTRL_NONE, }, // X
|
||||
{ PS2_KEY_Y, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_Y, PC9801_CTRL_NONE, }, // Y
|
||||
{ PS2_KEY_Z, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_Z, PC9801_CTRL_NONE, }, // Z
|
||||
// Numeric keys.
|
||||
{ PS2_KEY_0, PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_9, PC9801_CTRL_NONE, }, // Close Bracket )
|
||||
{ PS2_KEY_0, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_0, PC9801_CTRL_NONE, }, // 0
|
||||
{ PS2_KEY_1, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_1, PC9801_CTRL_NONE, }, // 1
|
||||
{ PS2_KEY_2, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_2, PC9801_CTRL_NONE, }, // 2
|
||||
{ PS2_KEY_3, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_3, PC9801_CTRL_NONE, }, // 3
|
||||
{ PS2_KEY_4, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_4, PC9801_CTRL_NONE, }, // 4
|
||||
{ PS2_KEY_5, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_5, PC9801_CTRL_NONE, }, // 5
|
||||
{ PS2_KEY_6, PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_CIRCUMFLEX, PC9801_CTRL_RELEASESHIFT, }, // Circumflex ^
|
||||
{ PS2_KEY_6, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_6, PC9801_CTRL_NONE, }, // 6
|
||||
{ PS2_KEY_7, PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_6, PC9801_CTRL_NONE, }, // &
|
||||
{ PS2_KEY_7, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_7, PC9801_CTRL_NONE, }, // 7
|
||||
{ PS2_KEY_8, PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_COLON, PC9801_CTRL_NONE, }, // Start *
|
||||
{ PS2_KEY_8, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_8, PC9801_CTRL_NONE, }, // 8
|
||||
{ PS2_KEY_9, PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_8, PC9801_CTRL_NONE, }, // Open Bracket (
|
||||
{ PS2_KEY_9, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_9, PC9801_CTRL_NONE, }, // 9
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Machine PC-9801 Data PC-9801 Ctrl (Flags to Set).
|
||||
// Punctuation keys.
|
||||
{ PS2_KEY_SPACE, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_SPACE, PC9801_CTRL_NONE, }, // Space
|
||||
{ PS2_KEY_MINUS, PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_CIRCUMFLEX, PC9801_CTRL_NONE, }, // Upper Bar
|
||||
{ PS2_KEY_MINUS, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_MINUS, PC9801_CTRL_NONE, }, // Minus -
|
||||
{ PS2_KEY_EQUAL, PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_SEMI, PC9801_CTRL_SHIFT, }, // Plus +
|
||||
{ PS2_KEY_EQUAL, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_MINUS, PC9801_CTRL_SHIFT, }, // Equal =
|
||||
{ PS2_KEY_DOT, PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_DOT, PC9801_CTRL_NONE, }, // Greater Than >
|
||||
{ PS2_KEY_DOT, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_DOT, PC9801_CTRL_NONE, }, // Dot
|
||||
{ PS2_KEY_DIV, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_DIV, PC9801_CTRL_NONE, }, // Divide /
|
||||
{ PS2_KEY_SEMI, PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_COLON, PC9801_CTRL_RELEASESHIFT, }, // Colon :
|
||||
{ PS2_KEY_SEMI, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_SEMI, PC9801_CTRL_NONE, }, // Semi-Colon ;
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_OPEN_SQ, PC9801_CTRL_NONE, }, // [
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_CLOSE_SQ, PC9801_CTRL_NONE, }, // ]
|
||||
{ PS2_KEY_APOS, PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_AT, PC9801_CTRL_RELEASESHIFT, }, // @
|
||||
{ PS2_KEY_APOS, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_7, PC9801_CTRL_SHIFT, }, // '
|
||||
{ PS2_KEY_BACK, PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_YEN, PC9801_CTRL_NONE, }, // Back slash maps to Yen
|
||||
{ PS2_KEY_BACK, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_YEN, PC9801_CTRL_NONE, }, // Back slash maps to Yen
|
||||
{ PS2_KEY_HASH, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_3, PC9801_CTRL_SHIFT, }, // Hash
|
||||
{ PS2_KEY_COMMA, PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_COMMA, PC9801_CTRL_NONE, }, // Less Than <
|
||||
{ PS2_KEY_COMMA, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_COMMA, PC9801_CTRL_NONE, }, // Comma ,
|
||||
{ PS2_KEY_BTICK, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_UNDERLINE, PC9801_CTRL_SHIFT, }, // Underline
|
||||
{ PS2_KEY_BTICK, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_AT, PC9801_CTRL_SHIFT, }, // Back Tick `
|
||||
// Control keys.
|
||||
{ PS2_KEY_TAB, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_TAB, PC9801_CTRL_NONE, }, // TAB
|
||||
{ PS2_KEY_BS, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_BS, PC9801_CTRL_NONE, }, // Backspace
|
||||
{ PS2_KEY_ESC, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_ESC, PC9801_CTRL_NONE, }, // ESCape
|
||||
{ PS2_KEY_INSERT, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_INS, PC9801_CTRL_NONE, }, // INSERT
|
||||
{ PS2_KEY_HOME, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_CLR, PC9801_CTRL_NONE, }, // CLR
|
||||
{ PS2_KEY_HOME, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_HOME, PC9801_CTRL_NONE, }, // HOME
|
||||
{ PS2_KEY_DELETE, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_DEL, PC9801_CTRL_NONE, }, // DELETE
|
||||
{ PS2_KEY_UP_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_UP_ARROW, PC9801_CTRL_NONE, }, // Up Arrow
|
||||
{ PS2_KEY_L_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_L_ARROW, PC9801_CTRL_NONE, }, // Left Arrow
|
||||
{ PS2_KEY_DN_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_DN_ARROW, PC9801_CTRL_NONE, }, // Down Arrow
|
||||
{ PS2_KEY_R_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_R_ARROW, PC9801_CTRL_NONE, }, // Right Arrow
|
||||
{ PS2_KEY_PGUP, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_ROLLUP, PC9801_CTRL_NONE, }, // Roll Up.
|
||||
{ PS2_KEY_PGDN, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_ROLLDN, PC9801_CTRL_NONE, }, // Roll Down
|
||||
{ PS2_KEY_SCROLL, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, ' ', PC9801_CTRL_NONE, }, // Not assigned.
|
||||
{ PS2_KEY_ENTER, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_RETURN, PC9801_CTRL_NONE, }, // Not assigned.
|
||||
{ PS2_KEY_CAPS, PS2CTRL_CAPS, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_CAPS, PC9801_CTRL_NONE, }, // CAPS
|
||||
{ PS2_KEY_END, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_UNDO, PC9801_CTRL_NONE, }, // UNDO
|
||||
// Keypad.
|
||||
{ PS2_KEY_KP0, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP0, PC9801_CTRL_NONE, }, // Keypad 0
|
||||
{ PS2_KEY_KP1, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP1, PC9801_CTRL_NONE, }, // Keypad 1
|
||||
{ PS2_KEY_KP2, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP2, PC9801_CTRL_NONE, }, // Keypad 2
|
||||
{ PS2_KEY_KP3, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP3, PC9801_CTRL_NONE, }, // Keypad 3
|
||||
{ PS2_KEY_KP4, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP4, PC9801_CTRL_NONE, }, // Keypad 4
|
||||
{ PS2_KEY_KP5, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP5, PC9801_CTRL_NONE, }, // Keypad 5
|
||||
{ PS2_KEY_KP6, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP6, PC9801_CTRL_NONE, }, // Keypad 6
|
||||
{ PS2_KEY_KP7, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP7, PC9801_CTRL_NONE, }, // Keypad 7
|
||||
{ PS2_KEY_KP8, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP8, PC9801_CTRL_NONE, }, // Keypad 8
|
||||
{ PS2_KEY_KP9, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP9, PC9801_CTRL_NONE, }, // Keypad 9
|
||||
{ PS2_KEY_KP_COMMA, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP_COMMA, PC9801_CTRL_NONE, }, // Keypad Comma ,
|
||||
{ PS2_KEY_KP_DOT, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP_DOT, PC9801_CTRL_NONE, }, // Keypad Full stop .
|
||||
{ PS2_KEY_KP_PLUS, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP_PLUS, PC9801_CTRL_NONE, }, // Keypad Plus +
|
||||
{ PS2_KEY_KP_MINUS, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP_MINUS, PC9801_CTRL_NONE, }, // Keypad Minus -
|
||||
{ PS2_KEY_KP_TIMES, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP_TIMES, PC9801_CTRL_NONE, }, // Keypad Times *
|
||||
{ PS2_KEY_KP_DIV, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP_DIV, PC9801_CTRL_NONE, }, // Keypad Divide /
|
||||
{ PS2_KEY_KP_EQUAL, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_MINUS, PC9801_CTRL_SHIFT, }, // Keypad Equal =
|
||||
{ PS2_KEY_KP_ENTER, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP_ENTER, PC9801_CTRL_NONE, }, // Keypad Ebter /
|
||||
{ PS2_KEY_KP_ENTER, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_KP_EQUAL, PC9801_CTRL_NONE, }, // Keypad Ebter /
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Machine PC-9801 Data PC-9801 Ctrl (Flags to Set).
|
||||
// Special keys.
|
||||
{ PS2_KEY_PRTSCR, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, 0x00, PC9801_CTRL_NONE, }, //
|
||||
{ PS2_KEY_PAUSE, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_BREAK, PC9801_CTRL_RELEASESHIFT, }, // BREAK KEY
|
||||
// { PS2_KEY_L_GUI, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_XF1, PC9801_CTRL_NONE, }, // XF1
|
||||
// { PS2_KEY_L_ALT, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_XF2, PC9801_CTRL_NONE, }, // XF2
|
||||
// { PS2_KEY_R_ALT, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_XF3, PC9801_CTRL_NONE, }, // XF3
|
||||
// { PS2_KEY_R_GUI, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_XF4, PC9801_CTRL_NONE, }, // XF4
|
||||
// { PS2_KEY_MENU, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_XF5, PC9801_CTRL_NONE, }, // XF5
|
||||
// Modifiers are last, only being selected if an earlier match isnt made.
|
||||
{ PS2_KEY_L_SHIFT, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_SHIFT, PC9801_CTRL_NONE, }, //
|
||||
{ PS2_KEY_R_SHIFT, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_SHIFT, PC9801_CTRL_NONE, }, //
|
||||
{ PS2_KEY_L_CTRL, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_CTRL, PC9801_CTRL_NONE, }, // Map to Control
|
||||
{ PS2_KEY_R_CTRL, PS2CTRL_FUNC, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_CTRL, PC9801_CTRL_NONE, }, // Map to Control
|
||||
{ 0, PS2CTRL_NONE, KEYMAP_STANDARD, PC9801_ALL, PC9801_KEY_NULL, PC9801_CTRL_NONE, }, //
|
||||
}};
|
||||
};
|
||||
|
||||
#endif // PC9801_H
|
||||
451
main/include/PS2KeyAdvanced.h
Normal file
451
main/include/PS2KeyAdvanced.h
Normal file
@@ -0,0 +1,451 @@
|
||||
/* Version V1.0.9
|
||||
PS2KeyAdvanced.h - PS2KeyAdvanced library
|
||||
Copyright (c) 2007 Free Software Foundation. All right reserved.
|
||||
Written by Paul Carpenter, PC Services <sales@pcserviceselectronics.co.uk>
|
||||
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
|
||||
<CTRL>+<ENTER> sends a special code to something else. If you wish to do that make a
|
||||
NEW library called SOMETHING different NOT a variant or revision of this one, as you
|
||||
are changing base functionality
|
||||
|
||||
See PS2KeyCode.h for codes from the keyboard this library uses to decode.
|
||||
(may disappear in updates do not rely on that file or definitions)
|
||||
|
||||
See this file for returned definitions of Keys
|
||||
|
||||
Note defines starting
|
||||
PS2_KC_* are internal defines for codes from the keyboard
|
||||
PS2_KEY_* are the codes this library returns
|
||||
PS2_* remaining defines for use in higher levels
|
||||
|
||||
To get the key as ASCII/UTF-8 single byte character conversion requires use
|
||||
of PS2KeyMap library AS WELL.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef PS2KeyAdvanced_h
|
||||
#define PS2KeyAdvanced_h
|
||||
|
||||
// Platform specific areas
|
||||
// Harvard architecture settings for PROGMEM
|
||||
// Add separate for EACH architecture as easier to maintain
|
||||
// AVR (includes Teensy 2.0)
|
||||
#if defined( ARDUINO_ARCH_AVR )
|
||||
#define PS2_SUPPORTED 1
|
||||
#define PS2_REQUIRES_PROGMEM 1
|
||||
#define PS2_CLEAR_PENDING_IRQ 1
|
||||
#endif
|
||||
// SAM (Due)
|
||||
#if defined( ARDUINO_ARCH_SAM )
|
||||
#define PS2_SUPPORTED 1
|
||||
#define PS2_CLEAR_PENDING_IRQ 1
|
||||
#endif
|
||||
// SAMD1
|
||||
#if defined( ARDUINO_ARCH_SAMD1 )
|
||||
#define PS2_SUPPORTED 1
|
||||
#define PS2_CLEAR_PENDING_IRQ 1
|
||||
#endif
|
||||
// STM32
|
||||
#if defined( ARDUINO_ARCH_STM32 )
|
||||
#define PS2_SUPPORTED 1
|
||||
#define PS2_CLEAR_PENDING_IRQ 1
|
||||
#endif
|
||||
// ESP32
|
||||
#if defined( ARDUINO_ARCH_ESP32 )
|
||||
#define PS2_SUPPORTED 1
|
||||
#define PS2_ONLY_CHANGE_IRQ 1
|
||||
#endif
|
||||
|
||||
// Invalid architecture
|
||||
#if !( defined( PS2_SUPPORTED ) )
|
||||
#warning Library is NOT supported on this board Use at your OWN risk
|
||||
#endif
|
||||
|
||||
/* Flags/bit masks for status bits in returned unsigned int value */
|
||||
#define PS2_BREAK 0x8000
|
||||
#define PS2_SHIFT 0x4000
|
||||
#define PS2_CTRL 0x2000
|
||||
#define PS2_CAPS 0x1000
|
||||
#define PS2_ALT 0x800
|
||||
#define PS2_ALT_GR 0x400
|
||||
#define PS2_GUI 0x200
|
||||
#define PS2_FUNCTION 0x100
|
||||
|
||||
/* General defines of communications codes */
|
||||
/* Command or response */
|
||||
#define PS2_KEY_RESEND 0xFE
|
||||
#define PS2_KEY_ACK 0xFA
|
||||
#define PS2_KEY_ECHO 0xEE
|
||||
/* Responses */
|
||||
#define PS2_KEY_BAT 0xAA
|
||||
// Actually buffer overrun
|
||||
#define PS2_KEY_OVERRUN 0xFF
|
||||
// Below is general error code
|
||||
#define PS2_KEY_ERROR 0xFC
|
||||
|
||||
/* Command parameters for functions */
|
||||
/* LED codes OR together */
|
||||
#define PS2_LOCK_SCROLL 0x01
|
||||
#define PS2_LOCK_NUM 0x02
|
||||
#define PS2_LOCK_CAPS 0x04
|
||||
/* Only useful for very few keyboards */
|
||||
#define PS2_LOCK_EXTRA 0x08
|
||||
|
||||
/* Returned keycode definitions */
|
||||
/* Do NOT change these codings as you will break base
|
||||
functionality use PS2KeyMap for that and internationalisation */
|
||||
#define PS2_KEY_NUM 0x01
|
||||
#define PS2_KEY_SCROLL 0x02
|
||||
#define PS2_KEY_CAPS 0x03
|
||||
#define PS2_KEY_PRTSCR 0x04
|
||||
#define PS2_KEY_PAUSE 0x05
|
||||
#define PS2_KEY_L_SHIFT 0x06
|
||||
#define PS2_KEY_R_SHIFT 0x07
|
||||
#define PS2_KEY_L_CTRL 0X08
|
||||
#define PS2_KEY_R_CTRL 0X09
|
||||
#define PS2_KEY_L_ALT 0x0A
|
||||
#define PS2_KEY_R_ALT 0x0B
|
||||
/* Sometimes called windows key */
|
||||
#define PS2_KEY_L_GUI 0x0C
|
||||
#define PS2_KEY_R_GUI 0x0D
|
||||
#define PS2_KEY_MENU 0x0E
|
||||
/* Break is CTRL + PAUSE generated inside keyboard */
|
||||
#define PS2_KEY_BREAK 0x0F
|
||||
/* Generated by some keyboards by ALT and PRTSCR */
|
||||
#define PS2_KEY_SYSRQ 0x10
|
||||
#define PS2_KEY_HOME 0x11
|
||||
#define PS2_KEY_END 0x12
|
||||
#define PS2_KEY_PGUP 0x13
|
||||
#define PS2_KEY_PGDN 0x14
|
||||
#define PS2_KEY_L_ARROW 0x15
|
||||
#define PS2_KEY_R_ARROW 0x16
|
||||
#define PS2_KEY_UP_ARROW 0x17
|
||||
#define PS2_KEY_DN_ARROW 0x18
|
||||
#define PS2_KEY_INSERT 0x19
|
||||
#define PS2_KEY_DELETE 0x1A
|
||||
#define PS2_KEY_ESC 0x1B
|
||||
#define PS2_KEY_BS 0x1C
|
||||
#define PS2_KEY_TAB 0x1D
|
||||
#define PS2_KEY_ENTER 0x1E
|
||||
#define PS2_KEY_SPACE 0x1F
|
||||
#define PS2_KEY_KP0 0x20
|
||||
#define PS2_KEY_KP1 0x21
|
||||
#define PS2_KEY_KP2 0x22
|
||||
#define PS2_KEY_KP3 0x23
|
||||
#define PS2_KEY_KP4 0x24
|
||||
#define PS2_KEY_KP5 0x25
|
||||
#define PS2_KEY_KP6 0x26
|
||||
#define PS2_KEY_KP7 0x27
|
||||
#define PS2_KEY_KP8 0x28
|
||||
#define PS2_KEY_KP9 0x29
|
||||
#define PS2_KEY_KP_DOT 0x2A
|
||||
#define PS2_KEY_KP_ENTER 0x2B
|
||||
#define PS2_KEY_KP_PLUS 0x2C
|
||||
#define PS2_KEY_KP_MINUS 0x2D
|
||||
#define PS2_KEY_KP_TIMES 0x2E
|
||||
#define PS2_KEY_KP_DIV 0x2F
|
||||
#define PS2_KEY_0 0X30
|
||||
#define PS2_KEY_1 0X31
|
||||
#define PS2_KEY_2 0X32
|
||||
#define PS2_KEY_3 0X33
|
||||
#define PS2_KEY_4 0X34
|
||||
#define PS2_KEY_5 0X35
|
||||
#define PS2_KEY_6 0X36
|
||||
#define PS2_KEY_7 0X37
|
||||
#define PS2_KEY_8 0X38
|
||||
#define PS2_KEY_9 0X39
|
||||
#define PS2_KEY_APOS 0X3A
|
||||
#define PS2_KEY_COMMA 0X3B
|
||||
#define PS2_KEY_MINUS 0X3C
|
||||
#define PS2_KEY_DOT 0X3D
|
||||
#define PS2_KEY_DIV 0X3E
|
||||
/* Some Numeric keyboards have an '=' on right keypad */
|
||||
#define PS2_KEY_KP_EQUAL 0x3F
|
||||
/* Single quote or back quote */
|
||||
#define PS2_KEY_SINGLE 0X40
|
||||
#define PS2_KEY_A 0X41
|
||||
#define PS2_KEY_B 0X42
|
||||
#define PS2_KEY_C 0X43
|
||||
#define PS2_KEY_D 0X44
|
||||
#define PS2_KEY_E 0X45
|
||||
#define PS2_KEY_F 0X46
|
||||
#define PS2_KEY_G 0X47
|
||||
#define PS2_KEY_H 0X48
|
||||
#define PS2_KEY_I 0X49
|
||||
#define PS2_KEY_J 0X4A
|
||||
#define PS2_KEY_K 0X4B
|
||||
#define PS2_KEY_L 0X4C
|
||||
#define PS2_KEY_M 0X4D
|
||||
#define PS2_KEY_N 0X4E
|
||||
#define PS2_KEY_O 0X4F
|
||||
#define PS2_KEY_P 0X50
|
||||
#define PS2_KEY_Q 0X51
|
||||
#define PS2_KEY_R 0X52
|
||||
#define PS2_KEY_S 0X53
|
||||
#define PS2_KEY_T 0X54
|
||||
#define PS2_KEY_U 0X55
|
||||
#define PS2_KEY_V 0X56
|
||||
#define PS2_KEY_W 0X57
|
||||
#define PS2_KEY_X 0X58
|
||||
#define PS2_KEY_Y 0X59
|
||||
#define PS2_KEY_Z 0X5A
|
||||
#define PS2_KEY_SEMI 0X5B
|
||||
#define PS2_KEY_BACK 0X5C
|
||||
#define PS2_KEY_OPEN_SQ 0X5D
|
||||
#define PS2_KEY_CLOSE_SQ 0X5E
|
||||
#define PS2_KEY_EQUAL 0X5F
|
||||
/* Some Numeric keypads have a comma key */
|
||||
#define PS2_KEY_KP_COMMA 0x60
|
||||
#define PS2_KEY_F1 0X61
|
||||
#define PS2_KEY_F2 0X62
|
||||
#define PS2_KEY_F3 0X63
|
||||
#define PS2_KEY_F4 0X64
|
||||
#define PS2_KEY_F5 0X65
|
||||
#define PS2_KEY_F6 0X66
|
||||
#define PS2_KEY_F7 0X67
|
||||
#define PS2_KEY_F8 0X68
|
||||
#define PS2_KEY_F9 0X69
|
||||
#define PS2_KEY_F10 0X6A
|
||||
#define PS2_KEY_F11 0X6B
|
||||
#define PS2_KEY_F12 0X6C
|
||||
#define PS2_KEY_F13 0X6D
|
||||
#define PS2_KEY_F14 0X6E
|
||||
#define PS2_KEY_F15 0X6F
|
||||
#define PS2_KEY_F16 0X70
|
||||
#define PS2_KEY_F17 0X71
|
||||
#define PS2_KEY_F18 0X72
|
||||
#define PS2_KEY_F19 0X73
|
||||
#define PS2_KEY_F20 0X74
|
||||
#define PS2_KEY_F21 0X75
|
||||
#define PS2_KEY_F22 0X76
|
||||
#define PS2_KEY_F23 0X77
|
||||
#define PS2_KEY_F24 0X78
|
||||
#define PS2_KEY_NEXT_TR 0X79
|
||||
#define PS2_KEY_PREV_TR 0X7A
|
||||
#define PS2_KEY_STOP 0X7B
|
||||
#define PS2_KEY_PLAY 0X7C
|
||||
#define PS2_KEY_MUTE 0X7D
|
||||
#define PS2_KEY_VOL_UP 0X7E
|
||||
#define PS2_KEY_VOL_DN 0X7F
|
||||
#define PS2_KEY_MEDIA 0X80
|
||||
#define PS2_KEY_EMAIL 0X81
|
||||
#define PS2_KEY_CALC 0X82
|
||||
#define PS2_KEY_COMPUTER 0X83
|
||||
#define PS2_KEY_WEB_SEARCH 0X84
|
||||
#define PS2_KEY_WEB_HOME 0X85
|
||||
#define PS2_KEY_WEB_BACK 0X86
|
||||
#define PS2_KEY_WEB_FORWARD 0X87
|
||||
#define PS2_KEY_WEB_STOP 0X88
|
||||
#define PS2_KEY_WEB_REFRESH 0X89
|
||||
#define PS2_KEY_WEB_FAVOR 0X8A
|
||||
#define PS2_KEY_EUROPE2 0X8B
|
||||
#define PS2_KEY_POWER 0X8C
|
||||
#define PS2_KEY_SLEEP 0X8D
|
||||
#define PS2_KEY_WAKE 0X90
|
||||
#define PS2_KEY_INTL1 0X91
|
||||
#define PS2_KEY_INTL2 0X92
|
||||
#define PS2_KEY_INTL3 0X93
|
||||
#define PS2_KEY_INTL4 0X94
|
||||
#define PS2_KEY_INTL5 0X95
|
||||
#define PS2_KEY_LANG1 0X96
|
||||
#define PS2_KEY_LANG2 0X97
|
||||
#define PS2_KEY_LANG3 0X98
|
||||
#define PS2_KEY_LANG4 0X99
|
||||
#define PS2_KEY_LANG5 0xA0
|
||||
#define PS2_KEY_BTICK 0X9A
|
||||
#define PS2_KEY_HASH 0X9B
|
||||
|
||||
/*
|
||||
Purpose: Provides advanced access to PS2 keyboards
|
||||
Public class definitions
|
||||
|
||||
See standard error codes for error code returns
|
||||
*/
|
||||
class PS2KeyAdvanced {
|
||||
public:
|
||||
/* This constructor does basically nothing. Please call the begin(int,int)
|
||||
method before using any other method of this class. */
|
||||
PS2KeyAdvanced( );
|
||||
|
||||
// Destructor - disable and detach interrupts and free up resources.
|
||||
~PS2KeyAdvanced( );
|
||||
|
||||
/* Starts the keyboard "service" by registering the external interrupt.
|
||||
setting the pin modes correctly and driving those needed to high.
|
||||
Sets default LOCK status (LEDs) to passed in value or default of all off
|
||||
The best place to call this method is in the setup routine. */
|
||||
void begin( uint8_t, uint8_t );
|
||||
|
||||
// Additional key available check which doesnt affect the queue.
|
||||
uint8_t keyAvailable(void);
|
||||
|
||||
/* Returns number of codes available or 0 for none */
|
||||
uint8_t available( );
|
||||
|
||||
/* Returns the key last read from the keyboard.
|
||||
If there is no key available, 0 is returned. */
|
||||
uint16_t read( );
|
||||
|
||||
/* Returns the current status of Locks
|
||||
Use Macro to mask out bits from
|
||||
PS2_LOCK_NUM PS2_LOCK_CAPS PS2_LOCK_SCROLL */
|
||||
uint8_t getLock( );
|
||||
|
||||
/* Sets the current status of Locks and LEDs
|
||||
Use macro defines added together from
|
||||
PS2_LOCK_NUM PS2_LOCK_CAPS PS2_LOCK_SCROLL */
|
||||
void setLock( 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 );
|
||||
|
||||
// Method to suspend PS2 activity, primarily by disabling the interrupts.
|
||||
void suspend(bool suspend);
|
||||
|
||||
/* 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
|
||||
393
main/include/PS2KeyTable.h
Normal file
393
main/include/PS2KeyTable.h
Normal file
@@ -0,0 +1,393 @@
|
||||
/* 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 <sales@pcserviceselectronics.co.uk>
|
||||
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
|
||||
*/
|
||||
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
|
||||
};
|
||||
|
||||
//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
|
||||
187
main/include/PS2Mouse.h
Normal file
187
main/include/PS2Mouse.h
Normal file
@@ -0,0 +1,187 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: PS2Mouse.h
|
||||
// Created: Jan 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Header file for the PS/2 Mouse Class.
|
||||
//
|
||||
// Credits:
|
||||
// Copyright: (c) 2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef MOUSE_H_
|
||||
#define MOUSE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <functional>
|
||||
#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"
|
||||
|
||||
// PS/2 Mouse Class.
|
||||
class PS2Mouse {
|
||||
|
||||
// mode status flags
|
||||
#define _PS2_BUSY 0x04
|
||||
#define _TX_MODE 0x02
|
||||
#define _WAIT_RESPONSE 0x01
|
||||
|
||||
// Constants.
|
||||
#define MAX_PS2_XMIT_KEY_BUF 16
|
||||
#define MAX_PS2_RCV_KEY_BUF 16
|
||||
#define INTELLI_MOUSE 3
|
||||
#define SCALING_1_TO_1 0xE6
|
||||
#define DEFAULT_MOUSE_TIMEOUT 100
|
||||
|
||||
public:
|
||||
// Public structures used for containment of mouse movement and control data. These are used by the insantiating
|
||||
// object to request and process mouse data.
|
||||
// Postional data - X/Y co-ordinates of mouse movement.
|
||||
typedef struct {
|
||||
int x, y;
|
||||
} Position;
|
||||
|
||||
// Mouse data, containing positional data, status, wheel data and validity.
|
||||
typedef struct {
|
||||
bool valid;
|
||||
bool overrun;
|
||||
int status;
|
||||
Position position;
|
||||
int wheel;
|
||||
} MouseData;
|
||||
|
||||
// Enumeration of all processed mouse responses.
|
||||
enum Responses {
|
||||
MOUSE_RESP_ACK = 0xFA,
|
||||
};
|
||||
|
||||
// Enumeration of all processed mouse commands.
|
||||
enum Commands {
|
||||
MOUSE_CMD_SET_SCALING_1_1 = 0xE6,
|
||||
MOUSE_CMD_SET_SCALING_2_1 = 0xE7,
|
||||
MOUSE_CMD_SET_RESOLUTION = 0xE8,
|
||||
MOUSE_CMD_GET_STATUS = 0xE9,
|
||||
MOUSE_CMD_SET_STREAM_MODE = 0xEA,
|
||||
MOUSE_CMD_REQUEST_DATA = 0xEB,
|
||||
MOUSE_CMD_SET_REMOTE_MODE = 0xF0,
|
||||
MOUSE_CMD_GET_DEVICE_ID = 0xF2,
|
||||
MOUSE_CMD_SET_SAMPLE_RATE = 0xF3,
|
||||
MOUSE_CMD_ENABLE_STREAMING = 0xF4,
|
||||
MOUSE_CMD_DISABLE_STREAMING = 0xF5,
|
||||
MOUSE_CMD_RESEND = 0xFE,
|
||||
MOUSE_CMD_RESET = 0xFF,
|
||||
};
|
||||
|
||||
// Resolution - the PS/2 mouse can digitize movement from 1mm to 1/8mm, the default being 1/4 (ie. 1mm = 4 counts). This allows configuration for a finer or rougher
|
||||
// tracking digitisation.
|
||||
enum PS2_RESOLUTION {
|
||||
PS2_MOUSE_RESOLUTION_1_1 = 0x00,
|
||||
PS2_MOUSE_RESOLUTION_1_2 = 0x01,
|
||||
PS2_MOUSE_RESOLUTION_1_4 = 0x02,
|
||||
PS2_MOUSE_RESOLUTION_1_8 = 0x03,
|
||||
};
|
||||
|
||||
// Scaling - the PS/2 mouse can provide linear (1:1 no scaling) or non liner (2:1 scaling) adaptation of the digitised data. This allows configuration for amplification of movements.
|
||||
enum PS2_SCALING {
|
||||
PS2_MOUSE_SCALING_1_1 = 0x00,
|
||||
PS2_MOUSE_SCALING_2_1 = 0x01,
|
||||
};
|
||||
|
||||
// Sampling rate - the PS/2 mouse, in streaming mode, the mouse sends with movement updates. This allows for finer or rougher digitisation of movements. The default is 100 samples per
|
||||
// second and the X68000 is fixed at 100 samples per second. Adjusting the ps/2 sample rate will affect tracking granularity on the X68000.
|
||||
enum PS2_SAMPLING {
|
||||
PS2_MOUSE_SAMPLE_RATE_10 = 10,
|
||||
PS2_MOUSE_SAMPLE_RATE_20 = 20,
|
||||
PS2_MOUSE_SAMPLE_RATE_40 = 40,
|
||||
PS2_MOUSE_SAMPLE_RATE_60 = 60,
|
||||
PS2_MOUSE_SAMPLE_RATE_80 = 80,
|
||||
PS2_MOUSE_SAMPLE_RATE_100 = 100,
|
||||
PS2_MOUSE_SAMPLE_RATE_200 = 200,
|
||||
};
|
||||
|
||||
// Public accessible prototypes.
|
||||
PS2Mouse(int clockPin, int dataPin);
|
||||
~PS2Mouse();
|
||||
void writeByte(uint8_t);
|
||||
bool setResolution(enum PS2_RESOLUTION resolution);
|
||||
bool setStreamMode(void);
|
||||
bool setRemoteMode(void);
|
||||
bool setScaling(enum PS2_SCALING scaling);
|
||||
char getDeviceId(void);
|
||||
bool checkIntelliMouseExtensions(void);
|
||||
bool setSampleRate(enum PS2_SAMPLING rate);
|
||||
bool enableStreaming(void);
|
||||
bool disableStreaming(void);
|
||||
bool getStatus(uint8_t *respBuf);
|
||||
bool reset(void);
|
||||
MouseData readData(void);
|
||||
void initialize(void);
|
||||
|
||||
// Method to register an object method for callback with context.
|
||||
template<typename A, typename B>
|
||||
void setMouseDataCallback(A func_ptr, B obj_ptr)
|
||||
{
|
||||
ps2Ctrl.mouseDataCallback = bind(func_ptr, obj_ptr, 0, std::placeholders::_1);
|
||||
}
|
||||
|
||||
private:
|
||||
// PS/2 Control structure - maintains all data and variables relevant to forming a connection with a PS/2 mouse, interaction and processing of its data.
|
||||
struct {
|
||||
int clkPin; // Hardware clock pin - bidirectional.
|
||||
int dataPin; // Hardware data pin - bidirectional.
|
||||
volatile uint8_t mode; // mode contains _PS2_BUSY bit 2 = busy until all expected bytes RX/TX
|
||||
// _TX_MODE bit 1 = direction 1 = TX, 0 = RX (default)
|
||||
// _WAIT_RESPONSE bit 0 = expecting data response
|
||||
bool supportsIntelliMouseExtensions; // Intellimouse extensions supported.
|
||||
bool streamingEnabled; // Streaming mode has been enabled.
|
||||
volatile uint8_t bitCount; // Main state variable and bit count for interrupts
|
||||
volatile uint8_t shiftReg; // Incoming/Outgoing data shift register.
|
||||
volatile uint8_t parity; // Parity flag for data being sent/received.
|
||||
uint16_t rxBuf[16]; // RX buffer - assembled bytes are stored in this buffer awaiting processing.
|
||||
int rxPos; // Position in buffer to store next byte.
|
||||
|
||||
// Callback for streaming processed mouse data to HID handler.
|
||||
std::function<void(PS2Mouse::MouseData)> mouseDataCallback;
|
||||
} ps2Ctrl;
|
||||
|
||||
// Structure to store incoming streamed mouse data along with validity flags.
|
||||
struct {
|
||||
MouseData mouseData;
|
||||
bool newData; // An update has occurred since the last query.
|
||||
bool overrun; // A data overrun has occurred since the last query.
|
||||
} streaming;
|
||||
|
||||
// Interrupt handler - needs to be declared static and assigned to internal RAM (within the ESP32) to function correctly.
|
||||
IRAM_ATTR static void ps2interrupt( void );
|
||||
|
||||
// Prototypes.
|
||||
bool requestData(uint8_t expectedBytes, uint8_t *respBuf, uint32_t timeout);
|
||||
bool sendCmd(uint8_t cmd, uint8_t expectedBytes, uint8_t *respBuf, uint32_t timeout);
|
||||
|
||||
};
|
||||
|
||||
#endif // MOUSE_H_
|
||||
232
main/include/SWITCH.h
Normal file
232
main/include/SWITCH.h
Normal file
@@ -0,0 +1,232 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: SWITCH.h
|
||||
// Created: May 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Class definition to encapsulate the SharpKey WiFi/Config Switch.
|
||||
//
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: May 2022 - Initial write.
|
||||
// v1.00 Jun 2022 - Updates to add additional callbacks for RESET and CLEARNVS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SWITCH_H
|
||||
#define SWITCH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "driver/timer.h"
|
||||
#include "LED.h"
|
||||
|
||||
|
||||
// NB: Macros definitions put inside class for clarity, they are still global scope.
|
||||
|
||||
// Switch class.
|
||||
class SWITCH {
|
||||
|
||||
// Macros.
|
||||
//
|
||||
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
// Constants.
|
||||
#define SWITCH_VERSION 1.00
|
||||
|
||||
public:
|
||||
|
||||
// Prototypes.
|
||||
SWITCH(LED *led);
|
||||
SWITCH(void);
|
||||
virtual ~SWITCH(void);
|
||||
|
||||
// Method to register an object method for callback with context.
|
||||
template<typename A, typename B>
|
||||
void setCancelEventCallback(A func_ptr, B obj_ptr)
|
||||
{
|
||||
swCtrl.cancelEventCallback = std::bind(func_ptr, obj_ptr);
|
||||
}
|
||||
template<typename A>
|
||||
void setCancelEventCallback(A func_ptr)
|
||||
{
|
||||
swCtrl.cancelEventCallback = std::bind(func_ptr);
|
||||
}
|
||||
// Wifi enable (configured mode).
|
||||
template<typename A, typename B>
|
||||
void setWifiEnEventCallback(A func_ptr, B obj_ptr)
|
||||
{
|
||||
swCtrl.wifiEnEventCallback = std::bind(func_ptr, obj_ptr);
|
||||
}
|
||||
template<typename A>
|
||||
void setWifiEnEventCallback(A func_ptr)
|
||||
{
|
||||
swCtrl.wifiEnEventCallback = std::bind(func_ptr);
|
||||
}
|
||||
// Wifi default mode enable.
|
||||
template<typename A, typename B>
|
||||
void setWifiDefEventCallback(A func_ptr, B obj_ptr)
|
||||
{
|
||||
swCtrl.wifiDefEventCallback = std::bind(func_ptr, obj_ptr);
|
||||
}
|
||||
template<typename A>
|
||||
void setWifiDefEventCallback(A func_ptr)
|
||||
{
|
||||
swCtrl.wifiDefEventCallback = std::bind(func_ptr);
|
||||
}
|
||||
// Bluetooth start pairing event.
|
||||
template<typename A, typename B>
|
||||
void setBTPairingEventCallback(A func_ptr, B obj_ptr)
|
||||
{
|
||||
swCtrl.btPairingEventCallback = std::bind(func_ptr, obj_ptr);
|
||||
}
|
||||
template<typename A>
|
||||
void setBTPairingEventCallback(A func_ptr)
|
||||
{
|
||||
swCtrl.btPairingEventCallback = std::bind(func_ptr);
|
||||
}
|
||||
// RESET event - callback is executed prior to issuing an esp_restart().
|
||||
template<typename A, typename B>
|
||||
void setResetEventCallback(A func_ptr, B obj_ptr)
|
||||
{
|
||||
swCtrl.resetEventCallback = std::bind(func_ptr, obj_ptr);
|
||||
}
|
||||
template<typename A>
|
||||
void setResetEventCallback(A func_ptr)
|
||||
{
|
||||
swCtrl.resetEventCallback = std::bind(func_ptr);
|
||||
}
|
||||
// CLEARNVS event - callback when user requests all NVS settings are erased.
|
||||
template<typename A, typename B>
|
||||
void setClearNVSEventCallback(A func_ptr, B obj_ptr)
|
||||
{
|
||||
swCtrl.clearNVSEventCallback = std::bind(func_ptr, obj_ptr);
|
||||
}
|
||||
template<typename A>
|
||||
void setClearNVSEventCallback(A func_ptr)
|
||||
{
|
||||
swCtrl.clearNVSEventCallback = std::bind(func_ptr);
|
||||
}
|
||||
|
||||
// Helper method to identify the sub class, this is used in non volatile key management.
|
||||
// Warning: This method wont work if optimisation for size is enabled on the compiler.
|
||||
const char *getClassName(const std::string& prettyFunction)
|
||||
{
|
||||
// First find the CLASS :: METHOD seperation.
|
||||
size_t colons = prettyFunction.find("::");
|
||||
|
||||
// None, then this is not a class.
|
||||
if (colons == std::string::npos)
|
||||
return "::";
|
||||
|
||||
// Split out the class name.
|
||||
size_t begin = prettyFunction.substr(0,colons).rfind(" ") + 1;
|
||||
size_t end = colons - begin;
|
||||
|
||||
// Return the name.
|
||||
return(prettyFunction.substr(begin,end).c_str());
|
||||
}
|
||||
|
||||
// Helper method to change a file extension.
|
||||
void replaceExt(std::string& fileName, const std::string& newExt)
|
||||
{
|
||||
// Locals.
|
||||
std::string::size_type extPos = fileName.rfind('.', fileName.length());
|
||||
|
||||
if(extPos != std::string::npos)
|
||||
{
|
||||
fileName.replace(extPos+1, newExt.length(), newExt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Template to aid in conversion of an enum to integer.
|
||||
template <typename E> constexpr typename std::underlying_type<E>::type to_underlying(E e) noexcept
|
||||
{
|
||||
return static_cast<typename std::underlying_type<E>::type>(e);
|
||||
}
|
||||
|
||||
// Method to return the class version number.
|
||||
virtual float version(void)
|
||||
{
|
||||
return(SWITCH_VERSION);
|
||||
}
|
||||
|
||||
// Method to return the name of the class.
|
||||
virtual std::string ifName(void)
|
||||
{
|
||||
return(swCtrl.swClassName);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
// Prototypes.
|
||||
void init(void);
|
||||
IRAM_ATTR static void swInterface( void * pvParameters );
|
||||
inline uint32_t milliSeconds(void)
|
||||
{
|
||||
return( (uint32_t) clock() );
|
||||
}
|
||||
|
||||
// Structure to maintain an active setting for the LED. The LED control thread uses these values to effect the required lighting of the LED.
|
||||
typedef struct {
|
||||
// Name of the class for this instantiation.
|
||||
std::string swClassName;
|
||||
|
||||
// Thread handles - Switch interface.
|
||||
TaskHandle_t TaskSWIF = NULL;
|
||||
|
||||
// Callback for Cancel Event.
|
||||
std::function<void(void)> cancelEventCallback;
|
||||
|
||||
// Callback for WiFi Enable Event.
|
||||
std::function<void(void)> wifiEnEventCallback;
|
||||
|
||||
// Callback for WiFi Default Event.
|
||||
std::function<void(void)> wifiDefEventCallback;
|
||||
|
||||
// Callback for Bluetooth Pairing Event.
|
||||
std::function<void(void)> btPairingEventCallback;
|
||||
|
||||
// Callback is executed prior to issuing an esp_restart().
|
||||
std::function<bool(void)> resetEventCallback;
|
||||
|
||||
// Callback when user requests all NVS settings are erased.
|
||||
std::function<void(void)> clearNVSEventCallback;
|
||||
} t_swControl;
|
||||
|
||||
// Var to store all SWITCH control variables.
|
||||
t_swControl swCtrl;
|
||||
|
||||
// LED activity object handle.
|
||||
LED *led;
|
||||
};
|
||||
#endif // SWITCH_H
|
||||
400
main/include/WiFi.h
Normal file
400
main/include/WiFi.h
Normal file
@@ -0,0 +1,400 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: WiFi.h
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Header for the WiFi AP/Client logic.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// v1.01 May 2022 - Initial release version.
|
||||
// v1.02 Jun 2022 - Seperated out the WiFi Enable switch and made the WiFi module active/
|
||||
// via a reboot process. This is necessary now that Bluetooth is inbuilt
|
||||
// as the ESP32 shares an antenna and both operating together electrically
|
||||
// is difficult but also the IDF stack conflicts as well.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef WIFI_H
|
||||
#define WIFI_H
|
||||
|
||||
#if defined(CONFIG_IF_WIFI_ENABLED)
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sys.h"
|
||||
#include <esp_http_server.h>
|
||||
#include "esp_littlefs.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <arpa/inet.h>
|
||||
#include "NVS.h"
|
||||
#include "LED.h"
|
||||
#include "HID.h"
|
||||
|
||||
// Include the specification class.
|
||||
#include "KeyInterface.h"
|
||||
|
||||
// Encapsulate the WiFi functionality.
|
||||
class WiFi {
|
||||
// Constants.
|
||||
#define WIFI_VERSION 1.02
|
||||
#define OBJECT_VERSION_LIST_MAX 18
|
||||
#define FILEPACK_VERSION_FILE "version.txt"
|
||||
#define WIFI_AP_DEFAULT_IP "192.168.4.1"
|
||||
#define WIFI_AP_DEFAULT_GW "192.168.4.1"
|
||||
#define WIFI_AP_DEFAULT_NETMASK "255.255.255.0"
|
||||
|
||||
// The event group allows multiple bits for each event, but we only care about two events:
|
||||
// - we are connected to the AP with an IP
|
||||
// - we failed to connect after the maximum amount of retries
|
||||
#define WIFI_CONNECTED_BIT BIT0
|
||||
#define WIFI_FAIL_BIT BIT1
|
||||
|
||||
// Tag for ESP WiFi logging.
|
||||
#define WIFITAG "WiFi"
|
||||
|
||||
// Menu selection types.
|
||||
enum WIFIMODES {
|
||||
WIFI_OFF = 0x00, // WiFi is disabled.
|
||||
WIFI_ON = 0x01, // WiFi is enabled.
|
||||
WIFI_CONFIG_AP = 0x02, // WiFi is set to enable Access Point to configure WiFi settings.
|
||||
WIFI_CONFIG_CLIENT = 0x03 // WiFi is set to enable Client mode using persisted settings.
|
||||
};
|
||||
|
||||
// Default WiFi parameters.
|
||||
#define MAX_WIFI_SSID_LEN 31
|
||||
#define MAX_WIFI_PWD_LEN 63
|
||||
#define MAX_WIFI_IP_LEN 15
|
||||
#define MAX_WIFI_NETMASK_LEN 15
|
||||
#define MAX_WIFI_GATEWAY_LEN 15
|
||||
|
||||
// Buffer size for sending file data in chunks to the browser.
|
||||
#define MAX_CHUNK_SIZE 4096
|
||||
|
||||
// Max length a file path can have on the embedded storage device.
|
||||
#define FILE_PATH_MAX (15 + CONFIG_LITTLEFS_OBJ_NAME_LEN)
|
||||
|
||||
public:
|
||||
// Types for holding and maintaining a class/object to version number array.
|
||||
typedef struct {
|
||||
std::string object;
|
||||
float version;
|
||||
} t_versionItem;
|
||||
typedef struct {
|
||||
int elements;
|
||||
t_versionItem *item[OBJECT_VERSION_LIST_MAX];
|
||||
} t_versionList;
|
||||
|
||||
// Prototypes.
|
||||
WiFi(KeyInterface *hdlKeyIf, KeyInterface *hdlMouseIf, bool defaultMode, NVS *nvs, LED *led, const char *fsPath, t_versionList *versionList);
|
||||
WiFi(void);
|
||||
~WiFi(void);
|
||||
void run(void);
|
||||
|
||||
// Primary encapsulated interface object handle.
|
||||
KeyInterface *keyIf;
|
||||
|
||||
// Secondary encapsulated interface object handle.
|
||||
KeyInterface *mouseIf;
|
||||
|
||||
// Non Volatile Storage handle.
|
||||
NVS *nvs;
|
||||
|
||||
// LED activity handle.
|
||||
LED *led;
|
||||
|
||||
// Method to return the class version number.
|
||||
float version(void)
|
||||
{
|
||||
return(WIFI_VERSION);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
// Type for key:value pairs.
|
||||
typedef struct {
|
||||
std::string name;
|
||||
std::string value;
|
||||
} t_kvPair;
|
||||
|
||||
// Structure to maintain wifi configuration data. This data is persisted through powercycles as needed.
|
||||
typedef struct {
|
||||
// Client access parameters, these, when valid, are used for binding to a known wifi access point.
|
||||
struct {
|
||||
bool valid;
|
||||
char ssid[MAX_WIFI_SSID_LEN+1];
|
||||
char pwd[MAX_WIFI_PWD_LEN+1];
|
||||
bool useDHCP;
|
||||
char ip[MAX_WIFI_IP_LEN+1];
|
||||
char netmask[MAX_WIFI_NETMASK_LEN+1];
|
||||
char gateway[MAX_WIFI_GATEWAY_LEN+1];
|
||||
} clientParams;
|
||||
|
||||
// Structure to maintain Access Point parameters. These are configurable to allow possibility of changing them.
|
||||
struct {
|
||||
char ssid[MAX_WIFI_SSID_LEN+1];
|
||||
char pwd[MAX_WIFI_PWD_LEN+1];
|
||||
char ip[MAX_WIFI_IP_LEN+1];
|
||||
char netmask[MAX_WIFI_NETMASK_LEN+1];
|
||||
char gateway[MAX_WIFI_GATEWAY_LEN+1];
|
||||
} apParams;
|
||||
|
||||
// General runtime control parameters.
|
||||
struct {
|
||||
// Configured mode of the Wifi: Access Point or Client.
|
||||
enum WIFIMODES wifiMode;
|
||||
} params;
|
||||
} t_wifiConfig;
|
||||
|
||||
// Configuration data.
|
||||
t_wifiConfig wifiConfig;
|
||||
|
||||
// Structure to manage the WiFi control variables, signifying the state of the Client or Access Point, runtime dependent, and
|
||||
// necessary dedicated run variables (as opposed to locals).
|
||||
typedef struct {
|
||||
// Client mode variables, active when in client mode.
|
||||
struct {
|
||||
int clientRetryCnt;
|
||||
bool connected;
|
||||
char ssid[MAX_WIFI_SSID_LEN+1];
|
||||
char pwd[MAX_WIFI_PWD_LEN+1];
|
||||
char ip[MAX_WIFI_IP_LEN+1];
|
||||
char netmask[MAX_WIFI_NETMASK_LEN+1];
|
||||
char gateway[MAX_WIFI_GATEWAY_LEN+1];
|
||||
} client;
|
||||
|
||||
// Access Point mode variabls, active when in AP mode.
|
||||
struct {
|
||||
char ssid[MAX_WIFI_SSID_LEN+1];
|
||||
char pwd[MAX_WIFI_PWD_LEN+1];
|
||||
char ip[MAX_WIFI_IP_LEN+1];
|
||||
char netmask[MAX_WIFI_NETMASK_LEN+1];
|
||||
char gateway[MAX_WIFI_GATEWAY_LEN+1];
|
||||
} ap;
|
||||
|
||||
// HTTP session variables, parsed out of incoming connections. The sessions are synchronous so only maintain
|
||||
// one copy.
|
||||
struct {
|
||||
std::string host;
|
||||
std::string queryStr;
|
||||
std::string fileName;
|
||||
std::string filePath;
|
||||
bool gzip;
|
||||
bool deflate;
|
||||
} session;
|
||||
|
||||
// Runtime variables, used for global control of the WiFi module.
|
||||
//
|
||||
struct {
|
||||
// Default path on the underlying filesystem. This is where the NVS/SD partition is mounted and all files under this directory are accessible.
|
||||
const char * fsPath;
|
||||
|
||||
// Version list of all objects used to build the SharpKey interface along with their version numbers.
|
||||
t_versionList *versionList;
|
||||
|
||||
// Run mode of the Wifi: Off, On or Access Point.
|
||||
enum WIFIMODES wifiMode;
|
||||
|
||||
// Handle to http server.
|
||||
httpd_handle_t server;
|
||||
|
||||
// Class name, used for NVS keys.
|
||||
std::string thisClass;
|
||||
|
||||
// Flag to raise a reboot button on the displayed page.
|
||||
bool rebootButton;
|
||||
|
||||
// Flag to indicate a hard reboot needed.
|
||||
bool reboot;
|
||||
|
||||
// Base path of file storag.
|
||||
char basePath[FILE_PATH_MAX];
|
||||
|
||||
// String to hold any response error message.
|
||||
std::string errorMsg;
|
||||
} run;
|
||||
} t_wifiControl;
|
||||
|
||||
// Control data.
|
||||
t_wifiControl wifiCtrl;
|
||||
|
||||
// Prototypes.
|
||||
bool setupWifiClient(void);
|
||||
bool setupWifiAP(void);
|
||||
bool stopWifi(void);
|
||||
bool startWebserver(void);
|
||||
void stopWebserver(void);
|
||||
float getVersionNumber(std::string name);
|
||||
esp_err_t expandAndSendFile(httpd_req_t *req, const char *basePath, std::string fileName);
|
||||
esp_err_t expandVarsAndSend(httpd_req_t *req, std::string str);
|
||||
esp_err_t sendKeyMapHeaders(httpd_req_t *req);
|
||||
esp_err_t sendKeyMapTypes(httpd_req_t *req);
|
||||
esp_err_t sendKeyMapCustomTypeFields(httpd_req_t *req);
|
||||
esp_err_t sendKeyMapData(httpd_req_t *req);
|
||||
esp_err_t sendKeyMapPopovers(httpd_req_t *req);
|
||||
esp_err_t sendMouseRadioChoice(httpd_req_t *req, const char *option);
|
||||
|
||||
|
||||
|
||||
esp_err_t wifiDataPOSTHandler(httpd_req_t *req, std::vector<t_kvPair> pairs, std::string& resp);
|
||||
esp_err_t mouseDataPOSTHandler(httpd_req_t *req, std::vector<t_kvPair> pairs, std::string& resp);
|
||||
static esp_err_t defaultDataPOSTHandler(httpd_req_t *req);
|
||||
static esp_err_t defaultDataGETHandler(httpd_req_t *req);
|
||||
IRAM_ATTR static esp_err_t otaFirmwareUpdatePOSTHandler(httpd_req_t *req);
|
||||
IRAM_ATTR static esp_err_t otaFilepackUpdatePOSTHandler(httpd_req_t *req);
|
||||
static esp_err_t keymapUploadPOSTHandler(httpd_req_t *req);
|
||||
static esp_err_t keymapTablePOSTHandler(httpd_req_t *req);
|
||||
|
||||
static esp_err_t defaultRebootHandler(httpd_req_t *req);
|
||||
esp_err_t getPOSTData(httpd_req_t *req, std::vector<t_kvPair> *pairs);
|
||||
|
||||
bool isFileExt(std::string fileName, std::string extension);
|
||||
esp_err_t setContentTypeFromFileType(httpd_req_t *req, std::string fileName);
|
||||
esp_err_t getPathFromURI(std::string& destPath, std::string& destFile, const char *basePath, const char *uri);
|
||||
esp_err_t getPathFromURI(std::string& destPath, const char *basePath, const char *uri);
|
||||
static esp_err_t defaultFileHandler(httpd_req_t *req);
|
||||
std::string esp32PartitionType(esp_partition_type_t type);
|
||||
std::string esp32PartitionSubType(esp_partition_subtype_t subtype);
|
||||
|
||||
|
||||
IRAM_ATTR static void pairBluetoothDevice(void *pvParameters);
|
||||
IRAM_ATTR static void wifiAPHandler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
||||
IRAM_ATTR static void wifiClientHandler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
||||
|
||||
// Method to split a string based on a delimiter and store in a vector.
|
||||
std::vector<std::string> split(std::string s, std::string delimiter)
|
||||
{
|
||||
// Locals.
|
||||
size_t pos_start = 0;
|
||||
size_t pos_end;
|
||||
size_t delim_len = delimiter.length();
|
||||
std::string token;
|
||||
std::vector<std::string> res;
|
||||
|
||||
// Loop through the string locating delimiters and split on each occurrence.
|
||||
while((pos_end = s.find (delimiter, pos_start)) != std::string::npos)
|
||||
{
|
||||
token = s.substr (pos_start, pos_end - pos_start);
|
||||
pos_start = pos_end + delim_len;
|
||||
// Push each occurrence onto Vector.
|
||||
res.push_back (token);
|
||||
}
|
||||
|
||||
// Store last item in vector.
|
||||
res.push_back (s.substr (pos_start));
|
||||
return res;
|
||||
}
|
||||
|
||||
// check if a given string is a numeric string or not
|
||||
bool isNumber(const std::string &str)
|
||||
{
|
||||
// `std::find_first_not_of` searches the string for the first character
|
||||
// that does not match any of the characters specified in its arguments
|
||||
return !str.empty() &&
|
||||
(str.find_first_not_of("[0123456789]") == std::string::npos);
|
||||
}
|
||||
|
||||
// Function to split string `str` using a given delimiter
|
||||
std::vector<std::string> split(const std::string &str, char delim)
|
||||
{
|
||||
auto i = 0;
|
||||
std::vector<std::string> list;
|
||||
|
||||
auto pos = str.find(delim);
|
||||
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
list.push_back(str.substr(i, pos - i));
|
||||
i = ++pos;
|
||||
pos = str.find(delim, pos);
|
||||
}
|
||||
|
||||
list.push_back(str.substr(i, str.length()));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
// Function to validate an IP address
|
||||
bool validateIP(std::string ip)
|
||||
{
|
||||
// split the string into tokens
|
||||
std::vector<std::string> list = split(ip, '.');
|
||||
|
||||
// if the token size is not equal to four
|
||||
if (list.size() != 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate each token
|
||||
for (std::string str: list)
|
||||
{
|
||||
// verify that the string is a number or not, and the numbers
|
||||
// are in the valid range
|
||||
if (!isNumber(str) || std::stoi(str) > 255 || std::stoi(str) < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Method to split an IP4 address into its components, checking each for validity.
|
||||
bool splitIP(std::string ip, int *a, int *b, int *c, int *d)
|
||||
{
|
||||
// Init.
|
||||
*a = *b = *c = *d = 0;
|
||||
|
||||
// split the string into tokens
|
||||
std::vector<std::string> list = split(ip, '.');
|
||||
|
||||
// if the token size is not equal to four
|
||||
if (list.size() != 4) {
|
||||
printf("Size:%d\n", list.size());
|
||||
return false;
|
||||
}
|
||||
// Loop through vector and check each number for validity before assigning.
|
||||
for(int idx=0; idx < 4; idx++)
|
||||
{
|
||||
// verify that the string is a number or not, and the numbers
|
||||
// are in the valid range
|
||||
if (!isNumber(list.at(idx)) || std::stoi(list.at(idx)) > 255 || std::stoi(list.at(idx)) < 0) {
|
||||
printf("Item:%d, %s\n", idx, list.at(idx).c_str());
|
||||
return false;
|
||||
}
|
||||
int frag = std::stoi(list.at(idx));
|
||||
if(idx == 0) *a = frag;
|
||||
if(idx == 1) *b = frag;
|
||||
if(idx == 2) *c = frag;
|
||||
if(idx == 3) *d = frag;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // WIFI_H
|
||||
687
main/include/X1.h
Normal file
687
main/include/X1.h
Normal file
@@ -0,0 +1,687 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: X1.h
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Header for the Sharp X1 to PS/2 interface logic.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// v1.01 May 2022 - Initial release version.
|
||||
// v1.02 Jun 2022 - Updates to reflect changes realised in other modules due to addition of
|
||||
// bluetooth and suspend logic due to NVS issues using both cores.
|
||||
// v1.03 Jun 2022 - Further updates adding in keymaps for UK BT and Japan OADG109.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef X1_H
|
||||
#define X1_H
|
||||
|
||||
// Include the specification class.
|
||||
#include "KeyInterface.h"
|
||||
#include "NVS.h"
|
||||
#include "LED.h"
|
||||
#include "HID.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
// NB: Macros definitions put inside class for clarity, they are still global scope.
|
||||
|
||||
// Encapsulate the Sharp X1 interface.
|
||||
class X1 : public KeyInterface {
|
||||
// Macros.
|
||||
//
|
||||
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
// Constants.
|
||||
#define X1IF_VERSION 1.03
|
||||
#define X1IF_KEYMAP_FILE "X1_KeyMap.BIN"
|
||||
#define MAX_X1_XMIT_KEY_BUF 16
|
||||
#define PS2TBL_X1_MAXROWS 349
|
||||
|
||||
// X1 Key control bit mask.
|
||||
#define X1_CTRL_TENKEY ((unsigned char) (1 << 7))
|
||||
#define X1_CTRL_PRESS ((unsigned char) (1 << 6))
|
||||
#define X1_CTRL_REPEAT ((unsigned char) (1 << 5))
|
||||
#define X1_CTRL_GRAPH ((unsigned char) (1 << 4))
|
||||
#define X1_CTRL_CAPS ((unsigned char) (1 << 3))
|
||||
#define X1_CTRL_KANA ((unsigned char) (1 << 2))
|
||||
#define X1_CTRL_SHIFT ((unsigned char) (1 << 1))
|
||||
#define X1_CTRL_CTRL ((unsigned char) (1 << 0))
|
||||
|
||||
// X1 Special Key definitions.
|
||||
#define X1KEY_UP 0x1E // ↑
|
||||
#define X1KEY_DOWN 0x1F // ↓
|
||||
#define X1KEY_LEFT 0x1D // ←
|
||||
#define X1KEY_RIGHT 0x1C // → →
|
||||
#define X1KEY_INS 0x12 // INS
|
||||
#define X1KEY_DEL 0x08 // DEL
|
||||
#define X1KEY_CLR 0x0C // CLR
|
||||
#define X1KEY_HOME 0x0B // HOME
|
||||
|
||||
// PS2 Flag definitions.
|
||||
#define PS2CTRL_NONE 0x00 // No keys active = 0
|
||||
#define PS2CTRL_SHIFT 0x01 // Shfit Key active = 1
|
||||
#define PS2CTRL_CTRL 0x02 // Ctrl Key active = 1
|
||||
#define PS2CTRL_CAPS 0x04 // CAPS active = 1
|
||||
#define PS2CTRL_KANA 0x08 // KANA active = 1
|
||||
#define PS2CTRL_GRAPH 0x10 // GRAPH active = 1
|
||||
#define PS2CTRL_GUI 0x20 // GUI Key active = 1
|
||||
#define PS2CTRL_FUNC 0x40 // Special Function Keys active = 1
|
||||
#define PS2CTRL_BREAK 0x80 // BREAK Key active = 1
|
||||
#define PS2CTRL_EXACT 0x80 // EXACT Match active = 1
|
||||
|
||||
// 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 extract the X1 key code and control data.
|
||||
// ie. PS/2 Scan Code -> ASCII + Flags -> X1 Key Code + Ctrl Data
|
||||
|
||||
// Keyboard mapping table column names.
|
||||
#define PS2TBL_PS2KEYCODE_NAME "PS/2 KeyCode"
|
||||
#define PS2TBL_PS2CTRL_NAME "PS/2 Control Key"
|
||||
#define PS2TBL_KEYBOARDMODEL_NAME "For Keyboard"
|
||||
#define PS2TBL_MACHINE_NAME "For Host Model"
|
||||
#define PS2TBL_X1MODE_NAME "X1 Mode"
|
||||
#define PS2TBL_X1KEYCODE_NAME "X1 KeyCode 1"
|
||||
#define PS2TBL_X1KEYCODE_BYTE2_NAME "X1 KeyCode 2"
|
||||
#define PS2TBL_X1_CTRL_NAME "X1 Control Key"
|
||||
|
||||
// Keyboard mapping table column types.
|
||||
#define PS2TBL_PS2KEYCODE_TYPE "hex"
|
||||
#define PS2TBL_PS2CTRL_TYPE "custom_cbp_ps2ctrl"
|
||||
#define PS2TBL_KEYBOARDMODEL_TYPE "custom_cbp_keybmodel"
|
||||
#define PS2TBL_MACHINE_TYPE "custom_cbp_machine"
|
||||
#define PS2TBL_X1MODE_TYPE "custom_cbp_x1mode"
|
||||
#define PS2TBL_X1KEYCODE_TYPE "hex"
|
||||
#define PS2TBL_X1KEYCODE_BYTE2_TYPE "hex"
|
||||
#define PS2TBL_X1CTRL_TYPE "custom_cbn_x1ctrl"
|
||||
|
||||
// Keyboard mapping table select list for PS2CTRL.
|
||||
#define PS2TBL_PS2CTRL_SEL_NONE "NONE"
|
||||
#define PS2TBL_PS2CTRL_SEL_SHIFT "SHIFT"
|
||||
#define PS2TBL_PS2CTRL_SEL_CTRL "CTRL"
|
||||
#define PS2TBL_PS2CTRL_SEL_CAPS "CAPS"
|
||||
#define PS2TBL_PS2CTRL_SEL_KANA "KANA"
|
||||
#define PS2TBL_PS2CTRL_SEL_GRAPH "GRAPH"
|
||||
#define PS2TBL_PS2CTRL_SEL_GUI "GUI"
|
||||
#define PS2TBL_PS2CTRL_SEL_FUNC "FUNC"
|
||||
#define PS2TBL_PS2CTRL_SEL_EXACT "EXACT"
|
||||
|
||||
// Keyboard mapping table select list for Model of keyboard.
|
||||
#define KEYMAP_SEL_STANDARD "ALL"
|
||||
#define KEYMAP_SEL_UK_WYSE_KB3926 "UK_WYSE_KB3926"
|
||||
#define KEYMAP_SEL_JAPAN_OADG109 "JAPAN_OADG109"
|
||||
#define KEYMAP_SEL_JAPAN_SANWA_SKBL1 "JAPAN_SANWA_SKBL1"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_4 "KEYBOARD_4"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_5 "KEYBOARD_5"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_6 "KEYBOARD_6"
|
||||
#define KEYMAP_SEL_UK_PERIBOARD_810 "UK_PERIBOARD_810"
|
||||
#define KEYMAP_SEL_UK_OMOTON_K8508 "UK_OMOTON_K8508"
|
||||
|
||||
// Keyboard mapping table select list for keyboard mode.
|
||||
#define X1_SEL_MODE_A "Mode_A"
|
||||
#define X1_SEL_MODE_B "Mode_B"
|
||||
|
||||
// Keyboard mapping table select list for target machine.
|
||||
#define X1_SEL_ALL "ALL"
|
||||
#define X1_SEL_ORIG "ORIGINAL"
|
||||
#define X1_SEL_TURBO "TURBO"
|
||||
#define X1_SEL_TURBOZ "TURBOZ"
|
||||
|
||||
// Keyboard mapping table select list for X1 Control codes.
|
||||
#define X1_CTRL_SEL_TENKEY "TENKEY"
|
||||
#define X1_CTRL_SEL_PRESS "PRESS"
|
||||
#define X1_CTRL_SEL_REPEAT "REPEAT"
|
||||
#define X1_CTRL_SEL_GRAPH "GRAPH"
|
||||
#define X1_CTRL_SEL_CAPS "CAPS"
|
||||
#define X1_CTRL_SEL_KANA "KANA"
|
||||
#define X1_CTRL_SEL_SHIFT "SHIFT"
|
||||
#define X1_CTRL_SEL_CTRL "CTRL"
|
||||
|
||||
// The Sharp X1 Series was released over a number of years and each iteration added changes/updates. In order to cater for differences, it is possible to assign a key mapping
|
||||
// to a specific machine type(s) or all of the series by adding the flags below into the mapping table.
|
||||
#define X1_ALL 0xFF
|
||||
#define X1_ORIG 0x01
|
||||
#define X1_TURBO 0x02
|
||||
#define X1_TURBOZ 0x04
|
||||
|
||||
// The X1 Turbo onwards had a mode switch on the keyboard, Mode A was normal use, Mode B was for games, speeding up the key press by shortening the timing and setting common game keys pressed in a 24bit bit map.
|
||||
// The mapping table caters for both, OR'ing data in Mode B so that multiple key presses are sent across as a bit map.
|
||||
#define X1_MODE_A 0x01
|
||||
#define X1_MODE_B 0x02
|
||||
|
||||
// Keyboard models. The base on which this interface was created was a Wyse KB3926 PS/2 Keyboard and this is deemed STANDARD. Other models need to insert difference maps
|
||||
// prior to the STANDARD entry along with the keyboard model so that it is processed first thus allowing differing keyboards with different maps.
|
||||
#define KEYMAP_STANDARD 0xFF
|
||||
#define KEYMAP_UK_WYSE_KB3926 0x01
|
||||
#define KEYMAP_JAPAN_OADG109 0x02
|
||||
#define KEYMAP_JAPAN_SANWA_SKBL1 0x04
|
||||
#define KEYMAP_NOT_ASSIGNED_4 0x08
|
||||
#define KEYMAP_NOT_ASSIGNED_5 0x10
|
||||
#define KEYMAP_NOT_ASSIGNED_6 0x20
|
||||
#define KEYMAP_UK_PERIBOARD_810 0x40
|
||||
#define KEYMAP_UK_OMOTON_K8508 0x80
|
||||
|
||||
public:
|
||||
// Prototypes.
|
||||
X1(void);
|
||||
X1(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID, const char *fsPath);
|
||||
X1(NVS *hdlNVS, HID *hdlHID, const char *fsPath);
|
||||
~X1(void);
|
||||
bool createKeyMapFile(std::fstream &outFile);
|
||||
bool storeDataToKeyMapFile(std::fstream &outFile, char *data, int size);
|
||||
bool storeDataToKeyMapFile(std::fstream & outFile, std::vector<uint32_t>& dataArray);
|
||||
bool closeAndCommitKeyMapFile(std::fstream &outFile, bool cleanupOnly);
|
||||
std::string getKeyMapFileName(void) { return(X1IF_KEYMAP_FILE); };
|
||||
void getKeyMapHeaders(std::vector<std::string>& headerList);
|
||||
void getKeyMapTypes(std::vector<std::string>& typeList);
|
||||
bool getKeyMapSelectList(std::vector<std::pair<std::string, int>>& selectList, std::string option);
|
||||
bool getKeyMapData(std::vector<uint32_t>& dataArray, int *row, bool start);
|
||||
|
||||
// Method to return the class version number.
|
||||
float version(void)
|
||||
{
|
||||
return(X1IF_VERSION);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
// Prototypes.
|
||||
void pushKeyToQueue(bool keybMode, uint32_t key);
|
||||
IRAM_ATTR static void x1Interface( void * pvParameters );
|
||||
IRAM_ATTR static void hidInterface( void * pvParameters );
|
||||
void selectOption(uint8_t optionCode);
|
||||
uint32_t mapKey(uint16_t scanCode);
|
||||
bool loadKeyMap();
|
||||
bool saveKeyMap(void);
|
||||
void init(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID);
|
||||
void init(NVS *hdlNVS, HID *hdlHID);
|
||||
|
||||
// // Overload the base yield method to include suspension of the PS/2 Keyboard interface. This interface uses interrupts which are not mutex protected and clash with the
|
||||
// // WiFi API methods.
|
||||
// inline void yield(uint32_t delay)
|
||||
// {
|
||||
// // If suspended, go into a permanent loop until the suspend flag is reset.
|
||||
// if(this->suspend)
|
||||
// {
|
||||
// // Suspend the keyboard interface.
|
||||
// Keyboard->suspend(true);
|
||||
//
|
||||
// // Use the base method logic.
|
||||
// KeyInterface::yield(delay);
|
||||
//
|
||||
// // Release the keyboard interface.
|
||||
// Keyboard->suspend(false);
|
||||
// } else
|
||||
// // Otherwise just delay by the required amount for timing and to give other threads a time slice.
|
||||
// {
|
||||
// KeyInterface::yield(delay);
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Structure to encapsulate a single key map from PS/2 to X1.
|
||||
typedef struct {
|
||||
uint8_t ps2KeyCode;
|
||||
uint8_t ps2Ctrl;
|
||||
uint8_t keyboardModel;
|
||||
uint8_t machine;
|
||||
uint8_t x1Mode;
|
||||
uint8_t x1Key;
|
||||
uint8_t x1Key2;
|
||||
uint8_t x1Ctrl;
|
||||
} t_keyMapEntry;
|
||||
|
||||
// Structure to encapsulate the entire static keyboard mapping table.
|
||||
typedef struct {
|
||||
t_keyMapEntry kme[PS2TBL_X1_MAXROWS];
|
||||
} t_keyMap;
|
||||
|
||||
// Structure to maintain the X1 interface configuration data. This data is persisted through powercycles as needed.
|
||||
typedef struct {
|
||||
struct {
|
||||
uint8_t activeKeyboardMap; // Model of keyboard a keymap entry is applicable to.
|
||||
uint8_t activeMachineModel; // Machine model a keymap entry is applicable to.
|
||||
} params;
|
||||
} t_x1Config;
|
||||
|
||||
// Configuration data.
|
||||
t_x1Config x1Config;
|
||||
|
||||
// Structure to manage the control signals signifying the state of the X1 keyboard.
|
||||
typedef struct {
|
||||
bool optionSelect; // Flag to indicate a user requested keyboard configuration option is being selected.
|
||||
bool modeB; // Mode B (Game mode) flag. If set, Mode B active, clear, Mode A active (normal keyboard).
|
||||
uint8_t keyCtrl; // Keyboard state flag control.
|
||||
|
||||
std::string fsPath; // Path on the underlying filesystem where storage is mounted and accessible.
|
||||
t_keyMapEntry *kme; // Pointer to an array in memory to contain PS2 to X1 mapping values.
|
||||
int kmeRows; // Number of rows in the kme table.
|
||||
std::string keyMapFileName; // Name of file where extension or replacement key map entries are stored.
|
||||
bool persistConfig; // Flag to request saving of the config into NVS storage.
|
||||
} t_x1Control;
|
||||
|
||||
// Transmit buffer queue item.
|
||||
typedef struct {
|
||||
uint32_t keyCode; // 32bit because normal mode A is 16bit, game mode B is 24bit
|
||||
bool modeB; // True if in game mode B.
|
||||
} t_xmitQueueMessage;
|
||||
|
||||
// Thread handles - one per function, ie. HID interface and host target interface.
|
||||
TaskHandle_t TaskHostIF = NULL;
|
||||
TaskHandle_t TaskHIDIF = NULL;
|
||||
|
||||
// Control structure to control interaction and mapping of keys for the host.
|
||||
t_x1Control x1Control;
|
||||
|
||||
// Spin lock mutex to hold a coresied to an uninterruptable method. This only works on dual core ESP32's.
|
||||
portMUX_TYPE x1Mutex;
|
||||
|
||||
// Lookup table to match PS/2 codes to X1 Key and Control Data.
|
||||
//
|
||||
// Given that the X1 had many variants, with potential differences between them, the mapping table allows for ALL or variant specific entries, the first entry matching is selected.
|
||||
//
|
||||
|
||||
//
|
||||
// This mapping is for the UK Wyse KB-3926 PS/2 keyboard
|
||||
//
|
||||
t_keyMap PS2toX1 = {
|
||||
{
|
||||
// HELP
|
||||
// COPY
|
||||
// ModeB Byte1 ModeB Byte2 ModeB Byte3
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Keyboard Model Machine X1 Keyb Mode X1 Data X1 Ctrl (Flags to Set).
|
||||
{ PS2_KEY_F1, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'v', 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // SHIFT+F1
|
||||
{ PS2_KEY_F2, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'w', 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // SHIFT+F2
|
||||
{ PS2_KEY_F3, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'x', 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // SHIFT+F3
|
||||
{ PS2_KEY_F4, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'y', 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // SHIFT+F4
|
||||
{ PS2_KEY_F5, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'z', 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // SHIFT+F5
|
||||
{ PS2_KEY_F1, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'q', 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // F1
|
||||
{ PS2_KEY_F2, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'r', 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // F2
|
||||
{ PS2_KEY_F3, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 's', 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // F3
|
||||
{ PS2_KEY_F4, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 't', 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // F4
|
||||
{ PS2_KEY_F5, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'u', 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // F5
|
||||
{ PS2_KEY_F6, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xEC, 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // F6
|
||||
{ PS2_KEY_F7, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xEB, 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // F7
|
||||
{ PS2_KEY_F8, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xE2, 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // F8
|
||||
{ PS2_KEY_F9, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xE1, 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // F9
|
||||
{ PS2_KEY_F10, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // XFER
|
||||
{ PS2_KEY_F11, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xFE, 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // HELP
|
||||
{ PS2_KEY_F12, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // COPY
|
||||
{ PS2_KEY_TAB, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x09, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // TAB
|
||||
// Control keys.
|
||||
{ PS2_KEY_APOS, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-@
|
||||
{ PS2_KEY_A, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x01, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-A
|
||||
{ PS2_KEY_B, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x02, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-B
|
||||
{ PS2_KEY_C, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x03, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-C
|
||||
{ PS2_KEY_D, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x04, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-D
|
||||
{ PS2_KEY_E, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x05, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-E
|
||||
{ PS2_KEY_F, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x06, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-F
|
||||
{ PS2_KEY_G, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x07, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-G
|
||||
{ PS2_KEY_H, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x08, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-H
|
||||
{ PS2_KEY_I, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x09, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-I
|
||||
{ PS2_KEY_J, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x0A, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-J
|
||||
{ PS2_KEY_K, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x0B, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-K
|
||||
{ PS2_KEY_L, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x0C, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-L
|
||||
{ PS2_KEY_M, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x0D, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-M
|
||||
{ PS2_KEY_N, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x0E, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-N
|
||||
{ PS2_KEY_O, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x0F, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-O
|
||||
{ PS2_KEY_P, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x10, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-P
|
||||
{ PS2_KEY_Q, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x11, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-Q
|
||||
{ PS2_KEY_R, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x12, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-R
|
||||
{ PS2_KEY_S, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x13, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-S
|
||||
{ PS2_KEY_T, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x14, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-T
|
||||
{ PS2_KEY_U, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x15, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-U
|
||||
{ PS2_KEY_V, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x16, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-V
|
||||
{ PS2_KEY_W, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x17, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-W
|
||||
{ PS2_KEY_X, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x18, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-X
|
||||
{ PS2_KEY_Y, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x19, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-Y
|
||||
{ PS2_KEY_Z, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x1A, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-Z
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x1B, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-[
|
||||
{ PS2_KEY_BACK, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x1C, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-BACKSLASH
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x1D, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-]
|
||||
{ PS2_KEY_6, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x1E, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-^
|
||||
{ PS2_KEY_MINUS, PS2CTRL_CTRL, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x1F, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CTRL-_
|
||||
// Numeric keys.
|
||||
{ PS2_KEY_0, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '0', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // 0
|
||||
{ PS2_KEY_1, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '1', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // 1
|
||||
{ PS2_KEY_2, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '2', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // 2
|
||||
{ PS2_KEY_3, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '3', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // 3
|
||||
{ PS2_KEY_4, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '4', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // 4
|
||||
{ PS2_KEY_5, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '5', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // 5
|
||||
{ PS2_KEY_6, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '6', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // 6
|
||||
{ PS2_KEY_7, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '7', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // 7
|
||||
{ PS2_KEY_8, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '8', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // 8
|
||||
{ PS2_KEY_9, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '9', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // 9
|
||||
// Punctuation keys.
|
||||
{ PS2_KEY_0, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, ')', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Close Right Bracket )
|
||||
{ PS2_KEY_1, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '!', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Exclamation
|
||||
{ PS2_KEY_2, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '"', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Double quote.
|
||||
{ PS2_KEY_3, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x23, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Pound Sign -> Hash
|
||||
{ PS2_KEY_4, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '$', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Dollar
|
||||
{ PS2_KEY_5, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '%', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Percent
|
||||
{ PS2_KEY_6, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '^', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Kappa
|
||||
{ PS2_KEY_7, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '&', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Ampersand
|
||||
{ PS2_KEY_8, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '*', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Star
|
||||
{ PS2_KEY_9, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '(', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Open Left Bracket (
|
||||
// ALPHA keys, lower and uppercase.
|
||||
// ModeB Byte1 ModeB Byte2 ModeB Byte3
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Machine X1 Keyb Mode X1 Data X1 Ctrl (Flags to Set).
|
||||
{ PS2_KEY_A, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'a', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // a
|
||||
{ PS2_KEY_A, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'A', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // A
|
||||
{ PS2_KEY_B, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'b', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // b
|
||||
{ PS2_KEY_B, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'B', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // B
|
||||
{ PS2_KEY_C, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'c', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // c
|
||||
{ PS2_KEY_C, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'C', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // C
|
||||
{ PS2_KEY_D, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'd', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // d
|
||||
{ PS2_KEY_D, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'D', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // D
|
||||
{ PS2_KEY_E, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'e', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // e
|
||||
{ PS2_KEY_E, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'E', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // E
|
||||
{ PS2_KEY_F, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'f', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // f
|
||||
{ PS2_KEY_F, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'F', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // F
|
||||
{ PS2_KEY_G, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'g', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // g
|
||||
{ PS2_KEY_G, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'G', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // G
|
||||
{ PS2_KEY_H, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'h', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // h
|
||||
{ PS2_KEY_H, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'H', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // H
|
||||
{ PS2_KEY_I, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'i', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // i
|
||||
{ PS2_KEY_I, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'I', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // I
|
||||
{ PS2_KEY_J, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'j', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // j
|
||||
{ PS2_KEY_J, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'J', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // J
|
||||
{ PS2_KEY_K, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'k', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // k
|
||||
{ PS2_KEY_K, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'K', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // K
|
||||
{ PS2_KEY_L, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'l', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // l
|
||||
{ PS2_KEY_L, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'L', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // L
|
||||
{ PS2_KEY_M, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'm', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // m
|
||||
{ PS2_KEY_M, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'M', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // M
|
||||
{ PS2_KEY_N, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'n', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // n
|
||||
{ PS2_KEY_N, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'N', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // N
|
||||
{ PS2_KEY_O, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'o', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // o
|
||||
{ PS2_KEY_O, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'O', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // O
|
||||
{ PS2_KEY_P, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'p', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // p
|
||||
{ PS2_KEY_P, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'P', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // P
|
||||
{ PS2_KEY_Q, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'q', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // q
|
||||
{ PS2_KEY_Q, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'Q', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Q
|
||||
{ PS2_KEY_R, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'r', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // r
|
||||
{ PS2_KEY_R, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'R', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // R
|
||||
{ PS2_KEY_S, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 's', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // s
|
||||
{ PS2_KEY_S, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'S', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // S
|
||||
{ PS2_KEY_T, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 't', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // t
|
||||
{ PS2_KEY_T, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'T', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // T
|
||||
{ PS2_KEY_U, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'u', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // u
|
||||
{ PS2_KEY_U, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'U', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // U
|
||||
{ PS2_KEY_V, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'v', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // v
|
||||
{ PS2_KEY_V, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'V', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // V
|
||||
{ PS2_KEY_W, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'w', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // w
|
||||
{ PS2_KEY_W, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'W', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // W
|
||||
{ PS2_KEY_X, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'x', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // x
|
||||
{ PS2_KEY_X, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'X', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // X
|
||||
{ PS2_KEY_Y, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'y', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // y
|
||||
{ PS2_KEY_Y, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'Y', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Y
|
||||
{ PS2_KEY_Z, PS2CTRL_SHIFT | PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'z', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // z
|
||||
{ PS2_KEY_Z, PS2CTRL_CAPS, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 'Z', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Z
|
||||
// Mode B Mappings.
|
||||
{ PS2_KEY_Q, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b10000000, 0b00000000, 0b00000000, }, // MODE B - Q
|
||||
{ PS2_KEY_W, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b01000000, 0b00000000, 0b00000000, }, // MODE B - W
|
||||
{ PS2_KEY_E, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00100000, 0b00000000, 0b00000000, }, // MODE B - E
|
||||
{ PS2_KEY_A, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00010000, 0b00000000, 0b00000000, }, // MODE B - A
|
||||
{ PS2_KEY_D, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00001000, 0b00000000, 0b00000000, }, // MODE B - D
|
||||
{ PS2_KEY_Z, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000100, 0b00000000, 0b00000000, }, // MODE B - Z
|
||||
{ PS2_KEY_X, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000010, 0b00000000, 0b00000000, }, // MODE B - X
|
||||
{ PS2_KEY_C, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000001, 0b00000000, 0b00000000, }, // MODE B - C
|
||||
{ PS2_KEY_I, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000000, 0b01000000, }, // MODE B - I - this is not 100%, the specs arent clear.
|
||||
{ PS2_KEY_1, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00100000, 0b00000000, }, // MODE B - 1
|
||||
{ PS2_KEY_2, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00001000, 0b00000000, }, // MODE B - 2
|
||||
{ PS2_KEY_3, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000001, 0b00000000, }, // MODE B - 3
|
||||
{ PS2_KEY_4, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b01000000, 0b00000000, }, // MODE B - 4
|
||||
{ PS2_KEY_6, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000010, 0b00000000, }, // MODE B - 6
|
||||
{ PS2_KEY_7, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b10000000, 0b00000000, }, // MODE B - 7
|
||||
{ PS2_KEY_8, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00010000, 0b00000000, }, // MODE B - 8
|
||||
{ PS2_KEY_9, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000100, 0b00000000, }, // MODE B - 9
|
||||
{ PS2_KEY_ESC, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000000, 0b10000000, }, // MODE B - ESC
|
||||
{ PS2_KEY_MINUS, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000000, 0b00100000, }, // MODE B - MINUS
|
||||
{ PS2_KEY_EQUAL, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000000, 0b00010000, }, // MODE B - PLUS
|
||||
{ PS2_KEY_8, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000000, 0b00001000, }, // MODE B - TIMES
|
||||
{ PS2_KEY_TAB, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000000, 0b00000100, }, // MODE B - TAB
|
||||
{ PS2_KEY_SPACE, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000000, 0b00000010, }, // MODE B - SPACE
|
||||
{ PS2_KEY_ENTER, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000000, 0b00000001, }, // MODE B - RET
|
||||
{ PS2_KEY_KP1, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00100000, 0b00000000, }, // MODE B - KeyPad 1
|
||||
{ PS2_KEY_KP2, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00001000, 0b00000000, }, // MODE B - KeyPad 2
|
||||
{ PS2_KEY_KP3, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000001, 0b00000000, }, // MODE B - KeyPad 3
|
||||
{ PS2_KEY_KP4, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b01000000, 0b00000000, }, // MODE B - KeyPad 4
|
||||
{ PS2_KEY_KP6, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000010, 0b00000000, }, // MODE B - KeyPad 6
|
||||
{ PS2_KEY_KP7, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b10000000, 0b00000000, }, // MODE B - KeyPad 7
|
||||
{ PS2_KEY_KP8, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00010000, 0b00000000, }, // MODE B - KeyPad 8
|
||||
{ PS2_KEY_KP9, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000100, 0b00000000, }, // MODE B - KeyPad 9
|
||||
{ PS2_KEY_KP_MINUS, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000000, 0b00100000, }, // MODE B - KeyPad MINUS
|
||||
{ PS2_KEY_KP_PLUS, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000000, 0b00010000, }, // MODE B - KeyPad PLUS
|
||||
{ PS2_KEY_KP_TIMES, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_B, 0b00000000, 0b00000000, 0b00001000, }, // MODE B - KeyPad TIMES
|
||||
|
||||
// ModeB Byte1 ModeB Byte2 ModeB Byte3
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Machine X1 Keyb Mode X1 Data X1 Ctrl (Flags to Set).
|
||||
{ PS2_KEY_SPACE, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, ' ', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Space
|
||||
{ PS2_KEY_COMMA, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '<', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Less Than <
|
||||
{ PS2_KEY_COMMA, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, ',', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Comma ,
|
||||
{ PS2_KEY_SEMI, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, ':', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Colon :
|
||||
{ PS2_KEY_SEMI, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, ';', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Semi-Colon ;
|
||||
{ PS2_KEY_DOT, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '>', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Greater Than >
|
||||
{ PS2_KEY_DOT, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '.', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Full stop .
|
||||
{ PS2_KEY_DIV, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '?', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Question ?
|
||||
{ PS2_KEY_DIV, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '/', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Divide /
|
||||
{ PS2_KEY_MINUS, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '_', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Underscore
|
||||
{ PS2_KEY_MINUS, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '-', 0x00, 0xFF & ~(X1_CTRL_PRESS), },
|
||||
{ PS2_KEY_APOS, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '@', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // At @
|
||||
{ PS2_KEY_APOS, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '\'', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Single quote '
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '{', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Open Left Brace {
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '[', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Open Left Square Bracket [
|
||||
{ PS2_KEY_EQUAL, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '+', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Plus +
|
||||
{ PS2_KEY_EQUAL, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '=', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Equal =
|
||||
{ PS2_KEY_CAPS, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, ' ', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // LOCK
|
||||
{ PS2_KEY_ENTER, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x0D, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // ENTER/RETURN
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '}', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Close Right Brace }
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, ']', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Close Right Square Bracket ]
|
||||
{ PS2_KEY_BACK, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '|', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, //
|
||||
{ PS2_KEY_BACK, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '\\', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Back slash maps to Yen
|
||||
{ PS2_KEY_BTICK, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '`', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Pipe
|
||||
{ PS2_KEY_BTICK, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '|', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Back tick `
|
||||
{ PS2_KEY_HASH, PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '~', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Tilde has no mapping.
|
||||
{ PS2_KEY_HASH, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '#', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Hash
|
||||
{ PS2_KEY_BS, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x08, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Backspace
|
||||
{ PS2_KEY_ESC, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x1B, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // ESCape
|
||||
{ PS2_KEY_SCROLL, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, ' ', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Not assigned.
|
||||
{ PS2_KEY_INSERT, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, X1KEY_INS, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // INSERT
|
||||
{ PS2_KEY_HOME, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, X1KEY_CLR, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // CLR
|
||||
{ PS2_KEY_HOME, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, X1KEY_HOME, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // HOME
|
||||
{ PS2_KEY_DELETE, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, X1KEY_DEL, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // DELETE
|
||||
{ PS2_KEY_END, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x11, 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // END
|
||||
{ PS2_KEY_PGUP, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x0E, 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // Roll Up.
|
||||
{ PS2_KEY_PGDN, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x0F, 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // Roll Down
|
||||
{ PS2_KEY_UP_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, X1KEY_UP, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Up Arrow
|
||||
{ PS2_KEY_L_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, X1KEY_LEFT, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Left Arrow
|
||||
{ PS2_KEY_DN_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, X1KEY_DOWN, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Down Arrow
|
||||
{ PS2_KEY_R_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, X1KEY_RIGHT, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Right Arrow
|
||||
{ PS2_KEY_NUM, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Not assigned.
|
||||
// GRPH (Alt Gr)
|
||||
// ModeB Byte1 ModeB Byte2 ModeB Byte3
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Machine X1 Keyb Mode X1 Data X1 Ctrl (Flags to Set).
|
||||
{ PS2_KEY_0, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xFA, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+0
|
||||
{ PS2_KEY_1, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xF1, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+1
|
||||
{ PS2_KEY_2, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xF2, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+2
|
||||
{ PS2_KEY_3, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xF3, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+3
|
||||
{ PS2_KEY_4, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xF4, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+4
|
||||
{ PS2_KEY_5, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xF5, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+5
|
||||
{ PS2_KEY_6, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xF6, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+6
|
||||
{ PS2_KEY_7, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xF7, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+7
|
||||
{ PS2_KEY_8, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xF8, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+8
|
||||
{ PS2_KEY_9, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xF9, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+9
|
||||
{ PS2_KEY_A, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x7F, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+A
|
||||
{ PS2_KEY_B, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x84, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+B
|
||||
{ PS2_KEY_C, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x82, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+C
|
||||
{ PS2_KEY_D, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xEA, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+D
|
||||
{ PS2_KEY_E, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xE2, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+E
|
||||
{ PS2_KEY_F, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xEB, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+F
|
||||
{ PS2_KEY_G, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xEC, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+G
|
||||
{ PS2_KEY_H, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xED, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+H
|
||||
{ PS2_KEY_I, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xE7, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+I
|
||||
{ PS2_KEY_J, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xEE, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+J
|
||||
{ PS2_KEY_K, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xEF, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+K
|
||||
{ PS2_KEY_L, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x8E, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+L
|
||||
{ PS2_KEY_M, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x86, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+M
|
||||
{ PS2_KEY_N, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x85, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+N
|
||||
{ PS2_KEY_O, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xF0, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+O
|
||||
{ PS2_KEY_P, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x8D, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+P
|
||||
{ PS2_KEY_Q, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xE0, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+Q
|
||||
{ PS2_KEY_R, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xE3, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+R
|
||||
{ PS2_KEY_S, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xE9, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+S
|
||||
{ PS2_KEY_T, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xE4, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+T
|
||||
{ PS2_KEY_U, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xE6, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+U
|
||||
{ PS2_KEY_V, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x83, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+V
|
||||
{ PS2_KEY_W, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xE1, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+W
|
||||
{ PS2_KEY_X, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x81, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+X
|
||||
{ PS2_KEY_Y, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xE5, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+Y
|
||||
{ PS2_KEY_Z, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x80, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+Z
|
||||
{ PS2_KEY_COMMA, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x87, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+,
|
||||
{ PS2_KEY_SEMI, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x89, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+;
|
||||
{ PS2_KEY_DOT, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x88, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+.
|
||||
{ PS2_KEY_DIV, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xFE, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+/
|
||||
{ PS2_KEY_MINUS, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x8C, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+-
|
||||
{ PS2_KEY_APOS, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x8A, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+'
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xFC, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+[
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xE8, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+]
|
||||
{ PS2_KEY_BACK, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x90, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRPH+Backslash
|
||||
{ PS2_KEY_KP0, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x8F, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad 0
|
||||
{ PS2_KEY_KP1, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x99, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad 1
|
||||
{ PS2_KEY_KP2, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x92, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad 2
|
||||
{ PS2_KEY_KP3, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x98, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad 3
|
||||
{ PS2_KEY_KP4, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x95, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad 4
|
||||
{ PS2_KEY_KP5, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x96, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad 5
|
||||
{ PS2_KEY_KP6, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x94, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad 6
|
||||
{ PS2_KEY_KP7, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x9A, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad 7
|
||||
{ PS2_KEY_KP8, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x93, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad 8
|
||||
{ PS2_KEY_KP9, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x97, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad 9
|
||||
{ PS2_KEY_KP_DOT, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x91, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad Full stop .
|
||||
{ PS2_KEY_KP_PLUS, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x9D, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad Plus +
|
||||
{ PS2_KEY_KP_MINUS, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x9C, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad Minus -
|
||||
{ PS2_KEY_KP_TIMES, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x9B, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad Times *
|
||||
{ PS2_KEY_KP_DIV, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x9E, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad Divide /
|
||||
{ PS2_KEY_KP_ENTER, PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x90, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // GRPH+Keypad Enter /
|
||||
// KANA (Alt)
|
||||
// ModeB Byte1 ModeB Byte2 ModeB Byte3
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Machine X1 Keyb Mode X1 Data X1 Ctrl (Flags to Set).
|
||||
{ PS2_KEY_0, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xA6, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+0
|
||||
{ PS2_KEY_0, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xDC, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+0
|
||||
{ PS2_KEY_1, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xC7, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+1
|
||||
{ PS2_KEY_2, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xCC, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+2
|
||||
{ PS2_KEY_3, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xA7, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+3
|
||||
{ PS2_KEY_3, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xB1, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+3
|
||||
{ PS2_KEY_4, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xA9, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+4
|
||||
{ PS2_KEY_4, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xB3, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+4
|
||||
{ PS2_KEY_5, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xAA, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+5
|
||||
{ PS2_KEY_5, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xB4, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+5
|
||||
{ PS2_KEY_6, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xAB, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+6
|
||||
{ PS2_KEY_6, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xB5, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+6
|
||||
{ PS2_KEY_7, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xAC, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+7
|
||||
{ PS2_KEY_7, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xD4, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+7
|
||||
{ PS2_KEY_8, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xAD, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+8
|
||||
{ PS2_KEY_8, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xD5, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+8
|
||||
{ PS2_KEY_9, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xAE, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+9
|
||||
{ PS2_KEY_9, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xD6, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+9
|
||||
{ PS2_KEY_A, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xC1, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+A
|
||||
{ PS2_KEY_B, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xBA, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+B
|
||||
{ PS2_KEY_C, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xBF, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+C
|
||||
{ PS2_KEY_D, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xBC, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+D
|
||||
{ PS2_KEY_E, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xA8, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+E
|
||||
{ PS2_KEY_E, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xB2, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+E
|
||||
{ PS2_KEY_F, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xCA, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+F
|
||||
{ PS2_KEY_G, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xB7, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+G
|
||||
{ PS2_KEY_H, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xB8, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+H
|
||||
{ PS2_KEY_I, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xC6, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+I
|
||||
{ PS2_KEY_J, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xCF, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+J
|
||||
{ PS2_KEY_K, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xC9, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+K
|
||||
{ PS2_KEY_L, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xD8, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+L
|
||||
{ PS2_KEY_M, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xD3, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+M
|
||||
{ PS2_KEY_N, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xD0, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+N
|
||||
{ PS2_KEY_O, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xD7, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+O
|
||||
{ PS2_KEY_P, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xBE, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+P
|
||||
{ PS2_KEY_Q, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xC0, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+Q
|
||||
{ PS2_KEY_R, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xBD, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+R
|
||||
{ PS2_KEY_S, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xC4, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+S
|
||||
{ PS2_KEY_T, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xB6, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+T
|
||||
{ PS2_KEY_U, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xC5, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+U
|
||||
{ PS2_KEY_V, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xCB, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+V
|
||||
{ PS2_KEY_W, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xC3, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+W
|
||||
{ PS2_KEY_X, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xBB, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+X
|
||||
{ PS2_KEY_Y, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xDD, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+Y
|
||||
{ PS2_KEY_Z, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xAF, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+Z
|
||||
{ PS2_KEY_Z, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xC2, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+Z
|
||||
{ PS2_KEY_COMMA, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xA4, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+,
|
||||
{ PS2_KEY_COMMA, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xC8, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+,
|
||||
{ PS2_KEY_SEMI, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xDA, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+;
|
||||
{ PS2_KEY_DOT, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xA1, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+.
|
||||
{ PS2_KEY_DOT, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xD9, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+.
|
||||
{ PS2_KEY_DIV, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xA5, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+/
|
||||
{ PS2_KEY_DIV, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xD2, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+/
|
||||
{ PS2_KEY_MINUS, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xCE, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+-
|
||||
{ PS2_KEY_APOS, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xDE, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+'
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xA2, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+[
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xDF, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+[
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xA3, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+]
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xD1, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+]
|
||||
{ PS2_KEY_BACK, PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0xDB, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+Backslash
|
||||
{ PS2_KEY_BS, PS2CTRL_KANA | PS2CTRL_SHIFT, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x12, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA+SHIFT+Backspace
|
||||
// Keypad.
|
||||
{ PS2_KEY_KP0, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '0', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad 0
|
||||
{ PS2_KEY_KP1, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '1', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad 1
|
||||
{ PS2_KEY_KP2, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '2', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad 2
|
||||
{ PS2_KEY_KP3, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '3', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad 3
|
||||
{ PS2_KEY_KP4, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '4', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad 4
|
||||
{ PS2_KEY_KP5, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '5', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad 5
|
||||
{ PS2_KEY_KP6, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '6', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad 6
|
||||
{ PS2_KEY_KP7, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '7', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad 7
|
||||
{ PS2_KEY_KP8, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '8', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad 8
|
||||
{ PS2_KEY_KP9, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '9', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad 9
|
||||
{ PS2_KEY_KP_COMMA, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, ',', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad Comma ,
|
||||
{ PS2_KEY_KP_DOT, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '.', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad Full stop .
|
||||
{ PS2_KEY_KP_PLUS, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '+', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad Plus +
|
||||
{ PS2_KEY_KP_MINUS, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '-', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad Minus -
|
||||
{ PS2_KEY_KP_TIMES, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '*', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad Times *
|
||||
{ PS2_KEY_KP_DIV, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '/', 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad Divide /
|
||||
{ PS2_KEY_KP_ENTER, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x0D, 0x00, 0xFF & ~(X1_CTRL_TENKEY | X1_CTRL_PRESS), }, // Keypad Enter /
|
||||
{ PS2_KEY_KP_EQUAL, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, '=', 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Keypad Equal =
|
||||
// ModeB Byte1 ModeB Byte2 ModeB Byte3
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Machine X1 Keyb Mode X1 Data X1 Ctrl (Flags to Set).
|
||||
// Special keys.
|
||||
{ PS2_KEY_PRTSCR, PS2CTRL_FUNC, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // ARGO KEY
|
||||
{ PS2_KEY_PAUSE, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x03, 0x00, 0xFF & ~(X1_CTRL_PRESS | X1_CTRL_TENKEY), }, // BREAK KEY
|
||||
{ PS2_KEY_L_GUI, PS2CTRL_FUNC | PS2CTRL_GUI, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // GRAPH KEY
|
||||
//{ PS2_KEY_L_ALT, PS2CTRL_FUNC | PS2CTRL_KANA, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KJ1 Sentence
|
||||
//{ PS2_KEY_R_ALT, PS2CTRL_FUNC | PS2CTRL_GRAPH, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KJ2 Transform
|
||||
{ PS2_KEY_R_GUI, PS2CTRL_FUNC | PS2CTRL_GUI, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // KANA KEY
|
||||
{ PS2_KEY_MENU, PS2CTRL_FUNC | PS2CTRL_GUI, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Not assigned.
|
||||
// Modifiers are last, only being selected if an earlier match isnt made.
|
||||
{ PS2_KEY_L_SHIFT, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS), },
|
||||
{ PS2_KEY_R_SHIFT, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS), },
|
||||
{ PS2_KEY_L_CTRL, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS), },
|
||||
{ PS2_KEY_R_CTRL, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS), }, // Map to Control
|
||||
{ 0, PS2CTRL_NONE, KEYMAP_STANDARD, X1_ALL, X1_MODE_A, 0x00, 0x00, 0xFF & ~(X1_CTRL_PRESS), },
|
||||
}};
|
||||
};
|
||||
|
||||
#endif // X1_H
|
||||
533
main/include/X68K.h
Normal file
533
main/include/X68K.h
Normal file
@@ -0,0 +1,533 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: X68K.h
|
||||
// Created: Mar 2022
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Header for the Sharp X68000 to PS/2 interface logic class.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2022 - Initial write.
|
||||
// v1.01 May 2022 - Initial release version.
|
||||
// v1.02 Jun 2022 - Updates to reflect changes realised in other modules due to addition of
|
||||
// bluetooth and suspend logic due to NVS issues using both cores.
|
||||
// v1.03 Jun 2022 - Further updates adding in keymaps for UK BT and Japan OADG109.
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef X68K_H
|
||||
#define X68K_H
|
||||
|
||||
// Include the specification class.
|
||||
#include "KeyInterface.h"
|
||||
#include "NVS.h"
|
||||
#include "LED.h"
|
||||
#include "HID.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
// NB: Macros definitions put inside class for clarity, they are still global scope.
|
||||
|
||||
// Encapsulate the Sharp X68K interface.
|
||||
class X68K : public KeyInterface {
|
||||
// Macros.
|
||||
//
|
||||
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
// Constants.
|
||||
#define X68KIF_VERSION 1.03
|
||||
#define X68KIF_KEYMAP_FILE "X68K_KeyMap.BIN"
|
||||
#define MAX_X68K_XMIT_KEY_BUF 16
|
||||
#define MAX_X68K_RCV_KEY_BUF 16
|
||||
|
||||
// PS2 Flag definitions.
|
||||
#define PS2CTRL_NONE 0x00 // No keys active = 0
|
||||
#define PS2CTRL_SHIFT 0x01 // Shfit Key active = 1
|
||||
#define PS2CTRL_CTRL 0x02 // Ctrl Key active = 1
|
||||
#define PS2CTRL_CAPS 0x04 // CAPS active = 1
|
||||
#define PS2CTRL_R_CTRL 0x08 // ALT flag used as Right CTRL flag, active = 1
|
||||
#define PS2CTRL_ALTGR 0x10 // ALTGR active = 1
|
||||
#define PS2CTRL_GUI 0x20 // GUI Key active = 1
|
||||
#define PS2CTRL_FUNC 0x40 // Special Function Keys active = 1
|
||||
#define PS2CTRL_BREAK 0x80 // BREAK Key active = 1
|
||||
#define PS2CTRL_EXACT 0x80 // EXACT Match active = 1
|
||||
|
||||
// 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 extract the X68K key code and control data.
|
||||
// ie. PS/2 Scan Code -> ASCII + Flags -> X68K Key Code + Ctrl Data
|
||||
#define PS2TBL_X68K_MAXCOLS 6
|
||||
#define PS2TBL_X68K_MAXROWS 131
|
||||
|
||||
// Keyboard mapping table column names.
|
||||
#define PS2TBL_PS2KEYCODE_NAME "PS/2 KeyCode"
|
||||
#define PS2TBL_PS2CTRL_NAME "PS/2 Control Key"
|
||||
#define PS2TBL_KEYBOARDMODEL_NAME "For Keyboard"
|
||||
#define PS2TBL_MACHINE_NAME "For Host Model"
|
||||
#define PS2TBL_X68KKEYCODE_NAME "X68K KeyCode"
|
||||
#define PS2TBL_X68KCTRL_NAME "X68K Control Key"
|
||||
|
||||
// Keyboard mapping table column types.
|
||||
#define PS2TBL_PS2KEYCODE_TYPE "hex"
|
||||
#define PS2TBL_PS2CTRL_TYPE "custom_cbp_ps2ctrl"
|
||||
#define PS2TBL_KEYBOARDMODEL_TYPE "custom_cbp_keybmodel"
|
||||
#define PS2TBL_MACHINE_TYPE "custom_cbp_machine"
|
||||
#define PS2TBL_X68KKEYCODE_TYPE "hex"
|
||||
#define PS2TBL_X68KCTRL_TYPE "custom_cbp_x68kctrl"
|
||||
|
||||
// Keyboard mapping table select list for PS2CTRL.
|
||||
#define PS2TBL_PS2CTRL_SEL_NONE "NONE"
|
||||
#define PS2TBL_PS2CTRL_SEL_SHIFT "SHIFT"
|
||||
#define PS2TBL_PS2CTRL_SEL_CTRL "CTRL"
|
||||
#define PS2TBL_PS2CTRL_SEL_CAPS "CAPS"
|
||||
#define PS2TBL_PS2CTRL_SEL_R_CTRL "RCTRL"
|
||||
#define PS2TBL_PS2CTRL_SEL_ALTGR "ALTGR"
|
||||
#define PS2TBL_PS2CTRL_SEL_GUI "GUI"
|
||||
#define PS2TBL_PS2CTRL_SEL_FUNC "FUNC"
|
||||
#define PS2TBL_PS2CTRL_SEL_EXACT "EXACT"
|
||||
|
||||
// Keyboard mapping table select list for target machine.
|
||||
#define X68K_SEL_ALL "ALL"
|
||||
#define X68K_SEL_ORIG "ORIGINAL"
|
||||
#define X68K_SEL_ACE "ACE"
|
||||
#define X68K_SEL_EXPERT "EXPERT"
|
||||
#define X68K_SEL_PRO "PRO"
|
||||
#define X68K_SEL_SUPER "SUPER"
|
||||
#define X68K_SEL_XVI "XVI"
|
||||
#define X68K_SEL_COMPACT "COMPACT"
|
||||
#define X68K_SEL_X68030 "68030"
|
||||
|
||||
// Keyboard mapping table select list for Model of keyboard.
|
||||
#define KEYMAP_SEL_STANDARD "ALL"
|
||||
#define KEYMAP_SEL_UK_WYSE_KB3926 "UK_WYSE_KB3926"
|
||||
#define KEYMAP_SEL_JAPAN_OADG109 "JAPAN_OADG109"
|
||||
#define KEYMAP_SEL_JAPAN_SANWA_SKBL1 "JAPAN_SANWA_SKBL1"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_4 "KEYBOARD_4"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_5 "KEYBOARD_5"
|
||||
#define KEYMAP_SEL_NOT_ASSIGNED_6 "KEYBOARD_6"
|
||||
#define KEYMAP_SEL_UK_PERIBOARD_810 "UK_PERIBOARD_810"
|
||||
#define KEYMAP_SEL_UK_OMOTON_K8508 "UK_OMOTON_K8508"
|
||||
|
||||
// Keyboard mapping table select list for X68K Control codes.
|
||||
#define X68K_CTRL_SEL_NONE "NONE"
|
||||
#define X68K_CTRL_SEL_SHIFT "SHIFT"
|
||||
#define X68K_CTRL_SEL_RELEASESHIFT "RELEASESHIFT"
|
||||
#define X68K_CTRL_SEL_R_CTRL "RCTRL"
|
||||
|
||||
// X68K Key control bit mask.
|
||||
#define X68K_CTRL_SHIFT ((unsigned char) (1 << 7))
|
||||
#define X68K_CTRL_RELEASESHIFT ((unsigned char) (1 << 6))
|
||||
#define X68K_CTRL_R_CTRL ((unsigned char) (1 << 0))
|
||||
#define X68K_CTRL_NONE 0x00
|
||||
|
||||
// The Sharp X68000 Series was released over a number of years with several iterations containing changes/updates. Generally Sharp kept the X68000 compatible through the range but just in case
|
||||
// differences are found, it is possible to assign a key mapping to a specific machine type(s) or all of the series by adding the flags below into the mapping table.
|
||||
#define X68K_ALL 0xFF
|
||||
#define X68K_ORIG 0x01
|
||||
#define X68K_ACE 0x02
|
||||
#define X68K_EXPERT 0x04
|
||||
#define X68K_PRO 0x08
|
||||
#define X68K_SUPER 0x10
|
||||
#define X68K_XVI 0x20
|
||||
#define X68K_COMPACT 0x40
|
||||
#define X68K_X68030 0x80
|
||||
|
||||
// Keyboard models. The base on which this interface was created was a Wyse KB3926 PS/2 Keyboard and this is deemed STANDARD. Other models need to insert difference maps
|
||||
// prior to the STANDARD entry along with the keyboard model so that it is processed first thus allowing differing keyboards with different maps.
|
||||
#define KEYMAP_STANDARD 0xFF
|
||||
#define KEYMAP_UK_WYSE_KB3926 0x01
|
||||
#define KEYMAP_JAPAN_OADG109 0x02
|
||||
#define KEYMAP_JAPAN_SANWA_SKBL1 0x04
|
||||
#define KEYMAP_NOT_ASSIGNED_4 0x08
|
||||
#define KEYMAP_NOT_ASSIGNED_5 0x10
|
||||
#define KEYMAP_NOT_ASSIGNED_6 0x20
|
||||
#define KEYMAP_UK_PERIBOARD_810 0x40
|
||||
#define KEYMAP_UK_OMOTON_K8508 0x80
|
||||
|
||||
// X68000 Scan codes - PS2 codes along with function keys (SHIFT, CTRL etc) are mapped to the X68000 scan codes below.
|
||||
#define X68K_KEY_NULL 0x00
|
||||
#define X68K_KEY_ESC 0x01
|
||||
#define X68K_KEY_0 0x0B
|
||||
#define X68K_KEY_1 0x02
|
||||
#define X68K_KEY_2 0x03
|
||||
#define X68K_KEY_3 0x04
|
||||
#define X68K_KEY_4 0x05
|
||||
#define X68K_KEY_5 0x06
|
||||
#define X68K_KEY_6 0x07
|
||||
#define X68K_KEY_7 0x08
|
||||
#define X68K_KEY_8 0x09
|
||||
#define X68K_KEY_9 0x0A
|
||||
#define X68K_KEY_A 0x1E
|
||||
#define X68K_KEY_B 0x2E
|
||||
#define X68K_KEY_C 0x2C
|
||||
#define X68K_KEY_D 0x20
|
||||
#define X68K_KEY_E 0x13
|
||||
#define X68K_KEY_F 0x21
|
||||
#define X68K_KEY_G 0x22
|
||||
#define X68K_KEY_H 0x23
|
||||
#define X68K_KEY_I 0x18
|
||||
#define X68K_KEY_J 0x24
|
||||
#define X68K_KEY_K 0x25
|
||||
#define X68K_KEY_L 0x26
|
||||
#define X68K_KEY_M 0x30
|
||||
#define X68K_KEY_N 0x2F
|
||||
#define X68K_KEY_O 0x19
|
||||
#define X68K_KEY_P 0x1A
|
||||
#define X68K_KEY_Q 0x11
|
||||
#define X68K_KEY_R 0x14
|
||||
#define X68K_KEY_S 0x1F
|
||||
#define X68K_KEY_T 0x15
|
||||
#define X68K_KEY_U 0x17
|
||||
#define X68K_KEY_V 0x2D
|
||||
#define X68K_KEY_W 0x12
|
||||
#define X68K_KEY_X 0x2B
|
||||
#define X68K_KEY_Y 0x16
|
||||
#define X68K_KEY_Z 0x2A
|
||||
#define X68K_KEY_AT 0x1B
|
||||
#define X68K_KEY_MINUS 0x0C
|
||||
#define X68K_KEY_CIRCUMFLEX 0x0D
|
||||
#define X68K_KEY_YEN 0x0E
|
||||
#define X68K_KEY_BS 0x0F
|
||||
#define X68K_KEY_TAB 0x10
|
||||
#define X68K_KEY_OPEN_SQ 0x1C
|
||||
#define X68K_KEY_CLOSE_SQ 0x29
|
||||
#define X68K_KEY_RETURN 0x1D
|
||||
#define X68K_KEY_SEMI 0x27
|
||||
#define X68K_KEY_COLON 0x28
|
||||
#define X68K_KEY_COMMA 0x31
|
||||
#define X68K_KEY_DOT 0x32
|
||||
#define X68K_KEY_DIV 0x33
|
||||
#define X68K_KEY_UNDERLINE 0x34
|
||||
#define X68K_KEY_SPACE 0x35
|
||||
#define X68K_KEY_HOME 0x36
|
||||
#define X68K_KEY_ROLLUP 0x38
|
||||
#define X68K_KEY_ROLLDN 0x39
|
||||
#define X68K_KEY_UNDO 0x3A
|
||||
#define X68K_KEY_L_ARROW 0x3B
|
||||
#define X68K_KEY_UP_ARROW 0x3C
|
||||
#define X68K_KEY_R_ARROW 0x3D
|
||||
#define X68K_KEY_DN_ARROW 0x3E
|
||||
#define X68K_KEY_CLR 0x3F
|
||||
#define X68K_KEY_KP0 0x4F
|
||||
#define X68K_KEY_KP1 0x4B
|
||||
#define X68K_KEY_KP2 0x4C
|
||||
#define X68K_KEY_KP3 0x4D
|
||||
#define X68K_KEY_KP4 0x47
|
||||
#define X68K_KEY_KP5 0x48
|
||||
#define X68K_KEY_KP6 0x49
|
||||
#define X68K_KEY_KP7 0x43
|
||||
#define X68K_KEY_KP8 0x44
|
||||
#define X68K_KEY_KP9 0x45
|
||||
#define X68K_KEY_KP_DIV 0x40
|
||||
#define X68K_KEY_KP_TIMES 0x41
|
||||
#define X68K_KEY_KP_MINUS 0x42
|
||||
#define X68K_KEY_KP_PLUS 0x46
|
||||
#define X68K_KEY_KP_EQUAL 0x4A
|
||||
#define X68K_KEY_KP_ENTER 0x4E
|
||||
#define X68K_KEY_KP_COMMA 0x50
|
||||
#define X68K_KEY_KP_DOT 0x51
|
||||
#define X68K_KEY_SYMBOL 0x52
|
||||
#define X68K_KEY_HELP 0x54
|
||||
#define X68K_KEY_CAPS 0x5D
|
||||
#define X68K_KEY_INS 0x5E
|
||||
#define X68K_KEY_DEL 0x37
|
||||
#define X68K_KEY_BREAK 0x61
|
||||
#define X68K_KEY_COPY 0x62
|
||||
#define X68K_KEY_SHIFT 0x70
|
||||
#define X68K_KEY_CTRL 0x71
|
||||
#define X68K_KEY_XF1 0x55
|
||||
#define X68K_KEY_XF2 0x56
|
||||
#define X68K_KEY_XF3 0x57
|
||||
#define X68K_KEY_XF4 0x58
|
||||
#define X68K_KEY_XF5 0x59
|
||||
#define X68K_KEY_REGISTRATION 0x53
|
||||
#define X68K_KEY_KATAKANA 0x5A
|
||||
#define X68K_KEY_ROMAJI 0x5B
|
||||
#define X68K_KEY_TRANSPOSE 0x5C
|
||||
#define X68K_KEY_HIRAGANA 0x5F
|
||||
#define X68K_KEY_FULLWIDTH 0x60
|
||||
#define X68K_KEY_F1 0x63
|
||||
#define X68K_KEY_F2 0x64
|
||||
#define X68K_KEY_F3 0x65
|
||||
#define X68K_KEY_F4 0x66
|
||||
#define X68K_KEY_F5 0x67
|
||||
#define X68K_KEY_F6 0x68
|
||||
#define X68K_KEY_F7 0x69
|
||||
#define X68K_KEY_F8 0x6A
|
||||
#define X68K_KEY_F9 0x6B
|
||||
#define X68K_KEY_F10 0x6C
|
||||
#define X68K_KEY_OPT_1 0x72
|
||||
#define X68K_KEY_OPT_2 0x73
|
||||
|
||||
public:
|
||||
// Prototypes.
|
||||
X68K(void);
|
||||
X68K(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID, const char *fsPath);
|
||||
X68K(NVS *hdlNVS, HID *hdlHID, const char *fsPath);
|
||||
~X68K(void);
|
||||
bool createKeyMapFile(std::fstream &outFile);
|
||||
bool storeDataToKeyMapFile(std::fstream &outFile, char *data, int size);
|
||||
bool storeDataToKeyMapFile(std::fstream & outFile, std::vector<uint32_t>& dataArray);
|
||||
bool closeAndCommitKeyMapFile(std::fstream &outFile, bool cleanupOnly);
|
||||
std::string getKeyMapFileName(void) { return(X68KIF_KEYMAP_FILE); };
|
||||
void getKeyMapHeaders(std::vector<std::string>& headerList);
|
||||
void getKeyMapTypes(std::vector<std::string>& typeList);
|
||||
bool getKeyMapSelectList(std::vector<std::pair<std::string, int>>& selectList, std::string option);
|
||||
bool getKeyMapData(std::vector<uint32_t>& dataArray, int *row, bool start);
|
||||
|
||||
// Method to return the class version number.
|
||||
float version(void)
|
||||
{
|
||||
return(X68KIF_VERSION);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
// Prototypes.
|
||||
IRAM_ATTR void pushKeyToQueue(uint32_t key);
|
||||
IRAM_ATTR void pushHostCmdToQueue(uint8_t cmd);
|
||||
IRAM_ATTR static void x68kInterface( void * pvParameters );
|
||||
IRAM_ATTR static void hidInterface( void * pvParameters );
|
||||
void selectOption(uint8_t optionCode);
|
||||
uint32_t mapKey(uint16_t scanCode);
|
||||
bool loadKeyMap();
|
||||
bool saveKeyMap(void);
|
||||
void init(uint32_t ifMode, NVS *hdlNVS, LED *hdlLED, HID *hdlHID);
|
||||
void init(NVS *hdlNVS, HID *hdlHID);
|
||||
|
||||
// Structure to encapsulate a single key map from PS/2 to X68K.
|
||||
typedef struct {
|
||||
uint8_t ps2KeyCode;
|
||||
uint8_t ps2Ctrl;
|
||||
uint8_t keyboardModel;
|
||||
uint8_t machine;
|
||||
uint8_t x68kKey;
|
||||
uint8_t x68kCtrl;
|
||||
} t_keyMapEntry;
|
||||
|
||||
// Structure to encapsulate the entire static keyboard mapping table.
|
||||
typedef struct {
|
||||
t_keyMapEntry kme[PS2TBL_X68K_MAXROWS];
|
||||
} t_keyMap;
|
||||
|
||||
// Structure to maintain the X68000 interface configuration data. This data is persisted through powercycles as needed.
|
||||
typedef struct {
|
||||
struct {
|
||||
uint8_t activeKeyboardMap; // Model of keyboard a keymap entry is applicable to.
|
||||
uint8_t activeMachineModel; // Machine model a keymap entry is applicable to.
|
||||
bool useOnlyPersisted; // Flag to indicate wether the inbuilt keymap array should be combined with persisted values or the inbuilt array is ignored and only persisted values used.
|
||||
} params;
|
||||
} t_x68kConfig;
|
||||
|
||||
// Configuration data.
|
||||
t_x68kConfig x68kConfig;
|
||||
|
||||
// Structure to manage the control signals signifying the state of the X68K keyboard.
|
||||
typedef struct {
|
||||
uint8_t keyCtrl; // Keyboard state flag control.
|
||||
bool optionSelect; // Flag to indicate a user requested keyboard configuration option is being selected.
|
||||
int uartNum;
|
||||
int uartBufferSize;
|
||||
int uartQueueSize;
|
||||
|
||||
std::string fsPath; // Path on the underlying filesystem where storage is mounted and accessible.
|
||||
t_keyMapEntry *kme; // Pointer to an array in memory to contain PS2 to X68K mapping values.
|
||||
int kmeRows; // Number of rows in the kme table.
|
||||
std::string keyMapFileName; // Name of file where extension or replacement key map entries are stored.
|
||||
bool persistConfig; // Flag to request saving of the config into NVS storage.
|
||||
} t_x68kControl;
|
||||
|
||||
// Transmit buffer queue item.
|
||||
typedef struct {
|
||||
uint32_t keyCode; // Key data to be sent to X68000.
|
||||
} t_xmitQueueMessage;
|
||||
|
||||
// Receive buffer queue item.
|
||||
typedef struct {
|
||||
uint8_t hostCmd; // Keyboard configuration command received from X68000.
|
||||
} t_rcvQueueMessage;
|
||||
|
||||
// Thread handles - one per function, ie. HID interface and host target interface.
|
||||
TaskHandle_t TaskHostIF = NULL;
|
||||
TaskHandle_t TaskHIDIF = NULL;
|
||||
|
||||
// Control structure to control interaction and mapping of keys for the host.
|
||||
t_x68kControl x68kControl;
|
||||
|
||||
// Spin lock mutex to hold a coresied to an uninterruptable method. This only works on dual core ESP32's.
|
||||
portMUX_TYPE x68kMutex;
|
||||
|
||||
// Lookup table to match PS/2 codes to X68K Key and Control Data.
|
||||
//
|
||||
// Given that the X68K had many variants, with potential differences between them, the mapping table allows for ALL or variant specific entries, the first entry matching is selected.
|
||||
//
|
||||
// This mapping is for the UK Wyse KB-3926 PS/2 keyboard which is deemed the KEYMAP_STANDARD and all other variants need to add additional mappings below, position sensitive, ie. add non-standard entries before standard entry.
|
||||
//
|
||||
//const unsigned char PS2toX68K[PS2TBL_X68K_MAXROWS][PS2TBL_X68K_MAXCOLS] =
|
||||
//t_keyMapEntry PS2toX68K[PS2TBL_X68K_MAXROWS] =
|
||||
t_keyMap PS2toX68K = {
|
||||
{
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Keyboard Model Machine X68K Data X68K Ctrl (Flags to Set).
|
||||
// Function keys
|
||||
{ PS2_KEY_F1, PS2CTRL_FUNC | PS2CTRL_CTRL | PS2CTRL_R_CTRL, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_HIRAGANA, X68K_CTRL_NONE, }, // R_CTRL + F1 = Hiragana
|
||||
{ PS2_KEY_F2, PS2CTRL_FUNC | PS2CTRL_CTRL | PS2CTRL_R_CTRL, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_FULLWIDTH, X68K_CTRL_NONE, }, // R_CTRL + F2 = Full Width
|
||||
{ PS2_KEY_F3, PS2CTRL_FUNC | PS2CTRL_CTRL | PS2CTRL_R_CTRL, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KATAKANA, X68K_CTRL_NONE, }, // R_CTRL + F3 = Katakana
|
||||
{ PS2_KEY_F4, PS2CTRL_FUNC | PS2CTRL_CTRL | PS2CTRL_R_CTRL, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_ROMAJI, X68K_CTRL_NONE, }, // R_CTRL + F4 = Romaji
|
||||
{ PS2_KEY_F5, PS2CTRL_FUNC | PS2CTRL_CTRL | PS2CTRL_R_CTRL, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_TRANSPOSE, X68K_CTRL_NONE, }, // R_CTRL + F5 = Tranpose
|
||||
{ PS2_KEY_F6, PS2CTRL_FUNC | PS2CTRL_CTRL | PS2CTRL_R_CTRL, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_SYMBOL, X68K_CTRL_NONE, }, // R_CTRL + F6 = Symbol
|
||||
{ PS2_KEY_F7, PS2CTRL_FUNC | PS2CTRL_CTRL | PS2CTRL_R_CTRL, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_REGISTRATION, X68K_CTRL_NONE, }, // R_CTRL + F7 = Registration - maybe a poor translation, needs better one!
|
||||
{ PS2_KEY_F9, PS2CTRL_FUNC | PS2CTRL_CTRL | PS2CTRL_R_CTRL, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_COPY, X68K_CTRL_NONE, }, // R_CTRL + F9 = Copy
|
||||
{ PS2_KEY_F10, PS2CTRL_FUNC | PS2CTRL_CTRL | PS2CTRL_R_CTRL, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_HELP, X68K_CTRL_NONE, }, // R_CTRL + F10 = Help
|
||||
{ PS2_KEY_F1, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_F1, X68K_CTRL_NONE, }, // F1
|
||||
{ PS2_KEY_F2, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_F2, X68K_CTRL_NONE, }, // F2
|
||||
{ PS2_KEY_F3, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_F3, X68K_CTRL_NONE, }, // F3
|
||||
{ PS2_KEY_F4, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_F4, X68K_CTRL_NONE, }, // F4
|
||||
{ PS2_KEY_F5, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_F5, X68K_CTRL_NONE, }, // F5
|
||||
{ PS2_KEY_F6, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_F6, X68K_CTRL_NONE, }, // F6
|
||||
{ PS2_KEY_F7, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_F7, X68K_CTRL_NONE, }, // F7
|
||||
{ PS2_KEY_F8, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_F8, X68K_CTRL_NONE, }, // F8
|
||||
{ PS2_KEY_F9, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_F9, X68K_CTRL_NONE, }, // F9
|
||||
{ PS2_KEY_F10, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_F10, X68K_CTRL_NONE, }, // F10
|
||||
{ PS2_KEY_F11, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_OPT_1, X68K_CTRL_NONE, }, // F11 - OPT.1
|
||||
{ PS2_KEY_F12, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_OPT_2, X68K_CTRL_NONE, }, // F12 - OPT.2
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Machine X68K Data X68K Ctrl (Flags to Set).
|
||||
// ALPHA keys, case is maaped in the X68000 via the SHIFT key event or CAPS key.
|
||||
{ PS2_KEY_A, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_A, X68K_CTRL_NONE, }, // A
|
||||
{ PS2_KEY_B, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_B, X68K_CTRL_NONE, }, // B
|
||||
{ PS2_KEY_C, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_C, X68K_CTRL_NONE, }, // C
|
||||
{ PS2_KEY_D, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_D, X68K_CTRL_NONE, }, // D
|
||||
{ PS2_KEY_E, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_E, X68K_CTRL_NONE, }, // E
|
||||
{ PS2_KEY_F, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_F, X68K_CTRL_NONE, }, // F
|
||||
{ PS2_KEY_G, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_G, X68K_CTRL_NONE, }, // G
|
||||
{ PS2_KEY_H, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_H, X68K_CTRL_NONE, }, // H
|
||||
{ PS2_KEY_I, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_I, X68K_CTRL_NONE, }, // I
|
||||
{ PS2_KEY_J, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_J, X68K_CTRL_NONE, }, // J
|
||||
{ PS2_KEY_K, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_K, X68K_CTRL_NONE, }, // K
|
||||
{ PS2_KEY_L, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_L, X68K_CTRL_NONE, }, // L
|
||||
{ PS2_KEY_M, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_M, X68K_CTRL_NONE, }, // M
|
||||
{ PS2_KEY_N, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_N, X68K_CTRL_NONE, }, // N
|
||||
{ PS2_KEY_O, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_O, X68K_CTRL_NONE, }, // O
|
||||
{ PS2_KEY_P, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_P, X68K_CTRL_NONE, }, // P
|
||||
{ PS2_KEY_Q, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_Q, X68K_CTRL_NONE, }, // Q
|
||||
{ PS2_KEY_R, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_R, X68K_CTRL_NONE, }, // R
|
||||
{ PS2_KEY_S, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_S, X68K_CTRL_NONE, }, // S
|
||||
{ PS2_KEY_T, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_T, X68K_CTRL_NONE, }, // T
|
||||
{ PS2_KEY_U, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_U, X68K_CTRL_NONE, }, // U
|
||||
{ PS2_KEY_V, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_V, X68K_CTRL_NONE, }, // V
|
||||
{ PS2_KEY_W, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_W, X68K_CTRL_NONE, }, // W
|
||||
{ PS2_KEY_X, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_X, X68K_CTRL_NONE, }, // X
|
||||
{ PS2_KEY_Y, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_Y, X68K_CTRL_NONE, }, // Y
|
||||
{ PS2_KEY_Z, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_Z, X68K_CTRL_NONE, }, // Z
|
||||
// Numeric keys.
|
||||
{ PS2_KEY_0, PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_9, X68K_CTRL_NONE, }, // Close Bracket )
|
||||
{ PS2_KEY_0, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_0, X68K_CTRL_NONE, }, // 0
|
||||
{ PS2_KEY_1, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_1, X68K_CTRL_NONE, }, // 1
|
||||
{ PS2_KEY_2, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_2, X68K_CTRL_NONE, }, // 2
|
||||
{ PS2_KEY_3, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_3, X68K_CTRL_NONE, }, // 3
|
||||
{ PS2_KEY_4, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_4, X68K_CTRL_NONE, }, // 4
|
||||
{ PS2_KEY_5, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_5, X68K_CTRL_NONE, }, // 5
|
||||
{ PS2_KEY_6, PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_CIRCUMFLEX, X68K_CTRL_RELEASESHIFT, }, // Circumflex ^
|
||||
{ PS2_KEY_6, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_6, X68K_CTRL_NONE, }, // 6
|
||||
{ PS2_KEY_7, PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_6, X68K_CTRL_NONE, }, // &
|
||||
{ PS2_KEY_7, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_7, X68K_CTRL_NONE, }, // 7
|
||||
{ PS2_KEY_8, PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_COLON, X68K_CTRL_NONE, }, // Start *
|
||||
{ PS2_KEY_8, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_8, X68K_CTRL_NONE, }, // 8
|
||||
{ PS2_KEY_9, PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_8, X68K_CTRL_NONE, }, // Open Bracket (
|
||||
{ PS2_KEY_9, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_9, X68K_CTRL_NONE, }, // 9
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Machine X68K Data X68K Ctrl (Flags to Set).
|
||||
// Punctuation keys.
|
||||
{ PS2_KEY_SPACE, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_SPACE, X68K_CTRL_NONE, }, // Space
|
||||
{ PS2_KEY_MINUS, PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_CIRCUMFLEX, X68K_CTRL_NONE, }, // Upper Bar
|
||||
{ PS2_KEY_MINUS, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_MINUS, X68K_CTRL_NONE, }, // Minus -
|
||||
{ PS2_KEY_EQUAL, PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_SEMI, X68K_CTRL_SHIFT, }, // Plus +
|
||||
{ PS2_KEY_EQUAL, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_MINUS, X68K_CTRL_SHIFT, }, // Equal =
|
||||
{ PS2_KEY_DOT, PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_DOT, X68K_CTRL_NONE, }, // Greater Than >
|
||||
{ PS2_KEY_DOT, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_DOT, X68K_CTRL_NONE, }, // Dot
|
||||
{ PS2_KEY_DIV, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_DIV, X68K_CTRL_NONE, }, // Divide /
|
||||
{ PS2_KEY_SEMI, PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_COLON, X68K_CTRL_RELEASESHIFT, }, // Colon :
|
||||
{ PS2_KEY_SEMI, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_SEMI, X68K_CTRL_NONE, }, // Semi-Colon ;
|
||||
{ PS2_KEY_OPEN_SQ, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_OPEN_SQ, X68K_CTRL_NONE, }, // [
|
||||
{ PS2_KEY_CLOSE_SQ, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_CLOSE_SQ, X68K_CTRL_NONE, }, // ]
|
||||
{ PS2_KEY_APOS, PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_AT, X68K_CTRL_RELEASESHIFT, }, // @
|
||||
{ PS2_KEY_APOS, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_7, X68K_CTRL_SHIFT, }, // '
|
||||
{ PS2_KEY_BACK, PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_YEN, X68K_CTRL_NONE, }, // Back slash maps to Yen
|
||||
{ PS2_KEY_BACK, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_YEN, X68K_CTRL_NONE, }, // Back slash maps to Yen
|
||||
{ PS2_KEY_HASH, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_3, X68K_CTRL_SHIFT, }, // Hash
|
||||
{ PS2_KEY_COMMA, PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_COMMA, X68K_CTRL_NONE, }, // Less Than <
|
||||
{ PS2_KEY_COMMA, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_COMMA, X68K_CTRL_NONE, }, // Comma ,
|
||||
{ PS2_KEY_BTICK, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_UNDERLINE, X68K_CTRL_SHIFT, }, // Underline
|
||||
{ PS2_KEY_BTICK, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_AT, X68K_CTRL_SHIFT, }, // Back Tick `
|
||||
// Control keys.
|
||||
{ PS2_KEY_TAB, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_TAB, X68K_CTRL_NONE, }, // TAB
|
||||
{ PS2_KEY_BS, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_BS, X68K_CTRL_NONE, }, // Backspace
|
||||
{ PS2_KEY_ESC, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_ESC, X68K_CTRL_NONE, }, // ESCape
|
||||
{ PS2_KEY_INSERT, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_INS, X68K_CTRL_NONE, }, // INSERT
|
||||
{ PS2_KEY_HOME, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_CLR, X68K_CTRL_NONE, }, // CLR
|
||||
{ PS2_KEY_HOME, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_HOME, X68K_CTRL_NONE, }, // HOME
|
||||
{ PS2_KEY_DELETE, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_DEL, X68K_CTRL_NONE, }, // DELETE
|
||||
{ PS2_KEY_UP_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_UP_ARROW, X68K_CTRL_NONE, }, // Up Arrow
|
||||
{ PS2_KEY_L_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_L_ARROW, X68K_CTRL_NONE, }, // Left Arrow
|
||||
{ PS2_KEY_DN_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_DN_ARROW, X68K_CTRL_NONE, }, // Down Arrow
|
||||
{ PS2_KEY_R_ARROW, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_R_ARROW, X68K_CTRL_NONE, }, // Right Arrow
|
||||
{ PS2_KEY_PGUP, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_ROLLUP, X68K_CTRL_NONE, }, // Roll Up.
|
||||
{ PS2_KEY_PGDN, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_ROLLDN, X68K_CTRL_NONE, }, // Roll Down
|
||||
{ PS2_KEY_SCROLL, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, ' ', X68K_CTRL_NONE, }, // Not assigned.
|
||||
{ PS2_KEY_ENTER, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_RETURN, X68K_CTRL_NONE, }, // Not assigned.
|
||||
{ PS2_KEY_CAPS, PS2CTRL_CAPS, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_CAPS, X68K_CTRL_NONE, }, // CAPS
|
||||
{ PS2_KEY_END, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_UNDO, X68K_CTRL_NONE, }, // UNDO
|
||||
// Keypad.
|
||||
{ PS2_KEY_KP0, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP0, X68K_CTRL_NONE, }, // Keypad 0
|
||||
{ PS2_KEY_KP1, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP1, X68K_CTRL_NONE, }, // Keypad 1
|
||||
{ PS2_KEY_KP2, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP2, X68K_CTRL_NONE, }, // Keypad 2
|
||||
{ PS2_KEY_KP3, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP3, X68K_CTRL_NONE, }, // Keypad 3
|
||||
{ PS2_KEY_KP4, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP4, X68K_CTRL_NONE, }, // Keypad 4
|
||||
{ PS2_KEY_KP5, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP5, X68K_CTRL_NONE, }, // Keypad 5
|
||||
{ PS2_KEY_KP6, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP6, X68K_CTRL_NONE, }, // Keypad 6
|
||||
{ PS2_KEY_KP7, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP7, X68K_CTRL_NONE, }, // Keypad 7
|
||||
{ PS2_KEY_KP8, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP8, X68K_CTRL_NONE, }, // Keypad 8
|
||||
{ PS2_KEY_KP9, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP9, X68K_CTRL_NONE, }, // Keypad 9
|
||||
{ PS2_KEY_KP_COMMA, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP_COMMA, X68K_CTRL_NONE, }, // Keypad Comma ,
|
||||
{ PS2_KEY_KP_DOT, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP_DOT, X68K_CTRL_NONE, }, // Keypad Full stop .
|
||||
{ PS2_KEY_KP_PLUS, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP_PLUS, X68K_CTRL_NONE, }, // Keypad Plus +
|
||||
{ PS2_KEY_KP_MINUS, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP_MINUS, X68K_CTRL_NONE, }, // Keypad Minus -
|
||||
{ PS2_KEY_KP_TIMES, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP_TIMES, X68K_CTRL_NONE, }, // Keypad Times *
|
||||
{ PS2_KEY_KP_DIV, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP_DIV, X68K_CTRL_NONE, }, // Keypad Divide /
|
||||
{ PS2_KEY_KP_EQUAL, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_MINUS, X68K_CTRL_SHIFT, }, // Keypad Equal =
|
||||
{ PS2_KEY_KP_ENTER, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP_ENTER, X68K_CTRL_NONE, }, // Keypad Ebter /
|
||||
{ PS2_KEY_KP_ENTER, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_KP_EQUAL, X68K_CTRL_NONE, }, // Keypad Ebter /
|
||||
//PS2 Code PS2 Ctrl (Flags to Match) Machine X68K Data X68K Ctrl (Flags to Set).
|
||||
// Special keys.
|
||||
{ PS2_KEY_PRTSCR, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, 0x00, X68K_CTRL_NONE, }, //
|
||||
{ PS2_KEY_PAUSE, PS2CTRL_FUNC | PS2CTRL_SHIFT, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_BREAK, X68K_CTRL_RELEASESHIFT, }, // BREAK KEY
|
||||
{ PS2_KEY_L_GUI, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_XF1, X68K_CTRL_NONE, }, // XF1
|
||||
{ PS2_KEY_L_ALT, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_XF2, X68K_CTRL_NONE, }, // XF2
|
||||
{ PS2_KEY_R_ALT, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_XF3, X68K_CTRL_NONE, }, // XF3
|
||||
{ PS2_KEY_R_GUI, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_XF4, X68K_CTRL_NONE, }, // XF4
|
||||
{ PS2_KEY_MENU, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_XF5, X68K_CTRL_NONE, }, // XF5
|
||||
// Modifiers are last, only being selected if an earlier match isnt made.
|
||||
{ PS2_KEY_L_SHIFT, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_SHIFT, X68K_CTRL_NONE, }, //
|
||||
{ PS2_KEY_R_SHIFT, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_SHIFT, X68K_CTRL_NONE, }, //
|
||||
{ PS2_KEY_L_CTRL, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_CTRL, X68K_CTRL_NONE, }, // Map to Control
|
||||
{ PS2_KEY_R_CTRL, PS2CTRL_FUNC, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_CTRL, X68K_CTRL_NONE, }, // Map to Control
|
||||
{ 0, PS2CTRL_NONE, KEYMAP_STANDARD, X68K_ALL, X68K_KEY_NULL, X68K_CTRL_NONE, }, //
|
||||
}};
|
||||
};
|
||||
|
||||
#endif // X68K_H
|
||||
BIN
releases/SharpKey_FW_v01_02_27052022.img.gz
Normal file
BIN
releases/SharpKey_FW_v01_02_27052022.img.gz
Normal file
Binary file not shown.
BIN
releases/SharpKey_FilePack_v01_01_27052022.img.gz
Normal file
BIN
releases/SharpKey_FilePack_v01_01_27052022.img.gz
Normal file
Binary file not shown.
393
sdkconfig
393
sdkconfig
@@ -40,10 +40,10 @@ CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16
|
||||
#
|
||||
CONFIG_ENABLE_ARDUINO_DEPENDS=y
|
||||
# CONFIG_AUTOSTART_ARDUINO is not set
|
||||
CONFIG_ARDUINO_RUN_CORE0=y
|
||||
# CONFIG_ARDUINO_RUN_CORE0 is not set
|
||||
# CONFIG_ARDUINO_RUN_CORE1 is not set
|
||||
# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set
|
||||
CONFIG_ARDUINO_RUNNING_CORE=0
|
||||
CONFIG_ARDUINO_RUN_NO_AFFINITY=y
|
||||
CONFIG_ARDUINO_RUNNING_CORE=-1
|
||||
CONFIG_ARDUINO_LOOP_STACK_SIZE=8192
|
||||
CONFIG_ARDUINO_EVENT_RUN_CORE0=y
|
||||
# CONFIG_ARDUINO_EVENT_RUN_CORE1 is not set
|
||||
@@ -77,7 +77,34 @@ CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y
|
||||
# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set
|
||||
# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set
|
||||
CONFIG_ARDUHAL_PARTITION_SCHEME="default"
|
||||
# CONFIG_ARDUINO_SELECTIVE_COMPILATION is not set
|
||||
CONFIG_ARDUINO_SELECTIVE_COMPILATION=y
|
||||
CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y
|
||||
# CONFIG_ARDUINO_SELECTIVE_AsyncUDP is not set
|
||||
# CONFIG_ARDUINO_SELECTIVE_AzureIoT is not set
|
||||
# CONFIG_ARDUINO_SELECTIVE_BLE is not set
|
||||
# CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set
|
||||
# CONFIG_ARDUINO_SELECTIVE_DNSServer is not set
|
||||
# CONFIG_ARDUINO_SELECTIVE_EEPROM is not set
|
||||
CONFIG_ARDUINO_SELECTIVE_ESP32=y
|
||||
CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y
|
||||
# CONFIG_ARDUINO_SELECTIVE_FFat is not set
|
||||
CONFIG_ARDUINO_SELECTIVE_FS=y
|
||||
CONFIG_ARDUINO_SELECTIVE_HTTPClient=y
|
||||
CONFIG_ARDUINO_SELECTIVE_LITTLEFS=y
|
||||
# CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set
|
||||
CONFIG_ARDUINO_SELECTIVE_Preferences=y
|
||||
# CONFIG_ARDUINO_SELECTIVE_SD is not set
|
||||
# CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set
|
||||
# CONFIG_ARDUINO_SELECTIVE_SimpleBLE is not set
|
||||
# CONFIG_ARDUINO_SELECTIVE_SPI is not set
|
||||
# CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set
|
||||
# CONFIG_ARDUINO_SELECTIVE_Ticker is not set
|
||||
# CONFIG_ARDUINO_SELECTIVE_Update is not set
|
||||
CONFIG_ARDUINO_SELECTIVE_WebServer=y
|
||||
CONFIG_ARDUINO_SELECTIVE_WiFi=y
|
||||
CONFIG_ARDUINO_SELECTIVE_WiFiClientSecure=y
|
||||
# CONFIG_ARDUINO_SELECTIVE_WiFiProv is not set
|
||||
# CONFIG_ARDUINO_SELECTIVE_Wire is not set
|
||||
# end of Arduino Configuration
|
||||
|
||||
#
|
||||
@@ -90,11 +117,11 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set
|
||||
# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set
|
||||
# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
|
||||
# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
|
||||
# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set
|
||||
# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set
|
||||
# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL=3
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL=2
|
||||
# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set
|
||||
CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y
|
||||
# CONFIG_BOOTLOADER_FACTORY_RESET is not set
|
||||
@@ -163,100 +190,114 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_SINGLE_APP=y
|
||||
# CONFIG_PARTITION_TABLE_SINGLE_APP is not set
|
||||
# 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_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="sharpkey_partition_table.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="sharpkey_partition_table.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
CONFIG_PARTITION_TABLE_MD5=y
|
||||
# end of Partition Table
|
||||
|
||||
#
|
||||
# MZ25Key Configuration
|
||||
# SharpKey Configuration
|
||||
#
|
||||
# CONFIG_SHARPKEY is not set
|
||||
CONFIG_MZ25KEY_MZ2500=y
|
||||
# CONFIG_MZ25KEY_MZ2800 is not set
|
||||
CONFIG_DISABLE_FEATURE_SECURITY=y
|
||||
# CONFIG_ENABLE_FEATURE_SECURITY is not set
|
||||
|
||||
#
|
||||
# PS2 Keyboard
|
||||
#
|
||||
CONFIG_PS2_HW_DATAPIN=32
|
||||
CONFIG_PS2_HW_CLKPIN=33
|
||||
CONFIG_KEYMAP_WYSE_KB3926=y
|
||||
# CONFIG_KEYMAP_STANDARD is not set
|
||||
# end of PS2 Keyboard
|
||||
|
||||
#
|
||||
# MZ-2500/2800 Interface
|
||||
# Host Interface
|
||||
#
|
||||
|
||||
#
|
||||
# 4Bit Strobe Input
|
||||
#
|
||||
CONFIG_MZ_KDB0=23
|
||||
CONFIG_MZ_KDB1=25
|
||||
CONFIG_MZ_KDB2=26
|
||||
CONFIG_MZ_KDB3=27
|
||||
CONFIG_HOST_KDB0=23
|
||||
CONFIG_HOST_KDB1=25
|
||||
CONFIG_HOST_KDB2=26
|
||||
CONFIG_HOST_KDB3=27
|
||||
# end of 4Bit Strobe Input
|
||||
|
||||
#
|
||||
# 8Bit Scan Data Output
|
||||
#
|
||||
CONFIG_MZ_KDO0=14
|
||||
CONFIG_MZ_KDO1=15
|
||||
CONFIG_MZ_KDO2=16
|
||||
CONFIG_MZ_KDO3=17
|
||||
CONFIG_MZ_KDO4=18
|
||||
CONFIG_MZ_KDO5=19
|
||||
CONFIG_MZ_KDO6=21
|
||||
CONFIG_MZ_KDO7=22
|
||||
CONFIG_HOST_KDO0=14
|
||||
CONFIG_HOST_KDO1=15
|
||||
CONFIG_HOST_KDO2=16
|
||||
CONFIG_HOST_KDO3=17
|
||||
CONFIG_HOST_KDO4=18
|
||||
CONFIG_HOST_KDO5=19
|
||||
CONFIG_HOST_KDO6=21
|
||||
CONFIG_HOST_KDO7=22
|
||||
# end of 8Bit Scan Data Output
|
||||
|
||||
CONFIG_MZ_RTSNI=35
|
||||
CONFIG_MZ_KDI4=13
|
||||
# end of MZ-2500/2800 Interface
|
||||
CONFIG_HOST_BITBANG_UART=y
|
||||
# CONFIG_HOST_HW_UART is not set
|
||||
CONFIG_HOST_RTSNI=35
|
||||
CONFIG_HOST_MPXI=12
|
||||
CONFIG_HOST_KDI4=13
|
||||
# end of Host Interface
|
||||
|
||||
#
|
||||
# WiFi
|
||||
#
|
||||
# CONFIG_MZ_WIFI_ENABLED is not set
|
||||
CONFIG_IF_WIFI_ENABLED=y
|
||||
CONFIG_IF_WIFI_EN_KEY=34
|
||||
CONFIG_IF_WIFI_SSID="sharpkey"
|
||||
CONFIG_IF_WIFI_DEFAULT_SSID_PWD="sharpkey"
|
||||
CONFIG_IF_WIFI_MAX_RETRIES=20
|
||||
CONFIG_IF_WIFI_AP_CHANNEL=8
|
||||
CONFIG_IF_WIFI_SSID_HIDDEN=0
|
||||
CONFIG_IF_WIFI_MAX_CONNECTIONS=5
|
||||
# end of WiFi
|
||||
|
||||
#
|
||||
# Debug Options
|
||||
#
|
||||
|
||||
#
|
||||
# OLED
|
||||
#
|
||||
# CONFIG_OLED_DISABLED is not set
|
||||
CONFIG_I2C_INTERFACE=y
|
||||
# CONFIG_SPI_INTERFACE is not set
|
||||
# CONFIG_SSD1306_128x32 is not set
|
||||
CONFIG_SSD1306_128x64=y
|
||||
CONFIG_OFFSETX=0
|
||||
# CONFIG_FLIP is not set
|
||||
CONFIG_SCL_GPIO=4
|
||||
CONFIG_SDA_GPIO=5
|
||||
CONFIG_RESET_GPIO=16
|
||||
# end of OLED
|
||||
|
||||
# CONFIG_MZ_DEBUG_SERIAL is not set
|
||||
# CONFIG_MZ_DISABLE_KDB is not set
|
||||
# CONFIG_MZ_DISABLE_KDO is not set
|
||||
# CONFIG_MZ_DISABLE_RTSNI is not set
|
||||
# CONFIG_MZ_DISABLE_KDI is not set
|
||||
# CONFIG_DEBUG_SERIAL is not set
|
||||
# CONFIG_DEBUG_DISABLE_KDB is not set
|
||||
# CONFIG_DEBUG_DISABLE_KDO is not set
|
||||
# CONFIG_DEBUG_DISABLE_RTSNI is not set
|
||||
# CONFIG_DEBUG_DISABLE_MPXI is not set
|
||||
# CONFIG_DEBUG_DISABLE_KDI is not set
|
||||
# end of Debug Options
|
||||
|
||||
CONFIG_PWRLED=2
|
||||
# end of MZ25Key Configuration
|
||||
# end of SharpKey Configuration
|
||||
|
||||
#
|
||||
# Arduino Configuration
|
||||
#
|
||||
# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set
|
||||
# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set
|
||||
CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y
|
||||
CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1
|
||||
CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048
|
||||
CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24
|
||||
|
||||
#
|
||||
# Debug Log Configuration
|
||||
#
|
||||
# end of Debug Log Configuration
|
||||
# end of Arduino Configuration
|
||||
|
||||
#
|
||||
# Compiler options
|
||||
#
|
||||
CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y
|
||||
# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set
|
||||
# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set
|
||||
# CONFIG_COMPILER_OPTIMIZATION_PERF is not set
|
||||
CONFIG_COMPILER_OPTIMIZATION_PERF=y
|
||||
# CONFIG_COMPILER_OPTIMIZATION_NONE is not set
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
|
||||
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
|
||||
@@ -296,9 +337,101 @@ CONFIG_APPTRACE_LOCK_ENABLE=y
|
||||
#
|
||||
# Bluetooth
|
||||
#
|
||||
# CONFIG_BT_ENABLED is not set
|
||||
CONFIG_BT_ENABLED=y
|
||||
|
||||
#
|
||||
# Bluetooth controller
|
||||
#
|
||||
# CONFIG_BTDM_CTRL_MODE_BLE_ONLY is not set
|
||||
# CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set
|
||||
CONFIG_BTDM_CTRL_MODE_BTDM=y
|
||||
CONFIG_BTDM_CTRL_BLE_MAX_CONN=5
|
||||
CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN=5
|
||||
CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN=0
|
||||
CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI=y
|
||||
# CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_PCM is not set
|
||||
CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0
|
||||
CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0
|
||||
CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0
|
||||
CONFIG_BTDM_CTRL_AUTO_LATENCY=y
|
||||
CONFIG_BTDM_CTRL_AUTO_LATENCY_EFF=y
|
||||
CONFIG_BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT=y
|
||||
CONFIG_BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT_EFF=y
|
||||
CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=5
|
||||
CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=5
|
||||
CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0
|
||||
CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y
|
||||
# CONFIG_BTDM_CTRL_PINNED_TO_CORE_1 is not set
|
||||
CONFIG_BTDM_CTRL_PINNED_TO_CORE=0
|
||||
CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y
|
||||
# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set
|
||||
|
||||
#
|
||||
# MODEM SLEEP Options
|
||||
#
|
||||
# CONFIG_BTDM_CTRL_MODEM_SLEEP is not set
|
||||
# end of MODEM SLEEP Options
|
||||
|
||||
CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM=y
|
||||
CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1
|
||||
CONFIG_BTDM_BLE_SCAN_DUPL=y
|
||||
CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y
|
||||
# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA is not set
|
||||
# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE is not set
|
||||
CONFIG_BTDM_SCAN_DUPL_TYPE=0
|
||||
CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=10
|
||||
# CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set
|
||||
CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y
|
||||
CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y
|
||||
CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100
|
||||
CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20
|
||||
CONFIG_BTDM_RESERVE_DRAM=0xdb5c
|
||||
CONFIG_BTDM_CTRL_HLI=y
|
||||
# end of Bluetooth controller
|
||||
|
||||
CONFIG_BT_BLUEDROID_ENABLED=y
|
||||
# CONFIG_BT_NIMBLE_ENABLED is not set
|
||||
# CONFIG_BT_CONTROLLER_ONLY is not set
|
||||
|
||||
#
|
||||
# Bluedroid Options
|
||||
#
|
||||
CONFIG_BT_BTC_TASK_STACK_SIZE=3072
|
||||
CONFIG_BT_BLUEDROID_PINNED_TO_CORE_0=y
|
||||
# CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1 is not set
|
||||
CONFIG_BT_BLUEDROID_PINNED_TO_CORE=0
|
||||
CONFIG_BT_BTU_TASK_STACK_SIZE=4096
|
||||
# CONFIG_BT_BLUEDROID_MEM_DEBUG is not set
|
||||
CONFIG_BT_CLASSIC_ENABLED=y
|
||||
# CONFIG_BT_A2DP_ENABLE is not set
|
||||
# CONFIG_BT_SPP_ENABLED is not set
|
||||
# CONFIG_BT_HFP_ENABLE is not set
|
||||
CONFIG_BT_HID_ENABLED=y
|
||||
CONFIG_BT_HID_HOST_ENABLED=y
|
||||
# CONFIG_BT_HID_DEVICE_ENABLED is not set
|
||||
CONFIG_BT_SSP_ENABLED=y
|
||||
CONFIG_BT_BLE_ENABLED=y
|
||||
# CONFIG_BT_GATTS_ENABLE is not set
|
||||
CONFIG_BT_GATTC_ENABLE=y
|
||||
# CONFIG_BT_GATTC_CACHE_NVS_FLASH is not set
|
||||
CONFIG_BT_GATTC_CONNECT_RETRY_COUNT=7
|
||||
CONFIG_BT_BLE_SMP_ENABLE=y
|
||||
# CONFIG_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set
|
||||
CONFIG_BT_STACK_NO_LOG=y
|
||||
CONFIG_BT_ACL_CONNECTIONS=5
|
||||
CONFIG_BT_MULTI_CONNECTION_ENBALE=y
|
||||
# CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST is not set
|
||||
CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=y
|
||||
# CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set
|
||||
CONFIG_BT_SMP_ENABLE=y
|
||||
# CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set
|
||||
CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=60
|
||||
# CONFIG_BT_BLE_RPA_SUPPORTED is not set
|
||||
# end of Bluedroid Options
|
||||
# end of Bluetooth
|
||||
|
||||
# CONFIG_BLE_MESH is not set
|
||||
|
||||
#
|
||||
# CoAP Configuration
|
||||
#
|
||||
@@ -373,12 +506,13 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
|
||||
#
|
||||
# eFuse Bit Manager
|
||||
#
|
||||
# CONFIG_EFUSE_CUSTOM_TABLE is not set
|
||||
CONFIG_EFUSE_CUSTOM_TABLE=y
|
||||
CONFIG_EFUSE_CUSTOM_TABLE_FILENAME="main/esp_efuse_custom_table.csv"
|
||||
# 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_NONE=y
|
||||
# CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4 is not set
|
||||
# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set
|
||||
CONFIG_EFUSE_MAX_BLK_LEN=192
|
||||
CONFIG_EFUSE_MAX_BLK_LEN=256
|
||||
# end of eFuse Bit Manager
|
||||
|
||||
#
|
||||
@@ -436,7 +570,6 @@ CONFIG_ESP32_XTAL_FREQ_40=y
|
||||
# CONFIG_ESP32_XTAL_FREQ_AUTO is not set
|
||||
CONFIG_ESP32_XTAL_FREQ=40
|
||||
# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set
|
||||
# CONFIG_ESP32_NO_BLOBS is not set
|
||||
# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
|
||||
# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set
|
||||
# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set
|
||||
@@ -469,10 +602,7 @@ CONFIG_ETH_RMII_CLK_IN_GPIO=0
|
||||
CONFIG_ETH_DMA_BUFFER_SIZE=512
|
||||
CONFIG_ETH_DMA_RX_BUFFER_NUM=10
|
||||
CONFIG_ETH_DMA_TX_BUFFER_NUM=10
|
||||
CONFIG_ETH_USE_SPI_ETHERNET=y
|
||||
# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set
|
||||
# CONFIG_ETH_SPI_ETHERNET_W5500 is not set
|
||||
# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set
|
||||
# CONFIG_ETH_USE_SPI_ETHERNET is not set
|
||||
# CONFIG_ETH_USE_OPENETH is not set
|
||||
# end of Ethernet
|
||||
|
||||
@@ -500,7 +630,7 @@ CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y
|
||||
#
|
||||
# HTTP Server
|
||||
#
|
||||
CONFIG_HTTPD_MAX_REQ_HDR_LEN=512
|
||||
CONFIG_HTTPD_MAX_REQ_HDR_LEN=2048
|
||||
CONFIG_HTTPD_MAX_URI_LEN=512
|
||||
CONFIG_HTTPD_ERR_RESP_NO_DELAY=y
|
||||
CONFIG_HTTPD_PURGE_BUF_LEN=32
|
||||
@@ -581,7 +711,7 @@ 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
|
||||
# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set
|
||||
# end of PHY
|
||||
|
||||
#
|
||||
@@ -605,8 +735,8 @@ CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y
|
||||
# end of Memory protection
|
||||
|
||||
CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
|
||||
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
|
||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584
|
||||
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=6144
|
||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=6144
|
||||
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
|
||||
@@ -620,16 +750,15 @@ CONFIG_ESP_CONSOLE_MULTIPLE_UART=y
|
||||
CONFIG_ESP_CONSOLE_UART_NUM=0
|
||||
CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200
|
||||
CONFIG_ESP_INT_WDT=y
|
||||
CONFIG_ESP_INT_WDT_TIMEOUT_MS=1000
|
||||
CONFIG_ESP_INT_WDT_TIMEOUT_MS=5000
|
||||
# CONFIG_ESP_INT_WDT_CHECK_CPU1 is not set
|
||||
CONFIG_ESP_TASK_WDT=y
|
||||
# CONFIG_ESP_TASK_WDT_PANIC is not set
|
||||
CONFIG_ESP_TASK_WDT_PANIC=y
|
||||
CONFIG_ESP_TASK_WDT_TIMEOUT_S=5
|
||||
# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set
|
||||
# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set
|
||||
# CONFIG_ESP_PANIC_HANDLER_IRAM is not set
|
||||
# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set
|
||||
CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y
|
||||
CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y
|
||||
# end of ESP System Settings
|
||||
|
||||
#
|
||||
@@ -649,13 +778,14 @@ CONFIG_ESP_TIMER_IMPL_TG0_LAC=y
|
||||
# Wi-Fi
|
||||
#
|
||||
CONFIG_ESP32_WIFI_ENABLED=y
|
||||
# CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE is not set
|
||||
CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10
|
||||
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32
|
||||
# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set
|
||||
CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y
|
||||
CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1
|
||||
CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32
|
||||
# CONFIG_ESP32_WIFI_CSI_ENABLED is not set
|
||||
CONFIG_ESP32_WIFI_CSI_ENABLED=y
|
||||
CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
|
||||
CONFIG_ESP32_WIFI_TX_BA_WIN=6
|
||||
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
||||
@@ -667,7 +797,7 @@ CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752
|
||||
CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32
|
||||
CONFIG_ESP32_WIFI_IRAM_OPT=y
|
||||
CONFIG_ESP32_WIFI_RX_IRAM_OPT=y
|
||||
CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y
|
||||
# CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE is not set
|
||||
# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set
|
||||
# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set
|
||||
# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set
|
||||
@@ -784,7 +914,6 @@ 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
|
||||
@@ -936,10 +1065,10 @@ CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y
|
||||
# end of Checksums
|
||||
|
||||
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072
|
||||
CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y
|
||||
# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set
|
||||
# CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY is not set
|
||||
CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0=y
|
||||
# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set
|
||||
CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF
|
||||
CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x0
|
||||
# CONFIG_LWIP_PPP_SUPPORT is not set
|
||||
CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3
|
||||
CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5
|
||||
@@ -1011,8 +1140,8 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y
|
||||
# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set
|
||||
# end of Certificate Bundle
|
||||
|
||||
# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set
|
||||
# CONFIG_MBEDTLS_CMAC_C is not set
|
||||
CONFIG_MBEDTLS_ECP_RESTARTABLE=y
|
||||
CONFIG_MBEDTLS_CMAC_C=y
|
||||
CONFIG_MBEDTLS_HARDWARE_AES=y
|
||||
CONFIG_MBEDTLS_HARDWARE_MPI=y
|
||||
CONFIG_MBEDTLS_HARDWARE_SHA=y
|
||||
@@ -1129,10 +1258,9 @@ CONFIG_MDNS_MULTIPLE_INSTANCE=y
|
||||
#
|
||||
# ESP-MQTT Configurations
|
||||
#
|
||||
CONFIG_MQTT_PROTOCOL_311=y
|
||||
CONFIG_MQTT_TRANSPORT_SSL=y
|
||||
CONFIG_MQTT_TRANSPORT_WEBSOCKET=y
|
||||
CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y
|
||||
# CONFIG_MQTT_PROTOCOL_311 is not set
|
||||
# CONFIG_MQTT_TRANSPORT_SSL is not set
|
||||
# CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set
|
||||
# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set
|
||||
# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set
|
||||
# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set
|
||||
@@ -1162,7 +1290,7 @@ CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y
|
||||
# OpenSSL
|
||||
#
|
||||
# CONFIG_OPENSSL_DEBUG is not set
|
||||
CONFIG_OPENSSL_ERROR_STACK=y
|
||||
# CONFIG_OPENSSL_ERROR_STACK is not set
|
||||
# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set
|
||||
CONFIG_OPENSSL_ASSERT_EXIT=y
|
||||
# end of OpenSSL
|
||||
@@ -1215,7 +1343,7 @@ CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y
|
||||
CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y
|
||||
# end of Auto-detect flash chips
|
||||
|
||||
CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y
|
||||
# CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE is not set
|
||||
# end of SPI Flash driver
|
||||
|
||||
#
|
||||
@@ -1308,6 +1436,7 @@ CONFIG_WL_SECTOR_SIZE=4096
|
||||
#
|
||||
CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16
|
||||
CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
|
||||
# CONFIG_WIFI_PROV_BLE_BONDING is not set
|
||||
# end of Wi-Fi Provisioning Manager
|
||||
|
||||
#
|
||||
@@ -1321,6 +1450,26 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y
|
||||
# CONFIG_WPA_WPS_STRICT is not set
|
||||
# CONFIG_WPA_11KV_SUPPORT is not set
|
||||
# end of Supplicant
|
||||
|
||||
#
|
||||
# LittleFS
|
||||
#
|
||||
CONFIG_LITTLEFS_MAX_PARTITIONS=3
|
||||
CONFIG_LITTLEFS_PAGE_SIZE=256
|
||||
CONFIG_LITTLEFS_OBJ_NAME_LEN=64
|
||||
CONFIG_LITTLEFS_READ_SIZE=128
|
||||
CONFIG_LITTLEFS_WRITE_SIZE=128
|
||||
CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128
|
||||
CONFIG_LITTLEFS_CACHE_SIZE=512
|
||||
CONFIG_LITTLEFS_BLOCK_CYCLES=512
|
||||
CONFIG_LITTLEFS_USE_MTIME=y
|
||||
# CONFIG_LITTLEFS_USE_ONLY_HASH is not set
|
||||
# CONFIG_LITTLEFS_HUMAN_READABLE is not set
|
||||
CONFIG_LITTLEFS_MTIME_USE_SECONDS=y
|
||||
# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set
|
||||
# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set
|
||||
# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set
|
||||
# end of LittleFS
|
||||
# end of Component config
|
||||
|
||||
#
|
||||
@@ -1333,11 +1482,11 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y
|
||||
CONFIG_TOOLPREFIX="xtensa-esp32-elf-"
|
||||
# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set
|
||||
# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set
|
||||
# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set
|
||||
CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y
|
||||
CONFIG_LOG_BOOTLOADER_LEVEL_WARN=y
|
||||
# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set
|
||||
# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set
|
||||
# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set
|
||||
CONFIG_LOG_BOOTLOADER_LEVEL=3
|
||||
CONFIG_LOG_BOOTLOADER_LEVEL=2
|
||||
# CONFIG_APP_ROLLBACK_ENABLE is not set
|
||||
# CONFIG_FLASH_ENCRYPTION_ENABLED is not set
|
||||
# CONFIG_FLASHMODE_QIO is not set
|
||||
@@ -1353,7 +1502,7 @@ CONFIG_MONITOR_BAUD_115200B=y
|
||||
# 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_DEBUG is not set
|
||||
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set
|
||||
CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
|
||||
# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
|
||||
@@ -1369,6 +1518,50 @@ CONFIG_STACK_CHECK_NONE=y
|
||||
# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
|
||||
CONFIG_ESP32_APPTRACE_DEST_NONE=y
|
||||
CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
|
||||
# CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY is not set
|
||||
# CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY is not set
|
||||
CONFIG_BTDM_CONTROLLER_MODE_BTDM=y
|
||||
CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=5
|
||||
CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN=5
|
||||
CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN=0
|
||||
CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=5
|
||||
CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=5
|
||||
CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0
|
||||
CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0
|
||||
CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y
|
||||
# CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 is not set
|
||||
# CONFIG_BTDM_CONTROLLER_MODEM_SLEEP is not set
|
||||
CONFIG_BLE_SCAN_DUPLICATE=y
|
||||
CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y
|
||||
# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA is not set
|
||||
# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set
|
||||
CONFIG_SCAN_DUPLICATE_TYPE=0
|
||||
CONFIG_DUPLICATE_SCAN_CACHE_SIZE=10
|
||||
# CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set
|
||||
CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y
|
||||
CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y
|
||||
CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM=100
|
||||
CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD=20
|
||||
CONFIG_BLUEDROID_ENABLED=y
|
||||
# CONFIG_NIMBLE_ENABLED is not set
|
||||
CONFIG_BTC_TASK_STACK_SIZE=3072
|
||||
CONFIG_BLUEDROID_PINNED_TO_CORE_0=y
|
||||
# CONFIG_BLUEDROID_PINNED_TO_CORE_1 is not set
|
||||
CONFIG_BLUEDROID_PINNED_TO_CORE=0
|
||||
CONFIG_BTU_TASK_STACK_SIZE=4096
|
||||
# CONFIG_BLUEDROID_MEM_DEBUG is not set
|
||||
CONFIG_CLASSIC_BT_ENABLED=y
|
||||
# CONFIG_A2DP_ENABLE is not set
|
||||
# CONFIG_HFP_ENABLE is not set
|
||||
# CONFIG_GATTS_ENABLE is not set
|
||||
CONFIG_GATTC_ENABLE=y
|
||||
# CONFIG_GATTC_CACHE_NVS_FLASH is not set
|
||||
CONFIG_BLE_SMP_ENABLE=y
|
||||
# CONFIG_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set
|
||||
# CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK is not set
|
||||
CONFIG_SMP_ENABLE=y
|
||||
# CONFIG_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY is not set
|
||||
CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT=60
|
||||
CONFIG_ADC2_DISABLE_DAC=y
|
||||
# CONFIG_SPIRAM_SUPPORT is not set
|
||||
CONFIG_TRACEMEM_RESERVE_DRAM=0x0
|
||||
@@ -1389,7 +1582,6 @@ CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y
|
||||
# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set
|
||||
# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set
|
||||
# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set
|
||||
# CONFIG_NO_BLOBS is not set
|
||||
# CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
|
||||
# CONFIG_EVENT_LOOP_PROFILING is not set
|
||||
CONFIG_POST_EVENTS_FROM_ISR=y
|
||||
@@ -1404,14 +1596,14 @@ 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_ESP32_REDUCE_PHY_TX_POWER is not set
|
||||
# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set
|
||||
CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y
|
||||
# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set
|
||||
# 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_SYSTEM_EVENT_TASK_STACK_SIZE=6144
|
||||
CONFIG_MAIN_TASK_STACK_SIZE=6144
|
||||
CONFIG_CONSOLE_UART_DEFAULT=y
|
||||
# CONFIG_CONSOLE_UART_CUSTOM is not set
|
||||
# CONFIG_ESP_CONSOLE_UART_NONE is not set
|
||||
@@ -1419,14 +1611,15 @@ CONFIG_CONSOLE_UART=y
|
||||
CONFIG_CONSOLE_UART_NUM=0
|
||||
CONFIG_CONSOLE_UART_BAUDRATE=115200
|
||||
CONFIG_INT_WDT=y
|
||||
CONFIG_INT_WDT_TIMEOUT_MS=1000
|
||||
CONFIG_INT_WDT_TIMEOUT_MS=5000
|
||||
# CONFIG_INT_WDT_CHECK_CPU1 is not set
|
||||
CONFIG_TASK_WDT=y
|
||||
# CONFIG_TASK_WDT_PANIC is not set
|
||||
CONFIG_TASK_WDT_PANIC=y
|
||||
CONFIG_TASK_WDT_TIMEOUT_S=5
|
||||
# CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set
|
||||
# CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set
|
||||
CONFIG_TIMER_TASK_STACK_SIZE=3584
|
||||
# CONFIG_SW_COEXIST_ENABLE is not set
|
||||
# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set
|
||||
# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set
|
||||
CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y
|
||||
@@ -1468,10 +1661,10 @@ CONFIG_TCP_OVERSIZE_MSS=y
|
||||
# CONFIG_TCP_OVERSIZE_DISABLE is not set
|
||||
CONFIG_UDP_RECVMBOX_SIZE=6
|
||||
CONFIG_TCPIP_TASK_STACK_SIZE=3072
|
||||
CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y
|
||||
# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set
|
||||
# CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY is not set
|
||||
CONFIG_TCPIP_TASK_AFFINITY_CPU0=y
|
||||
# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set
|
||||
CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF
|
||||
CONFIG_TCPIP_TASK_AFFINITY=0x0
|
||||
# CONFIG_PPP_SUPPORT is not set
|
||||
CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5
|
||||
CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072
|
||||
|
||||
7
sharpkey_partition_table.csv
Normal file
7
sharpkey_partition_table.csv
Normal file
@@ -0,0 +1,7 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
otadata, data, ota, 0x9000, 0x2000
|
||||
nvs, data, nvs, , 0x4000
|
||||
phy_init, data, phy, , 0x1000
|
||||
ota_0, app, ota_0, , 0x1A0000
|
||||
ota_1, app, ota_1, , 0x1A0000
|
||||
filesys, data, spiffs, , 0xA0000
|
||||
|
8
v1.2/CMakeLists.txt
Normal file
8
v1.2/CMakeLists.txt
Normal file
@@ -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)
|
||||
4
v1.2/main/CMakeLists.txt
Normal file
4
v1.2/main/CMakeLists.txt
Normal file
@@ -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()
|
||||
416
v1.2/main/Kconfig.projbuild
Normal file
416
v1.2/main/Kconfig.projbuild
Normal file
@@ -0,0 +1,416 @@
|
||||
menu "MZ25Key Configuration"
|
||||
|
||||
menu "PS2 Keyboard"
|
||||
|
||||
config PS2_HW_DATAPIN
|
||||
int "GPIO pin number used for the PS/2 DATA line"
|
||||
range 0 46
|
||||
default 14
|
||||
help
|
||||
GPIO number (IOxx) used to connect with the PS/2 Keyboard DATA line.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
config PS2_HW_CLKPIN
|
||||
int "GPIO pin number used for the PS/2 CLK line"
|
||||
range 0 46
|
||||
default 13
|
||||
help
|
||||
GPIO number (IOxx) used to connect with the PS/2 Keyboard CLK line.
|
||||
This pin must be interrupt capable.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
choice KEYBOARD
|
||||
prompt "Keyboard mapping"
|
||||
default KEYMAP_WYSE_KB3926
|
||||
help
|
||||
Choose the PS/2 Keyboard being used with the interface. This option selects the map defined in
|
||||
PS2KeyTable.h which maps the PS/2 Keyboard scan codes to the standard PS2_KEY_* definitions used
|
||||
in the map to MZ-2500/2800 keys.
|
||||
|
||||
config KEYMAP_WYSE_KB3926
|
||||
bool "Wyse KB-3926"
|
||||
help
|
||||
The Wyse KB3296 PS/2 keyboard mapping.
|
||||
|
||||
config KEYMAP_STANDARD
|
||||
bool "Standard Definition"
|
||||
help
|
||||
A generic PS/2 keyboard mapping.
|
||||
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
|
||||
menu "MZ-2500/2800 Interface"
|
||||
choice "Model"
|
||||
prompt "Machine Model"
|
||||
default MODEL_MZ2500
|
||||
help
|
||||
Choose the target machine on which the interface will be used. The MZ-2500 and MZ-2800 have the same keyboard hardware but the protocol differs and this option
|
||||
will choose the correct protocol.
|
||||
|
||||
config MODEL_MZ2500
|
||||
bool "Sharp MZ-2500"
|
||||
help
|
||||
The target machine is a Sharp MZ-2500.
|
||||
|
||||
config MODEL_MZ2800
|
||||
bool "Sharp MZ-2800"
|
||||
help
|
||||
The target machine is a Sharp MZ-2800.
|
||||
endchoice
|
||||
|
||||
menu "4Bit Strobe Input"
|
||||
|
||||
config MZ_KDB0
|
||||
int "KDB0 GPIO pin number"
|
||||
range 0 46
|
||||
default 23
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 4bit bidirectional data bus Bit 0 with the ESP32. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDB1
|
||||
int "KDB1 GPIO pin number"
|
||||
range 0 46
|
||||
default 25
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 4bit bidirectional data bus Bit 1 with the ESP32. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDB2
|
||||
int "KDB2 GPIO pin number"
|
||||
range 0 46
|
||||
default 26
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 4bit bidirectional data bus Bit 2 with the ESP32. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDB3
|
||||
int "KDB3 GPIO pin number"
|
||||
range 0 46
|
||||
default 27
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 4bit bidirectional data bus Bit 3 with the ESP32. See schematic for actual used value. May change with revisions.
|
||||
endmenu
|
||||
|
||||
menu "8Bit Scan Data Output"
|
||||
config MZ_KDO0
|
||||
int "KDO0 GPIO pin number"
|
||||
range 0 46
|
||||
default 14
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 0 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO1
|
||||
int "KDO1 GPIO pin number"
|
||||
range 0 46
|
||||
default 15
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 1 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO2
|
||||
int "KDO2 GPIO pin number"
|
||||
range 0 46
|
||||
default 16
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 2 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO3
|
||||
int "KDO3 GPIO pin number"
|
||||
range 0 46
|
||||
default 17
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 3 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO4
|
||||
int "KDO4 GPIO pin number"
|
||||
range 0 46
|
||||
default 18
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 4 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO5
|
||||
int "KDO5 GPIO pin number"
|
||||
range 0 46
|
||||
default 19
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 5 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO6
|
||||
int "KDO6 GPIO pin number"
|
||||
range 0 46
|
||||
default 21
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 6 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDO7
|
||||
int "KDO7 GPIO pin number"
|
||||
range 0 46
|
||||
default 21
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 8bit scan data output Bit 7 to the 74HCT257 IC. See schematic for actual used value. May change with revisions.
|
||||
endmenu
|
||||
|
||||
config MZ_RTSNI
|
||||
int "RTSNi GPIO pin number"
|
||||
range 0 46
|
||||
default 35
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 RTSN line with the ESP32. See schematic for actual used value. May change with revisions.
|
||||
|
||||
config MZ_KDI4
|
||||
int "KDI4 GPIO pin number"
|
||||
range 0 46
|
||||
default 13
|
||||
help
|
||||
GPIO number (IOxx) used to connect the MZ-2500/2800 KDI4 line with the ESP32. See schematic for actual used value. May change with revisions.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "WiFi"
|
||||
|
||||
config MZ_WIFI_ENABLED
|
||||
bool "Enable WiFi connectivity"
|
||||
default false
|
||||
help
|
||||
Allow interface to act as an Access Point to allow external connectivity. Once connected the WiFi is intended to be used for making
|
||||
key mapping changes.
|
||||
This is an experimental feature and under development.
|
||||
|
||||
config MZ_WIFI_EN_KEY
|
||||
int "WiFi Enable GPIO pin number"
|
||||
range 0 46
|
||||
default 34
|
||||
depends on MZ_WIFI_ENABLED
|
||||
help
|
||||
GPIO number (IOxx) used by the WiFi En switch to enable wifi connectivity.
|
||||
|
||||
config MZ_SSID
|
||||
string "Default SSID in Access Point Mode"
|
||||
default "mz25key"
|
||||
depends on MZ_WIFI_ENABLED
|
||||
help
|
||||
The SSID broadcast whilst the mz25key module advertises wireless connectivity.
|
||||
|
||||
config MZ_DEFAULT_SSID_PWD
|
||||
string "Default password for initial connection to Access Point Mode"
|
||||
default "mz25key"
|
||||
depends on MZ_WIFI_ENABLED
|
||||
help
|
||||
The initial password needed to connect and logon to access point.
|
||||
|
||||
config MZ_WIFI_MAX_RETRIES
|
||||
int "Maximum number of connection retries."
|
||||
range 0 100
|
||||
default 10
|
||||
depends on MZ_WIFI_ENABLED
|
||||
help
|
||||
Number of retries allowed for making a wireless connection with a client.
|
||||
|
||||
config MZ_WIFI_AP_CHANNEL
|
||||
int "Channel of the Access Point."
|
||||
range 0 13
|
||||
default 7
|
||||
depends on MZ_WIFI_ENABLED
|
||||
help
|
||||
Channel use by the Access Point, default is 7.
|
||||
|
||||
config MZ_WIFI_SSID_HIDDEN
|
||||
int "Broadcast SSID?"
|
||||
range 0 1
|
||||
default 0
|
||||
depends on MZ_WIFI_ENABLED
|
||||
help
|
||||
Broadcast the SSID (0) or hide it (1).
|
||||
|
||||
config MZ_WIFI_MAX_CONNECTIONS
|
||||
int "Maximum sinultaneous connections."
|
||||
range 0 20
|
||||
default 5
|
||||
depends on MZ_WIFI_ENABLED
|
||||
help
|
||||
Maximum number of simultaneous open connections supported.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Debug Options"
|
||||
|
||||
menu "OLED"
|
||||
|
||||
choice INTERFACE
|
||||
prompt "OLED Interface Type"
|
||||
default OLED_DISABLED
|
||||
help
|
||||
Select Interface.
|
||||
config OLED_DISABLED
|
||||
bool "Interface disabled"
|
||||
help
|
||||
No OLED present or to be disabled.
|
||||
config I2C_INTERFACE
|
||||
bool "I2C Interface"
|
||||
help
|
||||
I2C Interface.
|
||||
config SPI_INTERFACE
|
||||
bool "SPI Interface"
|
||||
help
|
||||
SPI Interface.
|
||||
endchoice
|
||||
|
||||
choice PANEL
|
||||
prompt "OLED Panel Type"
|
||||
depends on I2C_INTERFACE || SPI_INTERFACE
|
||||
default SSD1306_128x64
|
||||
help
|
||||
Select Panel Type.
|
||||
config SSD1306_128x32
|
||||
bool "128x32 Panel"
|
||||
help
|
||||
Panel is 128x32.
|
||||
config SSD1306_128x64
|
||||
bool "128x64 Panel"
|
||||
help
|
||||
Panel is 128x64.
|
||||
endchoice
|
||||
|
||||
config OFFSETX
|
||||
int "GRAM X OFFSET"
|
||||
range 0 99
|
||||
default 0
|
||||
help
|
||||
When your TFT have offset(X), set it.
|
||||
|
||||
config FLIP
|
||||
bool "Flip upside down"
|
||||
default false
|
||||
help
|
||||
Flip upside down.
|
||||
|
||||
config SCL_GPIO
|
||||
depends on I2C_INTERFACE
|
||||
int "SCL GPIO number"
|
||||
range 0 46
|
||||
default 22 if IDF_TARGET_ESP32
|
||||
default 12 if IDF_TARGET_ESP32S2
|
||||
default 9 if IDF_TARGET_ESP32C3
|
||||
default 15 if IDF_TARGET_HELTEC32
|
||||
help
|
||||
GPIO number (IOxx) to I2C SCL.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
config SDA_GPIO
|
||||
depends on I2C_INTERFACE
|
||||
int "SDA GPIO number"
|
||||
range 0 46
|
||||
default 21 if IDF_TARGET_ESP32
|
||||
default 11 if IDF_TARGET_ESP32S2
|
||||
default 10 if IDF_TARGET_ESP32C3
|
||||
default 4 if IDF_TARGET_HELTEC32
|
||||
help
|
||||
GPIO number (IOxx) to I2C SDA.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
config RESET_GPIO
|
||||
int "RESET GPIO number"
|
||||
range -1 46
|
||||
default -1 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3
|
||||
default 16 if IDF_TARGET_HELTEC32
|
||||
help
|
||||
GPIO number (IOxx) to RESET.
|
||||
When it is -1, RESET isn't performed.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to Reset.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
config MOSI_GPIO
|
||||
depends on SPI_INTERFACE
|
||||
int "MOSI GPIO number"
|
||||
range 0 46
|
||||
default 23 if IDF_TARGET_ESP32
|
||||
default 35 if IDF_TARGET_ESP32S2
|
||||
default 0 if IDF_TARGET_ESP32C3
|
||||
help
|
||||
GPIO number (IOxx) to SPI MOSI.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to DC.
|
||||
On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs.
|
||||
|
||||
config SCLK_GPIO
|
||||
depends on SPI_INTERFACE
|
||||
int "SCLK GPIO number"
|
||||
range 0 46
|
||||
default 18 if IDF_TARGET_ESP32
|
||||
default 36 if IDF_TARGET_ESP32S2
|
||||
default 1 if IDF_TARGET_ESP32C3
|
||||
help
|
||||
GPIO number (IOxx) to SPI SCLK.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to DC.
|
||||
On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs.
|
||||
|
||||
config CS_GPIO
|
||||
depends on SPI_INTERFACE
|
||||
int "CS GPIO number"
|
||||
range 0 34
|
||||
default 5 if IDF_TARGET_ESP32
|
||||
default 34 if IDF_TARGET_ESP32S2
|
||||
default 10 if IDF_TARGET_ESP32C3
|
||||
help
|
||||
GPIO number (IOxx) to SPI CS.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to CS.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
config DC_GPIO
|
||||
depends on SPI_INTERFACE
|
||||
int "DC GPIO number"
|
||||
range 0 34
|
||||
default 2
|
||||
help
|
||||
GPIO number (IOxx) to SPI DC.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to DC.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
endmenu
|
||||
|
||||
config MZ_DEBUG_SERIAL
|
||||
bool "Serial debug output"
|
||||
default false
|
||||
help
|
||||
Enable debug output (non ESP logging) on the serial port.
|
||||
|
||||
config MZ_DISABLE_KDB
|
||||
bool "Disable input mode actuation of the KDB data bus"
|
||||
default false
|
||||
help
|
||||
Disable the MZ Interface KDB input configuration step, useful feature for debugging.
|
||||
|
||||
config MZ_DISABLE_KDO
|
||||
bool "Disable output mode actuation of the KDO strobe row"
|
||||
default false
|
||||
help
|
||||
Disable the MZ Interface KDO output configuration step, useful feature for debugging.
|
||||
|
||||
config MZ_DISABLE_RTSNI
|
||||
bool "Disable input mode actuation of the RTSNi signal"
|
||||
default false
|
||||
help
|
||||
Disable the MZ Interface RTSNi input configuration step, useful feature for debugging.
|
||||
|
||||
config MZ_DISABLE_KDI
|
||||
bool "Disable input mode actuation of the KDI4 signal"
|
||||
default false
|
||||
help
|
||||
Disable the MZ Interface KDI input configuration step, useful feature for debugging.
|
||||
endmenu
|
||||
|
||||
config PWRLED
|
||||
int "GPIO pin number used for Power On and Status LED"
|
||||
range 0 46
|
||||
default 25
|
||||
help
|
||||
GPIO number (IOxx) used to control the Power On/Status LED.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -251,7 +251,12 @@
|
||||
PS2_KEY_PGUP, MZ_ALL, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Not assigned.
|
||||
PS2_KEY_DELETE, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0A, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // DELETE
|
||||
PS2_KEY_END, MZ_ALL, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Not assigned.
|
||||
PS2_KEY_PGDN, MZ_ALL, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
#if defined(CONFIG_MODEL_MZ2500)
|
||||
PS2_KEY_PGDN, MZ_ALL, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Not mapped
|
||||
#endif
|
||||
#if defined(CONFIG_MODEL_MZ2800)
|
||||
PS2_KEY_PGDN, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0C, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Japanese Key - Previous
|
||||
#endif
|
||||
PS2_KEY_UP_ARROW, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x03, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Up Arrow
|
||||
PS2_KEY_L_ARROW, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x03, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Left Arrow
|
||||
PS2_KEY_DN_ARROW, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x03, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Down Arrow
|
||||
@@ -291,7 +296,12 @@
|
||||
PS2_KEY_L_SHIFT, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
PS2_KEY_R_SHIFT, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0B, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
PS2_KEY_L_CTRL, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0B, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
PS2_KEY_R_CTRL, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0B, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
#if defined(CONFIG_MODEL_MZ2500)
|
||||
PS2_KEY_R_CTRL, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0B, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Map to Control
|
||||
#endif
|
||||
#if defined(CONFIG_MODEL_MZ2800)
|
||||
PS2_KEY_R_CTRL, MZ_ALL, 0, 0, 0, 0, 0, 0, 0x0C, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Japanese Key - Cancel
|
||||
#endif
|
||||
0, MZ_ALL, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
#endif
|
||||
1093
v1.2/main/PS2KeyAdvanced.cpp
Normal file
1093
v1.2/main/PS2KeyAdvanced.cpp
Normal file
File diff suppressed because it is too large
Load Diff
276
v1.2/main/PS2KeyCode.h
Normal file
276
v1.2/main/PS2KeyCode.h
Normal file
@@ -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 <sales@pcserviceselectronics.co.uk>
|
||||
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
|
||||
8
v1.2/main/component.mk
Normal file
8
v1.2/main/component.mk
Normal file
@@ -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.
|
||||
#
|
||||
@@ -65,9 +65,8 @@
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sys.h"
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sys.h"
|
||||
#endif
|
||||
#include "Arduino.h"
|
||||
#include "driver/gpio.h"
|
||||
@@ -110,8 +109,13 @@ PS2KeyAdvanced Keyboard;
|
||||
// Debug required objects.
|
||||
SSD1306_t SSD1306;
|
||||
|
||||
// Handle to interact with the mz-2500 interface, ps/2 interface and wifi threads.
|
||||
TaskHandle_t TaskMZ25IF = NULL;
|
||||
// Handle to interact with the mz-2500/mz-2800 interface, ps/2 interface and wifi threads.
|
||||
#if defined(CONFIG_MODEL_MZ2500)
|
||||
TaskHandle_t TaskMZ25IF = NULL;
|
||||
#endif
|
||||
#if defined(CONFIG_MODEL_MZ2800)
|
||||
TaskHandle_t TaskMZ28IF = NULL;
|
||||
#endif
|
||||
TaskHandle_t TaskPS2IF = NULL;
|
||||
#if defined(CONFIG_MZ_WIFI_ENABLED)
|
||||
TaskHandle_t TaskWIFI = NULL;
|
||||
@@ -121,7 +125,12 @@ TaskHandle_t TaskPS2IF = NULL;
|
||||
static portMUX_TYPE mzMutex = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
// Tag for ESP main application logging.
|
||||
#define MAINTAG "mz25key"
|
||||
#if defined(CONFIG_MODEL_MZ2500)
|
||||
#define MAINTAG "mz25key"
|
||||
#endif
|
||||
#if defined(CONFIG_MODEL_MZ2800)
|
||||
#define MAINTAG "mz28key"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MZ_WIFI_ENABLED)
|
||||
// The event group allows multiple bits for each event, but we only care about two events:
|
||||
@@ -180,12 +189,15 @@ static portMUX_TYPE mzMutex = portMUX_INITIALIZER_UNLOCKED;
|
||||
#define dbgprintf(a, ...) {};
|
||||
#endif
|
||||
|
||||
// Method to connect and interact with the MZ-2500/MZ-2800 keyboard controller.
|
||||
// Method to connect and interact with the MZ-2500 keyboard controller. This method is seperate from the MZ-2800
|
||||
// as the scan is different and as it is time critical it is better to be per target machine.
|
||||
//
|
||||
// The basic requirement is to:
|
||||
// 1. Detect a falling edge on the RTSN signal
|
||||
// 2. Read the provided ROW number.
|
||||
// 3. Lookup the matrix data for given ROW.
|
||||
// 4. Output data to LS257 Mux.
|
||||
// 5. Wait for RTSN to return inactive.
|
||||
// 5. Loop
|
||||
//
|
||||
// The ps2Interface method is responsible for obtaining a PS/2 Keyboard scancode and
|
||||
@@ -206,78 +218,190 @@ static portMUX_TYPE mzMutex = portMUX_INITIALIZER_UNLOCKED;
|
||||
// are in the first GPIO bank and RTSNi is in the second GPIO bank. Modify the code
|
||||
// if RTSNi is set in the first bank or KDB[3:0], KDI4 are in the second bank.
|
||||
//
|
||||
IRAM_ATTR void mz25Interface( void * pvParameters )
|
||||
{
|
||||
// Locals.
|
||||
volatile uint32_t gpioIN;
|
||||
volatile uint8_t strobeRow = 1;
|
||||
|
||||
// Mask values declared as variables, let the optimiser decide wether they are constants or placed in-memory.
|
||||
uint32_t rowBitMask = (1 << CONFIG_MZ_KDB3) | (1 << CONFIG_MZ_KDB2) | (1 << CONFIG_MZ_KDB1) | (1 << CONFIG_MZ_KDB0);
|
||||
uint32_t colBitMask = (1 << CONFIG_MZ_KDO7) | (1 << CONFIG_MZ_KDO6) | (1 << CONFIG_MZ_KDO5) | (1 << CONFIG_MZ_KDO4) |
|
||||
(1 << CONFIG_MZ_KDO3) | (1 << CONFIG_MZ_KDO2) | (1 << CONFIG_MZ_KDO1) | (1 << CONFIG_MZ_KDO0);
|
||||
uint32_t KDB3_MASK = (1 << CONFIG_MZ_KDB3);
|
||||
uint32_t KDB2_MASK = (1 << CONFIG_MZ_KDB2);
|
||||
uint32_t KDB1_MASK = (1 << CONFIG_MZ_KDB1);
|
||||
uint32_t KDB0_MASK = (1 << CONFIG_MZ_KDB0);
|
||||
uint32_t KDI4_MASK = (1 << CONFIG_MZ_KDI4);
|
||||
uint32_t RTSNI_MASK = (1 << (CONFIG_MZ_RTSNI - 32));
|
||||
|
||||
ESP_LOGI(MAINTAG, "Starting mz25Interface thread, colBitMask=%08x, rowBitMask=%08x.", colBitMask, rowBitMask);
|
||||
|
||||
// Create, initialise and hold a spinlock so the current core is bound to this one method.
|
||||
portENTER_CRITICAL(&mzMutex);
|
||||
|
||||
// Permanent loop, just wait for an RTSN strobe, latch the row, lookup matrix and output.
|
||||
// Timings with Power LED = LED Off to On = 108ns, LED On to Off = 392ns
|
||||
for(;;)
|
||||
#if defined(CONFIG_MODEL_MZ2500)
|
||||
IRAM_ATTR void mz25Interface( void * pvParameters )
|
||||
{
|
||||
#if defined(CONFIG_MZ_WIFI_ENABLED)
|
||||
// Whilst Wifi is active, suspend processing as we need to free up the core.
|
||||
if(wifiActivated)
|
||||
{
|
||||
portEXIT_CRITICAL(&mzMutex);
|
||||
while(wifiActivated);
|
||||
portENTER_CRITICAL(&mzMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Detect RTSN going high, the MZ will send the required row during this cycle.
|
||||
if(REG_READ(GPIO_IN1_REG) & RTSNI_MASK)
|
||||
// Locals.
|
||||
volatile uint32_t gpioIN;
|
||||
volatile uint8_t strobeRow = 1;
|
||||
|
||||
// Mask values declared as variables, let the optimiser decide wether they are constants or placed in-memory.
|
||||
uint32_t rowBitMask = (1 << CONFIG_MZ_KDB3) | (1 << CONFIG_MZ_KDB2) | (1 << CONFIG_MZ_KDB1) | (1 << CONFIG_MZ_KDB0);
|
||||
uint32_t colBitMask = (1 << CONFIG_MZ_KDO7) | (1 << CONFIG_MZ_KDO6) | (1 << CONFIG_MZ_KDO5) | (1 << CONFIG_MZ_KDO4) |
|
||||
(1 << CONFIG_MZ_KDO3) | (1 << CONFIG_MZ_KDO2) | (1 << CONFIG_MZ_KDO1) | (1 << CONFIG_MZ_KDO0);
|
||||
uint32_t KDB3_MASK = (1 << CONFIG_MZ_KDB3);
|
||||
uint32_t KDB2_MASK = (1 << CONFIG_MZ_KDB2);
|
||||
uint32_t KDB1_MASK = (1 << CONFIG_MZ_KDB1);
|
||||
uint32_t KDB0_MASK = (1 << CONFIG_MZ_KDB0);
|
||||
uint32_t KDI4_MASK = (1 << CONFIG_MZ_KDI4);
|
||||
uint32_t RTSNI_MASK = (1 << (CONFIG_MZ_RTSNI - 32));
|
||||
|
||||
ESP_LOGI(MAINTAG, "Starting mz25Interface thread, colBitMask=%08x, rowBitMask=%08x.", colBitMask, rowBitMask);
|
||||
|
||||
// Create, initialise and hold a spinlock so the current core is bound to this one method.
|
||||
portENTER_CRITICAL(&mzMutex);
|
||||
|
||||
// Permanent loop, just wait for an RTSN strobe, latch the row, lookup matrix and output.
|
||||
// Timings with Power LED = LED Off to On = 108ns, LED On to Off = 392ns
|
||||
for(;;)
|
||||
{
|
||||
// Read the GPIO ports to get latest Row and KDI4 states.
|
||||
gpioIN = REG_READ(GPIO_IN_REG);
|
||||
|
||||
// Assemble the required matrix row from the configured bits.
|
||||
strobeRow = ((gpioIN&KDB3_MASK) >> (CONFIG_MZ_KDB3-3)) | ((gpioIN&KDB2_MASK) >> (CONFIG_MZ_KDB2-2)) | ((gpioIN&KDB1_MASK) >> (CONFIG_MZ_KDB1-1)) | ((gpioIN&KDB0_MASK) >> CONFIG_MZ_KDB0);
|
||||
|
||||
// Clear all KDO bits - clear state = '1'
|
||||
GPIO.out_w1ts = colBitMask; // Reset all scan data bits to '1', inactive.
|
||||
|
||||
// KDI4 indicates if row data is needed or a single byte ANDing all the keys together, ie. to detect a key press without strobing all rows.
|
||||
if(gpioIN & KDI4_MASK)
|
||||
#if defined(CONFIG_MZ_WIFI_ENABLED)
|
||||
// Whilst Wifi is active, suspend processing as we need to free up the core.
|
||||
if(wifiActivated)
|
||||
{
|
||||
portEXIT_CRITICAL(&mzMutex);
|
||||
while(wifiActivated);
|
||||
portENTER_CRITICAL(&mzMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Detect RTSN going high, the MZ will send the required row during this cycle.
|
||||
if(REG_READ(GPIO_IN1_REG) & RTSNI_MASK)
|
||||
{
|
||||
// Set all required KDO bits according to keyMatrix, set state = '0'.
|
||||
GPIO.out_w1tc = mzControl.keyMatrixAsGPIO[strobeRow]; // Set to '0' active bits.
|
||||
} else
|
||||
{
|
||||
// Set all required KDO bits according to the strobe all value. set state = '0'.
|
||||
GPIO.out_w1tc = mzControl.strobeAllAsGPIO; // Set to '0' active bits.
|
||||
// Read the GPIO ports to get latest Row and KDI4 states.
|
||||
gpioIN = REG_READ(GPIO_IN_REG);
|
||||
|
||||
// Assemble the required matrix row from the configured bits.
|
||||
strobeRow = ((gpioIN&KDB3_MASK) >> (CONFIG_MZ_KDB3-3)) | ((gpioIN&KDB2_MASK) >> (CONFIG_MZ_KDB2-2)) | ((gpioIN&KDB1_MASK) >> (CONFIG_MZ_KDB1-1)) | ((gpioIN&KDB0_MASK) >> CONFIG_MZ_KDB0);
|
||||
|
||||
// Clear all KDO bits - clear state = '1'
|
||||
GPIO.out_w1ts = colBitMask; // Reset all scan data bits to '1', inactive.
|
||||
|
||||
// KDI4 indicates if row data is needed or a single byte ANDing all the keys together, ie. to detect a key press without strobing all rows.
|
||||
if(gpioIN & KDI4_MASK)
|
||||
{
|
||||
// Set all required KDO bits according to keyMatrix, set state = '0'.
|
||||
GPIO.out_w1tc = mzControl.keyMatrixAsGPIO[strobeRow]; // Set to '0' active bits.
|
||||
} else
|
||||
{
|
||||
// Set all required KDO bits according to the strobe all value. set state = '0'.
|
||||
GPIO.out_w1tc = mzControl.strobeAllAsGPIO; // Set to '0' active bits.
|
||||
}
|
||||
|
||||
// Wait for RTSN to go low. No lockup guarding as timing is critical also the watchdog is disabled, if RTSN never goes low then the user has probably unplugged the interface!
|
||||
while(REG_READ(GPIO_IN1_REG) & RTSNI_MASK);
|
||||
}
|
||||
|
||||
// Wait for RTSN to go low. No lockup guarding as timing is critical also the watchdog is disabled, if RTSN never goes low then the user has probably unplugged the interface!
|
||||
while(REG_READ(GPIO_IN1_REG) & RTSNI_MASK);
|
||||
|
||||
// Logic to feed the watchdog if needed. Watchdog disabled in menuconfig but if enabled this will need to be used.
|
||||
//TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable
|
||||
//TIMERG0.wdt_feed=1; // feed dog
|
||||
//TIMERG0.wdt_wprotect=0; // write protect
|
||||
//TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable
|
||||
//TIMERG1.wdt_feed=1; // feed dog
|
||||
//TIMERG1.wdt_wprotect=0; // write protect
|
||||
}
|
||||
|
||||
// Logic to feed the watchdog if needed. Watchdog disabled in menuconfig but if enabled this will need to be used.
|
||||
//TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable
|
||||
//TIMERG0.wdt_feed=1; // feed dog
|
||||
//TIMERG0.wdt_wprotect=0; // write protect
|
||||
//TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable
|
||||
//TIMERG1.wdt_feed=1; // feed dog
|
||||
//TIMERG1.wdt_wprotect=0; // write protect
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Method to connect and interact with the MZ-2800 keyboard controller. This method is seperate from the MZ-2500
|
||||
// as the scan is different and as it is time critical it needs to be per target machine.
|
||||
//
|
||||
// The basic requirement is to:
|
||||
// 1. Detect a rising edge on the RTSN signal
|
||||
// 2. Wait at least 200ns before sampling KD4
|
||||
// 3. Wait at least 650ns before reading ROW.
|
||||
// 4. Read the provided ROW number.
|
||||
// 5. If KD4 = 0 then output logical AND of all columns to LS257 Mux.
|
||||
// 6. If KD4 = 1 then lookup data for given row and output to LS257 Mux.
|
||||
// 7. Wait for RTSN to return low.
|
||||
// 7. Loop
|
||||
//
|
||||
// The ps2Interface method is responsible for obtaining a PS/2 Keyboard scancode and
|
||||
// creating the corresponding virtual matrix.
|
||||
//
|
||||
// NB: As this method holds Core 1 under spinlock, no FreeRTOS or Arduino access
|
||||
// can be made except for basic I/O ports. The spinlock has to be released for non
|
||||
// I/O work.
|
||||
//
|
||||
// The MZ 2800 timing period is 1.78uS RTSN going active high, KD4 changing state 150ns after RTSN goes active,
|
||||
// ROW number being set 650ns after RTSN goes active. MPX directly controls the LS257 latch so only need to write out
|
||||
// and 8 bit value prior to RTSN going inactive.
|
||||
// Normally the keyboard is in STROBE ALL mode. When a key is pressed, it commences a scan and when it arrives at the pressed
|
||||
// key, RTSN cycle is suspended for varying amounts of time (ie 500us or 19ms) as the controller is looking for debounce and repeat.
|
||||
//
|
||||
// WARNING: The GPIO's are configurable via menuconfig BUT it is assumed all except RTSNi
|
||||
// are in the first GPIO bank and RTSNi is in the second GPIO bank. Modify the code
|
||||
// if RTSNi is set in the first bank or KDB[3:0], KDI4 are in the second bank.
|
||||
//
|
||||
#if defined(CONFIG_MODEL_MZ2800)
|
||||
IRAM_ATTR void mz28Interface( void * pvParameters )
|
||||
{
|
||||
// Locals.
|
||||
volatile uint32_t gpioIN;
|
||||
volatile uint8_t strobeRow = 1;
|
||||
|
||||
// Mask values declared as variables, let the optimiser decide wether they are constants or placed in-memory.
|
||||
uint32_t rowBitMask = (1 << CONFIG_MZ_KDB3) | (1 << CONFIG_MZ_KDB2) | (1 << CONFIG_MZ_KDB1) | (1 << CONFIG_MZ_KDB0);
|
||||
uint32_t colBitMask = (1 << CONFIG_MZ_KDO7) | (1 << CONFIG_MZ_KDO6) | (1 << CONFIG_MZ_KDO5) | (1 << CONFIG_MZ_KDO4) |
|
||||
(1 << CONFIG_MZ_KDO3) | (1 << CONFIG_MZ_KDO2) | (1 << CONFIG_MZ_KDO1) | (1 << CONFIG_MZ_KDO0);
|
||||
uint32_t KDB3_MASK = (1 << CONFIG_MZ_KDB3);
|
||||
uint32_t KDB2_MASK = (1 << CONFIG_MZ_KDB2);
|
||||
uint32_t KDB1_MASK = (1 << CONFIG_MZ_KDB1);
|
||||
uint32_t KDB0_MASK = (1 << CONFIG_MZ_KDB0);
|
||||
uint32_t KDI4_MASK = (1 << CONFIG_MZ_KDI4);
|
||||
uint32_t RTSNI_MASK = (1 << (CONFIG_MZ_RTSNI - 32));
|
||||
|
||||
ESP_LOGI(MAINTAG, "Starting mz28Interface thread, colBitMask=%08x, rowBitMask=%08x.", colBitMask, rowBitMask);
|
||||
|
||||
// Create, initialise and hold a spinlock so the current core is bound to this one method.
|
||||
portENTER_CRITICAL(&mzMutex);
|
||||
|
||||
// Permanent loop, just wait for an RTSN strobe, latch the row, lookup matrix and output.
|
||||
for(;;)
|
||||
{
|
||||
#if defined(CONFIG_MZ_WIFI_ENABLED)
|
||||
// Whilst Wifi is active, suspend processing as we need to free up the core.
|
||||
if(wifiActivated)
|
||||
{
|
||||
portEXIT_CRITICAL(&mzMutex);
|
||||
while(wifiActivated);
|
||||
portENTER_CRITICAL(&mzMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Detect RTSN going high, the MZ will send the required row during this cycle.
|
||||
if(REG_READ(GPIO_IN1_REG) & RTSNI_MASK)
|
||||
{
|
||||
// Slight delay needed as KD4 lags behind RTSN by approx 200ns and ROW number lags 850ns behind RTSN.
|
||||
for(volatile uint32_t delay=0; delay < 8; delay++);
|
||||
|
||||
// Read the GPIO ports to get latest Row and KDI4 states.
|
||||
gpioIN = REG_READ(GPIO_IN_REG);
|
||||
|
||||
// Assemble the required matrix row from the configured bits.
|
||||
strobeRow = ((gpioIN&KDB3_MASK) >> (CONFIG_MZ_KDB3-3)) | ((gpioIN&KDB2_MASK) >> (CONFIG_MZ_KDB2-2)) | ((gpioIN&KDB1_MASK) >> (CONFIG_MZ_KDB1-1)) | ((gpioIN&KDB0_MASK) >> CONFIG_MZ_KDB0);
|
||||
|
||||
// Clear all KDO bits - clear state = '1'
|
||||
GPIO.out_w1ts = colBitMask; // Reset all scan data bits to '1', inactive.
|
||||
|
||||
// Another short delay once the row has been assembled as we dont want to change the latch setting too soon, changing too soon leads to ghosting on previous row.
|
||||
for(volatile uint32_t delay=0; delay < 5; delay++);
|
||||
|
||||
// KDI4 indicates if row data is needed or a single byte ANDing all the keys together, ie. to detect a key press without strobing all rows.
|
||||
if(gpioIN & KDI4_MASK)
|
||||
{
|
||||
// Set all required KDO bits according to keyMatrix, set state = '0'.
|
||||
GPIO.out_w1tc = mzControl.keyMatrixAsGPIO[strobeRow]; // Set to '0' active bits.
|
||||
} else
|
||||
{
|
||||
// Set all required KDO bits according to the strobe all value. set state = '0'.
|
||||
GPIO.out_w1tc = mzControl.strobeAllAsGPIO; // Set to '0' active bits.
|
||||
}
|
||||
|
||||
// Wait for RTSN to go low. No lockup guarding as timing is critical also the watchdog is disabled, if RTSN never goes low then the user has probably unplugged the interface!
|
||||
while(REG_READ(GPIO_IN1_REG) & RTSNI_MASK);
|
||||
}
|
||||
|
||||
// Logic to feed the watchdog if needed. Watchdog disabled in menuconfig but if enabled this will need to be used.
|
||||
//TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable
|
||||
//TIMERG0.wdt_feed=1; // feed dog
|
||||
//TIMERG0.wdt_wprotect=0; // write protect
|
||||
//TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable
|
||||
//TIMERG1.wdt_feed=1; // feed dog
|
||||
//TIMERG1.wdt_wprotect=0; // write protect
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Method to refresh the transposed matrix used in the MZ interface. The normal key matrix is transposed to save valuable time
|
||||
// because even though a core is dedicated to the MZ interface the timing is critical and the ESP-32 doesnt have spare horse power!
|
||||
@@ -1091,12 +1215,18 @@ void setup()
|
||||
|
||||
// Create a task pinned to core 0 which will fulfill the MZ-2500/2800 interface. This task has the highest priority
|
||||
// and it will also hold spinlock and manipulate the watchdog to ensure a scan cycle timing can be met. This means
|
||||
// all other tasks running on Core 1 will suspend. The PS/2 controller, running on the ULP processor will continue
|
||||
// to interact with the PS/2 keyboard and buffer scan codes.
|
||||
// all other tasks running on Core 1 will suspend. The PS/2 controller which runs on core 0 will continue to interact
|
||||
// with the PS/2 keyboard and buffer scan codes.
|
||||
//
|
||||
// Core 1 - MZ Interface
|
||||
ESP_LOGI(MAINTAG, "Starting mz25if thread...");
|
||||
xTaskCreatePinnedToCore(mz25Interface, "mz25if", 32768, NULL, 25, &TaskMZ25IF, 1);
|
||||
#if defined(CONFIG_MODEL_MZ2500)
|
||||
ESP_LOGI(MAINTAG, "Starting mz25if thread...");
|
||||
xTaskCreatePinnedToCore(mz25Interface, "mz25if", 32768, NULL, 25, &TaskMZ25IF, 1);
|
||||
#endif
|
||||
#if defined(CONFIG_MODEL_MZ2800)
|
||||
ESP_LOGI(MAINTAG, "Starting mz28if thread...");
|
||||
xTaskCreatePinnedToCore(mz28Interface, "mz28if", 32768, NULL, 25, &TaskMZ28IF, 1);
|
||||
#endif
|
||||
vTaskDelay(500);
|
||||
|
||||
// Core 0 - Application
|
||||
@@ -1105,7 +1235,7 @@ void setup()
|
||||
xTaskCreatePinnedToCore(ps2Interface, "ps2if", 32768, NULL, 22, &TaskPS2IF, 0);
|
||||
vTaskDelay(500);
|
||||
|
||||
// Core 9 - WiFi handler thread.
|
||||
// Core 0 - WiFi handler thread.
|
||||
#if defined(CONFIG_MZ_WIFI_ENABLED)
|
||||
ESP_LOGI(MAINTAG, "Starting wifi thread...");
|
||||
xTaskCreatePinnedToCore(wifiInterface, "wifi", 32768, NULL, 1, &TaskWIFI, 0);
|
||||
1493
v1.2/sdkconfig
Normal file
1493
v1.2/sdkconfig
Normal file
File diff suppressed because it is too large
Load Diff
BIN
webserver/css/bootstrap.min.css.gz
Normal file
BIN
webserver/css/bootstrap.min.css.gz
Normal file
Binary file not shown.
1
webserver/css/css
Symbolic link
1
webserver/css/css
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../sharpkey/webserver/css
|
||||
18
webserver/css/jquery.edittable.min.css
vendored
Normal file
18
webserver/css/jquery.edittable.min.css
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
table.inputtable{width:100%;border:1px solid #ddd;border-collapse:collapse;border-spacing:0;-moz-box-shadow:0 1px 3px rgba(0,0,0,.075);-webkit-box-shadow:0 1px 3px rgba(0,0,0,.075);box-shadow:0 1px 3px rgba(0,0,0,.075);margin:15px 0}
|
||||
table.inputtable a.icon-button{background-color:#ccc;display:inline-block;width:18px;height:18px;text-decoration:none;color:#fff;font-weight:800;line-height:16px;text-align:center;font-size:14px;-moz-border-radius:1px;-webkit-border-radius:1px;border-radius:1px;-moz-box-shadow:0 0 1px rgba(0,0,0,0.2);-webkit-box-shadow:0 0 1px rgba(0,0,0,0.2);box-shadow:0 0 1px rgba(0,0,0,0.2)}
|
||||
table.inputtable a.icon-button.addcol,table.inputtable a.icon-button.addrow{background-color:#81b71a}
|
||||
table.inputtable a.icon-button.delcol,table.inputtable a.icon-button.delrow{background-color:#db4a39}
|
||||
table.inputtable a.icon-button.disabled{background-color:#eee}
|
||||
table.inputtable td:last-child,table.inputtable th:last-child{width:54px;border:1px solid #eee;border-right:thick;}
|
||||
table.inputtable td,table.inputtable th{border:1px solid #eee;text-align:center;height:40px;vertical-align:middle;font-size:14px}
|
||||
table.inputtable th{background-color:#f1f1f1;border-top:none;border-bottom:2px solid #ddd;border-color:#ddd}
|
||||
table.inputtable td input[type=text]{border:0;width:90%;height:100%;text-align:center;padding:0 5%}
|
||||
table.inputtable tr td input:focus{background-color:#fafafa}
|
||||
table.inputtable.wh tbody tr:nth-child(1),table.inputtable.wh tbody tr:nth-child(1) input{background-color:#fdfdfd;font-weight:800}
|
||||
table.inputtable th:first-child,table.inputtable td:first-child{border-left:none}
|
||||
table.inputtable tr:last-child td{border-bottom:none}
|
||||
@media only screen and max-width 480px {
|
||||
table.inputtable td,table.inputtable th{min-width:40px;height:80px}
|
||||
table.inputtable a.icon-button{width:40px;height:40px;font-size:18px;min-width:40px;line-height:40px;margin:3px 0}
|
||||
table.inputtable td input{height:80px}
|
||||
}
|
||||
159
webserver/css/sb-admin.css
Normal file
159
webserver/css/sb-admin.css
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
Author: Start Bootstrap - http://startbootstrap.com
|
||||
'SB Admin' HTML Template by Start Bootstrap
|
||||
|
||||
All Start Bootstrap themes are licensed under Apache 2.0.
|
||||
For more info and more free Bootstrap 3 HTML themes, visit http://startbootstrap.com!
|
||||
*/
|
||||
|
||||
/* ATTN: This is mobile first CSS - to update 786px and up screen width use the media query near the bottom of the document! */
|
||||
|
||||
/* Global Styles */
|
||||
|
||||
body {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
#page-wrapper {
|
||||
width: 100%;
|
||||
padding: 5px 15px;
|
||||
}
|
||||
|
||||
/* Nav Messages */
|
||||
|
||||
.messages-dropdown .dropdown-menu .message-preview .avatar,
|
||||
.messages-dropdown .dropdown-menu .message-preview .name,
|
||||
.messages-dropdown .dropdown-menu .message-preview .message,
|
||||
.messages-dropdown .dropdown-menu .message-preview .time {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.messages-dropdown .dropdown-menu .message-preview .avatar {
|
||||
float: left;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.messages-dropdown .dropdown-menu .message-preview .name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.messages-dropdown .dropdown-menu .message-preview .message {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.messages-dropdown .dropdown-menu .message-preview .time {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
|
||||
/* Nav Announcements */
|
||||
|
||||
.announcement-heading {
|
||||
font-size: 50px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.announcement-text {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Table Headers */
|
||||
|
||||
table.tablesorter thead {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
table.tablesorter thead tr th:hover {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* Flot Chart Containers */
|
||||
|
||||
.flot-chart {
|
||||
display: block;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.flot-chart-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Edit Below to Customize Widths > 768px */
|
||||
@media (min-width:768px) {
|
||||
|
||||
/* Wrappers */
|
||||
|
||||
#wrapper {
|
||||
padding-left: 225px;
|
||||
}
|
||||
|
||||
#page-wrapper {
|
||||
padding: 15px 25px;
|
||||
}
|
||||
|
||||
/* Side Nav */
|
||||
|
||||
.side-nav {
|
||||
margin-left: -225px;
|
||||
left: 225px;
|
||||
width: 225px;
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
height: 100%;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
background-color: #222222;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Bootstrap Default Overrides - Customized Dropdowns for the Side Nav */
|
||||
|
||||
.side-nav>li.dropdown>ul.dropdown-menu {
|
||||
position: relative;
|
||||
min-width: 225px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
}
|
||||
|
||||
.side-nav>li.dropdown>ul.dropdown-menu>li>a {
|
||||
color: #999999;
|
||||
padding: 15px 15px 15px 25px;
|
||||
}
|
||||
|
||||
.side-nav>li.dropdown>ul.dropdown-menu>li>a:hover,
|
||||
.side-nav>li.dropdown>ul.dropdown-menu>li>a.active,
|
||||
.side-nav>li.dropdown>ul.dropdown-menu>li>a:focus {
|
||||
color: #fff;
|
||||
background-color: #080808;
|
||||
}
|
||||
|
||||
.side-nav>li>a {
|
||||
width: 225px;
|
||||
}
|
||||
|
||||
.navbar-inverse .navbar-nav>li>a:hover,
|
||||
.navbar-inverse .navbar-nav>li>a:focus {
|
||||
background-color: #080808;
|
||||
}
|
||||
|
||||
/* Nav Messages */
|
||||
|
||||
.messages-dropdown .dropdown-menu {
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
.messages-dropdown .dropdown-menu li a {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
}
|
||||
266
webserver/css/sharpkey.css
Normal file
266
webserver/css/sharpkey.css
Normal file
@@ -0,0 +1,266 @@
|
||||
.wm-button {
|
||||
width: 95px;
|
||||
height: 25px;
|
||||
background: blue;
|
||||
border: none;
|
||||
vertical-align: top;
|
||||
margin-left: 25px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
transition: 2s;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.wm-button:disabled {
|
||||
background: #999;
|
||||
color: #555;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.wm-button:hover {
|
||||
background-color: #81ecec;
|
||||
border: 2px solid #00cec9;
|
||||
}
|
||||
|
||||
input[type="file"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.firmware-file-upload {
|
||||
width: 95px;
|
||||
height: 25px;
|
||||
background: blue;
|
||||
border: none;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
line-height: 25px;
|
||||
margin-left: 35px;
|
||||
margin-bottom: 0px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
transition: 2s;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.firmware-file-upload:hover {
|
||||
background-color: #81ecec;
|
||||
border: 2px solid #00cec9;
|
||||
}
|
||||
|
||||
|
||||
.keymap-file-upload {
|
||||
width: 95px;
|
||||
height: 25px;
|
||||
background: blue;
|
||||
border: none;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
line-height: 25px;
|
||||
margin-left: 35px;
|
||||
margin-bottom: 0px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
transition: 2s;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.keymap-file-upload:hover {
|
||||
background-color: #81ecec;
|
||||
border: 2px solid #00cec9;
|
||||
}
|
||||
|
||||
input[type=file]::file-selector-button {
|
||||
border: 2px solid #6c5ce7;
|
||||
padding: .2em .4em;
|
||||
border-radius: .2em;
|
||||
background-color: #a29bfe;
|
||||
transition: 1s;
|
||||
}
|
||||
|
||||
input[type=file]::file-selector-button:hover {
|
||||
background-color: #81ecec;
|
||||
border: 2px solid #00cec9;
|
||||
}
|
||||
|
||||
.sk-modules-table {
|
||||
border: none;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.sk-modules-table caption {
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
.sk-modules-table th, .sk-modules-table td {
|
||||
border: none;
|
||||
padding: 0.2rem 2rem;
|
||||
}
|
||||
.sk-modules-table td {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.sk-modules-table th {
|
||||
font-weight: normal;
|
||||
}
|
||||
.sk-modules-table td {
|
||||
border-style: none;
|
||||
vertical-align: top;
|
||||
}
|
||||
.sk-modules-table th {
|
||||
padding: 0.2em;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sk-modules-table tbody td:first-child::after {
|
||||
content: leader(". ");
|
||||
}
|
||||
|
||||
.sk-client-wifi-config-table {
|
||||
border: none;
|
||||
border-collapse: collapse;
|
||||
width: 1px !important;
|
||||
table-layout: auto !important;
|
||||
}
|
||||
.sk-client-wifi-config-table caption {
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
.sk-client-wifi-config-table th, .sk-client-wifi-config-table td {
|
||||
border: none;
|
||||
padding: 0.2rem 2rem;
|
||||
padding-left: 0;
|
||||
padding-right: 4rem;
|
||||
}
|
||||
.sk-client-wifi-config-table td {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
border-style: none;
|
||||
vertical-align: top;
|
||||
width: auto !important;
|
||||
}
|
||||
.sk-client-wifi-config-table th {
|
||||
font-weight: normal;
|
||||
padding: 0.2em;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
#client-wifi-config-area {
|
||||
overflow-x: scroll;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
#firmware-revision-area {
|
||||
overflow-x: scroll;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
#esp32-partitions-area {
|
||||
overflow-x: scroll;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.sk-partitions-table {
|
||||
border: none;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.sk-partitions-table caption {
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
.sk-partitions-table th, .sk-partitions-table td {
|
||||
border: none;
|
||||
padding: 0.2rem 2rem;
|
||||
}
|
||||
.sk-partitions-table td {
|
||||
white-space: nowrap;
|
||||
border-style: none;
|
||||
vertical-align: top;
|
||||
}
|
||||
.sk-partitions-table th {
|
||||
font-weight: normal;
|
||||
padding: 0.2em;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sk-partitions-table tbody td:first-child::after {
|
||||
content: leader(". ");
|
||||
}
|
||||
|
||||
.sk-partitions-table tbody td:nth-child(4) {
|
||||
text-align: right;
|
||||
}
|
||||
.sk-partitions-table tbody td:nth-child(5) {
|
||||
text-align: right;
|
||||
}
|
||||
.sk-partitions-table tbody td:nth-child(6) {
|
||||
text-align: center;
|
||||
}
|
||||
.sk-partitions-table tbody td:nth-child(8) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.table-condensed .progress {
|
||||
margin-bottom: 0 !important;
|
||||
width: 400px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.table-borderless > tbody > tr > td,
|
||||
.table-borderless > thead > tr > td,
|
||||
.table-borderless {
|
||||
border-bottom: 0;
|
||||
border-top: 0;
|
||||
padding: 4px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.table-responsive {
|
||||
border-bottom: 0;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
padding: 4px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 0;
|
||||
white-space: nowrap;
|
||||
table-layout: auto;
|
||||
}
|
||||
|
||||
.table {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.justify {
|
||||
text-align: justify;
|
||||
text-justify: inter-word;
|
||||
}
|
||||
|
||||
.keymap {
|
||||
max-height: 36.2em;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.hr_no_margin {
|
||||
margin-top: 0.2em;
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
overflow: hidden;
|
||||
}
|
||||
.radio-mouse {
|
||||
padding-right: 1em;
|
||||
}
|
||||
.radio-mouse label {
|
||||
float: left;
|
||||
clear: none;
|
||||
display: block;
|
||||
padding: 0px 1em 0px 8px;
|
||||
}
|
||||
input[type=radio] .radio-mouse,
|
||||
input.radio .radio-mouse {
|
||||
float: left;
|
||||
clear: none;
|
||||
margin: 2px 0 0 2px;
|
||||
}
|
||||
253
webserver/css/style.css
Normal file
253
webserver/css/style.css
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-family: Tahoma, Arial, sans-serif;
|
||||
color: #06D85F;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
*/
|
||||
.box {
|
||||
width: 40%;
|
||||
margin: 0 auto;
|
||||
background: rgba(255,255,255,0.2);
|
||||
padding: 35px;
|
||||
border: 2px solid #fff;
|
||||
border-radius: 20px/50px;
|
||||
background-clip: padding-box;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
//transition: opacity 500ms;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
.overlay:target {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.popup {
|
||||
margin: 70px auto;
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
width: 30%;
|
||||
position: relative;
|
||||
transition: all 5s ease-in-out;
|
||||
}
|
||||
|
||||
.popup h2 {
|
||||
margin-top: 0;
|
||||
color: #333;
|
||||
font-family: Tahoma, Arial, sans-serif;
|
||||
}
|
||||
.popup .close {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 30px;
|
||||
transition: all 200ms;
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
}
|
||||
.popup .close:hover {
|
||||
color: #06D85F;
|
||||
}
|
||||
.popup .content {
|
||||
max-height: 30%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 700px){
|
||||
.box{
|
||||
width: 90%;
|
||||
}
|
||||
.popup{
|
||||
width: 90%;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
html {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.8rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
*/
|
||||
|
||||
.topnav {
|
||||
overflow: hidden;
|
||||
background-color: #0A1128;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 5%;
|
||||
}
|
||||
|
||||
.card-grid {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
display: grid;
|
||||
grid-gap: 2rem;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: lightyellow;
|
||||
box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: bold;
|
||||
color: #034078
|
||||
}
|
||||
/*
|
||||
input[type=submit] {
|
||||
border: none;
|
||||
color: #FEFCFB;
|
||||
background-color: #034078;
|
||||
padding: 15px 15px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
font-size: 18px;
|
||||
width: 30%;
|
||||
margin-right: 10px;
|
||||
border-radius: 4px;
|
||||
transition-duration: 0.4s;
|
||||
}
|
||||
|
||||
input[type=submit]:hover {
|
||||
background-color: #1282A2;
|
||||
}
|
||||
|
||||
input[type=text], input[type=number], select {
|
||||
width: 40%;
|
||||
padding: 8px 10px;
|
||||
margin: 12px;
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input[type=url], input[type=number], select {
|
||||
width: 50%;
|
||||
padding: 12px 20px;
|
||||
margin: 18px;
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 1rem;
|
||||
}
|
||||
*/
|
||||
.value{
|
||||
font-size: 1rem;
|
||||
color: #1282A2;
|
||||
}
|
||||
.state {
|
||||
font-size: 1rem;
|
||||
color: #1282A2;
|
||||
}
|
||||
|
||||
.button {
|
||||
font-size: 2em;
|
||||
padding: 3px;
|
||||
color: #dbd75e;
|
||||
border: 1px solid #000;
|
||||
border-radius: 5px;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: all 1s ease-out;
|
||||
|
||||
background: #1b06d8;
|
||||
}
|
||||
.button:hover {
|
||||
background: #06D85F;
|
||||
}
|
||||
|
||||
/*
|
||||
button {
|
||||
//border: none;
|
||||
// color: #FEFCFB;
|
||||
// padding: 15px 32px;
|
||||
// text-align: center;
|
||||
// font-size: 30px;
|
||||
// width: 100px;
|
||||
// border-radius: 4px;
|
||||
transition-duration: 0.4s;
|
||||
}
|
||||
.button-on {
|
||||
// background-color: #034078;
|
||||
}
|
||||
.button-on:hover {
|
||||
// background-color: #1282A2;
|
||||
}
|
||||
.button-off {
|
||||
// background-color: #858585;
|
||||
}
|
||||
.button-off:hover {
|
||||
// background-color: #252524;
|
||||
}
|
||||
*/
|
||||
#sk-modules-table {
|
||||
border: solid thin;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
#sk-modules-table caption {
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
#sk-modules-table th,
|
||||
#sk-modules-table td {
|
||||
border: solid thin;
|
||||
padding: 0.5rem 2rem;
|
||||
}
|
||||
#sk-modules-table td {
|
||||
white-space: nowrap;
|
||||
}
|
||||
#sk-modules-table th {
|
||||
font-weight: normal;
|
||||
}
|
||||
#sk-modules-table td {
|
||||
border-style: none solid;
|
||||
vertical-align: top;
|
||||
}
|
||||
#sk-modules-table th {
|
||||
padding: 0.2em;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#sk-modules-table tbody td:first-child::after {
|
||||
content: leader(". ");
|
||||
}
|
||||
|
||||
1
webserver/css/styles.css
Normal file
1
webserver/css/styles.css
Normal file
@@ -0,0 +1 @@
|
||||
body { padding-bottom: 70px; }
|
||||
BIN
webserver/favicon.ico
Normal file
BIN
webserver/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user