3232#include "shared/runtime/interrupt_char.h"
3333#include "supervisor/usb.h"
3434
35+ #ifndef DEBUG
36+ #define DEBUG (0)
37+ #endif
38+
3539// Buffer the incoming serial data in the background so that we can look for the
3640// interrupt character.
3741STATIC ringbuf_t _incoming_ringbuf ;
3842STATIC uint8_t _buf [16 ];
3943
40- uint8_t _dev_addr ;
41- uint8_t _interface ;
42-
43- #define FLAG_ALPHABETIC (1)
44- #define FLAG_SHIFT (2)
45- #define FLAG_NUMLOCK (4)
46- #define FLAG_CTRL (8)
47- #define FLAG_LUT (16)
48-
49- const char * const lut [] = {
50- "!@#$%^&*()" , /* 0 - shifted numeric keys */
51- "\r\x1b\10\t -=[]\\#;'`,./" , /* 1 - symbol keys */
52- "\n\x1b\177\t _+{}|~:\"~<>?" , /* 2 - shifted */
53- "\12\13\10\22" , /* 3 - arrow keys RLDU */
54- "/*-+\n1234567890." , /* 4 - keypad w/numlock */
55- "/*-+\n\xff\2\xff\4\xff\3\xff\1\xff\xff." , /* 5 - keypad w/o numlock */
56- };
44+ STATIC uint8_t _dev_addr ;
45+ STATIC uint8_t _interface ;
46+
47+ #define FLAG_SHIFT (1)
48+ #define FLAG_NUMLOCK (2)
49+ #define FLAG_CTRL (4)
50+ #define FLAG_STRING (8)
51+
52+ STATIC uint8_t user_keymap [384 ];
53+ STATIC size_t user_keymap_len = 0 ;
54+
55+ void usb_keymap_set (const uint8_t * buf , size_t len ) {
56+ user_keymap_len = len = MIN (len , sizeof (user_keymap ));
57+ memcpy (user_keymap , buf , len );
58+ memset (user_keymap + len , 0 , sizeof (user_keymap ) - len );
59+ }
5760
5861struct keycode_mapper {
5962 uint8_t first , last , code , flags ;
60- } keycode_to_ascii [] = {
61- { HID_KEY_A , HID_KEY_Z , 'a' , FLAG_ALPHABETIC , },
63+ const char * data ;
64+ };
6265
63- { HID_KEY_1 , HID_KEY_9 , 0 , FLAG_SHIFT | FLAG_LUT , },
66+ #define SEP "\0" // separator in FLAG_STRING sequences
67+ #define NOTHING "" // in FLAG_STRING sequences
68+ #define CURSOR_UP "\e[A"
69+ #define CURSOR_DOWN "\e[B"
70+ #define CURSOR_LEFT "\e[D"
71+ #define CURSOR_RIGHT "\e[C"
72+ #define CURSOR_PGUP "\e[5~"
73+ #define CURSOR_PGDN "\e[6~"
74+ #define CURSOR_HOME "\e[H"
75+ #define CURSOR_END "\e[F"
76+ #define CURSOR_INS "\e[2~"
77+ #define CURSOR_DEL "\e[3~"
78+
79+ STATIC struct keycode_mapper keycode_to_ascii [] = {
80+ { HID_KEY_A , HID_KEY_Z , 'a' , 0 , NULL },
81+
82+ { HID_KEY_1 , HID_KEY_9 , 0 , FLAG_SHIFT , "!@#$%^&*()" },
6483 { HID_KEY_1 , HID_KEY_9 , '1' , 0 , },
6584 { HID_KEY_0 , HID_KEY_0 , ')' , FLAG_SHIFT , },
6685 { HID_KEY_0 , HID_KEY_0 , '0' , 0 , },
6786
6887 { HID_KEY_ENTER , HID_KEY_ENTER , '\n' , FLAG_CTRL },
69- { HID_KEY_ENTER , HID_KEY_SLASH , 2 , FLAG_SHIFT | FLAG_LUT , },
70- { HID_KEY_ENTER , HID_KEY_SLASH , 1 , FLAG_LUT , },
88+ { HID_KEY_ENTER , HID_KEY_SLASH , 0 , FLAG_SHIFT , "\n\x1b\177\t _+{}|~:\"~<>?" },
89+ { HID_KEY_ENTER , HID_KEY_SLASH , 0 , 0 , "\r\x1b\10\t -=[]\\#;'`,./" },
7190
7291 { HID_KEY_F1 , HID_KEY_F1 , 0x1e , 0 , }, // help key on xerox 820 kbd
7392
74- { HID_KEY_ARROW_RIGHT , HID_KEY_ARROW_UP , 3 , FLAG_LUT },
93+ { HID_KEY_KEYPAD_DIVIDE , HID_KEY_KEYPAD_DECIMAL , 0 , FLAG_NUMLOCK | FLAG_STRING ,
94+ "/\0" "*\0" "-\0" "+\0" "\n\0" CURSOR_END SEP CURSOR_DOWN SEP CURSOR_PGDN SEP CURSOR_LEFT SEP NOTHING SEP CURSOR_RIGHT SEP CURSOR_HOME SEP CURSOR_UP SEP CURSOR_PGDN SEP CURSOR_INS SEP CURSOR_DEL },
95+ { HID_KEY_KEYPAD_DIVIDE , HID_KEY_KEYPAD_DECIMAL , 0 , 0 , "/*-+\n1234567890." },
96+
97+ { HID_KEY_ARROW_RIGHT , HID_KEY_ARROW_UP , 0 , FLAG_STRING , CURSOR_RIGHT SEP CURSOR_LEFT SEP CURSOR_DOWN SEP CURSOR_UP },
7598
76- { HID_KEY_KEYPAD_DIVIDE , HID_KEY_KEYPAD_DECIMAL , 4 , FLAG_NUMLOCK | FLAG_LUT },
77- { HID_KEY_KEYPAD_DIVIDE , HID_KEY_KEYPAD_DECIMAL , 5 , FLAG_LUT },
7899};
79100
80101STATIC bool report_contains (const hid_keyboard_report_t * report , uint8_t key ) {
@@ -86,30 +107,63 @@ STATIC bool report_contains(const hid_keyboard_report_t *report, uint8_t key) {
86107 return false;
87108}
88109
89- int old_ascii = -1 ;
90- uint32_t repeat_timeout ;
110+ STATIC const char * old_buf = NULL ;
111+ STATIC size_t buf_size = 0 ;
91112// this matches Linux default of 500ms to first repeat, 1/20s thereafter
92- const uint32_t default_repeat_time = 50 ;
93- const uint32_t initial_repeat_time = 500 ;
113+ STATIC const uint32_t initial_repeat_time = 500 ;
94114
95- STATIC void send_ascii (uint8_t code , uint32_t repeat_time ) {
96- old_ascii = code ;
115+ STATIC void send_bufn (const char * buf , size_t n , uint32_t repeat_time ) {
116+ old_buf = buf ;
117+ buf_size = n ;
97118 // repeat_timeout = millis() + repeat_time;
98- if (code == mp_interrupt_char ) {
99- mp_sched_keyboard_interrupt ();
100- return ;
119+ for (; n -- ; buf ++ ) {
120+ int code = * buf ;
121+ if (code == mp_interrupt_char ) {
122+ mp_sched_keyboard_interrupt ();
123+ return ;
124+ }
125+ if (ringbuf_num_empty (& _incoming_ringbuf ) == 0 ) {
126+ // Drop on the floor
127+ return ;
128+ }
129+ ringbuf_put (& _incoming_ringbuf , code );
101130 }
102- if (ringbuf_num_empty (& _incoming_ringbuf ) == 0 ) {
103- // Drop on the floor
104- return ;
131+ }
132+
133+ STATIC void send_bufz (const char * buf , uint32_t repeat_time ) {
134+ send_bufn (buf , strlen (buf ), repeat_time );
135+ }
136+
137+ STATIC void send_byte (uint8_t code , uint32_t repeat_time ) {
138+ static char buf [1 ];
139+ buf [0 ] = code ;
140+ send_bufn (buf , 1 , repeat_time );
141+ }
142+
143+ #if 0
144+ STATIC uint32_t repeat_timeout ;
145+ STATIC const uint32_t default_repeat_time = 50 ;
146+ // TODO: nothing actually SENDS the repetitions...
147+ STATIC void send_repeat () {
148+ if (old_buf ) {
149+ send_bufn (old_buf , old_buf_size , default_repeat_time );
105150 }
106- ringbuf_put (& _incoming_ringbuf , code );
107151}
152+ #endif
108153
109154hid_keyboard_report_t old_report ;
110155
156+ STATIC const char * skip_nuls (const char * buf , size_t n ) {
157+ while (n -- ) {
158+ buf += strlen (buf ) + 1 ;
159+ }
160+ return buf ;
161+ }
162+
111163STATIC void process_event (uint8_t dev_addr , uint8_t instance , const hid_keyboard_report_t * report ) {
112- bool alt = report -> modifier & 0x44 ;
164+ bool has_altgr = (user_keymap_len > 256 );
165+ bool altgr = has_altgr && report -> modifier & 0x40 ;
166+ bool alt = has_altgr ? report -> modifier & 0x4 : report -> modifier & 0x44 ;
113167 bool shift = report -> modifier & 0x22 ;
114168 bool ctrl = report -> modifier & 0x11 ;
115169 bool caps = old_report .reserved & 1 ;
@@ -122,7 +176,7 @@ STATIC void process_event(uint8_t dev_addr, uint8_t instance, const hid_keyboard
122176 }
123177
124178 // something was pressed or release, so cancel any key repeat
125- old_ascii = -1 ;
179+ old_buf = NULL ;
126180
127181 for (int i = 0 ; i < 6 ; i ++ ) {
128182 uint8_t keycode = report -> keycode [i ];
@@ -139,6 +193,22 @@ STATIC void process_event(uint8_t dev_addr, uint8_t instance, const hid_keyboard
139193 } else if (keycode == HID_KEY_CAPS_LOCK ) {
140194 caps = !caps ;
141195 } else {
196+ size_t idx = keycode + (altgr ? 256 : shift ? 128 : 0 );
197+ uint8_t ascii = user_keymap [idx ];
198+ #if DEBUG
199+ mp_printf (& mp_plat_print , "lookup HID keycode %d mod %x at idx %d -> ascii %d (%c)\n" ,
200+ keycode , report -> modifier , idx , ascii , ascii >= 32 && ascii <= 126 ? ascii : '.' );
201+ #endif
202+ if (ascii != 0 ) {
203+ if (ctrl ) {
204+ ascii &= 0x1f ;
205+ } else if (ascii >= 'a' && ascii <= 'z' && caps ) {
206+ ascii ^= ('a' ^ 'A' );
207+ }
208+ send_byte (ascii , initial_repeat_time );
209+ continue ;
210+ }
211+
142212 for (size_t j = 0 ; j < MP_ARRAY_SIZE (keycode_to_ascii ); j ++ ) {
143213 struct keycode_mapper * mapper = & keycode_to_ascii [j ];
144214 if (!(keycode >= mapper -> first && keycode <= mapper -> last )) {
@@ -153,23 +223,24 @@ STATIC void process_event(uint8_t dev_addr, uint8_t instance, const hid_keyboard
153223 if (mapper -> flags & FLAG_CTRL && !ctrl ) {
154224 continue ;
155225 }
156- if (mapper -> flags & FLAG_LUT ) {
157- code = lut [mapper -> code ][keycode - mapper -> first ];
226+ if (mapper -> flags & FLAG_STRING ) {
227+ const char * msg = skip_nuls (mapper -> data , keycode - mapper -> first );
228+ send_bufz (msg , initial_repeat_time );
229+ } else if (mapper -> data ) {
230+ code = mapper -> data [keycode - mapper -> first ];
158231 } else {
159232 code = keycode - mapper -> first + mapper -> code ;
160233 }
161- if (mapper -> flags & FLAG_ALPHABETIC ) {
162- if (shift ^ caps ) {
163- code ^= ('a' ^ 'A' );
164- }
234+ if (code >= 'a' && code <= 'z' && (shift ^ caps )) {
235+ code ^= ('a' ^ 'A' );
165236 }
166237 if (ctrl ) {
167238 code &= 0x1f ;
168239 }
169240 if (alt ) {
170241 code ^= 0x80 ;
171242 }
172- send_ascii (code , initial_repeat_time );
243+ send_byte (code , initial_repeat_time );
173244 break ;
174245 }
175246 }
0 commit comments