forked from micropython/micropython
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for Cardputer keyboard input.
- Loading branch information
1 parent
5836f11
commit 090f330
Showing
8 changed files
with
438 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
#define SHIFT_MOD 0x40 | ||
#define FN_MOD 0x80 | ||
|
||
#define KEY_OPT 0 | ||
#define KEY_Z 1 | ||
#define KEY_C 2 | ||
#define KEY_B 3 | ||
#define KEY_M 4 | ||
#define KEY_DOT 5 | ||
#define KEY_SPACE 6 | ||
#define KEY_SHIFT 7 | ||
#define KEY_S 8 | ||
#define KEY_F 9 | ||
#define KEY_H 10 | ||
#define KEY_K 11 | ||
#define KEY_SEMICOLON 12 | ||
#define KEY_ENTER 13 | ||
#define KEY_Q 14 | ||
#define KEY_E 15 | ||
#define KEY_T 16 | ||
#define KEY_U 17 | ||
#define KEY_O 18 | ||
#define KEY_LEFT_BRACKET 19 | ||
#define KEY_BACKSLASH 20 | ||
#define KEY_1 21 | ||
#define KEY_3 22 | ||
#define KEY_5 23 | ||
#define KEY_7 24 | ||
#define KEY_9 25 | ||
#define KEY_UNDERSCORE 26 | ||
#define KEY_BACKSPACE 27 | ||
#define KEY_CTRL 28 | ||
#define KEY_ALT 29 | ||
#define KEY_X 30 | ||
#define KEY_V 31 | ||
#define KEY_N 32 | ||
#define KEY_COMMA 33 | ||
#define KEY_SLASH 34 | ||
#define KEY_FN 35 | ||
#define KEY_A 36 | ||
#define KEY_D 37 | ||
#define KEY_G 38 | ||
#define KEY_J 39 | ||
#define KEY_L 40 | ||
#define KEY_APOSTROPHE 41 | ||
#define KEY_TAB 42 | ||
#define KEY_W 43 | ||
#define KEY_R 44 | ||
#define KEY_Y 45 | ||
#define KEY_I 46 | ||
#define KEY_P 47 | ||
#define KEY_RIGHT_BRACKET 48 | ||
#define KEY_GRAVE 49 | ||
#define KEY_2 50 | ||
#define KEY_4 51 | ||
#define KEY_6 52 | ||
#define KEY_8 53 | ||
#define KEY_0 54 | ||
#define KEY_EQUALS 55 | ||
|
||
#define KEY_GREATER (5 | SHIFT_MOD) | ||
#define KEY_COLON (12 | SHIFT_MOD) | ||
#define KEY_LEFT_CURLY_BRACKET (19 | SHIFT_MOD) | ||
#define KEY_PIPE (20 | SHIFT_MOD) | ||
#define KEY_EXCLAMATION (21 | SHIFT_MOD) | ||
#define KEY_HASH (22 | SHIFT_MOD) | ||
#define KEY_PERCENT (23 | SHIFT_MOD) | ||
#define KEY_AMPERSAND (24 | SHIFT_MOD) | ||
#define KEY_OPEN_PARENTHESIS (25 | SHIFT_MOD) | ||
#define KEY_MINUS (26 | SHIFT_MOD) | ||
#define KEY_LESS (33 | SHIFT_MOD) | ||
#define KEY_QUESTION (34 | SHIFT_MOD) | ||
#define KEY_DOUBLE_QUOTE (41 | SHIFT_MOD) | ||
#define KEY_RIGHT_CURLY_BRACKET (48 | SHIFT_MOD) | ||
#define KEY_TILDE (49 | SHIFT_MOD) | ||
#define KEY_AT (50 | SHIFT_MOD) | ||
#define KEY_DOLLAR (51 | SHIFT_MOD) | ||
#define KEY_CARET (52 | SHIFT_MOD) | ||
#define KEY_ASTERISK (53 | SHIFT_MOD) | ||
#define KEY_CLOSE_PARENTHESIS (54 | SHIFT_MOD) | ||
#define KEY_PLUS (55 | SHIFT_MOD) | ||
|
||
#define KEY_DOWN (5 | FN_MOD) | ||
#define KEY_UP (12 | FN_MOD) | ||
#define KEY_DELETE (27 | FN_MOD) | ||
#define KEY_LEFT (33 | FN_MOD) | ||
#define KEY_RIGHT (34 | FN_MOD) | ||
#define KEY_ESC (49 | FN_MOD) | ||
|
||
int keymap[56] = { | ||
0, // KEY_OPT | ||
'z', // KEY_Z | ||
'c', // KEY_C | ||
'b', // KEY_B | ||
'm', // KEY_M | ||
'.', // KEY_DOT | ||
' ', // KEY_SPACE | ||
0, // KEY_SHIFT | ||
's', // KEY_S | ||
'f', // KEY_F | ||
'h', // KEY_H | ||
'k', // KEY_K | ||
';', // KEY_SEMICOLON | ||
'\r',// KEY_ENTER | ||
'q', // KEY_Q | ||
'e', // KEY_E | ||
't', // KEY_T | ||
'u', // KEY_U | ||
'o', // KEY_O | ||
'[', // KEY_LEFT_BRACKET | ||
'\\',// KEY_BACKSLASH | ||
'1', // KEY_1 | ||
'3', // KEY_3 | ||
'5', // KEY_5 | ||
'7', // KEY_7 | ||
'9', // KEY_9 | ||
'_', // KEY_UNDERSCORE | ||
'\b',// KEY_BACKSPACE | ||
0, // KEY_CTRL | ||
0, // KEY_ALT | ||
'x', // KEY_X | ||
'v', // KEY_V | ||
'n', // KEY_N | ||
',', // KEY_COMMA | ||
'/', // KEY_SLASH | ||
0, // KEY_FN | ||
'a', // KEY_A | ||
'd', // KEY_D | ||
'g', // KEY_G | ||
'j', // KEY_J | ||
'l', // KEY_L | ||
'\'',// KEY_APOSTROPHE | ||
'\t',// KEY_TAB | ||
'w', // KEY_W | ||
'r', // KEY_R | ||
'y', // KEY_Y | ||
'i', // KEY_I | ||
'p', // KEY_P | ||
']', // KEY_RIGHT_BRACKET | ||
'`', // KEY_GRAVE | ||
'2', // KEY_2 | ||
'4', // KEY_4 | ||
'6', // KEY_6 | ||
'8', // KEY_8 | ||
'0', // KEY_0 | ||
'=' // KEY_EQUALS | ||
}; | ||
|
||
int keymap_shifted[56] = { | ||
0, // KEY_OPT | ||
'Z', // KEY_Z | ||
'C', // KEY_C | ||
'B', // KEY_B | ||
'M', // KEY_M | ||
'>', // KEY_DOT -> '>' | ||
' ', // KEY_SPACE | ||
0, // KEY_SHIFT | ||
'S', // KEY_S | ||
'F', // KEY_F | ||
'H', // KEY_H | ||
'K', // KEY_K | ||
':', // KEY_SEMICOLON -> ':' | ||
'\r',// KEY_ENTER | ||
'Q', // KEY_Q | ||
'E', // KEY_E | ||
'T', // KEY_T | ||
'U', // KEY_U | ||
'O', // KEY_O | ||
'{', // KEY_LEFT_BRACKET -> '{' | ||
'|', // KEY_BACKSLASH -> '|' | ||
'!', // KEY_1 -> '!' | ||
'#', // KEY_3 -> '#' | ||
'%', // KEY_5 -> '%' | ||
'&', // KEY_7 -> '&' | ||
'(', // KEY_9 -> '(' | ||
'_', // KEY_UNDERSCORE -> '-' | ||
'\x7F',// KEY_BACKSPACE | ||
0, // KEY_CTRL | ||
0, // KEY_ALT | ||
'X', // KEY_X | ||
'V', // KEY_V | ||
'N', // KEY_N | ||
'<', // KEY_COMMA -> '<' | ||
'?', // KEY_SLASH -> '?' | ||
0, // KEY_FN | ||
'A', // KEY_A | ||
'D', // KEY_D | ||
'G', // KEY_G | ||
'J', // KEY_J | ||
'L', // KEY_L | ||
'"', // KEY_APOSTROPHE -> '"' | ||
'\t',// KEY_TAB | ||
'W', // KEY_W | ||
'R', // KEY_R | ||
'Y', // KEY_Y | ||
'I', // KEY_I | ||
'P', // KEY_P | ||
'}', // KEY_RIGHT_BRACKET -> '}' | ||
'~', // KEY_GRAVE -> '~' | ||
'@', // KEY_2 -> '@' | ||
'$', // KEY_4 -> '$' | ||
'^', // KEY_6 -> '^' | ||
'*', // KEY_8 -> '*' | ||
')', // KEY_0 -> ')' | ||
'+' // KEY_EQUALS -> '+' | ||
}; |
Oops, something went wrong.
090f330
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How can one use the keyboard from the CircuitPython program? E.g. if I just try to manually create a DemuxKeyMatrix object, CircuitPython justifiably complains that "KB_A_0 is in use". Indeed, the keyboard has been configured for scanning at board initialization time in this commit.
Is there a way to get a hold of the event queue the keyboard events are being pushed by the pre-initialized object? Alternatively, is there a way to deinitialize the keyboard scanner (and free the pins) so that I could create an instance usable directly in my code?
090f330
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason you don't want to use input() or sys.stdin.read() ?
What are you trying to do?
090f330
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't realize the keys are accessible via stdin (didn't guess by just looking at the code that
board_serial_xxx
does that).I do not think this would be enough, though. I'm trying to use the keyboard as a sound controller of sorts and would like to get access to individual key up / key down events. I also want to use non-character keys. Would that be possible?
If not now, could the
board_keyboard
object be somehow exposed asboard.KEYBOARD
to the Python code here?090f330
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is it set up
The keyboard is set up like a serial input—a board-specific one. There's currently no alternative to this.
How does this work? It produces the same key strokes as you'd get from a serial terminal.
What are my key codes?
You can find out what they are! Look them up on the VT102 spec or even easier, just run this program and press the keys:
So you can get arrows, backspace, escape, ctrl-f, alt-r, opt-l, etc. Whatever's on the keyboard there's an output sequence for it!
For example, the up key will generate something like: \e[B (in hex that's: 0x1B, 0x5B, 0x41).
But that's only if you're holding down the fn modifier. Otherwise, you'd get what's printed in black, the semicolon.
Why is it set up this way?
Because it:
Can I check which keys are down?
No,
keyboard_demux
doesn't provide this, and it's the only viable built-in API.Can I access the key queue?
No, the system steals all the keystrokes before your program can see them.
Can you expose the keyboard object so I can deinit it and create my own?
I've tried... either the driver stops working or the whole system just crashes.
So I decided not to expose the keyboard object.
I'll get some advice and have another look later.
090f330
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, thanks for the detailed write-up.
Having access to individual key-up/key-down events is pretty important to be able to implement any sort of game-like interaction, however (which, for my personal purposes, is way more important than the built-in terminal. Neither do I want to be able to ctrl+C out of the uploaded program).
It would be nice then, if we could come up with a slighly looser integration here. Either of the following would work:
board.KEYBOARD
object that can however be released if necessary (in the same spiritdisplayio.release_display()
works).I'm happy to try some of these options (although it is literally the first time I am seeeing the micro/circuitpython codebase so I'll still need to figure out how to build it, expose C++ objects to Python, etc).
090f330
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... something like this, for example. WDYT?
090f330
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's great that you've already written some code to flesh out how this will work.
I do like the idea of controlling the keyboard mode with a config variable. Have you tested this code?
However, I wonder if there's a method to toggle whether the serial driver takes events from the queue.
One that can be controlled by the program.
I'll look over this tomorrow when I have some time.
Are you on the Adafruit Discord?
You'd be able to get support there, and you'd be able to send me a DM if you'd like.
Or use any of the socials linked to on my profile.
It's got to be a bit easier than having this discussion through the comments on an old GitHub commit message.
090f330
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Joined the discord, pinged you there.
I did of course check that the thing I wrote behaves as intended.