Use generic HID classes to minimize code duplic'n (#1254)
Move the Joystick, Keyboard, and Mouse into a base class which handles the operation/input, and a subclass which will implement the reporting as a HID device via USB, Bluetooth Classic, or Bluetooth Low Energy (BLE). Reduce copies of library code and makes maintainability much better.
This commit is contained in:
parent
0be1d9c3ea
commit
7aa1c08d17
68 changed files with 1668 additions and 3108 deletions
12
.gitmodules
vendored
12
.gitmodules
vendored
|
|
@ -14,14 +14,14 @@
|
||||||
path = libraries/ESP8266SdFat
|
path = libraries/ESP8266SdFat
|
||||||
url = https://github.com/earlephilhower/ESP8266SdFat.git
|
url = https://github.com/earlephilhower/ESP8266SdFat.git
|
||||||
[submodule "libraries/Keyboard"]
|
[submodule "libraries/Keyboard"]
|
||||||
path = libraries/Keyboard
|
path = libraries/HID_Keyboard
|
||||||
url = https://github.com/earlephilhower/Keyboard
|
url = https://github.com/earlephilhower/Keyboard.git
|
||||||
[submodule "libraries/Mouse"]
|
[submodule "libraries/Mouse"]
|
||||||
path = libraries/Mouse
|
path = libraries/HID_Mouse
|
||||||
url = https://github.com/earlephilhower/Mouse
|
url = https://github.com/earlephilhower/Mouse.git
|
||||||
[submodule "libraries/Joystick"]
|
[submodule "libraries/Joystick"]
|
||||||
path = libraries/Joystick
|
path = libraries/HID_Joystick
|
||||||
url = https://github.com/benjaminaigner/Joystick
|
url = https://github.com/earlephilhower/Joystick.git
|
||||||
[submodule "libraries/Adafruit_TinyUSB_Arduino"]
|
[submodule "libraries/Adafruit_TinyUSB_Arduino"]
|
||||||
path = libraries/Adafruit_TinyUSB_Arduino
|
path = libraries/Adafruit_TinyUSB_Arduino
|
||||||
url = https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git
|
url = https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
# Datatypes (KEYWORD1)
|
# Datatypes (KEYWORD1)
|
||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
|
PicoBluetoothHID KEYWORD1
|
||||||
PicoBluetoothBLEHID KEYWORD1
|
PicoBluetoothBLEHID KEYWORD1
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
|
|
@ -20,8 +21,10 @@ connected KEYWORD2
|
||||||
send KEYWORD2
|
send KEYWORD2
|
||||||
lockBluetooth KEYWORD2
|
lockBluetooth KEYWORD2
|
||||||
unlockBluetooth KEYWORD2
|
unlockBluetooth KEYWORD2
|
||||||
|
getCID KEYWORD2
|
||||||
setBattery KEYWORD2
|
setBattery KEYWORD2
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Constants (LITERAL1)
|
# Constants (LITERAL1)
|
||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
name=PicoBluetoothBLEHID
|
name=HID_Bluetooth
|
||||||
version=1.0.0
|
version=1.0.0
|
||||||
author=Earle F. Philhower, III <earlephilhower@yahoo.com>
|
author=Earle F. Philhower, III <earlephilhower@yahoo.com>
|
||||||
maintainer=Earle F. Philhower, III <earlephilhower@yahoo.com>
|
maintainer=Earle F. Philhower, III <earlephilhower@yahoo.com>
|
||||||
sentence=Implements a HID device base class for PicoW Bluetooth BLE
|
sentence=Implements a HID device base class for PicoW Bluetooth
|
||||||
paragraph=Implements a HID device base class for PicoW Bluetooth BLE
|
paragraph=Implements a HID device base class for PicoW Bluetooth
|
||||||
category=Device Control
|
category=Device Control
|
||||||
url=https://github.com/earlephilhower/arduino-pico
|
url=https://github.com/earlephilhower/arduino-pico
|
||||||
architectures=rp2040
|
architectures=rp2040
|
||||||
7
libraries/HID_Bluetooth/src/HID_Bluetooth.h
Normal file
7
libraries/HID_Bluetooth/src/HID_Bluetooth.h
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifdef ENABLE_CLASSIC
|
||||||
|
#include "PicoBluetoothHID.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_BLE
|
||||||
|
#include "PicoBluetoothBLEHID.h"
|
||||||
|
#endif
|
||||||
1
libraries/HID_Joystick
Submodule
1
libraries/HID_Joystick
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 4eb3e28dc20d44afe676a6c7e0e6264e29f82abb
|
||||||
1
libraries/HID_Keyboard
Submodule
1
libraries/HID_Keyboard
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 74c3b2fee7da9170a608e7458d4c08c6d8104fa9
|
||||||
1
libraries/HID_Mouse
Submodule
1
libraries/HID_Mouse
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 2aa06d16155c8cb20108e79aaa160a01ea96c0cf
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit af745f3e62377de71b7708b15f263dab8773e0c5
|
|
||||||
32
libraries/Joystick/README.adoc
Normal file
32
libraries/Joystick/README.adoc
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
:repository-owner: arduino-libraries
|
||||||
|
:repository-name: Joystick
|
||||||
|
|
||||||
|
= {repository-name} Library for Arduino (RP2040 based boards) =
|
||||||
|
|
||||||
|
This library allows an RaspberryPi RP2040 board to act as a Joystick when
|
||||||
|
Earle F. Philhower`s [arduino-pico](https://github.com/earlephilhower/arduino-pico)
|
||||||
|
Core is used.
|
||||||
|
|
||||||
|
== Acknowledgements / Credits ==
|
||||||
|
|
||||||
|
* [arduino-pico](https://github.com/earlephilhower/arduino-pico) Earle F. Philhower providing the Arduino Core, on which this library is based on, available under LGPL.
|
||||||
|
* [tinyUSB] (https://github.com/hathach/tinyusb) Ha Thach for providing tinyUSB under MIT license, which covers most of the USB functionality.
|
||||||
|
|
||||||
|
|
||||||
|
== License ==
|
||||||
|
|
||||||
|
Copyright (c) Benjamin Aigner <beni@asterics-foundation.org> All right reserved.
|
||||||
|
|
||||||
|
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
|
||||||
435
libraries/Joystick/docs/api.md
Normal file
435
libraries/Joystick/docs/api.md
Normal file
|
|
@ -0,0 +1,435 @@
|
||||||
|
# Joystick library
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
|
||||||
|
### `Joystick.begin()`
|
||||||
|
|
||||||
|
Must be called before starting using the Joystick emulation. To end control, use `Joystick.end()`.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Joystick.begin()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Joystick.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(2, INPUT_PULLUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Initialize the Joystick library when button is pressed
|
||||||
|
if (digitalRead(2) == LOW) {
|
||||||
|
Joystick.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
|
||||||
|
* [Joystick.button()](#joystickbutton)
|
||||||
|
* [Joystick.end()](#joystickend)
|
||||||
|
* [Joystick.send_now()](#joysticksend_now)
|
||||||
|
* [Joystick.position()](#joystickposition)
|
||||||
|
* [Joystick.X()](#joystickx)
|
||||||
|
* [Joystick.hat()](#joystickhat)
|
||||||
|
* [Joystick.use8bit()](#joystickuse8bit)
|
||||||
|
* [Joystick.useManualSend()](#joystickuseManualSend)
|
||||||
|
|
||||||
|
### `Joystick.button()`
|
||||||
|
|
||||||
|
Updates a button of the USB joystick.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Joystick.button(1,true);
|
||||||
|
delay(250);
|
||||||
|
Joystick.button(1,false);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* `button`: number of Joystick button, which status should be changed
|
||||||
|
* `val`: state of button, `true` for pressed, `false` for released
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Joystick.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(2, INPUT_PULLUP);
|
||||||
|
Joystick.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
uint8_t i = 1; //counter for the button number 1-32
|
||||||
|
if (digitalRead(2) == LOW) { //if button is pressed
|
||||||
|
Joystick.button(i,true); //"press" the Joystick button
|
||||||
|
delay(250); //wait for 0.25s
|
||||||
|
Joystick.button(i,false); //"release" the Joystick button
|
||||||
|
i = i + 1; //increment & use next Joystick button number
|
||||||
|
if(i > 32) i = 1; //we have 32 buttons available, wrap-around
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Notes
|
||||||
|
|
||||||
|
* Up to 32 buttons are available, numbered as button 1 to button 32.
|
||||||
|
* If manual_send is active, call `Joystick.send_now()` to send an update to the host.
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Joystick.send_now()](#joysticksend_now)
|
||||||
|
* [Joystick.useManualSend()](#joystickuseManualSend)
|
||||||
|
* [Joystick.X()](#joystickx)
|
||||||
|
* [Joystick.hat()](#joystickhat)
|
||||||
|
|
||||||
|
|
||||||
|
### `Joystick.end()`
|
||||||
|
|
||||||
|
Stops emulating the Joystick connected to a computer. To start control, use `Joystick.begin()`.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Joystick.end()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Joystick.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(2, INPUT_PULLUP);
|
||||||
|
// Initiate the Joystick library
|
||||||
|
Joystick.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// If the button is pressed, send a button 1 press / release
|
||||||
|
if (digitalRead(2) == LOW) {
|
||||||
|
Joystick.button(1,true);
|
||||||
|
delay(250);
|
||||||
|
Joystick.button(1,false);
|
||||||
|
// Then end the Joystick emulation
|
||||||
|
Joystick.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Joystick.begin()](#joystickbegin)
|
||||||
|
|
||||||
|
### `Joystick.use8bit()`
|
||||||
|
|
||||||
|
Switch axis value range between 10bit and 8bit.
|
||||||
|
* Default: 10bit, range for an axis from 0 to 1023
|
||||||
|
* 8bit mode: range from -127 to 127.
|
||||||
|
|
||||||
|
__Note:__ due to the gamepad descriptor of tinyUSB, the maximum range is -127/127. 10bit mode enables mapping, not a higher resolution.
|
||||||
|
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Joystick.use8bit(true)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* `mode`: true, if values from -127/127 are used. False to use a range from 0 to 1023.
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Joystick.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(2, INPUT_PULLUP);
|
||||||
|
Joystick.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
//send middle position in default 10bit mode
|
||||||
|
Joystick.position(512,512);
|
||||||
|
delay(250);
|
||||||
|
//enable 8bit mode
|
||||||
|
Joystick.use8bit(true);
|
||||||
|
//send middle position in 8bit mode
|
||||||
|
Joystick.position(0,0);
|
||||||
|
delay(250);
|
||||||
|
|
||||||
|
//send maximum left in 10bit mode
|
||||||
|
Joystick.use8bit(false);
|
||||||
|
Joystick.position(0,0);
|
||||||
|
delay(250);
|
||||||
|
//enable 8bit mode
|
||||||
|
Joystick.use8bit(true);
|
||||||
|
//send left position in 8bit mode
|
||||||
|
Joystick.position(-127,-127);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Joystick.position()](#joystickposition)
|
||||||
|
* [Joystick.X()](#joystickx)
|
||||||
|
* [Joystick.Y()](#joysticky)
|
||||||
|
* [Joystick.Z()](#joystickz)
|
||||||
|
* [Joystick.Zrotate()](#joystickrotate)
|
||||||
|
* [Joystick.slider()](#joystickslider)
|
||||||
|
* [Joystick.sliderLeft()](#joysticksliderleft)
|
||||||
|
* [Joystick.sliderRight()](#joysticksliderright)
|
||||||
|
|
||||||
|
|
||||||
|
### `Joystick.useManualSend()`
|
||||||
|
|
||||||
|
To fully control transmitting the USB-HID reports, enable manual sending.
|
||||||
|
If disabled, each call to a function updating the Joystick status (buttons, all axis, hat)
|
||||||
|
will send a HID report. If you update in a loop, the time between updates (at least 1ms) is too short and something might be not transmitted correctly.
|
||||||
|
If enabled, update all your axis values, buttons, hat and then send one report via `Joystick.send_now()`.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Joystick.useManualSend(true)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* `mode`: false is sending report each Joystick update, true enables manual sending via send_now().
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Joystick.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(2, INPUT_PULLUP);
|
||||||
|
Joystick.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (digitalRead(2) == LOW) {
|
||||||
|
// send data in 4 different reports
|
||||||
|
Joystick.button(1,true);
|
||||||
|
Joystick.button(2,true);
|
||||||
|
Joystick.button(3,true);
|
||||||
|
Joystick.button(4,true);
|
||||||
|
|
||||||
|
//enable manual send
|
||||||
|
Joystick.useManualSend(true);
|
||||||
|
|
||||||
|
//send same data in one report
|
||||||
|
Joystick.button(1,false);
|
||||||
|
Joystick.button(2,false);
|
||||||
|
Joystick.button(3,false);
|
||||||
|
Joystick.button(4,false);
|
||||||
|
Joystick.send_now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Joystick.send_now()](#joysticksend_now)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `Joystick.send_now()`
|
||||||
|
|
||||||
|
Send a HID report now. Used together with manual sending, see `Joystick.useManualSend()`.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Joystick.send_now()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Joystick.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(2, INPUT_PULLUP);
|
||||||
|
Joystick.begin();
|
||||||
|
//enable manual sending in setup
|
||||||
|
Joystick.useManualSend(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (digitalRead(2) == LOW) {
|
||||||
|
// update all buttons, but nothing is sent to the host
|
||||||
|
for(uint8_t i = 1; i<=32; i++) Joystick.button(i,true);
|
||||||
|
Joystick.X(256);
|
||||||
|
Joystick.sliderLeft(0);
|
||||||
|
|
||||||
|
//now send in one HID report
|
||||||
|
Joystick.send_now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Joystick.useManualSend()](#joystickusemanualsend)
|
||||||
|
|
||||||
|
|
||||||
|
### `Joystick.X()`
|
||||||
|
|
||||||
|
Update X axis.
|
||||||
|
__Note:__ If [manual send](#joystickusemanualsend) is active, the value is sent to the host only after calling [send_now](#joysticksend_now).
|
||||||
|
__Note:__ If in 10bit mode (default), the parameter is interpreted from 0 to 1023.
|
||||||
|
In 8bit mode from -127 to 127. The internal resolution is always 8bit. Change setting with [use8bit](#joystickuse8bit).
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Joystick.X(0)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* `val`: value from 0 to 1023 (default) or -127 to 127 (8bit mode)
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Joystick.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(2, INPUT_PULLUP);
|
||||||
|
Joystick.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (digitalRead(2) == LOW) {
|
||||||
|
Joystick.X(256);
|
||||||
|
delay(500);
|
||||||
|
Joystick.X(512);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Joystick.Y()](#joysticky)
|
||||||
|
* [Joystick.Z()](#joystickz)
|
||||||
|
* [Joystick.Zrotate()](#joystickrotate)
|
||||||
|
* [Joystick.slider()](#joystickslider)
|
||||||
|
* [Joystick.sliderLeft()](#joysticksliderleft)
|
||||||
|
* [Joystick.sliderRight()](#joysticksliderright)
|
||||||
|
* [Joystick.send_now()](#joysticksend_now)
|
||||||
|
* [Joystick.position()](#joystickposition)
|
||||||
|
* [Joystick.hat()](#joystickhat)
|
||||||
|
* [Joystick.use8bit()](#joystickuse8bit)
|
||||||
|
* [Joystick.useManualSend()](#joystickuseManualSend)
|
||||||
|
|
||||||
|
### `Joystick.Y()`
|
||||||
|
|
||||||
|
Update Y axis. Please refer to [Joystick.X()](#joystickx).
|
||||||
|
|
||||||
|
### `Joystick.Z()`
|
||||||
|
|
||||||
|
Update Z axis. Please refer to [Joystick.X()](#joystickx).
|
||||||
|
|
||||||
|
### `Joystick.Zrotate()`
|
||||||
|
|
||||||
|
Update Z rotate axis. Please refer to [Joystick.X()](#joystickx).
|
||||||
|
|
||||||
|
### `Joystick.sliderLeft()`
|
||||||
|
|
||||||
|
Left slider value. Please refer to [Joystick.X()](#joystickx).
|
||||||
|
|
||||||
|
### `Joystick.sliderRight()`
|
||||||
|
|
||||||
|
Right slider value. Please refer to [Joystick.X()](#joystickx).
|
||||||
|
|
||||||
|
### `Joystick.slider()`
|
||||||
|
|
||||||
|
Same as [Joystick.sliderLeft()](#joysticksliderleft).
|
||||||
|
|
||||||
|
### `Joystick.position()`
|
||||||
|
|
||||||
|
Sets X and Y axis in one call. If autosending is active, one report is generated. Please refer to [Joystick.X()](#joystickx).
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Joystick.position(512,512)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* `X`: value from 0 to 1023 (default) or -127 to 127 (8bit mode); for X axis
|
||||||
|
* `Y`: value from 0 to 1023 (default) or -127 to 127 (8bit mode); for Y axis
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Joystick.X()](#joystickx)
|
||||||
|
* [Joystick.Y()](#joysticky)
|
||||||
|
|
||||||
|
### `Joystick.hat()`
|
||||||
|
|
||||||
|
Set the hat value to selection angle or rest position.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Joystick.hat(-1), // released/rest position
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* `angle` Angle value from 0-360 degrees or -1 for released resting position. Mapped to 8 different directions.
|
||||||
14
libraries/Joystick/docs/readme.md
Normal file
14
libraries/Joystick/docs/readme.md
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Joystick library
|
||||||
|
|
||||||
|
The Joystick functions enable a RP2040 board to act as a HID game controller.
|
||||||
|
|
||||||
|
To use this library:
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Joystick.h>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
* [Joystick-AllFunctions] Includes example calls for each Joystick function
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
/* Benjamin Aigner, 2022 <beni@asterics-foundation.org> */
|
||||||
|
/* Public domain / CC 0 */
|
||||||
|
|
||||||
|
/** example code using all possibilities of the Joystick class
|
||||||
|
for the RP2040.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Joystick.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("Use BOOTSEL to start the Joystick demo.");
|
||||||
|
Joystick.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (BOOTSEL) {
|
||||||
|
Serial.println("Joystick buttons");
|
||||||
|
for (uint8_t i = 1; i <= 32; i++) {
|
||||||
|
Joystick.button(i, true);
|
||||||
|
delay(250);
|
||||||
|
Joystick.button(i, false);
|
||||||
|
delay(10); //we need a short delay here, sending packets with less than 1ms leads to packet loss!
|
||||||
|
}
|
||||||
|
//alternativ with manual send:
|
||||||
|
Joystick.useManualSend(true);
|
||||||
|
Serial.println("Joystick buttons - manual send");
|
||||||
|
for (uint8_t i = 1; i <= 32; i++) {
|
||||||
|
Joystick.button(i, true);
|
||||||
|
Joystick.send_now();
|
||||||
|
delay(250);
|
||||||
|
Joystick.button(i, false);
|
||||||
|
}
|
||||||
|
Joystick.useManualSend(false);
|
||||||
|
|
||||||
|
//iterate all joystick axis
|
||||||
|
//Note: although you can use 0-1023 here (10bit), internally 8bits are used (-127 to 127)
|
||||||
|
Serial.println("Joystick X");
|
||||||
|
for (uint16_t i = 0; i < 1023; i++) {
|
||||||
|
Joystick.X(i);
|
||||||
|
delay(2);
|
||||||
|
} Joystick.X(512);
|
||||||
|
Serial.println("Joystick Y");
|
||||||
|
for (uint16_t i = 0; i < 1023; i++) {
|
||||||
|
Joystick.Y(i);
|
||||||
|
delay(2);
|
||||||
|
} Joystick.Y(512);
|
||||||
|
Serial.println("Joystick Z");
|
||||||
|
for (uint16_t i = 0; i < 1023; i++) {
|
||||||
|
Joystick.Z(i);
|
||||||
|
delay(2);
|
||||||
|
} Joystick.Z(512);
|
||||||
|
Serial.println("Joystick Zrotate");
|
||||||
|
for (uint16_t i = 0; i < 1023; i++) {
|
||||||
|
Joystick.Zrotate(i);
|
||||||
|
delay(2);
|
||||||
|
} Joystick.Zrotate(512);
|
||||||
|
Serial.println("Joystick sliderLeft");
|
||||||
|
for (uint16_t i = 0; i < 1023; i++) {
|
||||||
|
Joystick.sliderLeft(i);
|
||||||
|
delay(2);
|
||||||
|
} Joystick.sliderLeft(0);
|
||||||
|
Serial.println("Joystick sliderRight");
|
||||||
|
for (uint16_t i = 0; i < 1023; i++) {
|
||||||
|
Joystick.sliderRight(i);
|
||||||
|
delay(2);
|
||||||
|
} Joystick.sliderRight(0);
|
||||||
|
Serial.println("Joystick hat");
|
||||||
|
for (uint16_t i = 0; i < 360; i++) {
|
||||||
|
Joystick.hat(i);
|
||||||
|
delay(20);
|
||||||
|
} Joystick.hat(-1);
|
||||||
|
|
||||||
|
//use int8 mode for the axis.
|
||||||
|
//Note: hat is not used differently.
|
||||||
|
Serial.println("Now all axis in 8bit mode, -127 to 127");
|
||||||
|
Joystick.use8bit(true);
|
||||||
|
Serial.println("Joystick X");
|
||||||
|
for (int16_t i = -127; i < 128; i++) {
|
||||||
|
Joystick.X(i);
|
||||||
|
delay(2);
|
||||||
|
} Joystick.X(0);
|
||||||
|
Serial.println("Joystick Y");
|
||||||
|
for (int16_t i = -127; i < 128; i++) {
|
||||||
|
Joystick.Y(i);
|
||||||
|
delay(2);
|
||||||
|
} Joystick.Y(0);
|
||||||
|
Serial.println("Joystick Z");
|
||||||
|
for (int16_t i = -127; i < 128; i++) {
|
||||||
|
Joystick.Z(i);
|
||||||
|
delay(2);
|
||||||
|
} Joystick.Z(0);
|
||||||
|
Serial.println("Joystick Zrotate");
|
||||||
|
for (int16_t i = -127; i < 128; i++) {
|
||||||
|
Joystick.Zrotate(i);
|
||||||
|
delay(2);
|
||||||
|
} Joystick.Zrotate(0);
|
||||||
|
Serial.println("Joystick sliderLeft");
|
||||||
|
for (int16_t i = -127; i < 128; i++) {
|
||||||
|
Joystick.sliderLeft(i);
|
||||||
|
delay(2);
|
||||||
|
} Joystick.sliderLeft(0);
|
||||||
|
Serial.println("Joystick sliderRight");
|
||||||
|
for (int16_t i = -127; i < 128; i++) {
|
||||||
|
Joystick.sliderRight(i);
|
||||||
|
delay(2);
|
||||||
|
} Joystick.sliderRight(0);
|
||||||
|
Joystick.use8bit(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
33
libraries/Joystick/keywords.txt
Normal file
33
libraries/Joystick/keywords.txt
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
#######################################
|
||||||
|
# Syntax Coloring Map For Joystick
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Datatypes (KEYWORD1)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
Joystick KEYWORD1
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
begin KEYWORD2
|
||||||
|
end KEYWORD2
|
||||||
|
use8bit KEYWORD2
|
||||||
|
X KEYWORD2
|
||||||
|
Y KEYWORD2
|
||||||
|
button KEYWORD2
|
||||||
|
position KEYWORD2
|
||||||
|
Z KEYWORD2
|
||||||
|
Zrotate KEYWORD2
|
||||||
|
sliderLeft KEYWORD2
|
||||||
|
slider KEYWORD2
|
||||||
|
sliderRight KEYWORD2
|
||||||
|
hat KEYWORD2
|
||||||
|
useManualSend KEYWORD2
|
||||||
|
send_now KEYWORD2
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Constants (LITERAL1)
|
||||||
|
#######################################
|
||||||
9
libraries/Joystick/library.properties
Normal file
9
libraries/Joystick/library.properties
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
name=Joystick
|
||||||
|
version=1.0.1
|
||||||
|
author=Benjamin Aigner
|
||||||
|
maintainer=Benjamin Aigner <beni@asterics-foundation.org>
|
||||||
|
sentence=Allows any RP2040 board to act as a joystick/gamepad
|
||||||
|
paragraph=Allows the RP2040 to emulate a USB Joystick
|
||||||
|
category=Device Control
|
||||||
|
url=https://github.com/benjaminaigner/Joystick
|
||||||
|
architectures=rp2040
|
||||||
49
libraries/Joystick/src/Joystick.cpp
Normal file
49
libraries/Joystick/src/Joystick.cpp
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
Joystick.cpp
|
||||||
|
|
||||||
|
Copyright (c) 2022, Benjamin Aigner <beni@asterics-foundation.org>
|
||||||
|
Implementation loosely based on:
|
||||||
|
Mouse library from https://github.com/earlephilhower/arduino-pico
|
||||||
|
Joystick functions from Teensyduino https://github.com/PaulStoffregen
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Joystick.h"
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include <RP2040USB.h>
|
||||||
|
|
||||||
|
#include "tusb.h"
|
||||||
|
#include "class/hid/hid_device.h"
|
||||||
|
|
||||||
|
// Weak function override to add our descriptor to the TinyUSB list
|
||||||
|
void __USBInstallJoystick() { /* noop */ }
|
||||||
|
|
||||||
|
Joystick_::Joystick_(void) {
|
||||||
|
// Everything set up in HID_Joystick constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//immediately send an HID report
|
||||||
|
void Joystick_::send_now(void) {
|
||||||
|
CoreMutex m(&__usb_mutex);
|
||||||
|
tud_task();
|
||||||
|
if (tud_hid_ready()) {
|
||||||
|
tud_hid_n_report(0, __USBGetJoystickReportID(), &data, sizeof(data));
|
||||||
|
}
|
||||||
|
tud_task();
|
||||||
|
}
|
||||||
|
|
||||||
|
Joystick_ Joystick;
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Keyboard_da_DK.h
|
Joystick.h
|
||||||
|
|
||||||
Copyright (c) 2021, Peter John
|
Copyright (c) 2022, Benjamin Aigner <beni@asterics-foundation.org>
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
@ -18,27 +18,18 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef KEYBOARD_DA_DK_h
|
#ifndef _JOYSTICK_h
|
||||||
#define KEYBOARD_DA_DK_h
|
#define _JOYSTICK_h
|
||||||
|
|
||||||
#include "HID.h"
|
#include <HID_Joystick.h>
|
||||||
|
#include "class/hid/hid.h"
|
||||||
|
|
||||||
#if !defined(_USING_HID)
|
//======================================================================
|
||||||
|
class Joystick_ : public HID_Joystick {
|
||||||
|
public:
|
||||||
|
Joystick_(void);
|
||||||
|
virtual void send_now(void) override;
|
||||||
|
};
|
||||||
|
extern Joystick_ Joystick;
|
||||||
|
|
||||||
#warning "Using legacy HID core (non pluggable)"
|
#endif /* _JOYSTICK_h */
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
//================================================================================
|
|
||||||
// Keyboard
|
|
||||||
|
|
||||||
// DA_DK keys
|
|
||||||
#define KEY_A_RING (136+0x2f)
|
|
||||||
#define KEY_SLASHED_O (136+0x34)
|
|
||||||
#define KEY_ASH (136+0x33)
|
|
||||||
#define KEY_UMLAUT (136+0x30)
|
|
||||||
#define KEY_ACUTE_ACC (136+0x2e)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
@ -32,48 +32,7 @@
|
||||||
// Joystick/Gamepad
|
// Joystick/Gamepad
|
||||||
|
|
||||||
JoystickBLE_::JoystickBLE_(void) {
|
JoystickBLE_::JoystickBLE_(void) {
|
||||||
_use8bit = false;
|
// Member vars set in base constructor
|
||||||
_autosend = true;
|
|
||||||
memset(&data, 0, sizeof(data));
|
|
||||||
//_X_axis = _Y_axis = _Z_axis = _Zrotate = _sliderLeft = _sliderRight = _hat = data.buttons = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** define the mapping of axes values
|
|
||||||
default: axes methods are accepting values from 0-1023 (compatibility to other Joystick libraries)
|
|
||||||
and are mapped internally to int8_t
|
|
||||||
if use8bit(true) is called, -127 to 127 values are used.*/
|
|
||||||
void JoystickBLE_::use8bit(bool mode) {
|
|
||||||
_use8bit = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if set, the gamepad report is not automatically sent after an update of axes/buttons; use send_now to update
|
|
||||||
void JoystickBLE_::useManualSend(bool mode) {
|
|
||||||
_autosend = !mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Maps values from 8bit signed or 10bit unsigned to report values
|
|
||||||
|
|
||||||
Depending on the setting via use8bit(), either values from 0-1023 or -127 - 127
|
|
||||||
are mapped.
|
|
||||||
*/
|
|
||||||
int JoystickBLE_::map8or10bit(int const value) {
|
|
||||||
if (_use8bit) {
|
|
||||||
if (value < -127) {
|
|
||||||
return -127;
|
|
||||||
} else if (value > 127) {
|
|
||||||
return 127;
|
|
||||||
} else {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (value < 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (value > 1023) {
|
|
||||||
return 1023;
|
|
||||||
}
|
|
||||||
return map(value, 0, 1023, -127, 127);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REPORT_ID 0x01
|
#define REPORT_ID 0x01
|
||||||
|
|
@ -90,97 +49,6 @@ void JoystickBLE_::setBattery(int lvl) {
|
||||||
PicoBluetoothBLEHID.setBattery(lvl);
|
PicoBluetoothBLEHID.setBattery(lvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoystickBLE_::button(uint8_t button, bool val) {
|
|
||||||
//I've no idea why, but without a second dword, it is not possible.
|
|
||||||
//maybe something with the alignment when using bit set/clear?!?
|
|
||||||
static uint32_t buttons_local = 0;
|
|
||||||
|
|
||||||
if (button >= 1 && button <= 32) {
|
|
||||||
if (val) {
|
|
||||||
buttons_local |= (1UL << (button - 1));
|
|
||||||
} else {
|
|
||||||
buttons_local &= ~(1UL << (button - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
data.buttons = buttons_local;
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JoystickBLE_::X(int val) {
|
|
||||||
data.x = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void JoystickBLE_::Y(int val) {
|
|
||||||
data.y = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void JoystickBLE_::Z(int val) {
|
|
||||||
data.z = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void JoystickBLE_::Zrotate(int val) {
|
|
||||||
data.rz = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void JoystickBLE_::sliderLeft(int val) {
|
|
||||||
data.rx = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void JoystickBLE_::sliderRight(int val) {
|
|
||||||
data.ry = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JoystickBLE_::slider(int val) {
|
|
||||||
data.rx = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JoystickBLE_::position(int X, int Y) {
|
|
||||||
data.x = map8or10bit(X);
|
|
||||||
data.y = map8or10bit(Y);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//compatibility: there is only one hat implemented, num parameter is ignored
|
|
||||||
void JoystickBLE_::hat(unsigned int num, int angle) {
|
|
||||||
(void) num;
|
|
||||||
hat(angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
//set the hat value, from 0-360. -1 is rest position
|
|
||||||
void JoystickBLE_::hat(int angle) {
|
|
||||||
if (angle < 0) {
|
|
||||||
data.hat = 0;
|
|
||||||
}
|
|
||||||
if (angle >= 0 && angle <= 360) {
|
|
||||||
data.hat = map(angle, 0, 360, 1, 8);
|
|
||||||
}
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//immediately send an HID report
|
|
||||||
void JoystickBLE_::send_now(void) {
|
void JoystickBLE_::send_now(void) {
|
||||||
PicoBluetoothBLEHID.send(&data, sizeof(data));
|
PicoBluetoothBLEHID.send(&data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,50 +21,16 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <HID_Joystick.h>
|
||||||
#include "class/hid/hid.h"
|
#include "class/hid/hid.h"
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
class JoystickBLE_ {
|
class JoystickBLE_ : public HID_Joystick {
|
||||||
private:
|
|
||||||
bool _autosend;
|
|
||||||
bool _use8bit;
|
|
||||||
hid_gamepad_report_t data;
|
|
||||||
int map8or10bit(int const value);
|
|
||||||
public:
|
public:
|
||||||
JoystickBLE_(void);
|
JoystickBLE_(void);
|
||||||
void begin(void);
|
void begin(void);
|
||||||
void end(void);
|
void end(void);
|
||||||
|
virtual void send_now(void) override;
|
||||||
//set a selected button to pressed/released
|
|
||||||
void button(uint8_t button, bool val);
|
|
||||||
//set axis values
|
|
||||||
void X(int val);
|
|
||||||
void Y(int val);
|
|
||||||
void position(int X, int Y);
|
|
||||||
void Z(int val);
|
|
||||||
void Zrotate(int val);
|
|
||||||
void sliderLeft(int val);
|
|
||||||
void sliderRight(int val);
|
|
||||||
//note: not implemented in TinyUSB gamepad, is mapped to sliderLeft.
|
|
||||||
void slider(int val);
|
|
||||||
|
|
||||||
//set the hat value, from 0-360. -1 is rest position
|
|
||||||
void hat(int angle);
|
|
||||||
//compatibility: there is only one hat implemented, num parameter is ignored
|
|
||||||
void hat(unsigned int num, int angle);
|
|
||||||
|
|
||||||
|
|
||||||
//if set, the gamepad report is not automatically sent after an update of axes/buttons; use send_now to update
|
|
||||||
void useManualSend(bool mode);
|
|
||||||
//immediately send an HID report
|
|
||||||
void send_now(void);
|
|
||||||
//define the mapping of axes values
|
|
||||||
//default: axes methods are accepting values from 0-1023 (compatibility to other Joystick libraries)
|
|
||||||
// and are mapped internally to int8_t
|
|
||||||
//if use8bit(true) is called, -127 to 127 values are used.
|
|
||||||
void use8bit(bool mode);
|
|
||||||
|
|
||||||
void setBattery(int lvl);
|
void setBattery(int lvl);
|
||||||
};
|
};
|
||||||
extern JoystickBLE_ JoystickBLE;
|
extern JoystickBLE_ JoystickBLE;
|
||||||
|
|
|
||||||
|
|
@ -32,48 +32,7 @@
|
||||||
// Joystick/Gamepad
|
// Joystick/Gamepad
|
||||||
|
|
||||||
JoystickBT_::JoystickBT_(void) {
|
JoystickBT_::JoystickBT_(void) {
|
||||||
_use8bit = false;
|
// HID_Joystick sets up all the member vars
|
||||||
_autosend = true;
|
|
||||||
memset(&data, 0, sizeof(data));
|
|
||||||
//_X_axis = _Y_axis = _Z_axis = _Zrotate = _sliderLeft = _sliderRight = _hat = data.buttons = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** define the mapping of axes values
|
|
||||||
default: axes methods are accepting values from 0-1023 (compatibility to other Joystick libraries)
|
|
||||||
and are mapped internally to int8_t
|
|
||||||
if use8bit(true) is called, -127 to 127 values are used.*/
|
|
||||||
void JoystickBT_::use8bit(bool mode) {
|
|
||||||
_use8bit = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if set, the gamepad report is not automatically sent after an update of axes/buttons; use send_now to update
|
|
||||||
void JoystickBT_::useManualSend(bool mode) {
|
|
||||||
_autosend = !mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Maps values from 8bit signed or 10bit unsigned to report values
|
|
||||||
|
|
||||||
Depending on the setting via use8bit(), either values from 0-1023 or -127 - 127
|
|
||||||
are mapped.
|
|
||||||
*/
|
|
||||||
int JoystickBT_::map8or10bit(int const value) {
|
|
||||||
if (_use8bit) {
|
|
||||||
if (value < -127) {
|
|
||||||
return -127;
|
|
||||||
} else if (value > 127) {
|
|
||||||
return 127;
|
|
||||||
} else {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (value < 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (value > 1023) {
|
|
||||||
return 1023;
|
|
||||||
}
|
|
||||||
return map(value, 0, 1023, -127, 127);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REPORT_ID 0x01
|
#define REPORT_ID 0x01
|
||||||
|
|
@ -86,96 +45,6 @@ void JoystickBT_::end(void) {
|
||||||
PicoBluetoothHID.end();
|
PicoBluetoothHID.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoystickBT_::button(uint8_t button, bool val) {
|
|
||||||
//I've no idea why, but without a second dword, it is not possible.
|
|
||||||
//maybe something with the alignment when using bit set/clear?!?
|
|
||||||
static uint32_t buttons_local = 0;
|
|
||||||
|
|
||||||
if (button >= 1 && button <= 32) {
|
|
||||||
if (val) {
|
|
||||||
buttons_local |= (1UL << (button - 1));
|
|
||||||
} else {
|
|
||||||
buttons_local &= ~(1UL << (button - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
data.buttons = buttons_local;
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JoystickBT_::X(int val) {
|
|
||||||
data.x = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void JoystickBT_::Y(int val) {
|
|
||||||
data.y = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void JoystickBT_::Z(int val) {
|
|
||||||
data.z = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void JoystickBT_::Zrotate(int val) {
|
|
||||||
data.rz = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void JoystickBT_::sliderLeft(int val) {
|
|
||||||
data.rx = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void JoystickBT_::sliderRight(int val) {
|
|
||||||
data.ry = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JoystickBT_::slider(int val) {
|
|
||||||
data.rx = map8or10bit(val);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JoystickBT_::position(int X, int Y) {
|
|
||||||
data.x = map8or10bit(X);
|
|
||||||
data.y = map8or10bit(Y);
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//compatibility: there is only one hat implemented, num parameter is ignored
|
|
||||||
void JoystickBT_::hat(unsigned int num, int angle) {
|
|
||||||
(void) num;
|
|
||||||
hat(angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
//set the hat value, from 0-360. -1 is rest position
|
|
||||||
void JoystickBT_::hat(int angle) {
|
|
||||||
if (angle < 0) {
|
|
||||||
data.hat = 0;
|
|
||||||
}
|
|
||||||
if (angle >= 0 && angle <= 360) {
|
|
||||||
data.hat = map(angle, 0, 360, 1, 8);
|
|
||||||
}
|
|
||||||
if (_autosend) {
|
|
||||||
send_now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//immediately send an HID report
|
//immediately send an HID report
|
||||||
void JoystickBT_::send_now(void) {
|
void JoystickBT_::send_now(void) {
|
||||||
PicoBluetoothHID.send(REPORT_ID, &data, sizeof(data));
|
PicoBluetoothHID.send(REPORT_ID, &data, sizeof(data));
|
||||||
|
|
|
||||||
|
|
@ -21,48 +21,15 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <HID_Joystick.h>
|
||||||
#include "class/hid/hid.h"
|
#include "class/hid/hid.h"
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
class JoystickBT_ {
|
class JoystickBT_ : public HID_Joystick {
|
||||||
private:
|
|
||||||
bool _autosend;
|
|
||||||
bool _use8bit;
|
|
||||||
hid_gamepad_report_t data;
|
|
||||||
int map8or10bit(int const value);
|
|
||||||
public:
|
public:
|
||||||
JoystickBT_(void);
|
JoystickBT_(void);
|
||||||
void begin(void);
|
void begin(void);
|
||||||
void end(void);
|
void end(void);
|
||||||
|
virtual void send_now(void) override;
|
||||||
//set a selected button to pressed/released
|
|
||||||
void button(uint8_t button, bool val);
|
|
||||||
//set axis values
|
|
||||||
void X(int val);
|
|
||||||
void Y(int val);
|
|
||||||
void position(int X, int Y);
|
|
||||||
void Z(int val);
|
|
||||||
void Zrotate(int val);
|
|
||||||
void sliderLeft(int val);
|
|
||||||
void sliderRight(int val);
|
|
||||||
//note: not implemented in TinyUSB gamepad, is mapped to sliderLeft.
|
|
||||||
void slider(int val);
|
|
||||||
|
|
||||||
//set the hat value, from 0-360. -1 is rest position
|
|
||||||
void hat(int angle);
|
|
||||||
//compatibility: there is only one hat implemented, num parameter is ignored
|
|
||||||
void hat(unsigned int num, int angle);
|
|
||||||
|
|
||||||
|
|
||||||
//if set, the gamepad report is not automatically sent after an update of axes/buttons; use send_now to update
|
|
||||||
void useManualSend(bool mode);
|
|
||||||
//immediately send an HID report
|
|
||||||
void send_now(void);
|
|
||||||
//define the mapping of axes values
|
|
||||||
//default: axes methods are accepting values from 0-1023 (compatibility to other Joystick libraries)
|
|
||||||
// and are mapped internally to int8_t
|
|
||||||
//if use8bit(true) is called, -127 to 127 values are used.
|
|
||||||
void use8bit(bool mode);
|
|
||||||
};
|
};
|
||||||
extern JoystickBT_ JoystickBT;
|
extern JoystickBT_ JoystickBT;
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit a6498d6228347ff8337a91b9c1ce934350214dd6
|
|
||||||
165
libraries/Keyboard/LICENSE
Normal file
165
libraries/Keyboard/LICENSE
Normal file
|
|
@ -0,0 +1,165 @@
|
||||||
|
GNU LESSER 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.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser 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
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
||||||
31
libraries/Keyboard/README.adoc
Normal file
31
libraries/Keyboard/README.adoc
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
:repository-owner: arduino-libraries
|
||||||
|
:repository-name: Keyboard
|
||||||
|
|
||||||
|
= {repository-name} Library for Arduino =
|
||||||
|
|
||||||
|
image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/check-arduino.yml/badge.svg["Check Arduino status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/check-arduino.yml"]
|
||||||
|
image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/compile-examples.yml/badge.svg["Compile Examples status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/compile-examples.yml"]
|
||||||
|
image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/spell-check.yml/badge.svg["Spell Check status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/spell-check.yml"]
|
||||||
|
|
||||||
|
This library allows an Arduino board with USB capabilities to act as a keyboard.
|
||||||
|
|
||||||
|
For more information about this library please visit us at
|
||||||
|
https://www.arduino.cc/reference/en/language/functions/usb/keyboard/
|
||||||
|
|
||||||
|
== License ==
|
||||||
|
|
||||||
|
Copyright (c) Arduino LLC. All right reserved.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
/* Released into the public domain */
|
||||||
|
/* Earle F. Philhower, III <earlephilhower@yahoo.com> */
|
||||||
|
|
||||||
|
#include <Keyboard.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
Keyboard.begin();
|
||||||
|
delay(5000);
|
||||||
|
Serial.printf("Arduino USB Password Typer\n");
|
||||||
|
Serial.printf("Press BOOTSEL to enter your super-secure(not!) password\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (BOOTSEL) {
|
||||||
|
Serial.println("Typing password for you...shhhh....");
|
||||||
|
Keyboard.print("ThisPasswordIsWeakLikeABaby");
|
||||||
|
while (BOOTSEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
39
libraries/Keyboard/examples/Serial/Serial.ino
Normal file
39
libraries/Keyboard/examples/Serial/Serial.ino
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
Keyboard test
|
||||||
|
|
||||||
|
For the Arduino Leonardo, Micro or Due
|
||||||
|
|
||||||
|
Reads a byte from the serial port, sends a keystroke back.
|
||||||
|
The sent keystroke is one higher than what's received, e.g. if you send a,
|
||||||
|
you get b, send A you get B, and so forth.
|
||||||
|
|
||||||
|
The circuit:
|
||||||
|
- none
|
||||||
|
|
||||||
|
created 21 Oct 2011
|
||||||
|
modified 27 Mar 2012
|
||||||
|
by Tom Igoe
|
||||||
|
|
||||||
|
This example code is in the public domain.
|
||||||
|
|
||||||
|
https://www.arduino.cc/en/Tutorial/BuiltInExamples/KeyboardSerial
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Keyboard.h"
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// open the serial port:
|
||||||
|
Serial.begin(9600);
|
||||||
|
// initialize control over the keyboard:
|
||||||
|
Keyboard.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// check for incoming serial data:
|
||||||
|
if (Serial.available() > 0) {
|
||||||
|
// read incoming serial data:
|
||||||
|
char inChar = Serial.read();
|
||||||
|
// Type the next ASCII value from what you received:
|
||||||
|
Keyboard.write(inChar + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,26 +1,22 @@
|
||||||
#######################################
|
#######################################
|
||||||
# Syntax Coloring Map
|
# Syntax Coloring Map For Keyboard
|
||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Datatypes (KEYWORD1)
|
# Datatypes (KEYWORD1)
|
||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
PicoBluetoothHID KEYWORD1
|
Keyboard KEYWORD1
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Methods and Functions (KEYWORD2)
|
# Methods and Functions (KEYWORD2)
|
||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
setOpenedCB KEYWORD2
|
begin KEYWORD2
|
||||||
setClosedCB KEYWORD2
|
write KEYWORD2
|
||||||
setCanSendNowCB KEYWORD2
|
press KEYWORD2
|
||||||
startHID KEYWORD2
|
release KEYWORD2
|
||||||
connected KEYWORD2
|
releaseAll KEYWORD2
|
||||||
send KEYWORD2
|
|
||||||
lockBluetooth KEYWORD2
|
|
||||||
unlockBluetooth KEYWORD2
|
|
||||||
getCID KEYWORD2
|
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Constants (LITERAL1)
|
# Constants (LITERAL1)
|
||||||
9
libraries/Keyboard/library.properties
Normal file
9
libraries/Keyboard/library.properties
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
name=Keyboard
|
||||||
|
version=1.0.3
|
||||||
|
author=Arduino and EFP3
|
||||||
|
maintainer=Earle F. Philhower, III <earlephilhower@yahoo.com>
|
||||||
|
sentence=Allows a RP2040 to act as a Keyboard.
|
||||||
|
paragraph=Port of pure Arduino Keyboard
|
||||||
|
category=Device Control
|
||||||
|
url=https://www.arduino.cc/reference/en/language/functions/usb/keyboard/
|
||||||
|
architectures=rp2040
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
/*
|
/*
|
||||||
Keyboard_sv_SE.h
|
Keyboard.cpp
|
||||||
|
|
||||||
Copyright (c) 2021, Peter John
|
Modified by Earle F. Philhower, III <earlephilhower@yahoo.com>
|
||||||
|
Main Arduino Library Copyright (c) 2015, Arduino LLC
|
||||||
|
Original code (pre-library): Copyright (c) 2011, Peter Barrett
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
@ -18,27 +20,30 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef KEYBOARD_SV_SE_h
|
#include "Keyboard.h"
|
||||||
#define KEYBOARD_SV_SE_h
|
#include <RP2040USB.h>
|
||||||
|
|
||||||
#include "HID.h"
|
#include "tusb.h"
|
||||||
|
#include "class/hid/hid_device.h"
|
||||||
|
|
||||||
#if !defined(_USING_HID)
|
// Weak function override to add our descriptor to the TinyUSB list
|
||||||
|
void __USBInstallKeyboard() { /* noop */ }
|
||||||
#warning "Using legacy HID core (non pluggable)"
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
//================================================================================
|
//================================================================================
|
||||||
// Keyboard
|
// Keyboard
|
||||||
|
|
||||||
// SV_SE keys
|
Keyboard_::Keyboard_(void) {
|
||||||
#define KEY_A_RING (136+0x2f)
|
// Base class clears the members we care about
|
||||||
#define KEY_A_UMLAUT (136+0x34)
|
}
|
||||||
#define KEY_O_UMLAUT (136+0x33)
|
|
||||||
#define KEY_UMLAUT (136+0x30)
|
|
||||||
#define KEY_ACUTE_ACC (136+0x2e)
|
|
||||||
|
|
||||||
#endif
|
void Keyboard_::sendReport(KeyReport* keys) {
|
||||||
#endif
|
CoreMutex m(&__usb_mutex);
|
||||||
|
tud_task();
|
||||||
|
if (tud_hid_ready()) {
|
||||||
|
tud_hid_keyboard_report(__USBGetKeyboardReportID(), keys->modifiers, keys->keys);
|
||||||
|
}
|
||||||
|
tud_task();
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyboard_ Keyboard;
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
/*
|
/*
|
||||||
Keyboard_sv_SE.h
|
Keyboard.h
|
||||||
|
|
||||||
Copyright (c) 2021, Peter John
|
Modified by Earle F. Philhower, III <earlephilhower@yahoo.com>
|
||||||
|
Main Arduino Library Copyright (c) 2015, Arduino LLC
|
||||||
|
Original code (pre-library): Copyright (c) 2011, Peter Barrett
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
@ -18,27 +20,17 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef KEYBOARD_SV_SE_h
|
#ifndef KEYBOARD_h
|
||||||
#define KEYBOARD_SV_SE_h
|
#define KEYBOARD_h
|
||||||
|
|
||||||
#include "HID.h"
|
#include <HID_Keyboard.h>
|
||||||
|
|
||||||
#if !defined(_USING_HID)
|
class Keyboard_ : public HID_Keyboard {
|
||||||
|
protected:
|
||||||
#warning "Using legacy HID core (non pluggable)"
|
virtual void sendReport(KeyReport* keys) override;
|
||||||
|
public:
|
||||||
#else
|
Keyboard_(void);
|
||||||
|
};
|
||||||
//================================================================================
|
extern Keyboard_ Keyboard;
|
||||||
//================================================================================
|
|
||||||
// Keyboard
|
|
||||||
|
|
||||||
// SV_SE keys
|
|
||||||
#define KEY_A_RING (136+0x2f)
|
|
||||||
#define KEY_A_UMLAUT (136+0x34)
|
|
||||||
#define KEY_O_UMLAUT (136+0x33)
|
|
||||||
#define KEY_UMLAUT (136+0x30)
|
|
||||||
#define KEY_ACUTE_ACC (136+0x2e)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
@ -29,8 +29,7 @@
|
||||||
// Keyboard
|
// Keyboard
|
||||||
|
|
||||||
KeyboardBLE_::KeyboardBLE_(void) {
|
KeyboardBLE_::KeyboardBLE_(void) {
|
||||||
bzero(&_keyReport, sizeof(_keyReport));
|
// Base class clears the members we care about
|
||||||
_asciimap = KeyboardLayout_en_US;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REPORT_ID 0x01
|
#define REPORT_ID 0x01
|
||||||
|
|
@ -57,127 +56,4 @@ void KeyboardBLE_::sendReport(KeyReport* keys) {
|
||||||
PicoBluetoothBLEHID.send(&data, sizeof(data));
|
PicoBluetoothBLEHID.send(&data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
// press() adds the specified key (printing, non-printing, or modifier)
|
|
||||||
// to the persistent key report and sends the report. Because of the way
|
|
||||||
// USB HID works, the host acts like the key remains pressed until we
|
|
||||||
// call release(), releaseAll(), or otherwise clear the report and resend.
|
|
||||||
size_t KeyboardBLE_::press(uint8_t k) {
|
|
||||||
uint8_t i;
|
|
||||||
if (k >= 136) { // it's a non-printing key (not a modifier)
|
|
||||||
k = k - 136;
|
|
||||||
} else if (k >= 128) { // it's a modifier key
|
|
||||||
_keyReport.modifiers |= (1 << (k - 128));
|
|
||||||
k = 0;
|
|
||||||
} else { // it's a printing key
|
|
||||||
k = pgm_read_byte(_asciimap + k);
|
|
||||||
if (!k) {
|
|
||||||
setWriteError();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if ((k & ALT_GR) == ALT_GR) {
|
|
||||||
_keyReport.modifiers |= 0x40; // AltGr = right Alt
|
|
||||||
k &= 0x3F;
|
|
||||||
} else if ((k & SHIFT) == SHIFT) {
|
|
||||||
_keyReport.modifiers |= 0x02; // the left shift modifier
|
|
||||||
k &= 0x7F;
|
|
||||||
}
|
|
||||||
if (k == ISO_REPLACEMENT) {
|
|
||||||
k = ISO_KEY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add k to the key report only if it's not already present
|
|
||||||
// and if there is an empty slot.
|
|
||||||
if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
|
|
||||||
_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
|
|
||||||
_keyReport.keys[4] != k && _keyReport.keys[5] != k) {
|
|
||||||
|
|
||||||
for (i = 0; i < 6; i++) {
|
|
||||||
if (_keyReport.keys[i] == 0x00) {
|
|
||||||
_keyReport.keys[i] = k;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i == 6) {
|
|
||||||
setWriteError();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sendReport(&_keyReport);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// release() takes the specified key out of the persistent key report and
|
|
||||||
// sends the report. This tells the OS the key is no longer pressed and that
|
|
||||||
// it shouldn't be repeated any more.
|
|
||||||
size_t KeyboardBLE_::release(uint8_t k) {
|
|
||||||
uint8_t i;
|
|
||||||
if (k >= 136) { // it's a non-printing key (not a modifier)
|
|
||||||
k = k - 136;
|
|
||||||
} else if (k >= 128) { // it's a modifier key
|
|
||||||
_keyReport.modifiers &= ~(1 << (k - 128));
|
|
||||||
k = 0;
|
|
||||||
} else { // it's a printing key
|
|
||||||
k = pgm_read_byte(_asciimap + k);
|
|
||||||
if (!k) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if ((k & ALT_GR) == ALT_GR) {
|
|
||||||
_keyReport.modifiers &= ~(0x40); // AltGr = right Alt
|
|
||||||
k &= 0x3F;
|
|
||||||
} else if ((k & SHIFT) == SHIFT) {
|
|
||||||
_keyReport.modifiers &= ~(0x02); // the left shift modifier
|
|
||||||
k &= 0x7F;
|
|
||||||
}
|
|
||||||
if (k == ISO_REPLACEMENT) {
|
|
||||||
k = ISO_KEY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test the key report to see if k is present. Clear it if it exists.
|
|
||||||
// Check all positions in case the key is present more than once (which it shouldn't be)
|
|
||||||
for (i = 0; i < 6; i++) {
|
|
||||||
if (0 != k && _keyReport.keys[i] == k) {
|
|
||||||
_keyReport.keys[i] = 0x00;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sendReport(&_keyReport);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyboardBLE_::releaseAll(void) {
|
|
||||||
_keyReport.keys[0] = 0;
|
|
||||||
_keyReport.keys[1] = 0;
|
|
||||||
_keyReport.keys[2] = 0;
|
|
||||||
_keyReport.keys[3] = 0;
|
|
||||||
_keyReport.keys[4] = 0;
|
|
||||||
_keyReport.keys[5] = 0;
|
|
||||||
_keyReport.modifiers = 0;
|
|
||||||
sendReport(&_keyReport);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t KeyboardBLE_::write(uint8_t c) {
|
|
||||||
uint8_t p = press(c); // Keydown
|
|
||||||
delay(10);
|
|
||||||
release(c); // Keyup
|
|
||||||
delay(10);
|
|
||||||
return p; // just return the result of press() since release() almost always returns 1
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t KeyboardBLE_::write(const uint8_t *buffer, size_t size) {
|
|
||||||
size_t n = 0;
|
|
||||||
while (size--) {
|
|
||||||
if (*buffer != '\r') {
|
|
||||||
if (write(*buffer)) {
|
|
||||||
n++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buffer++;
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyboardBLE_ KeyboardBLE;
|
KeyboardBLE_ KeyboardBLE;
|
||||||
|
|
|
||||||
|
|
@ -23,118 +23,15 @@
|
||||||
#ifndef KEYBOARDBLE_h
|
#ifndef KEYBOARDBLE_h
|
||||||
#define KEYBOARDBLE_h
|
#define KEYBOARDBLE_h
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <HID_Keyboard.h>
|
||||||
|
|
||||||
//================================================================================
|
class KeyboardBLE_ : public HID_Keyboard {
|
||||||
//================================================================================
|
|
||||||
// Keyboard
|
|
||||||
|
|
||||||
// Modifiers
|
|
||||||
#define KEY_LEFT_CTRL 0x80
|
|
||||||
#define KEY_LEFT_SHIFT 0x81
|
|
||||||
#define KEY_LEFT_ALT 0x82
|
|
||||||
#define KEY_LEFT_GUI 0x83
|
|
||||||
#define KEY_RIGHT_CTRL 0x84
|
|
||||||
#define KEY_RIGHT_SHIFT 0x85
|
|
||||||
#define KEY_RIGHT_ALT 0x86
|
|
||||||
#define KEY_RIGHT_GUI 0x87
|
|
||||||
|
|
||||||
// Misc keys
|
|
||||||
#define KEY_UP_ARROW 0xDA
|
|
||||||
#define KEY_DOWN_ARROW 0xD9
|
|
||||||
#define KEY_LEFT_ARROW 0xD8
|
|
||||||
#define KEY_RIGHT_ARROW 0xD7
|
|
||||||
#define KEY_BACKSPACE 0xB2
|
|
||||||
#define KEY_TAB 0xB3
|
|
||||||
#define KEY_RETURN 0xB0
|
|
||||||
#define KEY_MENU 0xED // "Keyboard Application" in USB standard
|
|
||||||
#define KEY_ESC 0xB1
|
|
||||||
#define KEY_INSERT 0xD1
|
|
||||||
#define KEY_DELETE 0xD4
|
|
||||||
#define KEY_PAGE_UP 0xD3
|
|
||||||
#define KEY_PAGE_DOWN 0xD6
|
|
||||||
#define KEY_HOME 0xD2
|
|
||||||
#define KEY_END 0xD5
|
|
||||||
#define KEY_CAPS_LOCK 0xC1
|
|
||||||
#define KEY_PRINT_SCREEN 0xCE // Print Screen / SysRq
|
|
||||||
#define KEY_SCROLL_LOCK 0xCF
|
|
||||||
#define KEY_PAUSE 0xD0 // Pause / Break
|
|
||||||
|
|
||||||
// Numeric keypad
|
|
||||||
#define KEY_NUM_LOCK 0xDB
|
|
||||||
#define KEY_KP_SLASH 0xDC
|
|
||||||
#define KEY_KP_ASTERISK 0xDD
|
|
||||||
#define KEY_KP_MINUS 0xDE
|
|
||||||
#define KEY_KP_PLUS 0xDF
|
|
||||||
#define KEY_KP_ENTER 0xE0
|
|
||||||
#define KEY_KP_1 0xE1
|
|
||||||
#define KEY_KP_2 0xE2
|
|
||||||
#define KEY_KP_3 0xE3
|
|
||||||
#define KEY_KP_4 0xE4
|
|
||||||
#define KEY_KP_5 0xE5
|
|
||||||
#define KEY_KP_6 0xE6
|
|
||||||
#define KEY_KP_7 0xE7
|
|
||||||
#define KEY_KP_8 0xE8
|
|
||||||
#define KEY_KP_9 0xE9
|
|
||||||
#define KEY_KP_0 0xEA
|
|
||||||
#define KEY_KP_DOT 0xEB
|
|
||||||
|
|
||||||
// Function keys
|
|
||||||
#define KEY_F1 0xC2
|
|
||||||
#define KEY_F2 0xC3
|
|
||||||
#define KEY_F3 0xC4
|
|
||||||
#define KEY_F4 0xC5
|
|
||||||
#define KEY_F5 0xC6
|
|
||||||
#define KEY_F6 0xC7
|
|
||||||
#define KEY_F7 0xC8
|
|
||||||
#define KEY_F8 0xC9
|
|
||||||
#define KEY_F9 0xCA
|
|
||||||
#define KEY_F10 0xCB
|
|
||||||
#define KEY_F11 0xCC
|
|
||||||
#define KEY_F12 0xCD
|
|
||||||
#define KEY_F13 0xF0
|
|
||||||
#define KEY_F14 0xF1
|
|
||||||
#define KEY_F15 0xF2
|
|
||||||
#define KEY_F16 0xF3
|
|
||||||
#define KEY_F17 0xF4
|
|
||||||
#define KEY_F18 0xF5
|
|
||||||
#define KEY_F19 0xF6
|
|
||||||
#define KEY_F20 0xF7
|
|
||||||
#define KEY_F21 0xF8
|
|
||||||
#define KEY_F22 0xF9
|
|
||||||
#define KEY_F23 0xFA
|
|
||||||
#define KEY_F24 0xFB
|
|
||||||
|
|
||||||
// Supported keyboard layouts
|
|
||||||
extern const uint8_t KeyboardLayout_de_DE[];
|
|
||||||
extern const uint8_t KeyboardLayout_en_US[];
|
|
||||||
extern const uint8_t KeyboardLayout_es_ES[];
|
|
||||||
extern const uint8_t KeyboardLayout_fr_FR[];
|
|
||||||
extern const uint8_t KeyboardLayout_it_IT[];
|
|
||||||
extern const uint8_t KeyboardLayout_sv_SE[];
|
|
||||||
extern const uint8_t KeyboardLayout_da_DK[];
|
|
||||||
|
|
||||||
// Low level key report: up to 6 keys and shift, ctrl etc at once
|
|
||||||
typedef struct {
|
|
||||||
uint8_t modifiers;
|
|
||||||
uint8_t reserved;
|
|
||||||
uint8_t keys[6];
|
|
||||||
} KeyReport;
|
|
||||||
|
|
||||||
class KeyboardBLE_ : public Print {
|
|
||||||
private:
|
private:
|
||||||
KeyReport _keyReport;
|
virtual void sendReport(KeyReport* keys) override;
|
||||||
const uint8_t *_asciimap;
|
|
||||||
void sendReport(KeyReport* keys);
|
|
||||||
public:
|
public:
|
||||||
KeyboardBLE_(void);
|
KeyboardBLE_(void);
|
||||||
void begin(const uint8_t *layout = KeyboardLayout_en_US);
|
void begin(const uint8_t *layout = KeyboardLayout_en_US);
|
||||||
void end(void);
|
void end(void);
|
||||||
size_t write(uint8_t k);
|
|
||||||
size_t write(const uint8_t *buffer, size_t size);
|
|
||||||
size_t press(uint8_t k);
|
|
||||||
size_t release(uint8_t k);
|
|
||||||
void releaseAll(void);
|
|
||||||
void setBattery(int lvl);
|
void setBattery(int lvl);
|
||||||
};
|
};
|
||||||
extern KeyboardBLE_ KeyboardBLE;
|
extern KeyboardBLE_ KeyboardBLE;
|
||||||
|
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
KeyboardLayout.h
|
|
||||||
|
|
||||||
This file is not part of the public API. It is meant to be included
|
|
||||||
only in Keyboard.cpp and the keyboard layout files. Layout files map
|
|
||||||
ASCII character codes to keyboard scan codes (technically, to USB HID
|
|
||||||
Usage codes), possibly altered by the SHIFT or ALT_GR modifiers.
|
|
||||||
|
|
||||||
== Creating your own layout ==
|
|
||||||
|
|
||||||
In order to create your own layout file, copy an existing layout that
|
|
||||||
is similar to yours, then modify it to use the correct keys. The
|
|
||||||
layout is an array in ASCII order. Each entry contains a scan code,
|
|
||||||
possibly modified by "|SHIFT" or "|ALT_GR", as in this excerpt from
|
|
||||||
the Italian layout:
|
|
||||||
|
|
||||||
0x35, // bslash
|
|
||||||
0x30|ALT_GR, // ]
|
|
||||||
0x2e|SHIFT, // ^
|
|
||||||
|
|
||||||
Do not change the control characters (those before scan code 0x2c,
|
|
||||||
corresponding to space). Do not attempt to grow the table past DEL. Do
|
|
||||||
not use both SHIFT and ALT_GR on the same character: this is not
|
|
||||||
supported. Unsupported characters should have 0x00 as scan code.
|
|
||||||
|
|
||||||
For a keyboard with an ISO physical layout, use the scan codes below:
|
|
||||||
|
|
||||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+-------+
|
|
||||||
|35 |1e |1f |20 |21 |22 |23 |24 |25 |26 |27 |2d |2e |BackSp |
|
|
||||||
+---+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-----+
|
|
||||||
| Tab |14 |1a |08 |15 |17 |1c |18 |0c |12 |13 |2f |30 | Ret |
|
|
||||||
+-----++--++--++--++--++--++--++--++--++--++--++--++--++ |
|
|
||||||
|CapsL |04 |16 |07 |09 |0a |0b |0d |0e |0f |33 |34 |31 | |
|
|
||||||
+----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+---+----+
|
|
||||||
|Shi.|32 |1d |1b |06 |19 |05 |11 |10 |36 |37 |38 | Shift |
|
|
||||||
+----+---++--+-+-+---+---+---+---+---+--++---+---++----+----+
|
|
||||||
|Ctrl|Win |Alt | |AlGr|Win |Menu|Ctrl|
|
|
||||||
+----+----+----+------------------------+----+----+----+----+
|
|
||||||
|
|
||||||
The ANSI layout is identical except that key 0x31 is above (rather
|
|
||||||
than next to) Return, and there is not key 0x32.
|
|
||||||
|
|
||||||
Give a unique name to the layout array, then declare it in Keyboard.h
|
|
||||||
with a line of the form:
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_xx_YY[];
|
|
||||||
|
|
||||||
== Encoding details ==
|
|
||||||
|
|
||||||
All scan codes are less than 0x80, which makes bit 7 available to
|
|
||||||
signal that a modifier (Shift or AltGr) is needed to generate the
|
|
||||||
character. With only one exception, keys that are used with modifiers
|
|
||||||
have scan codes that are less than 0x40. This makes bit 6 available
|
|
||||||
to signal whether the modifier is Shift or AltGr. The exception is
|
|
||||||
0x64, the key next next to Left Shift on the ISO layout (and absent
|
|
||||||
from the ANSI layout). We handle it by replacing its value by 0x32 in
|
|
||||||
the layout arrays.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
#define SHIFT 0x80
|
|
||||||
#define ALT_GR 0xc0
|
|
||||||
#define ISO_KEY 0x64
|
|
||||||
#define ISO_REPLACEMENT 0x32
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
Danish keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_da_DK[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x1e | SHIFT, // !
|
|
||||||
0x1f | SHIFT, // "
|
|
||||||
0x20 | SHIFT, // #
|
|
||||||
0x21 | ALT_GR, // $
|
|
||||||
0x22 | SHIFT, // %
|
|
||||||
0x23 | SHIFT, // &
|
|
||||||
0x31, // '
|
|
||||||
0x25 | SHIFT, // (
|
|
||||||
0x26 | SHIFT, // )
|
|
||||||
0x31 | SHIFT, // *
|
|
||||||
0x2d, // +
|
|
||||||
0x36, // ,
|
|
||||||
0x38, // -
|
|
||||||
0x37, // .
|
|
||||||
0x24 | SHIFT, // /
|
|
||||||
0x27, // 0
|
|
||||||
0x1e, // 1
|
|
||||||
0x1f, // 2
|
|
||||||
0x20, // 3
|
|
||||||
0x21, // 4
|
|
||||||
0x22, // 5
|
|
||||||
0x23, // 6
|
|
||||||
0x24, // 7
|
|
||||||
0x25, // 8
|
|
||||||
0x26, // 9
|
|
||||||
0x37 | SHIFT, // :
|
|
||||||
0x36 | SHIFT, // ;
|
|
||||||
0x32, // <
|
|
||||||
0x27 | SHIFT, // =
|
|
||||||
0x32 | SHIFT, // >
|
|
||||||
0x2d | SHIFT, // ?
|
|
||||||
0x1f | ALT_GR, // @
|
|
||||||
0x04 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x10 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x14 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1a | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1c | SHIFT, // Y
|
|
||||||
0x1d | SHIFT, // Z
|
|
||||||
0x25 | ALT_GR, // [
|
|
||||||
0x32 | ALT_GR, // bslash
|
|
||||||
0x26 | ALT_GR, // ]
|
|
||||||
0x00, // ^ not supported (requires dead key + space)
|
|
||||||
0x38 | SHIFT, // _
|
|
||||||
0x00, // ` not supported (requires dead key + space)
|
|
||||||
0x04, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x10, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x14, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1a, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1c, // y
|
|
||||||
0x1d, // z
|
|
||||||
0x24 | ALT_GR, // {
|
|
||||||
0x2e | ALT_GR, // |
|
|
||||||
0x27 | ALT_GR, // }
|
|
||||||
0x00, // ~ not supported (requires dead key + space)
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
German keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_de_DE[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x1e | SHIFT, // !
|
|
||||||
0x1f | SHIFT, // "
|
|
||||||
0x31, // #
|
|
||||||
0x21 | SHIFT, // $
|
|
||||||
0x22 | SHIFT, // %
|
|
||||||
0x23 | SHIFT, // &
|
|
||||||
0x31 | SHIFT, // '
|
|
||||||
0x25 | SHIFT, // (
|
|
||||||
0x26 | SHIFT, // )
|
|
||||||
0x30 | SHIFT, // *
|
|
||||||
0x30, // +
|
|
||||||
0x36, // ,
|
|
||||||
0x38, // -
|
|
||||||
0x37, // .
|
|
||||||
0x24 | SHIFT, // /
|
|
||||||
0x27, // 0
|
|
||||||
0x1e, // 1
|
|
||||||
0x1f, // 2
|
|
||||||
0x20, // 3
|
|
||||||
0x21, // 4
|
|
||||||
0x22, // 5
|
|
||||||
0x23, // 6
|
|
||||||
0x24, // 7
|
|
||||||
0x25, // 8
|
|
||||||
0x26, // 9
|
|
||||||
0x37 | SHIFT, // :
|
|
||||||
0x36 | SHIFT, // ;
|
|
||||||
0x32, // <
|
|
||||||
0x27 | SHIFT, // =
|
|
||||||
0x32 | SHIFT, // >
|
|
||||||
0x2d | SHIFT, // ?
|
|
||||||
0x14 | ALT_GR, // @
|
|
||||||
0x04 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x10 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x14 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1a | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1d | SHIFT, // Y
|
|
||||||
0x1c | SHIFT, // Z
|
|
||||||
0x25 | ALT_GR, // [
|
|
||||||
0x2d | ALT_GR, // bslash
|
|
||||||
0x26 | ALT_GR, // ]
|
|
||||||
0x00, // ^ not supported (requires dead key + space)
|
|
||||||
0x38 | SHIFT, // _
|
|
||||||
0x00, // ` not supported (requires dead key + space)
|
|
||||||
0x04, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x10, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x14, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1a, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1d, // y
|
|
||||||
0x1c, // z
|
|
||||||
0x24 | ALT_GR, // {
|
|
||||||
0x32 | ALT_GR, // |
|
|
||||||
0x27 | ALT_GR, // }
|
|
||||||
0x30 | ALT_GR, // ~
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
Standard US keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_en_US[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x1e | SHIFT, // !
|
|
||||||
0x34 | SHIFT, // "
|
|
||||||
0x20 | SHIFT, // #
|
|
||||||
0x21 | SHIFT, // $
|
|
||||||
0x22 | SHIFT, // %
|
|
||||||
0x24 | SHIFT, // &
|
|
||||||
0x34, // '
|
|
||||||
0x26 | SHIFT, // (
|
|
||||||
0x27 | SHIFT, // )
|
|
||||||
0x25 | SHIFT, // *
|
|
||||||
0x2e | SHIFT, // +
|
|
||||||
0x36, // ,
|
|
||||||
0x2d, // -
|
|
||||||
0x37, // .
|
|
||||||
0x38, // /
|
|
||||||
0x27, // 0
|
|
||||||
0x1e, // 1
|
|
||||||
0x1f, // 2
|
|
||||||
0x20, // 3
|
|
||||||
0x21, // 4
|
|
||||||
0x22, // 5
|
|
||||||
0x23, // 6
|
|
||||||
0x24, // 7
|
|
||||||
0x25, // 8
|
|
||||||
0x26, // 9
|
|
||||||
0x33 | SHIFT, // :
|
|
||||||
0x33, // ;
|
|
||||||
0x36 | SHIFT, // <
|
|
||||||
0x2e, // =
|
|
||||||
0x37 | SHIFT, // >
|
|
||||||
0x38 | SHIFT, // ?
|
|
||||||
0x1f | SHIFT, // @
|
|
||||||
0x04 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x10 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x14 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1a | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1c | SHIFT, // Y
|
|
||||||
0x1d | SHIFT, // Z
|
|
||||||
0x2f, // [
|
|
||||||
0x31, // bslash
|
|
||||||
0x30, // ]
|
|
||||||
0x23 | SHIFT, // ^
|
|
||||||
0x2d | SHIFT, // _
|
|
||||||
0x35, // `
|
|
||||||
0x04, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x10, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x14, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1a, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1c, // y
|
|
||||||
0x1d, // z
|
|
||||||
0x2f | SHIFT, // {
|
|
||||||
0x31 | SHIFT, // |
|
|
||||||
0x30 | SHIFT, // }
|
|
||||||
0x35 | SHIFT, // ~
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
Spanish keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_es_ES[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x1e | SHIFT, // !
|
|
||||||
0x1f | SHIFT, // "
|
|
||||||
0x20 | ALT_GR, // #
|
|
||||||
0x21 | SHIFT, // $
|
|
||||||
0x22 | SHIFT, // %
|
|
||||||
0x23 | SHIFT, // &
|
|
||||||
0x2d, // '
|
|
||||||
0x25 | SHIFT, // (
|
|
||||||
0x26 | SHIFT, // )
|
|
||||||
0x30 | SHIFT, // *
|
|
||||||
0x30, // +
|
|
||||||
0x36, // ,
|
|
||||||
0x38, // -
|
|
||||||
0x37, // .
|
|
||||||
0x24 | SHIFT, // /
|
|
||||||
0x27, // 0
|
|
||||||
0x1e, // 1
|
|
||||||
0x1f, // 2
|
|
||||||
0x20, // 3
|
|
||||||
0x21, // 4
|
|
||||||
0x22, // 5
|
|
||||||
0x23, // 6
|
|
||||||
0x24, // 7
|
|
||||||
0x25, // 8
|
|
||||||
0x26, // 9
|
|
||||||
0x37 | SHIFT, // :
|
|
||||||
0x36 | SHIFT, // ;
|
|
||||||
0x32, // <
|
|
||||||
0x27 | SHIFT, // =
|
|
||||||
0x32 | SHIFT, // >
|
|
||||||
0x2d | SHIFT, // ?
|
|
||||||
0x1f | ALT_GR, // @
|
|
||||||
0x04 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x10 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x14 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1a | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1c | SHIFT, // Y
|
|
||||||
0x1d | SHIFT, // Z
|
|
||||||
0x2f | ALT_GR, // [
|
|
||||||
0x35 | ALT_GR, // bslash
|
|
||||||
0x30 | ALT_GR, // ]
|
|
||||||
0x00, // ^ not supported (requires dead key + space)
|
|
||||||
0x38 | SHIFT, // _
|
|
||||||
0x00, // ` not supported (requires dead key + space)
|
|
||||||
0x04, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x10, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x14, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1a, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1c, // y
|
|
||||||
0x1d, // z
|
|
||||||
0x34 | ALT_GR, // {
|
|
||||||
0x1e | ALT_GR, // |
|
|
||||||
0x31 | ALT_GR, // }
|
|
||||||
0x00, // ~ not supported (requires dead key + space)
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
Traditional (not AFNOR) French keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_fr_FR[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x38, // !
|
|
||||||
0x20, // "
|
|
||||||
0x20 | ALT_GR, // #
|
|
||||||
0x30, // $
|
|
||||||
0x34 | SHIFT, // %
|
|
||||||
0x1E, // &
|
|
||||||
0x21, // '
|
|
||||||
0x22, // (
|
|
||||||
0x2d, // )
|
|
||||||
0x31, // *
|
|
||||||
0x2e | SHIFT, // +
|
|
||||||
0x10, // ,
|
|
||||||
0x23, // -
|
|
||||||
0x36 | SHIFT, // .
|
|
||||||
0x37 | SHIFT, // /
|
|
||||||
0x27 | SHIFT, // 0
|
|
||||||
0x1e | SHIFT, // 1
|
|
||||||
0x1f | SHIFT, // 2
|
|
||||||
0x20 | SHIFT, // 3
|
|
||||||
0x21 | SHIFT, // 4
|
|
||||||
0x22 | SHIFT, // 5
|
|
||||||
0x23 | SHIFT, // 6
|
|
||||||
0x24 | SHIFT, // 7
|
|
||||||
0x25 | SHIFT, // 8
|
|
||||||
0x26 | SHIFT, // 9
|
|
||||||
0x37, // :
|
|
||||||
0x36, // ;
|
|
||||||
0x32, // <
|
|
||||||
0x2e, // =
|
|
||||||
0x32 | SHIFT, // >
|
|
||||||
0x10 | SHIFT, // ?
|
|
||||||
0x27 | ALT_GR, // @
|
|
||||||
0x14 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x33 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x04 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1d | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1c | SHIFT, // Y
|
|
||||||
0x1a | SHIFT, // Z
|
|
||||||
0x22 | ALT_GR, // [
|
|
||||||
0x25 | ALT_GR, // bslash
|
|
||||||
0x2d | ALT_GR, // ]
|
|
||||||
0x26 | ALT_GR, // ^
|
|
||||||
0x25, // _
|
|
||||||
0x24 | ALT_GR, // `
|
|
||||||
0x14, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x33, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x04, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1d, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1c, // y
|
|
||||||
0x1a, // z
|
|
||||||
0x21 | ALT_GR, // {
|
|
||||||
0x23 | ALT_GR, // |
|
|
||||||
0x2e | ALT_GR, // }
|
|
||||||
0x1f | ALT_GR, // ~
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
Italian keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_it_IT[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x1e | SHIFT, // !
|
|
||||||
0x1f | SHIFT, // "
|
|
||||||
0x34 | ALT_GR, // #
|
|
||||||
0x21 | SHIFT, // $
|
|
||||||
0x22 | SHIFT, // %
|
|
||||||
0x23 | SHIFT, // &
|
|
||||||
0x2d, // '
|
|
||||||
0x25 | SHIFT, // (
|
|
||||||
0x26 | SHIFT, // )
|
|
||||||
0x30 | SHIFT, // *
|
|
||||||
0x30, // +
|
|
||||||
0x36, // ,
|
|
||||||
0x38, // -
|
|
||||||
0x37, // .
|
|
||||||
0x24 | SHIFT, // /
|
|
||||||
0x27, // 0
|
|
||||||
0x1e, // 1
|
|
||||||
0x1f, // 2
|
|
||||||
0x20, // 3
|
|
||||||
0x21, // 4
|
|
||||||
0x22, // 5
|
|
||||||
0x23, // 6
|
|
||||||
0x24, // 7
|
|
||||||
0x25, // 8
|
|
||||||
0x26, // 9
|
|
||||||
0x37 | SHIFT, // :
|
|
||||||
0x36 | SHIFT, // ;
|
|
||||||
0x32, // <
|
|
||||||
0x27 | SHIFT, // =
|
|
||||||
0x32 | SHIFT, // >
|
|
||||||
0x2d | SHIFT, // ?
|
|
||||||
0x33 | ALT_GR, // @
|
|
||||||
0x04 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x10 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x14 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1a | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1c | SHIFT, // Y
|
|
||||||
0x1d | SHIFT, // Z
|
|
||||||
0x2f | ALT_GR, // [
|
|
||||||
0x35, // bslash
|
|
||||||
0x30 | ALT_GR, // ]
|
|
||||||
0x2e | SHIFT, // ^
|
|
||||||
0x38 | SHIFT, // _
|
|
||||||
0x00, // ` not in this layout
|
|
||||||
0x04, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x10, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x14, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1a, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1c, // y
|
|
||||||
0x1d, // z
|
|
||||||
0x00, // { not supported (requires AltGr+Shift)
|
|
||||||
0x35 | SHIFT, // |
|
|
||||||
0x00, // } not supported (requires AltGr+Shift)
|
|
||||||
0x00, // ~ not in this layout
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
Swedish keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_sv_SE[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x1e | SHIFT, // !
|
|
||||||
0x1f | SHIFT, // "
|
|
||||||
0x20 | SHIFT, // #
|
|
||||||
0x21 | ALT_GR, // $
|
|
||||||
0x22 | SHIFT, // %
|
|
||||||
0x23 | SHIFT, // &
|
|
||||||
0x31, // '
|
|
||||||
0x25 | SHIFT, // (
|
|
||||||
0x26 | SHIFT, // )
|
|
||||||
0x31 | SHIFT, // *
|
|
||||||
0x2d, // +
|
|
||||||
0x36, // ,
|
|
||||||
0x38, // -
|
|
||||||
0x37, // .
|
|
||||||
0x24 | SHIFT, // /
|
|
||||||
0x27, // 0
|
|
||||||
0x1e, // 1
|
|
||||||
0x1f, // 2
|
|
||||||
0x20, // 3
|
|
||||||
0x21, // 4
|
|
||||||
0x22, // 5
|
|
||||||
0x23, // 6
|
|
||||||
0x24, // 7
|
|
||||||
0x25, // 8
|
|
||||||
0x26, // 9
|
|
||||||
0x37 | SHIFT, // :
|
|
||||||
0x36 | SHIFT, // ;
|
|
||||||
0x32, // <
|
|
||||||
0x27 | SHIFT, // =
|
|
||||||
0x32 | SHIFT, // >
|
|
||||||
0x2d | SHIFT, // ?
|
|
||||||
0x1f | ALT_GR, // @
|
|
||||||
0x04 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x10 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x14 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1a | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1c | SHIFT, // Y
|
|
||||||
0x1d | SHIFT, // Z
|
|
||||||
0x25 | ALT_GR, // [
|
|
||||||
0x2d | ALT_GR, // bslash
|
|
||||||
0x26 | ALT_GR, // ]
|
|
||||||
0x00, // ^ not supported (requires dead key + space)
|
|
||||||
0x38 | SHIFT, // _
|
|
||||||
0x00, // ` not supported (requires dead key + space)
|
|
||||||
0x04, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x10, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x14, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1a, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1c, // y
|
|
||||||
0x1d, // z
|
|
||||||
0x24 | ALT_GR, // {
|
|
||||||
0x32 | ALT_GR, // |
|
|
||||||
0x27 | ALT_GR, // }
|
|
||||||
0x00, // ~ not supported (requires dead key + space)
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -29,8 +29,7 @@
|
||||||
// Keyboard
|
// Keyboard
|
||||||
|
|
||||||
KeyboardBT_::KeyboardBT_(void) {
|
KeyboardBT_::KeyboardBT_(void) {
|
||||||
bzero(&_keyReport, sizeof(_keyReport));
|
// Base class clears the members we care about
|
||||||
_asciimap = KeyboardLayout_en_US;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REPORT_ID 0x01
|
#define REPORT_ID 0x01
|
||||||
|
|
@ -53,127 +52,4 @@ void KeyboardBT_::sendReport(KeyReport* keys) {
|
||||||
PicoBluetoothHID.send(REPORT_ID, &data, sizeof(data));
|
PicoBluetoothHID.send(REPORT_ID, &data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
// press() adds the specified key (printing, non-printing, or modifier)
|
|
||||||
// to the persistent key report and sends the report. Because of the way
|
|
||||||
// USB HID works, the host acts like the key remains pressed until we
|
|
||||||
// call release(), releaseAll(), or otherwise clear the report and resend.
|
|
||||||
size_t KeyboardBT_::press(uint8_t k) {
|
|
||||||
uint8_t i;
|
|
||||||
if (k >= 136) { // it's a non-printing key (not a modifier)
|
|
||||||
k = k - 136;
|
|
||||||
} else if (k >= 128) { // it's a modifier key
|
|
||||||
_keyReport.modifiers |= (1 << (k - 128));
|
|
||||||
k = 0;
|
|
||||||
} else { // it's a printing key
|
|
||||||
k = pgm_read_byte(_asciimap + k);
|
|
||||||
if (!k) {
|
|
||||||
setWriteError();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if ((k & ALT_GR) == ALT_GR) {
|
|
||||||
_keyReport.modifiers |= 0x40; // AltGr = right Alt
|
|
||||||
k &= 0x3F;
|
|
||||||
} else if ((k & SHIFT) == SHIFT) {
|
|
||||||
_keyReport.modifiers |= 0x02; // the left shift modifier
|
|
||||||
k &= 0x7F;
|
|
||||||
}
|
|
||||||
if (k == ISO_REPLACEMENT) {
|
|
||||||
k = ISO_KEY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add k to the key report only if it's not already present
|
|
||||||
// and if there is an empty slot.
|
|
||||||
if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
|
|
||||||
_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
|
|
||||||
_keyReport.keys[4] != k && _keyReport.keys[5] != k) {
|
|
||||||
|
|
||||||
for (i = 0; i < 6; i++) {
|
|
||||||
if (_keyReport.keys[i] == 0x00) {
|
|
||||||
_keyReport.keys[i] = k;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i == 6) {
|
|
||||||
setWriteError();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sendReport(&_keyReport);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// release() takes the specified key out of the persistent key report and
|
|
||||||
// sends the report. This tells the OS the key is no longer pressed and that
|
|
||||||
// it shouldn't be repeated any more.
|
|
||||||
size_t KeyboardBT_::release(uint8_t k) {
|
|
||||||
uint8_t i;
|
|
||||||
if (k >= 136) { // it's a non-printing key (not a modifier)
|
|
||||||
k = k - 136;
|
|
||||||
} else if (k >= 128) { // it's a modifier key
|
|
||||||
_keyReport.modifiers &= ~(1 << (k - 128));
|
|
||||||
k = 0;
|
|
||||||
} else { // it's a printing key
|
|
||||||
k = pgm_read_byte(_asciimap + k);
|
|
||||||
if (!k) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if ((k & ALT_GR) == ALT_GR) {
|
|
||||||
_keyReport.modifiers &= ~(0x40); // AltGr = right Alt
|
|
||||||
k &= 0x3F;
|
|
||||||
} else if ((k & SHIFT) == SHIFT) {
|
|
||||||
_keyReport.modifiers &= ~(0x02); // the left shift modifier
|
|
||||||
k &= 0x7F;
|
|
||||||
}
|
|
||||||
if (k == ISO_REPLACEMENT) {
|
|
||||||
k = ISO_KEY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test the key report to see if k is present. Clear it if it exists.
|
|
||||||
// Check all positions in case the key is present more than once (which it shouldn't be)
|
|
||||||
for (i = 0; i < 6; i++) {
|
|
||||||
if (0 != k && _keyReport.keys[i] == k) {
|
|
||||||
_keyReport.keys[i] = 0x00;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sendReport(&_keyReport);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyboardBT_::releaseAll(void) {
|
|
||||||
_keyReport.keys[0] = 0;
|
|
||||||
_keyReport.keys[1] = 0;
|
|
||||||
_keyReport.keys[2] = 0;
|
|
||||||
_keyReport.keys[3] = 0;
|
|
||||||
_keyReport.keys[4] = 0;
|
|
||||||
_keyReport.keys[5] = 0;
|
|
||||||
_keyReport.modifiers = 0;
|
|
||||||
sendReport(&_keyReport);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t KeyboardBT_::write(uint8_t c) {
|
|
||||||
uint8_t p = press(c); // Keydown
|
|
||||||
delay(10);
|
|
||||||
release(c); // Keyup
|
|
||||||
delay(10);
|
|
||||||
return p; // just return the result of press() since release() almost always returns 1
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t KeyboardBT_::write(const uint8_t *buffer, size_t size) {
|
|
||||||
size_t n = 0;
|
|
||||||
while (size--) {
|
|
||||||
if (*buffer != '\r') {
|
|
||||||
if (write(*buffer)) {
|
|
||||||
n++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buffer++;
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyboardBT_ KeyboardBT;
|
KeyboardBT_ KeyboardBT;
|
||||||
|
|
|
||||||
|
|
@ -23,118 +23,15 @@
|
||||||
#ifndef KEYBOARDBT_h
|
#ifndef KEYBOARDBT_h
|
||||||
#define KEYBOARDBT_h
|
#define KEYBOARDBT_h
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <HID_Keyboard.h>
|
||||||
|
|
||||||
//================================================================================
|
class KeyboardBT_ : public HID_Keyboard {
|
||||||
//================================================================================
|
protected:
|
||||||
// Keyboard
|
virtual void sendReport(KeyReport* keys) override;
|
||||||
|
|
||||||
// Modifiers
|
|
||||||
#define KEY_LEFT_CTRL 0x80
|
|
||||||
#define KEY_LEFT_SHIFT 0x81
|
|
||||||
#define KEY_LEFT_ALT 0x82
|
|
||||||
#define KEY_LEFT_GUI 0x83
|
|
||||||
#define KEY_RIGHT_CTRL 0x84
|
|
||||||
#define KEY_RIGHT_SHIFT 0x85
|
|
||||||
#define KEY_RIGHT_ALT 0x86
|
|
||||||
#define KEY_RIGHT_GUI 0x87
|
|
||||||
|
|
||||||
// Misc keys
|
|
||||||
#define KEY_UP_ARROW 0xDA
|
|
||||||
#define KEY_DOWN_ARROW 0xD9
|
|
||||||
#define KEY_LEFT_ARROW 0xD8
|
|
||||||
#define KEY_RIGHT_ARROW 0xD7
|
|
||||||
#define KEY_BACKSPACE 0xB2
|
|
||||||
#define KEY_TAB 0xB3
|
|
||||||
#define KEY_RETURN 0xB0
|
|
||||||
#define KEY_MENU 0xED // "Keyboard Application" in USB standard
|
|
||||||
#define KEY_ESC 0xB1
|
|
||||||
#define KEY_INSERT 0xD1
|
|
||||||
#define KEY_DELETE 0xD4
|
|
||||||
#define KEY_PAGE_UP 0xD3
|
|
||||||
#define KEY_PAGE_DOWN 0xD6
|
|
||||||
#define KEY_HOME 0xD2
|
|
||||||
#define KEY_END 0xD5
|
|
||||||
#define KEY_CAPS_LOCK 0xC1
|
|
||||||
#define KEY_PRINT_SCREEN 0xCE // Print Screen / SysRq
|
|
||||||
#define KEY_SCROLL_LOCK 0xCF
|
|
||||||
#define KEY_PAUSE 0xD0 // Pause / Break
|
|
||||||
|
|
||||||
// Numeric keypad
|
|
||||||
#define KEY_NUM_LOCK 0xDB
|
|
||||||
#define KEY_KP_SLASH 0xDC
|
|
||||||
#define KEY_KP_ASTERISK 0xDD
|
|
||||||
#define KEY_KP_MINUS 0xDE
|
|
||||||
#define KEY_KP_PLUS 0xDF
|
|
||||||
#define KEY_KP_ENTER 0xE0
|
|
||||||
#define KEY_KP_1 0xE1
|
|
||||||
#define KEY_KP_2 0xE2
|
|
||||||
#define KEY_KP_3 0xE3
|
|
||||||
#define KEY_KP_4 0xE4
|
|
||||||
#define KEY_KP_5 0xE5
|
|
||||||
#define KEY_KP_6 0xE6
|
|
||||||
#define KEY_KP_7 0xE7
|
|
||||||
#define KEY_KP_8 0xE8
|
|
||||||
#define KEY_KP_9 0xE9
|
|
||||||
#define KEY_KP_0 0xEA
|
|
||||||
#define KEY_KP_DOT 0xEB
|
|
||||||
|
|
||||||
// Function keys
|
|
||||||
#define KEY_F1 0xC2
|
|
||||||
#define KEY_F2 0xC3
|
|
||||||
#define KEY_F3 0xC4
|
|
||||||
#define KEY_F4 0xC5
|
|
||||||
#define KEY_F5 0xC6
|
|
||||||
#define KEY_F6 0xC7
|
|
||||||
#define KEY_F7 0xC8
|
|
||||||
#define KEY_F8 0xC9
|
|
||||||
#define KEY_F9 0xCA
|
|
||||||
#define KEY_F10 0xCB
|
|
||||||
#define KEY_F11 0xCC
|
|
||||||
#define KEY_F12 0xCD
|
|
||||||
#define KEY_F13 0xF0
|
|
||||||
#define KEY_F14 0xF1
|
|
||||||
#define KEY_F15 0xF2
|
|
||||||
#define KEY_F16 0xF3
|
|
||||||
#define KEY_F17 0xF4
|
|
||||||
#define KEY_F18 0xF5
|
|
||||||
#define KEY_F19 0xF6
|
|
||||||
#define KEY_F20 0xF7
|
|
||||||
#define KEY_F21 0xF8
|
|
||||||
#define KEY_F22 0xF9
|
|
||||||
#define KEY_F23 0xFA
|
|
||||||
#define KEY_F24 0xFB
|
|
||||||
|
|
||||||
// Supported keyboard layouts
|
|
||||||
extern const uint8_t KeyboardLayout_de_DE[];
|
|
||||||
extern const uint8_t KeyboardLayout_en_US[];
|
|
||||||
extern const uint8_t KeyboardLayout_es_ES[];
|
|
||||||
extern const uint8_t KeyboardLayout_fr_FR[];
|
|
||||||
extern const uint8_t KeyboardLayout_it_IT[];
|
|
||||||
extern const uint8_t KeyboardLayout_sv_SE[];
|
|
||||||
extern const uint8_t KeyboardLayout_da_DK[];
|
|
||||||
|
|
||||||
// Low level key report: up to 6 keys and shift, ctrl etc at once
|
|
||||||
typedef struct {
|
|
||||||
uint8_t modifiers;
|
|
||||||
uint8_t reserved;
|
|
||||||
uint8_t keys[6];
|
|
||||||
} KeyReport;
|
|
||||||
|
|
||||||
class KeyboardBT_ : public Print {
|
|
||||||
private:
|
|
||||||
KeyReport _keyReport;
|
|
||||||
const uint8_t *_asciimap;
|
|
||||||
void sendReport(KeyReport* keys);
|
|
||||||
public:
|
public:
|
||||||
KeyboardBT_(void);
|
KeyboardBT_(void);
|
||||||
void begin(const uint8_t *layout = KeyboardLayout_en_US);
|
void begin(const uint8_t *layout = KeyboardLayout_en_US);
|
||||||
void end(void);
|
void end(void);
|
||||||
size_t write(uint8_t k);
|
|
||||||
size_t write(const uint8_t *buffer, size_t size);
|
|
||||||
size_t press(uint8_t k);
|
|
||||||
size_t release(uint8_t k);
|
|
||||||
void releaseAll(void);
|
|
||||||
};
|
};
|
||||||
extern KeyboardBT_ KeyboardBT;
|
extern KeyboardBT_ KeyboardBT;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
KeyboardLayout.h
|
|
||||||
|
|
||||||
This file is not part of the public API. It is meant to be included
|
|
||||||
only in Keyboard.cpp and the keyboard layout files. Layout files map
|
|
||||||
ASCII character codes to keyboard scan codes (technically, to USB HID
|
|
||||||
Usage codes), possibly altered by the SHIFT or ALT_GR modifiers.
|
|
||||||
|
|
||||||
== Creating your own layout ==
|
|
||||||
|
|
||||||
In order to create your own layout file, copy an existing layout that
|
|
||||||
is similar to yours, then modify it to use the correct keys. The
|
|
||||||
layout is an array in ASCII order. Each entry contains a scan code,
|
|
||||||
possibly modified by "|SHIFT" or "|ALT_GR", as in this excerpt from
|
|
||||||
the Italian layout:
|
|
||||||
|
|
||||||
0x35, // bslash
|
|
||||||
0x30|ALT_GR, // ]
|
|
||||||
0x2e|SHIFT, // ^
|
|
||||||
|
|
||||||
Do not change the control characters (those before scan code 0x2c,
|
|
||||||
corresponding to space). Do not attempt to grow the table past DEL. Do
|
|
||||||
not use both SHIFT and ALT_GR on the same character: this is not
|
|
||||||
supported. Unsupported characters should have 0x00 as scan code.
|
|
||||||
|
|
||||||
For a keyboard with an ISO physical layout, use the scan codes below:
|
|
||||||
|
|
||||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+-------+
|
|
||||||
|35 |1e |1f |20 |21 |22 |23 |24 |25 |26 |27 |2d |2e |BackSp |
|
|
||||||
+---+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-----+
|
|
||||||
| Tab |14 |1a |08 |15 |17 |1c |18 |0c |12 |13 |2f |30 | Ret |
|
|
||||||
+-----++--++--++--++--++--++--++--++--++--++--++--++--++ |
|
|
||||||
|CapsL |04 |16 |07 |09 |0a |0b |0d |0e |0f |33 |34 |31 | |
|
|
||||||
+----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+---+----+
|
|
||||||
|Shi.|32 |1d |1b |06 |19 |05 |11 |10 |36 |37 |38 | Shift |
|
|
||||||
+----+---++--+-+-+---+---+---+---+---+--++---+---++----+----+
|
|
||||||
|Ctrl|Win |Alt | |AlGr|Win |Menu|Ctrl|
|
|
||||||
+----+----+----+------------------------+----+----+----+----+
|
|
||||||
|
|
||||||
The ANSI layout is identical except that key 0x31 is above (rather
|
|
||||||
than next to) Return, and there is not key 0x32.
|
|
||||||
|
|
||||||
Give a unique name to the layout array, then declare it in Keyboard.h
|
|
||||||
with a line of the form:
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_xx_YY[];
|
|
||||||
|
|
||||||
== Encoding details ==
|
|
||||||
|
|
||||||
All scan codes are less than 0x80, which makes bit 7 available to
|
|
||||||
signal that a modifier (Shift or AltGr) is needed to generate the
|
|
||||||
character. With only one exception, keys that are used with modifiers
|
|
||||||
have scan codes that are less than 0x40. This makes bit 6 available
|
|
||||||
to signal whether the modifier is Shift or AltGr. The exception is
|
|
||||||
0x64, the key next next to Left Shift on the ISO layout (and absent
|
|
||||||
from the ANSI layout). We handle it by replacing its value by 0x32 in
|
|
||||||
the layout arrays.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
#define SHIFT 0x80
|
|
||||||
#define ALT_GR 0xc0
|
|
||||||
#define ISO_KEY 0x64
|
|
||||||
#define ISO_REPLACEMENT 0x32
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
Danish keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_da_DK[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x1e | SHIFT, // !
|
|
||||||
0x1f | SHIFT, // "
|
|
||||||
0x20 | SHIFT, // #
|
|
||||||
0x21 | ALT_GR, // $
|
|
||||||
0x22 | SHIFT, // %
|
|
||||||
0x23 | SHIFT, // &
|
|
||||||
0x31, // '
|
|
||||||
0x25 | SHIFT, // (
|
|
||||||
0x26 | SHIFT, // )
|
|
||||||
0x31 | SHIFT, // *
|
|
||||||
0x2d, // +
|
|
||||||
0x36, // ,
|
|
||||||
0x38, // -
|
|
||||||
0x37, // .
|
|
||||||
0x24 | SHIFT, // /
|
|
||||||
0x27, // 0
|
|
||||||
0x1e, // 1
|
|
||||||
0x1f, // 2
|
|
||||||
0x20, // 3
|
|
||||||
0x21, // 4
|
|
||||||
0x22, // 5
|
|
||||||
0x23, // 6
|
|
||||||
0x24, // 7
|
|
||||||
0x25, // 8
|
|
||||||
0x26, // 9
|
|
||||||
0x37 | SHIFT, // :
|
|
||||||
0x36 | SHIFT, // ;
|
|
||||||
0x32, // <
|
|
||||||
0x27 | SHIFT, // =
|
|
||||||
0x32 | SHIFT, // >
|
|
||||||
0x2d | SHIFT, // ?
|
|
||||||
0x1f | ALT_GR, // @
|
|
||||||
0x04 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x10 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x14 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1a | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1c | SHIFT, // Y
|
|
||||||
0x1d | SHIFT, // Z
|
|
||||||
0x25 | ALT_GR, // [
|
|
||||||
0x32 | ALT_GR, // bslash
|
|
||||||
0x26 | ALT_GR, // ]
|
|
||||||
0x00, // ^ not supported (requires dead key + space)
|
|
||||||
0x38 | SHIFT, // _
|
|
||||||
0x00, // ` not supported (requires dead key + space)
|
|
||||||
0x04, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x10, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x14, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1a, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1c, // y
|
|
||||||
0x1d, // z
|
|
||||||
0x24 | ALT_GR, // {
|
|
||||||
0x2e | ALT_GR, // |
|
|
||||||
0x27 | ALT_GR, // }
|
|
||||||
0x00, // ~ not supported (requires dead key + space)
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
German keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_de_DE[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x1e | SHIFT, // !
|
|
||||||
0x1f | SHIFT, // "
|
|
||||||
0x31, // #
|
|
||||||
0x21 | SHIFT, // $
|
|
||||||
0x22 | SHIFT, // %
|
|
||||||
0x23 | SHIFT, // &
|
|
||||||
0x31 | SHIFT, // '
|
|
||||||
0x25 | SHIFT, // (
|
|
||||||
0x26 | SHIFT, // )
|
|
||||||
0x30 | SHIFT, // *
|
|
||||||
0x30, // +
|
|
||||||
0x36, // ,
|
|
||||||
0x38, // -
|
|
||||||
0x37, // .
|
|
||||||
0x24 | SHIFT, // /
|
|
||||||
0x27, // 0
|
|
||||||
0x1e, // 1
|
|
||||||
0x1f, // 2
|
|
||||||
0x20, // 3
|
|
||||||
0x21, // 4
|
|
||||||
0x22, // 5
|
|
||||||
0x23, // 6
|
|
||||||
0x24, // 7
|
|
||||||
0x25, // 8
|
|
||||||
0x26, // 9
|
|
||||||
0x37 | SHIFT, // :
|
|
||||||
0x36 | SHIFT, // ;
|
|
||||||
0x32, // <
|
|
||||||
0x27 | SHIFT, // =
|
|
||||||
0x32 | SHIFT, // >
|
|
||||||
0x2d | SHIFT, // ?
|
|
||||||
0x14 | ALT_GR, // @
|
|
||||||
0x04 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x10 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x14 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1a | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1d | SHIFT, // Y
|
|
||||||
0x1c | SHIFT, // Z
|
|
||||||
0x25 | ALT_GR, // [
|
|
||||||
0x2d | ALT_GR, // bslash
|
|
||||||
0x26 | ALT_GR, // ]
|
|
||||||
0x00, // ^ not supported (requires dead key + space)
|
|
||||||
0x38 | SHIFT, // _
|
|
||||||
0x00, // ` not supported (requires dead key + space)
|
|
||||||
0x04, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x10, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x14, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1a, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1d, // y
|
|
||||||
0x1c, // z
|
|
||||||
0x24 | ALT_GR, // {
|
|
||||||
0x32 | ALT_GR, // |
|
|
||||||
0x27 | ALT_GR, // }
|
|
||||||
0x30 | ALT_GR, // ~
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
Standard US keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_en_US[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x1e | SHIFT, // !
|
|
||||||
0x34 | SHIFT, // "
|
|
||||||
0x20 | SHIFT, // #
|
|
||||||
0x21 | SHIFT, // $
|
|
||||||
0x22 | SHIFT, // %
|
|
||||||
0x24 | SHIFT, // &
|
|
||||||
0x34, // '
|
|
||||||
0x26 | SHIFT, // (
|
|
||||||
0x27 | SHIFT, // )
|
|
||||||
0x25 | SHIFT, // *
|
|
||||||
0x2e | SHIFT, // +
|
|
||||||
0x36, // ,
|
|
||||||
0x2d, // -
|
|
||||||
0x37, // .
|
|
||||||
0x38, // /
|
|
||||||
0x27, // 0
|
|
||||||
0x1e, // 1
|
|
||||||
0x1f, // 2
|
|
||||||
0x20, // 3
|
|
||||||
0x21, // 4
|
|
||||||
0x22, // 5
|
|
||||||
0x23, // 6
|
|
||||||
0x24, // 7
|
|
||||||
0x25, // 8
|
|
||||||
0x26, // 9
|
|
||||||
0x33 | SHIFT, // :
|
|
||||||
0x33, // ;
|
|
||||||
0x36 | SHIFT, // <
|
|
||||||
0x2e, // =
|
|
||||||
0x37 | SHIFT, // >
|
|
||||||
0x38 | SHIFT, // ?
|
|
||||||
0x1f | SHIFT, // @
|
|
||||||
0x04 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x10 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x14 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1a | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1c | SHIFT, // Y
|
|
||||||
0x1d | SHIFT, // Z
|
|
||||||
0x2f, // [
|
|
||||||
0x31, // bslash
|
|
||||||
0x30, // ]
|
|
||||||
0x23 | SHIFT, // ^
|
|
||||||
0x2d | SHIFT, // _
|
|
||||||
0x35, // `
|
|
||||||
0x04, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x10, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x14, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1a, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1c, // y
|
|
||||||
0x1d, // z
|
|
||||||
0x2f | SHIFT, // {
|
|
||||||
0x31 | SHIFT, // |
|
|
||||||
0x30 | SHIFT, // }
|
|
||||||
0x35 | SHIFT, // ~
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
Spanish keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_es_ES[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x1e | SHIFT, // !
|
|
||||||
0x1f | SHIFT, // "
|
|
||||||
0x20 | ALT_GR, // #
|
|
||||||
0x21 | SHIFT, // $
|
|
||||||
0x22 | SHIFT, // %
|
|
||||||
0x23 | SHIFT, // &
|
|
||||||
0x2d, // '
|
|
||||||
0x25 | SHIFT, // (
|
|
||||||
0x26 | SHIFT, // )
|
|
||||||
0x30 | SHIFT, // *
|
|
||||||
0x30, // +
|
|
||||||
0x36, // ,
|
|
||||||
0x38, // -
|
|
||||||
0x37, // .
|
|
||||||
0x24 | SHIFT, // /
|
|
||||||
0x27, // 0
|
|
||||||
0x1e, // 1
|
|
||||||
0x1f, // 2
|
|
||||||
0x20, // 3
|
|
||||||
0x21, // 4
|
|
||||||
0x22, // 5
|
|
||||||
0x23, // 6
|
|
||||||
0x24, // 7
|
|
||||||
0x25, // 8
|
|
||||||
0x26, // 9
|
|
||||||
0x37 | SHIFT, // :
|
|
||||||
0x36 | SHIFT, // ;
|
|
||||||
0x32, // <
|
|
||||||
0x27 | SHIFT, // =
|
|
||||||
0x32 | SHIFT, // >
|
|
||||||
0x2d | SHIFT, // ?
|
|
||||||
0x1f | ALT_GR, // @
|
|
||||||
0x04 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x10 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x14 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1a | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1c | SHIFT, // Y
|
|
||||||
0x1d | SHIFT, // Z
|
|
||||||
0x2f | ALT_GR, // [
|
|
||||||
0x35 | ALT_GR, // bslash
|
|
||||||
0x30 | ALT_GR, // ]
|
|
||||||
0x00, // ^ not supported (requires dead key + space)
|
|
||||||
0x38 | SHIFT, // _
|
|
||||||
0x00, // ` not supported (requires dead key + space)
|
|
||||||
0x04, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x10, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x14, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1a, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1c, // y
|
|
||||||
0x1d, // z
|
|
||||||
0x34 | ALT_GR, // {
|
|
||||||
0x1e | ALT_GR, // |
|
|
||||||
0x31 | ALT_GR, // }
|
|
||||||
0x00, // ~ not supported (requires dead key + space)
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
Traditional (not AFNOR) French keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_fr_FR[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x38, // !
|
|
||||||
0x20, // "
|
|
||||||
0x20 | ALT_GR, // #
|
|
||||||
0x30, // $
|
|
||||||
0x34 | SHIFT, // %
|
|
||||||
0x1E, // &
|
|
||||||
0x21, // '
|
|
||||||
0x22, // (
|
|
||||||
0x2d, // )
|
|
||||||
0x31, // *
|
|
||||||
0x2e | SHIFT, // +
|
|
||||||
0x10, // ,
|
|
||||||
0x23, // -
|
|
||||||
0x36 | SHIFT, // .
|
|
||||||
0x37 | SHIFT, // /
|
|
||||||
0x27 | SHIFT, // 0
|
|
||||||
0x1e | SHIFT, // 1
|
|
||||||
0x1f | SHIFT, // 2
|
|
||||||
0x20 | SHIFT, // 3
|
|
||||||
0x21 | SHIFT, // 4
|
|
||||||
0x22 | SHIFT, // 5
|
|
||||||
0x23 | SHIFT, // 6
|
|
||||||
0x24 | SHIFT, // 7
|
|
||||||
0x25 | SHIFT, // 8
|
|
||||||
0x26 | SHIFT, // 9
|
|
||||||
0x37, // :
|
|
||||||
0x36, // ;
|
|
||||||
0x32, // <
|
|
||||||
0x2e, // =
|
|
||||||
0x32 | SHIFT, // >
|
|
||||||
0x10 | SHIFT, // ?
|
|
||||||
0x27 | ALT_GR, // @
|
|
||||||
0x14 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x33 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x04 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1d | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1c | SHIFT, // Y
|
|
||||||
0x1a | SHIFT, // Z
|
|
||||||
0x22 | ALT_GR, // [
|
|
||||||
0x25 | ALT_GR, // bslash
|
|
||||||
0x2d | ALT_GR, // ]
|
|
||||||
0x26 | ALT_GR, // ^
|
|
||||||
0x25, // _
|
|
||||||
0x24 | ALT_GR, // `
|
|
||||||
0x14, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x33, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x04, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1d, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1c, // y
|
|
||||||
0x1a, // z
|
|
||||||
0x21 | ALT_GR, // {
|
|
||||||
0x23 | ALT_GR, // |
|
|
||||||
0x2e | ALT_GR, // }
|
|
||||||
0x1f | ALT_GR, // ~
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
Italian keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_it_IT[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x1e | SHIFT, // !
|
|
||||||
0x1f | SHIFT, // "
|
|
||||||
0x34 | ALT_GR, // #
|
|
||||||
0x21 | SHIFT, // $
|
|
||||||
0x22 | SHIFT, // %
|
|
||||||
0x23 | SHIFT, // &
|
|
||||||
0x2d, // '
|
|
||||||
0x25 | SHIFT, // (
|
|
||||||
0x26 | SHIFT, // )
|
|
||||||
0x30 | SHIFT, // *
|
|
||||||
0x30, // +
|
|
||||||
0x36, // ,
|
|
||||||
0x38, // -
|
|
||||||
0x37, // .
|
|
||||||
0x24 | SHIFT, // /
|
|
||||||
0x27, // 0
|
|
||||||
0x1e, // 1
|
|
||||||
0x1f, // 2
|
|
||||||
0x20, // 3
|
|
||||||
0x21, // 4
|
|
||||||
0x22, // 5
|
|
||||||
0x23, // 6
|
|
||||||
0x24, // 7
|
|
||||||
0x25, // 8
|
|
||||||
0x26, // 9
|
|
||||||
0x37 | SHIFT, // :
|
|
||||||
0x36 | SHIFT, // ;
|
|
||||||
0x32, // <
|
|
||||||
0x27 | SHIFT, // =
|
|
||||||
0x32 | SHIFT, // >
|
|
||||||
0x2d | SHIFT, // ?
|
|
||||||
0x33 | ALT_GR, // @
|
|
||||||
0x04 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x10 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x14 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1a | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1c | SHIFT, // Y
|
|
||||||
0x1d | SHIFT, // Z
|
|
||||||
0x2f | ALT_GR, // [
|
|
||||||
0x35, // bslash
|
|
||||||
0x30 | ALT_GR, // ]
|
|
||||||
0x2e | SHIFT, // ^
|
|
||||||
0x38 | SHIFT, // _
|
|
||||||
0x00, // ` not in this layout
|
|
||||||
0x04, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x10, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x14, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1a, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1c, // y
|
|
||||||
0x1d, // z
|
|
||||||
0x00, // { not supported (requires AltGr+Shift)
|
|
||||||
0x35 | SHIFT, // |
|
|
||||||
0x00, // } not supported (requires AltGr+Shift)
|
|
||||||
0x00, // ~ not in this layout
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
Swedish keyboard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "KeyboardLayout.h"
|
|
||||||
|
|
||||||
extern const uint8_t KeyboardLayout_sv_SE[128] PROGMEM = {
|
|
||||||
0x00, // NUL
|
|
||||||
0x00, // SOH
|
|
||||||
0x00, // STX
|
|
||||||
0x00, // ETX
|
|
||||||
0x00, // EOT
|
|
||||||
0x00, // ENQ
|
|
||||||
0x00, // ACK
|
|
||||||
0x00, // BEL
|
|
||||||
0x2a, // BS Backspace
|
|
||||||
0x2b, // TAB Tab
|
|
||||||
0x28, // LF Enter
|
|
||||||
0x00, // VT
|
|
||||||
0x00, // FF
|
|
||||||
0x00, // CR
|
|
||||||
0x00, // SO
|
|
||||||
0x00, // SI
|
|
||||||
0x00, // DEL
|
|
||||||
0x00, // DC1
|
|
||||||
0x00, // DC2
|
|
||||||
0x00, // DC3
|
|
||||||
0x00, // DC4
|
|
||||||
0x00, // NAK
|
|
||||||
0x00, // SYN
|
|
||||||
0x00, // ETB
|
|
||||||
0x00, // CAN
|
|
||||||
0x00, // EM
|
|
||||||
0x00, // SUB
|
|
||||||
0x00, // ESC
|
|
||||||
0x00, // FS
|
|
||||||
0x00, // GS
|
|
||||||
0x00, // RS
|
|
||||||
0x00, // US
|
|
||||||
|
|
||||||
0x2c, // ' '
|
|
||||||
0x1e | SHIFT, // !
|
|
||||||
0x1f | SHIFT, // "
|
|
||||||
0x20 | SHIFT, // #
|
|
||||||
0x21 | ALT_GR, // $
|
|
||||||
0x22 | SHIFT, // %
|
|
||||||
0x23 | SHIFT, // &
|
|
||||||
0x31, // '
|
|
||||||
0x25 | SHIFT, // (
|
|
||||||
0x26 | SHIFT, // )
|
|
||||||
0x31 | SHIFT, // *
|
|
||||||
0x2d, // +
|
|
||||||
0x36, // ,
|
|
||||||
0x38, // -
|
|
||||||
0x37, // .
|
|
||||||
0x24 | SHIFT, // /
|
|
||||||
0x27, // 0
|
|
||||||
0x1e, // 1
|
|
||||||
0x1f, // 2
|
|
||||||
0x20, // 3
|
|
||||||
0x21, // 4
|
|
||||||
0x22, // 5
|
|
||||||
0x23, // 6
|
|
||||||
0x24, // 7
|
|
||||||
0x25, // 8
|
|
||||||
0x26, // 9
|
|
||||||
0x37 | SHIFT, // :
|
|
||||||
0x36 | SHIFT, // ;
|
|
||||||
0x32, // <
|
|
||||||
0x27 | SHIFT, // =
|
|
||||||
0x32 | SHIFT, // >
|
|
||||||
0x2d | SHIFT, // ?
|
|
||||||
0x1f | ALT_GR, // @
|
|
||||||
0x04 | SHIFT, // A
|
|
||||||
0x05 | SHIFT, // B
|
|
||||||
0x06 | SHIFT, // C
|
|
||||||
0x07 | SHIFT, // D
|
|
||||||
0x08 | SHIFT, // E
|
|
||||||
0x09 | SHIFT, // F
|
|
||||||
0x0a | SHIFT, // G
|
|
||||||
0x0b | SHIFT, // H
|
|
||||||
0x0c | SHIFT, // I
|
|
||||||
0x0d | SHIFT, // J
|
|
||||||
0x0e | SHIFT, // K
|
|
||||||
0x0f | SHIFT, // L
|
|
||||||
0x10 | SHIFT, // M
|
|
||||||
0x11 | SHIFT, // N
|
|
||||||
0x12 | SHIFT, // O
|
|
||||||
0x13 | SHIFT, // P
|
|
||||||
0x14 | SHIFT, // Q
|
|
||||||
0x15 | SHIFT, // R
|
|
||||||
0x16 | SHIFT, // S
|
|
||||||
0x17 | SHIFT, // T
|
|
||||||
0x18 | SHIFT, // U
|
|
||||||
0x19 | SHIFT, // V
|
|
||||||
0x1a | SHIFT, // W
|
|
||||||
0x1b | SHIFT, // X
|
|
||||||
0x1c | SHIFT, // Y
|
|
||||||
0x1d | SHIFT, // Z
|
|
||||||
0x25 | ALT_GR, // [
|
|
||||||
0x2d | ALT_GR, // bslash
|
|
||||||
0x26 | ALT_GR, // ]
|
|
||||||
0x00, // ^ not supported (requires dead key + space)
|
|
||||||
0x38 | SHIFT, // _
|
|
||||||
0x00, // ` not supported (requires dead key + space)
|
|
||||||
0x04, // a
|
|
||||||
0x05, // b
|
|
||||||
0x06, // c
|
|
||||||
0x07, // d
|
|
||||||
0x08, // e
|
|
||||||
0x09, // f
|
|
||||||
0x0a, // g
|
|
||||||
0x0b, // h
|
|
||||||
0x0c, // i
|
|
||||||
0x0d, // j
|
|
||||||
0x0e, // k
|
|
||||||
0x0f, // l
|
|
||||||
0x10, // m
|
|
||||||
0x11, // n
|
|
||||||
0x12, // o
|
|
||||||
0x13, // p
|
|
||||||
0x14, // q
|
|
||||||
0x15, // r
|
|
||||||
0x16, // s
|
|
||||||
0x17, // t
|
|
||||||
0x18, // u
|
|
||||||
0x19, // v
|
|
||||||
0x1a, // w
|
|
||||||
0x1b, // x
|
|
||||||
0x1c, // y
|
|
||||||
0x1d, // z
|
|
||||||
0x24 | ALT_GR, // {
|
|
||||||
0x32 | ALT_GR, // |
|
|
||||||
0x27 | ALT_GR, // }
|
|
||||||
0x00, // ~ not supported (requires dead key + space)
|
|
||||||
0x00 // DEL
|
|
||||||
};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit be7395a597c748eda75ea40821637a63e596f09d
|
|
||||||
31
libraries/Mouse/README.adoc
Normal file
31
libraries/Mouse/README.adoc
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
:repository-owner: arduino-libraries
|
||||||
|
:repository-name: Mouse
|
||||||
|
|
||||||
|
= {repository-name} Library for Arduino =
|
||||||
|
|
||||||
|
image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/check-arduino.yml/badge.svg["Check Arduino status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/check-arduino.yml"]
|
||||||
|
image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/compile-examples.yml/badge.svg["Compile Examples status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/compile-examples.yml"]
|
||||||
|
image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/spell-check.yml/badge.svg["Spell Check status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/spell-check.yml"]
|
||||||
|
|
||||||
|
This library allows an Arduino board with USB capabilities to act as a Mouse.
|
||||||
|
|
||||||
|
For more information about this library please visit us at
|
||||||
|
https://www.arduino.cc/reference/en/language/functions/usb/mouse/
|
||||||
|
|
||||||
|
== License ==
|
||||||
|
|
||||||
|
Copyright (c) Arduino LLC. All right reserved.
|
||||||
|
|
||||||
|
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
|
||||||
428
libraries/Mouse/docs/api.md
Normal file
428
libraries/Mouse/docs/api.md
Normal file
|
|
@ -0,0 +1,428 @@
|
||||||
|
# Mouse library
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
|
||||||
|
### `Mouse.begin()`
|
||||||
|
|
||||||
|
Begins emulating the mouse connected to a computer. `begin()` must be called before controlling the computer. To end control, use `Mouse.end()`.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Mouse.begin()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Mouse.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(2, INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Initialize the Mouse library when button is pressed
|
||||||
|
if (digitalRead(2) == HIGH) {
|
||||||
|
Mouse.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Mouse.click()](#mouseclick)
|
||||||
|
* [Mouse.end()](#mouseend)
|
||||||
|
* [Mouse.move()](#mousemove)
|
||||||
|
* [Mouse.press()](#mousepress)
|
||||||
|
* [Mouse.release()](#mouserelease)
|
||||||
|
* [Mouse.isPressed()](#mouseispressed)
|
||||||
|
|
||||||
|
### `Mouse.click()`
|
||||||
|
|
||||||
|
Sends a momentary click to the computer at the location of the cursor. This is the same as pressing and immediately releasing the mouse button.
|
||||||
|
|
||||||
|
`Mouse.click()` defaults to the left mouse button.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Mouse.click()
|
||||||
|
Mouse.click(button)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* `button`: which mouse button to press (MOUSE_LEFT, MOUSE_RIGHT or MOUSE_MIDDLE, default is MOUSE_LEFT).
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Mouse.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(2, INPUT);
|
||||||
|
// Initialize the Mouse library
|
||||||
|
Mouse.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// If the button is pressed, send a left mouse click
|
||||||
|
if (digitalRead(2) == HIGH) {
|
||||||
|
Mouse.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Notes and warnings
|
||||||
|
|
||||||
|
When you use the `Mouse.click()` command, the Arduino takes over your mouse! Make sure you have control before you use the command. A pushbutton to toggle the mouse control state is effective.
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Mouse.begin()](#mousebegin)
|
||||||
|
* [Mouse.end()](#mouseend)
|
||||||
|
* [Mouse.move()](#mousemove)
|
||||||
|
* [Mouse.press()](#mousepress)
|
||||||
|
* [Mouse.release()](#mouserelease)
|
||||||
|
* [Mouse.isPressed()](#mouseispressed)
|
||||||
|
|
||||||
|
### `Mouse.end()`
|
||||||
|
|
||||||
|
Stops emulating the mouse connected to a computer. To start control, use `Mouse.begin()`.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Mouse.end()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Mouse.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(2, INPUT);
|
||||||
|
// Initiate the Mouse library
|
||||||
|
Mouse.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// If the button is pressed, send a left mouse click
|
||||||
|
if (digitalRead(2) == HIGH) {
|
||||||
|
Mouse.click();
|
||||||
|
// Then end the Mouse emulation
|
||||||
|
Mouse.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Mouse.begin()](#mousebegin)
|
||||||
|
* [Mouse.click()](#mouseclick)
|
||||||
|
* [Mouse.move()](#mousemove)
|
||||||
|
* [Mouse.press()](#mousepress)
|
||||||
|
* [Mouse.release()](#mouserelease)
|
||||||
|
* [Mouse.isPressed()](#mouseispressed)
|
||||||
|
|
||||||
|
### `Mouse.move()`
|
||||||
|
|
||||||
|
Moves the cursor on a connected computer. The motion onscreen is always relative to the cursor’s current location. Before using `Mouse.move()` you must call `Mouse.begin()`.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Mouse.move(xVal, yVal, wheel)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* `xVal`: amount to move along the x-axis. Allowed data types: signed char.
|
||||||
|
* `yVal`: amount to move along the y-axis. Allowed data types: signed char.
|
||||||
|
* `wheel`: amount to move scroll wheel. Allowed data types: signed char.
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Mouse.h>
|
||||||
|
|
||||||
|
const int xAxis = A1; // Analog sensor for X axis
|
||||||
|
const int yAxis = A2; // Analog sensor for Y axis
|
||||||
|
|
||||||
|
int range = 12; // Output range of X or Y movement
|
||||||
|
int responseDelay = 2; // Response delay of the mouse, in ms
|
||||||
|
int threshold = range / 4; // Resting threshold
|
||||||
|
int center = range / 2; // Resting position value
|
||||||
|
int minima[] = {1023, 1023}; // Actual analogRead minima for (x, y)
|
||||||
|
int maxima[] = {0, 0}; // Actual analogRead maxima for (x, y)
|
||||||
|
int axis[] = {xAxis, yAxis}; // Pin numbers for (x, y)
|
||||||
|
int mouseReading[2]; // Final mouse readings for (x, y)
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// Initialize the Mouse library
|
||||||
|
Mouse.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Read and scale the two axes
|
||||||
|
int xReading = readAxis(0);
|
||||||
|
int yReading = readAxis(1);
|
||||||
|
|
||||||
|
// Move the mouse
|
||||||
|
Mouse.move(xReading, yReading, 0);
|
||||||
|
delay(responseDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reads an axis (0 or 1 for x or y) and scales the
|
||||||
|
analog input range to a range from 0 to <range>
|
||||||
|
*/
|
||||||
|
int readAxis(int axisNumber) {
|
||||||
|
int distance = 0; // Distance from center of the output range
|
||||||
|
|
||||||
|
// Read the analog input
|
||||||
|
int reading = analogRead(axis[axisNumber]);
|
||||||
|
|
||||||
|
// Of the current reading exceeds the max or min for this axis, reset the max or min
|
||||||
|
if (reading < minima[axisNumber]) {
|
||||||
|
minima[axisNumber] = reading;
|
||||||
|
}
|
||||||
|
if (reading > maxima[axisNumber]) {
|
||||||
|
maxima[axisNumber] = reading;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map the reading from the analog input range to the output range
|
||||||
|
reading = map(reading, minima[axisNumber], maxima[axisNumber], 0, range);
|
||||||
|
|
||||||
|
// If the output reading is outside from the rest position threshold, use it
|
||||||
|
if (abs(reading - center) > threshold) {
|
||||||
|
distance = (reading - center);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Y axis needs to be inverted in order to map the movement correctly
|
||||||
|
if (axisNumber == 1) {
|
||||||
|
distance = -distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the distance for this axis
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Notes and warnings
|
||||||
|
|
||||||
|
When you use the `Mouse.move()` command, the Arduino takes over your mouse! Make sure you have control before you use the command. A pushbutton to toggle the mouse control state is effective.
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Mouse.begin()](#mousebegin)
|
||||||
|
* [Mouse.click()](#mouseclick)
|
||||||
|
* [Mouse.end()](#mouseend)
|
||||||
|
* [Mouse.press()](#mousepress)
|
||||||
|
* [Mouse.release()](#mouserelease)
|
||||||
|
* [Mouse.isPressed()](#mouseispressed)
|
||||||
|
|
||||||
|
### `Mouse.press()`
|
||||||
|
|
||||||
|
Sends a button press to a connected computer. A press is the equivalent of clicking and continuously holding the mouse button. A press is cancelled with `Mouse.release()`. Before using `Mouse.press()`, you need to start communication with `Mouse.begin()`. `Mouse.press()` defaults to a left button press.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Mouse.press()
|
||||||
|
Mouse.press(button)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* `button`: which mouse button to press (MOUSE_LEFT, MOUSE_RIGHT or MOUSE_MIDDLE, default is MOUSE_LEFT).
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Mouse.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// The switch that will initiate the Mouse press
|
||||||
|
pinMode(2, INPUT);
|
||||||
|
// The switch that will terminate the Mouse press
|
||||||
|
pinMode(3, INPUT);
|
||||||
|
// Initialize the Mouse library
|
||||||
|
Mouse.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// If the switch attached to pin 2 is closed, press and hold the left mouse button
|
||||||
|
if (digitalRead(2) == HIGH) {
|
||||||
|
Mouse.press();
|
||||||
|
}
|
||||||
|
// If the switch attached to pin 3 is closed, release the left mouse button
|
||||||
|
if (digitalRead(3) == HIGH) {
|
||||||
|
Mouse.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Notes and warnings
|
||||||
|
|
||||||
|
When you use the `Mouse.press()` command, the Arduino takes over your mouse! Make sure you have control before you use the command. A pushbutton to toggle the mouse control state is effective.
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Mouse.begin()](#mousebegin)
|
||||||
|
* [Mouse.click()](#mouseclick)
|
||||||
|
* [Mouse.end()](#mouseend)
|
||||||
|
* [Mouse.move()](#mousemove)
|
||||||
|
* [Mouse.release()](#mouserelease)
|
||||||
|
* [Mouse.isPressed()](#mouseispressed)
|
||||||
|
|
||||||
|
### `Mouse.release()`
|
||||||
|
|
||||||
|
Sends a message that a previously pressed button (invoked through `Mouse.press()`) is released. `Mouse.release()` defaults to the left button.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Mouse.press()
|
||||||
|
Mouse.press(button)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* `button`: which mouse button was released (MOUSE_LEFT, MOUSE_RIGHT or MOUSE_MIDDLE, default is MOUSE_LEFT).
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Mouse.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// The switch that will initiate the Mouse press
|
||||||
|
pinMode(2, INPUT);
|
||||||
|
// The switch that will terminate the Mouse press
|
||||||
|
pinMode(3, INPUT);
|
||||||
|
// Initialize the Mouse library
|
||||||
|
Mouse.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// If the switch attached to pin 2 is closed, press and hold the left mouse button
|
||||||
|
if (digitalRead(2) == HIGH) {
|
||||||
|
Mouse.press();
|
||||||
|
}
|
||||||
|
// If the switch attached to pin 3 is closed, release the left mouse button
|
||||||
|
if (digitalRead(3) == HIGH) {
|
||||||
|
Mouse.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Notes and warnings
|
||||||
|
|
||||||
|
When you use the `Mouse.release()` command, the Arduino takes over your mouse! Make sure you have control before you use the command. A pushbutton to toggle the mouse control state is effective.
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Mouse.begin()](#mousebegin)
|
||||||
|
* [Mouse.click()](#mouseclick)
|
||||||
|
* [Mouse.end()](#mouseend)
|
||||||
|
* [Mouse.move()](#mousemove)
|
||||||
|
* [Mouse.press()](#mousepress)
|
||||||
|
* [Mouse.isPressed()](#mouseispressed)
|
||||||
|
|
||||||
|
### `Mouse.isPressed()`
|
||||||
|
|
||||||
|
Checks the current status of all mouse buttons, and reports if any are pressed or not. By default, it checks the status of the left mouse button.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
Mouse.isPressed();
|
||||||
|
Mouse.isPressed(button);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* `button`: which mouse button was released (MOUSE_LEFT, MOUSE_RIGHT or MOUSE_MIDDLE, default is MOUSE_LEFT).
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
1 if a button was pressed, 0 if a not.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Mouse.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// The switch that will initiate the Mouse press
|
||||||
|
pinMode(2, INPUT);
|
||||||
|
// The switch that will terminate the Mouse press
|
||||||
|
pinMode(3, INPUT);
|
||||||
|
// Start serial communication with the computer
|
||||||
|
Serial.begin(9600);
|
||||||
|
// Initialize the Mouse library
|
||||||
|
Mouse.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// A variable for checking the button's state
|
||||||
|
int mouseState = 0;
|
||||||
|
// If the switch attached to pin 2 is closed, press and hold the left mouse button and save the state ina variable
|
||||||
|
if (digitalRead(2) == HIGH) {
|
||||||
|
Mouse.press();
|
||||||
|
mouseState = Mouse.isPressed();
|
||||||
|
}
|
||||||
|
// If the switch attached to pin 3 is closed, release the left mouse button and save the state in a variable
|
||||||
|
if (digitalRead(3) == HIGH) {
|
||||||
|
Mouse.release();
|
||||||
|
mouseState = Mouse.isPressed();
|
||||||
|
}
|
||||||
|
// Print out the current mouse button state
|
||||||
|
Serial.println(mouseState);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [Mouse.begin()](#mousebegin)
|
||||||
|
* [Mouse.click()](#mouseclick)
|
||||||
|
* [Mouse.end()](#mouseend)
|
||||||
|
* [Mouse.move()](#mousemove)
|
||||||
|
* [Mouse.press()](#mousepress)
|
||||||
|
* [Mouse.release()](#mouserelease)
|
||||||
23
libraries/Mouse/docs/readme.md
Normal file
23
libraries/Mouse/docs/readme.md
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Mouse library
|
||||||
|
|
||||||
|
The mouse functions enable 32u4 or SAMD micro based boards to control cursor movement on a connected computer through their micro’s native USB port. When updating the cursor position, it is always relative to the cursor’s previous location.
|
||||||
|
|
||||||
|
To use this library:
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <Mouse.h>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes and warnings
|
||||||
|
|
||||||
|
These core libraries allow the 32u4 and SAMD based boards (Leonardo, Esplora, Zero, Due and MKR Family) to appear as a native Mouse and/or Keyboard to a connected computer.
|
||||||
|
|
||||||
|
**A word of caution on using the Mouse and Keyboard libraries**: if the Mouse or Keyboard library is constantly running, it will be difficult to program your board. Functions such as `Mouse.move()` and `Keyboard.print()` will move your cursor or send keystrokes to a connected computer and should only be called when you are ready to handle them. It is recommended to use a control system to turn this functionality on, like a physical switch or only responding to specific input you can control. Refer to the Mouse and Keyboard examples for some ways to handle this.
|
||||||
|
|
||||||
|
When using the Mouse or Keyboard library, it may be best to test your output first using `Serial.print()`. This way, you can be sure you know what values are being reported.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
* [KeyboardAndMouseControl](https://www.arduino.cc/en/Tutorial/BuiltInExamples/KeyboardAndMouseControl): Demonstrates the Mouse and Keyboard commands in one program.
|
||||||
|
* [ButtonMouseControl](https://www.arduino.cc/en/Tutorial/BuiltInExamples/ButtonMouseControl): Control cursor movement with 5 pushbuttons.
|
||||||
|
* [JoystickMouseControl](https://www.arduino.cc/en/Tutorial/BuiltInExamples/JoystickMouseControl): Controls a computer’s cursor movement with a Joystick when a button is pressed.
|
||||||
34
libraries/Mouse/examples/Circle/Circle.ino
Normal file
34
libraries/Mouse/examples/Circle/Circle.ino
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
/* Earle F. Philhower, III <earlephilhower@yahoo.com> */
|
||||||
|
/* Released to the public domain */
|
||||||
|
|
||||||
|
|
||||||
|
#include <Mouse.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
Mouse.begin();
|
||||||
|
delay(5000);
|
||||||
|
Serial.printf("Press BOOTSEL to move the mouse in a circle\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (BOOTSEL) {
|
||||||
|
Serial.println("BARREL ROLL!!!");
|
||||||
|
float r = 100;
|
||||||
|
float ox = 0.0;
|
||||||
|
float oy = 0.0;
|
||||||
|
for (float a = 0; a < 2.0 * 3.14159; a += 0.1) {
|
||||||
|
float ax = r * cos(a);
|
||||||
|
float ay = r * sin(a);
|
||||||
|
float dx = ax - ox;
|
||||||
|
float dy = ay - oy;
|
||||||
|
Mouse.move(dx, dy, 0);
|
||||||
|
ox = ax;
|
||||||
|
oy = ay;
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
while (BOOTSEL) {
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
libraries/Mouse/keywords.txt
Normal file
24
libraries/Mouse/keywords.txt
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#######################################
|
||||||
|
# Syntax Coloring Map For Mouse
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Datatypes (KEYWORD1)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
Mouse KEYWORD1
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
begin KEYWORD2
|
||||||
|
click KEYWORD2
|
||||||
|
move KEYWORD2
|
||||||
|
press KEYWORD2
|
||||||
|
release KEYWORD2
|
||||||
|
isPressed KEYWORD2
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Constants (LITERAL1)
|
||||||
|
#######################################
|
||||||
9
libraries/Mouse/library.properties
Normal file
9
libraries/Mouse/library.properties
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
name=Mouse
|
||||||
|
version=1.0.1
|
||||||
|
author=Arduino and EFP3
|
||||||
|
maintainer=Earle F. Philhower, III <earlephilhower@yahoo.com>
|
||||||
|
sentence=Allows an Arduino board with USB capabilities to act as a Mouse.
|
||||||
|
paragraph=Allows the RP2040 to emulate a USB mouse
|
||||||
|
category=Device Control
|
||||||
|
url=https://www.arduino.cc/reference/en/language/functions/usb/mouse/
|
||||||
|
architectures=rp2040
|
||||||
53
libraries/Mouse/src/Mouse.cpp
Normal file
53
libraries/Mouse/src/Mouse.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
Mouse.cpp
|
||||||
|
|
||||||
|
Copyright (c) 2015, Arduino LLC
|
||||||
|
Original code (pre-library): Copyright (c) 2011, Peter Barrett
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Mouse.h"
|
||||||
|
#include <RP2040USB.h>
|
||||||
|
|
||||||
|
#include "tusb.h"
|
||||||
|
#include "class/hid/hid_device.h"
|
||||||
|
|
||||||
|
// Weak function override to add our descriptor to the TinyUSB list
|
||||||
|
void __USBInstallMouse() { /* noop */ }
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
//================================================================================
|
||||||
|
// Mouse
|
||||||
|
|
||||||
|
/* This function is for limiting the input value for x and y
|
||||||
|
axis to -127 <= x/y <= 127 since this is the allowed value
|
||||||
|
range for a USB HID device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Mouse_::Mouse_(void) {
|
||||||
|
/* noop */
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mouse_::move(int x, int y, signed char wheel) {
|
||||||
|
CoreMutex m(&__usb_mutex);
|
||||||
|
tud_task();
|
||||||
|
if (tud_hid_ready()) {
|
||||||
|
tud_hid_mouse_report(__USBGetMouseReportID(), _buttons, limit_xy(x), limit_xy(y), wheel, 0);
|
||||||
|
}
|
||||||
|
tud_task();
|
||||||
|
}
|
||||||
|
|
||||||
|
Mouse_ Mouse;
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
/*
|
/*
|
||||||
Keyboard_da_DK.h
|
Mouse.h
|
||||||
|
|
||||||
Copyright (c) 2021, Peter John
|
Copyright (c) 2015, Arduino LLC
|
||||||
|
Original code (pre-library): Copyright (c) 2011, Peter Barrett
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
@ -18,27 +19,16 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef KEYBOARD_DA_DK_h
|
#ifndef MOUSE_h
|
||||||
#define KEYBOARD_DA_DK_h
|
#define MOUSE_h
|
||||||
|
|
||||||
#include "HID.h"
|
#include <HID_Mouse.h>
|
||||||
|
|
||||||
#if !defined(_USING_HID)
|
class Mouse_ : public HID_Mouse {
|
||||||
|
public:
|
||||||
#warning "Using legacy HID core (non pluggable)"
|
Mouse_(void);
|
||||||
|
virtual void move(int x, int y, signed char wheel = 0) override;
|
||||||
#else
|
};
|
||||||
|
extern Mouse_ Mouse;
|
||||||
//================================================================================
|
|
||||||
//================================================================================
|
|
||||||
// Keyboard
|
|
||||||
|
|
||||||
// DA_DK keys
|
|
||||||
#define KEY_A_RING (136+0x2f)
|
|
||||||
#define KEY_SLASHED_O (136+0x34)
|
|
||||||
#define KEY_ASH (136+0x33)
|
|
||||||
#define KEY_UMLAUT (136+0x30)
|
|
||||||
#define KEY_ACUTE_ACC (136+0x2e)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
@ -22,25 +22,7 @@
|
||||||
#include "MouseBLE.h"
|
#include "MouseBLE.h"
|
||||||
#include <PicoBluetoothBLEHID.h>
|
#include <PicoBluetoothBLEHID.h>
|
||||||
|
|
||||||
//================================================================================
|
MouseBLE_::MouseBLE_(void) {
|
||||||
//================================================================================
|
|
||||||
// Mouse
|
|
||||||
|
|
||||||
/* This function is for limiting the input value for x and y
|
|
||||||
axis to -127 <= x/y <= 127 since this is the allowed value
|
|
||||||
range for a USB HID device.
|
|
||||||
*/
|
|
||||||
static signed char limit_xy(int const xy) {
|
|
||||||
if (xy < -127) {
|
|
||||||
return -127;
|
|
||||||
} else if (xy > 127) {
|
|
||||||
return 127;
|
|
||||||
} else {
|
|
||||||
return xy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseBLE_::MouseBLE_(void) : _buttons(0) {
|
|
||||||
/* noop */
|
/* noop */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,15 +40,6 @@ void MouseBLE_::setBattery(int lvl) {
|
||||||
PicoBluetoothBLEHID.setBattery(lvl);
|
PicoBluetoothBLEHID.setBattery(lvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseBLE_::click(uint8_t b) {
|
|
||||||
_buttons = b;
|
|
||||||
move(0, 0, 0);
|
|
||||||
delay(10);
|
|
||||||
_buttons = 0;
|
|
||||||
move(0, 0, 0);
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseBLE_::move(int x, int y, signed char wheel) {
|
void MouseBLE_::move(int x, int y, signed char wheel) {
|
||||||
hid_mouse_report_t data;
|
hid_mouse_report_t data;
|
||||||
data.buttons = _buttons;
|
data.buttons = _buttons;
|
||||||
|
|
@ -77,27 +50,4 @@ void MouseBLE_::move(int x, int y, signed char wheel) {
|
||||||
PicoBluetoothBLEHID.send(&data, sizeof(data));
|
PicoBluetoothBLEHID.send(&data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseBLE_::buttons(uint8_t b) {
|
|
||||||
if (b != _buttons) {
|
|
||||||
_buttons = b;
|
|
||||||
move(0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseBLE_::press(uint8_t b) {
|
|
||||||
buttons(_buttons | b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseBLE_::release(uint8_t b) {
|
|
||||||
buttons(_buttons & ~b);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MouseBLE_::isPressed(uint8_t b) {
|
|
||||||
if ((b & _buttons) > 0) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseBLE_ MouseBLE;
|
MouseBLE_ MouseBLE;
|
||||||
|
|
|
||||||
|
|
@ -22,30 +22,14 @@
|
||||||
#ifndef MOUSEBLE_h
|
#ifndef MOUSEBLE_h
|
||||||
#define MOUSEBLE_h
|
#define MOUSEBLE_h
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <HID_Mouse.h>
|
||||||
|
|
||||||
//================================================================================
|
class MouseBLE_ : public HID_Mouse {
|
||||||
//================================================================================
|
|
||||||
// Mouse
|
|
||||||
|
|
||||||
#define MOUSE_LEFT 1
|
|
||||||
#define MOUSE_RIGHT 2
|
|
||||||
#define MOUSE_MIDDLE 4
|
|
||||||
#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)
|
|
||||||
|
|
||||||
class MouseBLE_ {
|
|
||||||
private:
|
|
||||||
uint8_t _buttons;
|
|
||||||
void buttons(uint8_t b);
|
|
||||||
public:
|
public:
|
||||||
MouseBLE_(void);
|
MouseBLE_(void);
|
||||||
void begin(void);
|
void begin(void);
|
||||||
void end(void);
|
void end(void);
|
||||||
void click(uint8_t b = MOUSE_LEFT);
|
virtual void move(int x, int y, signed char wheel = 0) override;
|
||||||
void move(int x, int y, signed char wheel = 0);
|
|
||||||
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
|
|
||||||
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
|
|
||||||
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
|
|
||||||
void setBattery(int lvl);
|
void setBattery(int lvl);
|
||||||
};
|
};
|
||||||
extern MouseBLE_ MouseBLE;
|
extern MouseBLE_ MouseBLE;
|
||||||
|
|
|
||||||
|
|
@ -22,25 +22,7 @@
|
||||||
#include "MouseBT.h"
|
#include "MouseBT.h"
|
||||||
#include <PicoBluetoothHID.h>
|
#include <PicoBluetoothHID.h>
|
||||||
|
|
||||||
//================================================================================
|
MouseBT_::MouseBT_(void) {
|
||||||
//================================================================================
|
|
||||||
// Mouse
|
|
||||||
|
|
||||||
/* This function is for limiting the input value for x and y
|
|
||||||
axis to -127 <= x/y <= 127 since this is the allowed value
|
|
||||||
range for a USB HID device.
|
|
||||||
*/
|
|
||||||
static signed char limit_xy(int const xy) {
|
|
||||||
if (xy < -127) {
|
|
||||||
return -127;
|
|
||||||
} else if (xy > 127) {
|
|
||||||
return 127;
|
|
||||||
} else {
|
|
||||||
return xy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseBT_::MouseBT_(void) : _buttons(0) {
|
|
||||||
/* noop */
|
/* noop */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,15 +36,6 @@ void MouseBT_::end(void) {
|
||||||
PicoBluetoothHID.end();
|
PicoBluetoothHID.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseBT_::click(uint8_t b) {
|
|
||||||
_buttons = b;
|
|
||||||
move(0, 0, 0);
|
|
||||||
delay(10);
|
|
||||||
_buttons = 0;
|
|
||||||
move(0, 0, 0);
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseBT_::move(int x, int y, signed char wheel) {
|
void MouseBT_::move(int x, int y, signed char wheel) {
|
||||||
hid_mouse_report_t data;
|
hid_mouse_report_t data;
|
||||||
data.buttons = _buttons;
|
data.buttons = _buttons;
|
||||||
|
|
@ -73,27 +46,4 @@ void MouseBT_::move(int x, int y, signed char wheel) {
|
||||||
PicoBluetoothHID.send(REPORT_ID, &data, sizeof(data));
|
PicoBluetoothHID.send(REPORT_ID, &data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseBT_::buttons(uint8_t b) {
|
|
||||||
if (b != _buttons) {
|
|
||||||
_buttons = b;
|
|
||||||
move(0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseBT_::press(uint8_t b) {
|
|
||||||
buttons(_buttons | b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseBT_::release(uint8_t b) {
|
|
||||||
buttons(_buttons & ~b);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MouseBT_::isPressed(uint8_t b) {
|
|
||||||
if ((b & _buttons) > 0) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseBT_ MouseBT;
|
MouseBT_ MouseBT;
|
||||||
|
|
|
||||||
|
|
@ -22,30 +22,14 @@
|
||||||
#ifndef MOUSEBT_h
|
#ifndef MOUSEBT_h
|
||||||
#define MOUSEBT_h
|
#define MOUSEBT_h
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <HID_Mouse.h>
|
||||||
|
|
||||||
//================================================================================
|
class MouseBT_ : public HID_Mouse {
|
||||||
//================================================================================
|
|
||||||
// Mouse
|
|
||||||
|
|
||||||
#define MOUSE_LEFT 1
|
|
||||||
#define MOUSE_RIGHT 2
|
|
||||||
#define MOUSE_MIDDLE 4
|
|
||||||
#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)
|
|
||||||
|
|
||||||
class MouseBT_ {
|
|
||||||
private:
|
|
||||||
uint8_t _buttons;
|
|
||||||
void buttons(uint8_t b);
|
|
||||||
public:
|
public:
|
||||||
MouseBT_(void);
|
MouseBT_(void);
|
||||||
void begin(void);
|
void begin(void);
|
||||||
void end(void);
|
void end(void);
|
||||||
void click(uint8_t b = MOUSE_LEFT);
|
virtual void move(int x, int y, signed char wheel = 0) override;
|
||||||
void move(int x, int y, signed char wheel = 0);
|
|
||||||
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
|
|
||||||
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
|
|
||||||
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
|
|
||||||
};
|
};
|
||||||
extern MouseBT_ MouseBT;
|
extern MouseBT_ MouseBT;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
name=PicoBluetoothHID
|
|
||||||
version=1.0.0
|
|
||||||
author=Earle F. Philhower, III <earlephilhower@yahoo.com>
|
|
||||||
maintainer=Earle F. Philhower, III <earlephilhower@yahoo.com>
|
|
||||||
sentence=Implements a HID device base class for PicoW Bluetooth Classic
|
|
||||||
paragraph=Implements a HID device base class for PicoW Bluetooth Classic
|
|
||||||
category=Device Control
|
|
||||||
url=https://github.com/earlephilhower/arduino-pico
|
|
||||||
architectures=rp2040
|
|
||||||
|
|
@ -9,8 +9,9 @@ for dir in ./cores/rp2040 ./libraries/EEPROM ./libraries/I2S ./libraries/SingleF
|
||||||
./libraries/PicoOTA ./libraries/SDFS ./libraries/ArduinoOTA \
|
./libraries/PicoOTA ./libraries/SDFS ./libraries/ArduinoOTA \
|
||||||
./libraries/Updater ./libraries/HTTPClient ./libraries/HTTPUpdate \
|
./libraries/Updater ./libraries/HTTPClient ./libraries/HTTPUpdate \
|
||||||
./libraries/WebServer ./libraries/HTTPUpdateServer ./libraries/DNSServer \
|
./libraries/WebServer ./libraries/HTTPUpdateServer ./libraries/DNSServer \
|
||||||
./libraries/PicoBluetoothHID ./libraries/JoystickBT ./libraries/KeyboardBT \
|
./libraries/Joystick ./libraries/Keyboard ./libraries/Mouse \
|
||||||
./libraries/MouseBT ./libraries/SerialBT ./libraries/PicoBluetoothBLEHID \
|
./libraries/JoystickBT ./libraries/KeyboardBT \
|
||||||
|
./libraries/MouseBT ./libraries/SerialBT ./libraries/HID_Bluetooth \
|
||||||
./libraries/JoystickBLE ./libraries/KeyboardBLE ./libraries/MouseBLE ; do
|
./libraries/JoystickBLE ./libraries/KeyboardBLE ./libraries/MouseBLE ; do
|
||||||
find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" \) -a \! -path '*api*' -exec astyle --suffix=none --options=./tests/astyle_core.conf \{\} \;
|
find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" \) -a \! -path '*api*' -exec astyle --suffix=none --options=./tests/astyle_core.conf \{\} \;
|
||||||
find $dir -type f -name "*.ino" -exec astyle --suffix=none --options=./tests/astyle_examples.conf \{\} \;
|
find $dir -type f -name "*.ino" -exec astyle --suffix=none --options=./tests/astyle_examples.conf \{\} \;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue