Repository navigation
Expand file tree
/
Copy pathkeyboard.py
More file actions
164 lines (133 loc) · 5.56 KB
/
Copy pathkeyboard.py
File metadata and controls
164 lines (133 loc) · 5.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <https://www.gnu.org/licenses/>.
from enum import Enum
from pydantic import BaseModel, Field, NonNegativeInt, PositiveFloat, PositiveInt
class KeyboardUSBPort(str, Enum):
FULL_SPEED = "fs"
HIGH_SPEED = "hs"
# USB Configuration
class KeyboardUSB(BaseModel):
# USB Vendor ID
vid: str = Field(pattern=r"^0x[0-9A-Fa-f]{4}$")
# USB Product ID
pid: str = Field(pattern=r"^0x[0-9A-Fa-f]{4}$")
port: KeyboardUSBPort
# Keyboard Configuration
class KeyboardKeyboard(BaseModel):
num_profiles: int = Field(ge=1, le=8)
num_layers: int = Field(ge=1, le=8)
num_keys: int = Field(ge=1, le=256)
num_advanced_keys: int = Field(ge=1, le=64)
# Hardware Configuration
class KeyboardHardware(BaseModel):
# High-speed external oscillator value in Hz
hse_value: PositiveInt
# Keyboard driver name
driver: str
# Raw ADC input configuration
class KeyboardAnalogRaw(BaseModel):
# Array of raw ADC input channels. If a string is provided, it is used as the GPIO pin name
input: list[NonNegativeInt | str]
# Array of key index mappings for the raw ADC inputs
vector: list[NonNegativeInt]
# Analog Multiplexer ADC input configuration
class KeyboardAnalogMux(BaseModel):
# Array of GPIO pin names for the multiplexer select lines
select: list[str]
# Array of ADC input channels for the multiplexers. If a string is provided, it is used as the GPIO pin name
input: list[list[NonNegativeInt | str]]
# Mapping from multiplexers to ADC input channels
matrix: list[list[NonNegativeInt]]
# Rotary Encoder configuration
class KeyboardEncoder(BaseModel):
# Array of GPIO pin names for the encoder pins
pins: list[str] = Field(min_length=2, max_length=2)
# The two virtual keys for CCW and CW
keys: list[NonNegativeInt] = Field(min_length=2, max_length=2)
# The hardware timer to use for the encoder
timer: str
# The number of steps per detent
resolution: PositiveInt = 4
# The GPIO pin for the encoder button
button_pin: str | None = None
# The virtual key for the encoder button
button_key: NonNegativeInt | None = None
# Analog Configuration
class KeyboardAnalog(BaseModel):
# ADC resolution for this keyboard. A higher value means higher accuracy but slower matrix scans. Default to the maximum resolution supported by the MCU if not provided.
adc_resolution: PositiveInt | None = None
# Set to true if the ADC value is inversely proportional to the travel distance of the keys
invert_adc: bool = False
# Delay in microseconds between ADC scans
delay: int | None = None
raw: KeyboardAnalogRaw | None = None
mux: KeyboardAnalogMux | None = None
class KeyboardCalibration(BaseModel):
# See `include/lib/eeconfig.h`
initial_rest_value: NonNegativeInt
# See `include/lib/eeconfig.h`
initial_bottom_out_threshold: NonNegativeInt
# Total switch travel distance in millimeters
switch_travel: float = 4.0
# Wear leveling Configuration
class KeyboardWearLeveling(BaseModel):
# Size of the virtual persistent storage in bytes. There must be enough RAM of this size to hold the entire virtual storage.
virtual_size: int = Field(ge=1, le=8192)
# Size of the write log in bytes
write_log_size: int = Field(ge=1, le=65536)
# Keyboard Layout Encoder
class KeyboardLayoutEncoder(BaseModel):
# The two virtual keys for CCW and CW
keys: list[NonNegativeInt] = Field(min_length=2, max_length=2)
buttonKey: NonNegativeInt | None = None
x: float
y: float
w: PositiveFloat | None = None
h: PositiveFloat | None = None
class KeyboardLayoutKey(BaseModel):
key: NonNegativeInt
w: PositiveFloat | None = None
h: PositiveFloat | None = None
x: float | None = None
y: float | None = None
# Option key and value pairs for the corresponding labels
option: tuple[int, int] | None = None
# Keyboard Layout
class KeyboardLayout(BaseModel):
# Labels for each layout option. Use a string for a toggle option, or an array for a select option
labels: list[str | list[str]] | None = None
# Metadata for how the keyboard should be rendered in the web configurator
keymap: list[list[KeyboardLayoutKey]]
encoders: list[KeyboardLayoutEncoder] | None = None
# Actuation Configuration
class KeyboardActuation(BaseModel):
# Default actuation point
actuation_point: int = Field(ge=0, le=255)
# keyboard.json Schema
class Keyboard(BaseModel):
name: str
manufacturer: str
maintainer: str
usb: KeyboardUSB
keyboard: KeyboardKeyboard
hardware: KeyboardHardware
analog: KeyboardAnalog
calibration: KeyboardCalibration
wear_leveling: KeyboardWearLeveling | None = None
encoders: list[KeyboardEncoder] | None = None
layout: KeyboardLayout
# Default keymap
keymap: list[list[str]] | None = None
# Default keymaps for each profile. If not specified, the default keymap will be used for all profiles.
keymaps: list[list[list[str]]] | None = None
actuation: KeyboardActuation | None = None