├── Makefile
├── Soarer.hid
├── Soarer.inc
├── SoarerReverse.sln
├── SoarerReverse.vcproj
├── Soarer_at2usb_v1.12_atmega32u4.asm
├── Soarer_at2usb_v1.12_atmega32u4.bin
├── Soarer_at2usb_v1.12_atmega32u4.lst
├── Soarer_at2usb_v1.12_atmega32u4.txt
├── hwdefs.h
├── intkeys.h
├── kbdtbls.h
├── m32U4def.inc
├── print.c
├── print.h
├── processing.c
├── processing.h
├── readme.txt
├── salloc.c
├── salloc.h
├── soarer.c
├── soarer.h
├── usb_comm.c
└── usb_comm.h
/Makefile:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antonizoon/arakulas-soarers-converter/c32c5c882ea487889656bd893bdec62f70c7d2ee/Makefile
--------------------------------------------------------------------------------
/Soarer.hid:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antonizoon/arakulas-soarers-converter/c32c5c882ea487889656bd893bdec62f70c7d2ee/Soarer.hid
--------------------------------------------------------------------------------
/Soarer.inc:
--------------------------------------------------------------------------------
1 | db 5h, 1h ; USAGE_PAGE (Generic Desktop)
2 | db 9h, 6h ; USAGE (Keyboard)
3 | db a1h, 1h ; COLLECTION (Application)
4 | db 15h, 0h ; LOGICAL_MINIMUM (0)
5 | db 26h, ffh, 0h ; LOGICAL_MAXIMUM (255)
6 | db 95h, 8h ; REPORT_COUNT (8)
7 | db 75h, 8h ; REPORT_SIZE (8)
8 | db 81h, 3h ; INPUT (Cnst,Var,Abs)
9 | db c0h ; END_COLLECTION
10 | db 6h, 31h, ffh ; USAGE_PAGE (Not Defined)
11 | db 9h, 74h ; USAGE (Undefined)
12 | db a1h, 53h ; COLLECTION (VendorDefined)
13 | db 75h, 8h ; REPORT_SIZE (8)
14 | db 15h, 0h ; LOGICAL_MINIMUM (0)
15 | db 26h, ffh, 0h ; LOGICAL_MAXIMUM (255)
16 | db 95h, 20h ; REPORT_COUNT (32)
17 | db 9h, 75h ; USAGE (Undefined)
18 | db 81h, 2h ; INPUT (Data,Var,Abs)
19 | db c0h ; END_COLLECTION
20 | db 5h, 1h ; USAGE_PAGE (Generic Desktop)
21 | db 9h, 6h ; USAGE (Keyboard)
22 | db a1h, 1h ; COLLECTION (Application)
23 | db 85h, 1h ; REPORT_ID (1)
24 | db 75h, 1h ; REPORT_SIZE (1)
25 | db 95h, 8h ; REPORT_COUNT (8)
26 | db 5h, 7h ; USAGE_PAGE (Keyboard)
27 | db 19h, e0h ; USAGE_MINIMUM (Keyboard LeftControl)
28 | db 29h, e7h ; USAGE_MAXIMUM (Keyboard Right GUI)
29 | db 15h, 0h ; LOGICAL_MINIMUM (0)
30 | db 25h, 1h ; LOGICAL_MAXIMUM (1)
31 | db 81h, 2h ; INPUT (Data,Var,Abs)
32 | db 95h, 5h ; REPORT_COUNT (5)
33 | db 75h, 1h ; REPORT_SIZE (1)
34 | db 5h, 8h ; USAGE_PAGE (LEDs)
35 | db 19h, 1h ; USAGE_MINIMUM (Num Lock)
36 | db 29h, 5h ; USAGE_MAXIMUM (Kana)
37 | db 91h, 2h ; OUTPUT (Data,Var,Abs)
38 | db 95h, 1h ; REPORT_COUNT (1)
39 | db 75h, 3h ; REPORT_SIZE (3)
40 | db 91h, 3h ; OUTPUT (Cnst,Var,Abs)
41 | db 75h, 1h ; REPORT_SIZE (1)
42 | db 95h, 31h ; REPORT_COUNT (49)
43 | db 5h, 7h ; USAGE_PAGE (Keyboard)
44 | db 19h, 1h ; USAGE_MINIMUM (Keyboard ErrorRollOver)
45 | db 29h, 31h ; USAGE_MAXIMUM (Keyboard \ and |)
46 | db 15h, 0h ; LOGICAL_MINIMUM (0)
47 | db 25h, 1h ; LOGICAL_MAXIMUM (1)
48 | db 81h, 2h ; INPUT (Data,Var,Abs)
49 | db 95h, 1h ; REPORT_COUNT (1)
50 | db 75h, 1h ; REPORT_SIZE (1)
51 | db 81h, 3h ; INPUT (Cnst,Var,Abs)
52 | db 75h, 1h ; REPORT_SIZE (1)
53 | db 95h, 69h ; REPORT_COUNT (105)
54 | db 5h, 7h ; USAGE_PAGE (Keyboard)
55 | db 19h, 33h ; USAGE_MINIMUM (Keyboard ; and :)
56 | db 29h, 9bh ; USAGE_MAXIMUM (Keyboard Cancel)
57 | db 15h, 0h ; LOGICAL_MINIMUM (0)
58 | db 25h, 1h ; LOGICAL_MAXIMUM (1)
59 | db 81h, 2h ; INPUT (Data,Var,Abs)
60 | db 95h, 1h ; REPORT_COUNT (1)
61 | db 75h, 1h ; REPORT_SIZE (1)
62 | db 81h, 3h ; INPUT (Cnst,Var,Abs)
63 | db 75h, 1h ; REPORT_SIZE (1)
64 | db 95h, 8h ; REPORT_COUNT (8)
65 | db 5h, 7h ; USAGE_PAGE (Keyboard)
66 | db 19h, 9dh ; USAGE_MINIMUM (Keyboard Prior)
67 | db 29h, a4h ; USAGE_MAXIMUM (Keyboard ExSel)
68 | db 15h, 0h ; LOGICAL_MINIMUM (0)
69 | db 25h, 1h ; LOGICAL_MAXIMUM (1)
70 | db 81h, 2h ; INPUT (Data,Var,Abs)
71 | db 95h, 4h ; REPORT_COUNT (4)
72 | db 75h, 1h ; REPORT_SIZE (1)
73 | db 81h, 3h ; INPUT (Cnst,Var,Abs)
74 | db c0h ; END_COLLECTION
75 | db 5h, 1h ; USAGE_PAGE (Generic Desktop)
76 | db 9h, 80h ; USAGE (System Control)
77 | db a1h, 1h ; COLLECTION (Application)
78 | db 85h, 2h ; REPORT_ID (2)
79 | db 75h, 1h ; REPORT_SIZE (1)
80 | db 95h, 3h ; REPORT_COUNT (3)
81 | db 19h, 81h ; USAGE_MINIMUM (System Power Down)
82 | db 29h, 83h ; USAGE_MAXIMUM (System Wake Up)
83 | db 15h, 0h ; LOGICAL_MINIMUM (0)
84 | db 25h, 1h ; LOGICAL_MAXIMUM (1)
85 | db 81h, 2h ; INPUT (Data,Var,Abs)
86 | db 95h, 5h ; REPORT_COUNT (5)
87 | db 75h, 1h ; REPORT_SIZE (1)
88 | db 81h, 3h ; INPUT (Cnst,Var,Abs)
89 | db c0h ; END_COLLECTION
90 | db 5h, ch ; USAGE_PAGE (Consumer Devices)
91 | db 9h, 1h ; USAGE (Consumer Control)
92 | db a1h, 1h ; COLLECTION (Application)
93 | db 85h, 3h ; REPORT_ID (3)
94 | db 75h, 1h ; REPORT_SIZE (1)
95 | db 95h, 18h ; REPORT_COUNT (24)
96 | db 9h, b5h ; USAGE (Scan Next Track)
97 | db 9h, b6h ; USAGE (Scan Previous Track)
98 | db 9h, b7h ; USAGE (Stop)
99 | db 9h, cdh ; USAGE (Unassigned)
100 | db 9h, e2h ; USAGE (Mute)
101 | db 9h, e5h ; USAGE (Bass Boost)
102 | db 9h, e7h ; USAGE (Loudness)
103 | db 9h, e9h ; USAGE (Volume Up)
104 | db 9h, eah ; USAGE (Volume Down)
105 | db ah, 52h, 1h ; USAGE (Bass Increment)
106 | db ah, 53h, 1h ; USAGE (Bass Decrement)
107 | db ah, 54h, 1h ; USAGE (Treble Increment)
108 | db ah, 55h, 1h ; USAGE (Treble Decrement)
109 | db ah, 83h, 1h ; USAGE (AL Consumer Control Configuration)
110 | db ah, 8ah, 1h ; USAGE (AL Email Reader)
111 | db ah, 92h, 1h ; USAGE (AL Calculator)
112 | db ah, 94h, 1h ; USAGE (AL Local Machine Browser)
113 | db ah, 21h, 2h ; USAGE (AC Search)
114 | db ah, 23h, 2h ; USAGE (AC Home)
115 | db ah, 24h, 2h ; USAGE (AC Back)
116 | db ah, 25h, 2h ; USAGE (AC Forward)
117 | db ah, 26h, 2h ; USAGE (AC Stop)
118 | db ah, 27h, 2h ; USAGE (AC Refresh)
119 | db ah, 2ah, 2h ; USAGE (AC Bookmarks)
120 | db 15h, 0h ; LOGICAL_MINIMUM (0)
121 | db 25h, 1h ; LOGICAL_MAXIMUM (1)
122 | db 81h, 2h ; INPUT (Data,Var,Abs)
123 | db c0h ; END_COLLECTION
124 | db 6h, 99h, ffh ; USAGE_PAGE (Not Defined)
125 | db ah, 68h, 24h ; USAGE (Undefined)
126 | db a1h, 1h ; COLLECTION (Application)
127 | db 75h, 8h ; REPORT_SIZE (8)
128 | db 15h, 0h ; LOGICAL_MINIMUM (0)
129 | db 26h, ffh, 0h ; LOGICAL_MAXIMUM (255)
130 | db 95h, 40h ; REPORT_COUNT (64)
131 | db 9h, 1h ; USAGE (Undefined)
132 | db 81h, 2h ; INPUT (Data,Var,Abs)
133 | db 95h, 40h ; REPORT_COUNT (64)
134 | db 9h, 2h ; USAGE (Undefined)
135 | db 91h, 2h ; OUTPUT (Data,Var,Abs)
136 | db c0h ; END_COLLECTION
137 |
--------------------------------------------------------------------------------
/SoarerReverse.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 10.00
3 | # Visual Studio 2008
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SoarerReverse", "SoarerReverse.vcproj", "{468D68D6-D8DC-437C-A3BA-1388D081336B}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | AdaFruit|Win32 = AdaFruit|Win32
9 | ProMicro|Win32 = ProMicro|Win32
10 | Teensy20|Win32 = Teensy20|Win32
11 | TeensyPP1|Win32 = TeensyPP1|Win32
12 | TeensyPP2|Win32 = TeensyPP2|Win32
13 | EndGlobalSection
14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
15 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.AdaFruit|Win32.ActiveCfg = AdaFruit|Win32
16 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.AdaFruit|Win32.Build.0 = AdaFruit|Win32
17 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.ProMicro|Win32.ActiveCfg = ProMicro|Win32
18 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.ProMicro|Win32.Build.0 = ProMicro|Win32
19 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.Teensy20|Win32.ActiveCfg = Teensy20|Win32
20 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.Teensy20|Win32.Build.0 = Teensy20|Win32
21 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.TeensyPP1|Win32.ActiveCfg = TeensyPP1|Win32
22 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.TeensyPP1|Win32.Build.0 = TeensyPP1|Win32
23 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.TeensyPP2|Win32.ActiveCfg = TeensyPP2|Win32
24 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.TeensyPP2|Win32.Build.0 = TeensyPP2|Win32
25 | EndGlobalSection
26 | GlobalSection(SolutionProperties) = preSolution
27 | HideSolutionNode = FALSE
28 | EndGlobalSection
29 | EndGlobal
30 |
--------------------------------------------------------------------------------
/SoarerReverse.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
25 |
38 |
39 |
45 |
58 |
59 |
65 |
78 |
79 |
85 |
98 |
99 |
105 |
118 |
119 |
120 |
121 |
122 |
123 |
128 |
131 |
132 |
135 |
136 |
139 |
140 |
143 |
144 |
147 |
148 |
149 |
154 |
157 |
158 |
161 |
162 |
165 |
166 |
169 |
170 |
173 |
174 |
177 |
178 |
181 |
182 |
185 |
186 |
187 |
192 |
193 |
196 |
199 |
200 |
203 |
204 |
207 |
208 |
211 |
212 |
213 |
216 |
219 |
220 |
223 |
224 |
227 |
228 |
231 |
232 |
235 |
236 |
239 |
240 |
243 |
244 |
247 |
248 |
251 |
252 |
253 |
256 |
257 |
260 |
261 |
262 |
263 |
264 |
265 |
--------------------------------------------------------------------------------
/Soarer_at2usb_v1.12_atmega32u4.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antonizoon/arakulas-soarers-converter/c32c5c882ea487889656bd893bdec62f70c7d2ee/Soarer_at2usb_v1.12_atmega32u4.bin
--------------------------------------------------------------------------------
/hwdefs.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************/
2 | /* hwdefs.h : hardware definitions for the known HW configurations */
3 | /*****************************************************************************/
4 |
5 | #ifndef __hwdefs_h__
6 | #define __hwdefs_h__
7 |
8 | /*
9 | Currently supported configurations:
10 |
11 | LAYOUT_TEENSY_2
12 | ===============
13 | Teensy 2.0
14 | ATmega32U4
15 | Onboard LED PD6, Active High
16 | PS/2 Data PD0
17 | PS/2 Clock PD1
18 | PS/2 Reset PB7
19 | Caps Lock LED PF5
20 | Num Lock LED PF6
21 | Scroll Lock LED PF7
22 | Aux Key 1..5 PB0..PB4
23 |
24 | LAYOUT_PRO_MICRO
25 | ================
26 | Pro Micro
27 | ATmega32U4
28 | Onboard LED PD5, Active Low
29 | PS/2 Data PD0 (Pin 3)
30 | PS/2 Clock PD1 (Pin 2)
31 | PS/2 Reset PB6 (Pin 10)
32 | Caps Lock LED PF5 (Pin A2)
33 | Num Lock LED PF6 (Pin A1)
34 | Scroll Lock LED PF7 (Pin A0)
35 | Aux Key 1..5 PB1..PB5 (Pins labeled 15,16,14,8,9)
36 |
37 | LAYOUT_ADAFRUIT
38 | ===============
39 | AdaFruit Breakout Board
40 | ATmega32U4
41 | Onboard LED PE6, Active High
42 | PS/2 Data PD0
43 | PS/2 Clock PD1
44 | PS/2 Reset PB7
45 | Caps Lock LED PF5
46 | Num Lock LED PF6
47 | Scroll Lock LED PF7
48 | Aux Key 1..5 PB0..PB4
49 |
50 | LAYOUT_TEENSYPP_1
51 | =================
52 | Teensy++ 1.0
53 | AT90USB646
54 | Onboard LED PD6, Active Low
55 | PS/2 Data PD0
56 | PS/2 Clock PD1
57 | PS/2 Reset PB7
58 | Caps Lock LED PD3
59 | Num Lock LED PD4
60 | Scroll Lock LED PD5
61 | Aux Key 1..5 PB0..PB4
62 |
63 | LAYOUT_TEENSYPP_2
64 | =================
65 | Teensy++ 2.0
66 | AT90USB1286
67 | Onboard LED PD6, Active High
68 | PS/2 Data PD0
69 | PS/2 Clock PD1
70 | PS/2 Reset PB7
71 | Caps Lock LED PD3
72 | Num Lock LED PD4
73 | Scroll Lock LED PD5
74 | Aux Key 1..5 PB0..PB4
75 |
76 | LAYOUT_16U4
77 | ===========
78 | Unknown
79 | ATMega16U4
80 | Currently exactly like LAYOUT_TEENSY_2 (just less Flash etc.)
81 |
82 | */
83 |
84 | // LAYOUT_xxx may be passed in, but is overridden if it doesn't match the CPU
85 | // __AVR_ATmega16U4__ is always LAYOUT_16U4
86 | #if defined(LAYOUT_16U4)
87 | #undef LAYOUT_16U4
88 | #endif
89 | #define LAYOUT_16U4 !!defined(__AVR_ATmega16U4__)
90 |
91 | // __AVR_ATmega32U4__ may be Teensy 2.0 or Pro Micro
92 | #if !defined(__AVR_ATmega32U4__)
93 | #if defined(LAYOUT_PRO_MICRO)
94 | #undef LAYOUT_PRO_MICRO
95 | #endif
96 | #define LAYOUT_PRO_MICRO 0
97 | #if defined(LAYOUT_TEENSY_2)
98 | #undef LAYOUT_TEENSY_2
99 | #endif
100 | #define LAYOUT_TEENSY_2 0
101 | #if defined(LAYOUT_ADAFRUIT)
102 | #undef LAYOUT_ADAFRUIT
103 | #endif
104 | #define LAYOUT_ADAFRUIT 0
105 | #else
106 | // ATmega32U4 can be Teensy 2.0, Adafruit breakout board or Pro Micro; default to Teensy 2.0
107 | #if !defined(LAYOUT_PRO_MICRO)
108 | #define LAYOUT_PRO_MICRO 0
109 | #endif
110 | #if !defined(LAYOUT_ADAFRUIT)
111 | #define LAYOUT_ADAFRUIT 0
112 | #endif
113 | #if !defined(LAYOUT_TEENSY_2)
114 | #define LAYOUT_TEENSY_2 !(LAYOUT_PRO_MICRO | LAYOUT_ADAFRUIT)
115 | #endif
116 | // If both Pro Micro and Adafruit are passed in, use Pro Micro (debatable)
117 | #if LAYOUT_PRO_MICRO && LAYOUT_ADAFRUIT
118 | #undef LAYOUT_ADAFRUIT
119 | #define LAYOUT_ADAFRUIT 0
120 | #endif
121 | // If both Pro Micro/Adafruit and Teensy 2.0 are passed in,
122 | // use Pro Micro/Adafruit (more specialized)
123 | #if (LAYOUT_PRO_MICRO|LAYOUT_ADAFRUIT) && LAYOUT_TEENSY_2
124 | #undef LAYOUT_TEENSY_2
125 | #define LAYOUT_TEENSY_2 0
126 | #endif
127 | #endif
128 |
129 | // AT90USB646 is always treated as Teensy++ 1.0
130 | #if defined(LAYOUT_TEENSYPP_1)
131 | #undef LAYOUT_TEENSYPP_1
132 | #endif
133 | #define LAYOUT_TEENSYPP_1 !!defined(__AVR_AT90USB646__)
134 |
135 | // __AVR_AT90USB1286__ is always treated as Teensy++ 2.0
136 | #if defined(LAYOUT_TEENSYPP_2)
137 | #undef LAYOUT_TEENSYPP_2
138 | #endif
139 | #define LAYOUT_TEENSYPP_2 !!defined(__AVR_AT90USB1286__)
140 |
141 | // LAYOUT_16U4 is the same as LAYOUT_TEENSY_2 for the moment
142 | #if LAYOUT_16U4
143 | #undef LAYOUT_TEENSY_2
144 | #undef LAYOUT_16U4
145 | #define LAYOUT_TEENSY_2 1
146 | #endif
147 |
148 | #if LAYOUT_TEENSY_2
149 | /*****************************************************************************/
150 | /* Teensy 2.0 Layout */
151 | /*****************************************************************************/
152 | // #pragma message("Compiling for Teensy 2.0")
153 |
154 | #define OBLED_CONFIG ( DDRD |= (1<> PIND0) & 1 )
161 | #define KBDC_HIGH ( DDRD &= ~(1 << DDD1) , PORTD |= (1 << PORTD1) )
162 | // maybe wrong order?
163 | #define KBDC_LOW ( DDRD |= (1 << DDD1) , PORTD &= ~(1 << PORTD1) )
164 | #define KBDC_GET0 ( (PIND >> PIND1) & 1 )
165 | #define KBDC_GET ( PIND & (1 << PIND1) )
166 | #define KBDR_HIGH ( DDRB &= ~(1 << DDB7) , PORTB |= (1 << PORTB7) )
167 | #define KBDR_LOW ( PORTB &= ~(1 << PORTB7) , DDRB |= (1 << DDB7) )
168 |
169 | #define LLED_BITMASKD ( (1<> PIND0) & 1 )
197 | #define KBDC_HIGH ( DDRD &= ~(1 << DDD1) , PORTD |= (1 << PORTD1) )
198 | // maybe wrong order?
199 | #define KBDC_LOW ( DDRD |= (1 << DDD1) , PORTD &= ~(1 << PORTD1) )
200 | #define KBDC_GET0 ( (PIND >> PIND1) & 1 )
201 | #define KBDC_GET ( PIND & (1 << PIND1) )
202 | #define KBDR_HIGH ( DDRB &= ~(1 << DDB6) , PORTB |= (1 << PORTB6) )
203 | #define KBDR_LOW ( PORTB &= ~(1 << PORTB6) , DDRB |= (1 << DDB6) )
204 |
205 | #define LLED_BITMASKD ( (1<> 1 )
214 |
215 | #elif LAYOUT_ADAFRUIT
216 | /*****************************************************************************/
217 | /* Adafruit Breakout Board Layout */
218 | /*****************************************************************************/
219 | // #pragma message("Compiling for AdaFruit")
220 |
221 | #define OBLED_CONFIG ( DDRE |= (1<> PIND0) & 1 )
228 | #define KBDC_HIGH ( DDRD &= ~(1 << DDD1) , PORTD |= (1 << PORTD1) )
229 | // maybe wrong order?
230 | #define KBDC_LOW ( DDRD |= (1 << DDD1) , PORTD &= ~(1 << PORTD1) )
231 | #define KBDC_GET0 ( (PIND >> PIND1) & 1 )
232 | #define KBDC_GET ( PIND & (1 << PIND1) )
233 | #define KBDR_HIGH ( DDRB &= ~(1 << DDB7) , PORTB |= (1 << PORTB7) )
234 | #define KBDR_LOW ( PORTB &= ~(1 << PORTB7) , DDRB |= (1 << DDB7) )
235 |
236 | #define LLED_BITMASKD ( (1<> PIND0) & 1 )
259 | #define KBDC_HIGH ( DDRD &= ~(1 << DDD1) , PORTD |= (1 << PORTD1) )
260 | // maybe wrong order?
261 | #define KBDC_LOW ( DDRD |= (1 << DDD1) , PORTD &= ~(1 << PORTD1) )
262 | #define KBDC_GET0 ( (PIND >> PIND1) & 1 )
263 | #define KBDC_GET ( PIND & (1 << PIND1) )
264 | #define KBDR_HIGH ( DDRB &= ~(1 << DDB7) , PORTB |= (1 << PORTB7) )
265 | #define KBDR_LOW ( PORTB &= ~(1 << PORTB7) , DDRB |= (1 << DDB7) )
266 |
267 | #define LLED_BITMASKD ( (1<> PIND0) & 1 )
290 | #define KBDC_HIGH ( DDRD &= ~(1 << DDD1) , PORTD |= (1 << PORTD1) )
291 | // maybe wrong order?
292 | #define KBDC_LOW ( DDRD |= (1 << DDD1) , PORTD &= ~(1 << PORTD1) )
293 | #define KBDC_GET0 ( (PIND >> PIND1) & 1 )
294 | #define KBDC_GET ( PIND & (1 << PIND1) )
295 | #define KBDR_HIGH ( DDRB &= ~(1 << DDB7) , PORTB |= (1 << PORTB7) )
296 | #define KBDR_LOW ( PORTB &= ~(1 << PORTB7) , DDRB |= (1 << DDB7) )
297 |
298 | #define LLED_BITMASKD ( (1<> 8) & 255)
317 |
318 | // CPU Prescale
319 | #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
320 |
321 | #define _NOP() do { __asm__ __volatile__ ("nop"); } while (0)
322 |
323 | #endif /* defined(__hwdefs_h__) */
324 |
--------------------------------------------------------------------------------
/intkeys.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************/
2 | /* intkeys.h : internal key code names (modified HID code set 7 AKA HIDX) */
3 | /*****************************************************************************/
4 |
5 | #ifndef _intkeys_h_
6 | #define _intkeys_h_
7 |
8 | // special codes
9 | #define KEY_UNASSIGNED 0x00 // Unassigned
10 | #define KEY_OVERRUN_ERROR 0x01 // Overrun error
11 | #define KEY_POST_FAIL 0x02 // POST Fail
12 | #define KEY_ERROR_UNDEFINED 0x03 // ErrorUndefined
13 | // standard HID codes
14 | #define KEY_A 0x04 // a A
15 | #define KEY_B 0x05 // b B
16 | #define KEY_C 0x06 // c C
17 | #define KEY_D 0x07 // d D
18 | #define KEY_E 0x08 // e E
19 | #define KEY_F 0x09 // f F
20 | #define KEY_G 0x0A // g G
21 | #define KEY_H 0x0B // h H
22 | #define KEY_I 0x0C // i I
23 | #define KEY_J 0x0D // j J
24 | #define KEY_K 0x0E // k K
25 | #define KEY_L 0x0F // l L
26 | #define KEY_M 0x10 // m M
27 | #define KEY_N 0x11 // n N
28 | #define KEY_O 0x12 // o O
29 | #define KEY_P 0x13 // p P
30 | #define KEY_Q 0x14 // q Q
31 | #define KEY_R 0x15 // r R
32 | #define KEY_S 0x16 // s S
33 | #define KEY_T 0x17 // t T
34 | #define KEY_U 0x18 // u U
35 | #define KEY_V 0x19 // v V
36 | #define KEY_W 0x1A // w W
37 | #define KEY_X 0x1B // x X
38 | #define KEY_Y 0x1C // y Y
39 | #define KEY_Z 0x1D // z Z
40 | #define KEY_1 0x1E // 1 !
41 | #define KEY_2 0x1F // 2 @
42 | #define KEY_3 0x20 // 3 #
43 | #define KEY_4 0x21 // 4 $
44 | #define KEY_5 0x22 // 5 %
45 | #define KEY_6 0x23 // 6 ^
46 | #define KEY_7 0x24 // 7 &
47 | #define KEY_8 0x25 // 8 *
48 | #define KEY_9 0x26 // 9 (
49 | #define KEY_0 0x27 // 0 )
50 | #define KEY_ENTER 0x28 // Return
51 | #define KEY_ESC 0x29 // Escape
52 | #define KEY_BACKSPACE 0x2A // Backspace
53 | #define KEY_TAB 0x2B // Tab
54 | #define KEY_SPACE 0x2C // Space
55 | #define KEY_MINUS 0x2D // - _
56 | #define KEY_EQUAL 0x2E // = +
57 | #define KEY_LEFT_BRACE 0x2F // [ {
58 | #define KEY_RIGHT_BRACE 0x30 // ] }
59 | #define KEY_BACKSLASH 0x31 // \ |
60 | #define KEY_EUROPE_1 0x32 // Europe 1 (use BACKSLASH instead)
61 | #define KEY_SEMICOLON 0x33 // ; :
62 | #define KEY_QUOTE 0x34 // ' "
63 | #define KEY_BACK_QUOTE 0x35 // ` ~
64 | #define KEY_COMMA 0x36 // , <
65 | #define KEY_PERIOD 0x37 // . >
66 | #define KEY_SLASH 0x38 // / ?
67 | #define KEY_CAPS_LOCK 0x39 // Caps Lock
68 | #define KEY_F1 0x3A // F1
69 | #define KEY_F2 0x3B // F2
70 | #define KEY_F3 0x3C // F3
71 | #define KEY_F4 0x3D // F4
72 | #define KEY_F5 0x3E // F5
73 | #define KEY_F6 0x3F // F6
74 | #define KEY_F7 0x40 // F7
75 | #define KEY_F8 0x41 // F8
76 | #define KEY_F9 0x42 // F9
77 | #define KEY_F10 0x43 // F10
78 | #define KEY_F11 0x44 // F11
79 | #define KEY_F12 0x45 // F12
80 | #define KEY_PRINTSCREEN 0x46 // Print Screen
81 | #define KEY_SCROLL_LOCK 0x47 // Scroll Lock
82 | #define KEY_PAUSE 0x48 // Pause
83 | #define KEY_INSERT 0x49 // Insert
84 | #define KEY_HOME 0x4A // Home
85 | #define KEY_PAGE_UP 0x4B // Page Up
86 | #define KEY_DELETE 0x4C // Delete
87 | #define KEY_END 0x4D // End
88 | #define KEY_PAGE_DOWN 0x4E // Page Down
89 | #define KEY_RIGHT 0x4F // Right Arrow
90 | #define KEY_LEFT 0x50 // Left Arrow
91 | #define KEY_DOWN 0x51 // Down Arrow
92 | #define KEY_UP 0x52 // Up Arrow
93 | #define KEY_NUM_LOCK 0x53 // Num Lock
94 | #define KEY_PAD_SLASH 0x54 // Keypad /
95 | #define KEY_PAD_ASTERIX 0x55 // Keypad *
96 | #define KEY_PAD_MINUS 0x56 // Keypad -
97 | #define KEY_PAD_PLUS 0x57 // Keypad +
98 | #define KEY_PAD_ENTER 0x58 // Keypad Enter
99 | #define KEY_PAD_1 0x59 // Keypad 1 End
100 | #define KEY_PAD_2 0x5A // Keypad 2 Down
101 | #define KEY_PAD_3 0x5B // Keypad 3 PageDn
102 | #define KEY_PAD_4 0x5C // Keypad 4 Left
103 | #define KEY_PAD_5 0x5D // Keypad 5
104 | #define KEY_PAD_6 0x5E // Keypad 6 Right
105 | #define KEY_PAD_7 0x5F // Keypad 7 Home
106 | #define KEY_PAD_8 0x60 // Keypad 8 Up
107 | #define KEY_PAD_9 0x61 // Keypad 9 PageUp
108 | #define KEY_PAD_0 0x62 // Keypad 0 Insert
109 | #define KEY_PAD_PERIOD 0x63 // Keypad . Delete
110 | #define KEY_EUROPE_2 0x64 // Europe 2
111 | #define KEY_APP 0x65 // App (Windows Menu)
112 | #define KEY_POWER 0x66 // Keyboard Power
113 | #define KEY_PAD_EQUALS 0x67 // Keypad =
114 | #define KEY_F13 0x68 // F13
115 | #define KEY_F14 0x69 // F14
116 | #define KEY_F15 0x6A // F15
117 | #define KEY_F16 0x6B // F16
118 | #define KEY_F17 0x6C // F17
119 | #define KEY_F18 0x6D // F18
120 | #define KEY_F19 0x6E // F19
121 | #define KEY_F20 0x6F // F20
122 | #define KEY_F21 0x70 // F21
123 | #define KEY_F22 0x71 // F22
124 | #define KEY_F23 0x72 // F23
125 | #define KEY_F24 0x73 // F24
126 | #define KEY_EXECUTE 0x74 // Keyboard Execute
127 | #define KEY_HELP 0x75 // Keyboard Help
128 | #define KEY_MENU 0x76 // Keyboard Menu
129 | #define KEY_SELECT 0x77 // Keyboard Select
130 | #define KEY_STOP 0x78 // Keyboard Stop
131 | #define KEY_AGAIN 0x79 // Keyboard Again
132 | #define KEY_UNDO 0x7A // Keyboard Undo
133 | #define KEY_CUT 0x7B // Keyboard Cut
134 | #define KEY_COPY 0x7C // Keyboard Copy
135 | #define KEY_PASTE 0x7D // Keyboard Paste
136 | #define KEY_FIND 0x7E // Keyboard Find
137 | #define KEY_MUTE 0x7F // Keyboard Mute
138 | #define KEY_VOLUME_UP 0x80 // Keyboard Volume Up
139 | #define KEY_VOLUME_DOWN 0x81 // Keyboard Volume Dn
140 | #define KEY_LOCKING_CAPS_LOCK 0x82 // Keyboard Locking Caps Lock
141 | #define KEY_LOCKING_NUM_LOCK 0x83 // Keyboard Locking Num Lock
142 | #define KEY_LOCKING_SCROLL_LOCK 0x84 // Keyboard Locking Scroll Lock
143 | #define KEY_PAD_COMMA 0x85 // Keypad comma (Brazilian Keypad .)
144 | #define KEY_EQUAL_SIGN 0x86 // Keyboard Equal Sign
145 | #define KEY_INTERNATIONAL_1 0x87 // Keyboard Int'l 1 (Ro)
146 | #define KEY_INTERNATIONAL_2 0x88 // Keyboard Intl'2 (Katakana/Hiragana)
147 | #define KEY_INTERNATIONAL_3 0x89 // Keyboard Int'l 2 (Yen)
148 | #define KEY_INTERNATIONAL_4 0x8A // Keyboard Int'l 4 (Henkan)
149 | #define KEY_INTERNATIONAL_5 0x8B // Keyboard Int'l 5 (Muhenkan)
150 | #define KEY_INTERNATIONAL_6 0x8C // Keyboard Int'l 6 (PC9800 Keypad comma)
151 | #define KEY_INTERNATIONAL_7 0x8D // Keyboard Int'l 7
152 | #define KEY_INTERNATIONAL_8 0x8E // Keyboard Int'l 8
153 | #define KEY_INTERNATIONAL_9 0x8F // Keyboard Int'l 9
154 | #define KEY_LANG_1 0x90 // Keyboard Lang 1 (Hangul/English)
155 | #define KEY_LANG_2 0x91 // Keyboard Lang 2 (Hanja)
156 | #define KEY_LANG_3 0x92 // Keyboard Lang 3 (Katakana)
157 | #define KEY_LANG_4 0x93 // Keyboard Lang 4 (Hiragana)
158 | #define KEY_LANG_5 0x94 // Keyboard Lang 5 (Zenkaku/Hankaku)
159 | #define KEY_LANG_6 0x95 // Keyboard Lang 6
160 | #define KEY_LANG_7 0x96 // Keyboard Lang 7
161 | #define KEY_LANG_8 0x97 // Keyboard Lang 8
162 | #define KEY_LANG_9 0x98 // Keyboard Lang 9
163 | #define KEY_ALTERNATE_ERASE 0x99 // Keyboard Alternate Erase
164 | #define KEY_SYSREQ_ATTN 0x9A // Keyboard SysReq/Attention
165 | #define KEY_CANCEL 0x9B // Keyboard Cancel
166 | #define KEY_CLEAR 0x9C // Keyboard Clear (use DELETE instead)
167 | #define KEY_PRIOR 0x9D // Keyboard Prior
168 | #define KEY_RETURN 0x9E // Keyboard Return
169 | #define KEY_SEPARATOR 0x9F // Keyboard Separator
170 | #define KEY_OUT 0xA0 // Keyboard Out
171 | #define KEY_OPER 0xA1 // Keyboard Oper
172 | #define KEY_CLEAR_AGAIN 0xA2 // Keyboard Clear/Again
173 | #define KEY_CRSEL_PROPS 0xA3 // Keyboard CrSel/Props
174 | #define KEY_EXSEL 0xA4 // Keyboard ExSel
175 | // A5-A7 are invalid
176 | // Power code area
177 | #define KEY_SYSTEM_POWER 0xA8 // System Power
178 | #define KEY_SYSTEM_SLEEP 0xA9 // System Sleep
179 | #define KEY_SYSTEM_WAKE 0xAA // System Wake
180 | // Internal use area - must be remapped to appear on USB out
181 | #define KEY_AUX1 0xAB // Auxiliary key 1
182 | #define KEY_AUX2 0xAC // Auxiliary key 2
183 | #define KEY_AUX3 0xAD // Auxiliary key 3
184 | #define KEY_AUX4 0xAE // Auxiliary key 4
185 | #define KEY_AUX5 0xAF // Auxiliary key 5
186 | #define KEY_FAKE_01 0xB0 // legacy from earlier version?
187 | #define KEY_EXTRA_LALT 0xB1 // AT-F extra pad lhs of space
188 | #define KEY_EXTRA_PAD_PLUS 0xB2 // Term extra pad bottom of keypad +
189 | #define KEY_EXTRA_RALT 0xB3 // AT-F extra pad rhs of space
190 | #define KEY_EXTRA_EUROPE_2 0xB4 // AT-F extra pad lhs of enter
191 | #define KEY_EXTRA_BACKSLASH 0xB5 // AT-F extra pad top of enter
192 | #define KEY_EXTRA_INSERT 0xB6 // AT-F extra pad lhs of Insert
193 | #define KEY_EXTRA_F1 0xB7 // 122-key Terminal lhs F1
194 | #define KEY_EXTRA_F2 0xB8 // 122-key Terminal lhs F2
195 | #define KEY_EXTRA_F3 0xB9 // 122-key Terminal lhs F3
196 | #define KEY_EXTRA_F4 0xBA // 122-key Terminal lhs F4
197 | #define KEY_EXTRA_F5 0xBB // 122-key Terminal lhs F5
198 | #define KEY_EXTRA_F6 0xBC // 122-key Terminal lhs F6
199 | #define KEY_EXTRA_F7 0xBD // 122-key Terminal lhs F7
200 | #define KEY_EXTRA_F8 0xBE // 122-key Terminal lhs F8
201 | #define KEY_EXTRA_F9 0xBF // 122-key Terminal lhs F9
202 | #define KEY_EXTRA_F10 0xC0 // 122-key Terminal lhs F10
203 | #define KEY_FAKE_18 0xC1 // legacy from earlier version?
204 | #define KEY_EXTRA_SYSRQ 0xC2 // Sys Req (AT 84-key)
205 | // C3-CF unused
206 | #define KEY_FN1 0xD0 // Function layer key 1
207 | #define KEY_FN2 0xD1 // Function layer key 2
208 | #define KEY_FN3 0xD2 // Function layer key 3
209 | #define KEY_FN4 0xD3 // Function layer key 4
210 | #define KEY_FN5 0xD4 // Function layer key 5
211 | #define KEY_FN6 0xD5 // Function layer key 6
212 | #define KEY_FN7 0xD6 // Function layer key 7
213 | #define KEY_FN8 0xD7 // Function layer key 8
214 | #define KEY_SELECT_0 0xD8 // Select reset
215 | #define KEY_SELECT_1 0xD9 // Select 1 toggle
216 | #define KEY_SELECT_2 0xDA // Select 2 toggle
217 | #define KEY_SELECT_3 0xDB // Select 3 toggle
218 | #define KEY_SELECT_4 0xDC // Select 4 toggle
219 | #define KEY_SELECT_5 0xDD // Select 5 toggle
220 | #define KEY_SELECT_6 0xDE // Select 6 toggle
221 | #define KEY_SELECT_7 0xDF // Select 7 toggle
222 | // Modifier area
223 | #define KEY_LCTRL 0xE0 // Left Control
224 | #define KEY_LSHIFT 0xE1 // Left Shift
225 | #define KEY_LALT 0xE2 // Left Alt
226 | #define KEY_LGUI 0xE3 // Left GUI (Left Windows)
227 | #define KEY_RCTRL 0xE4 // Right Control
228 | #define KEY_RSHIFT 0xE5 // Right Shift
229 | #define KEY_RALT 0xE6 // Right Alt
230 | #define KEY_RGUI 0xE7 // Right GUI (Right Windows)
231 | // Multimedia area
232 | #define KEY_MEDIA_NEXT_TRACK 0xE8 // Scan Next Track
233 | #define KEY_MEDIA_PREV_TRACK 0xE9 // Scan Previous Track
234 | #define KEY_MEDIA_STOP 0xEA // Stop
235 | #define KEY_MEDIA_PLAY_PAUSE 0xEB // Play/ Pause
236 | #define KEY_MEDIA_MUTE 0xEC // Mute
237 | #define KEY_MEDIA_BASS_BOOST 0xED // Bass Boost
238 | #define KEY_MEDIA_LOUDNESS 0xEE // Loudness
239 | #define KEY_MEDIA_VOLUME_UP 0xEF // Volume Up
240 | #define KEY_MEDIA_VOLUME_DOWN 0xF0 // Volume Down
241 | #define KEY_MEDIA_BASS_UP 0xF1 // Bass Up
242 | #define KEY_MEDIA_BASS_DOWN 0xF2 // Bass Down
243 | #define KEY_MEDIA_TREBLE_UP 0xF3 // Treble Up
244 | #define KEY_MEDIA_TREBLE_DOWN 0xF4 // Treble Down
245 | #define KEY_MEDIA_MEDIA_SELECT 0xF5 // Media Select
246 | #define KEY_MEDIA_MAIL 0xF6 // Mail
247 | #define KEY_MEDIA_CALCULATOR 0xF7 // Calculator
248 | #define KEY_MEDIA_MY_COMPUTER 0xF8 // My Computer
249 | #define KEY_MEDIA_WWW_SEARCH 0xF9 // WWW Search
250 | #define KEY_MEDIA_WWW_HOME 0xFA // WWW Home
251 | #define KEY_MEDIA_WWW_BACK 0xFB // WWW Back
252 | #define KEY_MEDIA_WWW_FORWARD 0xFC // WWW Forward
253 | #define KEY_MEDIA_WWW_STOP 0xFD // WWW Stop
254 | #define KEY_MEDIA_WWW_REFRESH 0xFE // WWW Refresh
255 | #define KEY_MEDIA_WWW_FAVORITES 0xFF // WWW Favorites
256 |
257 | // Masks for the special areas
258 | #define KEY_AREA_MASK 0xF8
259 | #define IS_FN_KEY(keyid) (((keyid) & KEY_AREA_MASK) == KEY_FN1)
260 | #define IS_SELECT_KEY(keyid) (((keyid) & KEY_AREA_MASK) == KEY_SELECT_0)
261 | #define IS_MODIFIER_KEY(keyid) (((keyid) & KEY_AREA_MASK) == KEY_LCTRL)
262 |
263 | #endif /* defined _intkeys_h */
264 |
--------------------------------------------------------------------------------
/kbdtbls.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************/
2 | /* kbdtbls.h : keyboard scan code to USB HID scan code translation tables */
3 | /*****************************************************************************/
4 |
5 | #include "intkeys.h"
6 |
7 | /*****************************************************************************/
8 | /* Messages coming in from the keyboard */
9 | /*****************************************************************************/
10 |
11 | #define KBDM_BUFOVR 0x00 // Key detection error or buffer overrun
12 | #define KBDM_BATOK 0xaa // BAT returned OK
13 | #define KBDM_EXTENDED 0xe0 // Extended Key is coming in
14 | #define KBDM_EXTENDED2 0xe1 // Extended Key 2 (Pause) is coming in
15 | #define KBDM_ECHO 0xee // Response to ECHO command
16 | #define KBDM_BREAK 0xf0 // Break code coming in (if missing, it's a Make)
17 | #define KBDM_ACK 0xfa // Acknowledgement for a command from the host
18 | #define KBDM_ERR 0xfc // (BAT) Error
19 | #define KBDM_ERR2 0xfd // BAT Selftest Failed RC2
20 | #define KBDM_RESEND 0xfe // Keyboard requests resend
21 | #define KBDM_BUFOVR2 0xff // Key detection error or buffer overrun
22 |
23 | /*****************************************************************************/
24 | /* Commands sent to AT/PS2 keyboards */
25 | /*****************************************************************************/
26 |
27 | #define ATCMD_RESET 0xff // reset request; ACK + BATOK after some time is expected
28 | #define ATCMD_RESEND 0xfe // resend request
29 | // The following 6 are only required to work in Scan code set 3:
30 | #define ATCMD_SETMK 0xfd // Set Key Type "Make"
31 | #define ATCMD_SETMKBK 0xfc // Set Key Type "Make/Break" (i.e., no repeat)
32 | #define ATCMD_SETTYPEM 0xfb // Set Key Type "Typematic"
33 | // The above 3 are followed by list of scan codes and an unused scan code to end the list;
34 | // the keyboard is expected to answer with KBDM_ACK to each
35 | #define ATCMD_SETASTD 0xfa // Set All Keys back to their default type
36 | #define ATCMD_SETAMK 0xf9 // Set All Keys Type "Make"
37 | #define ATCMD_SETAMKBK 0xf8 // Set All Keys Type "Make/Break"
38 | #define ATCMD_SETATYPEM 0xf7 // Set All Keys Type "Typematic"
39 | #define ATCMD_SETDEFAULT 0xf6 // Reset Keyboard to Default State
40 | #define ATCMD_DISABLE 0xf5 // Reset Keyboard to Default State and Disable scanning
41 | #define ATCMD_ENABLE 0xf4 // (Re-)Enable Scanning after it has been disabled
42 | #define ATCMD_SETRATE 0xf3 // Set Typematic rate/delay
43 | #define ATCMD_READID 0xf2 // Keyboard is expected to respond with its 2-byte ID (ACK before 1st byte)
44 | #define ATCMD_SCANSET 0xf0 // Set Scancode Set (<- ACK/Err -> [new set(1|2|3) <- ACK/Err | 0 <- ACK+current|Err])
45 | #define ATCMD_ECHO 0xee // Send Echo (<- ECHO)
46 | #define ATCMD_SETLEDS 0xed // Set LED State (<- ACK -> Caps:2+Num:1+Scroll:0 <- ACK)
47 |
48 | /*****************************************************************************/
49 | /* Known keyboard IDs */
50 | /*****************************************************************************/
51 | // gleaned from http://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html
52 | #define KBDID_AT 0xab83 // IBM AT
53 | #define KBDID_SKBD 0xab84 // Short Keyboard: IBM Space Saver, Thinkpad etc.
54 | #define KBDID_HCON 0xab85 // 122-key host-connected keyboard
55 | #define KBDID_122 0xab86 // PS/2-compatible 122-key keyboards
56 | #define KBDID_JAPG 0xab90 // "old Japanese 'G' keyboard"
57 | #define KBDID_JAPP 0xab91 // "old Japanese 'P' keyboard"
58 | #define KBDID_JAPA 0xab92 // "old Japanese 'A' keyboard"
59 | #define KBDID_IBM_RT 0xbfb0 // IBM RT PC keyboard (with "special" LED command)
60 | #define KBDID_TERM122 0xbfbf // 122-key IBM 1390876 without jumpers (can be reconfigured!)
61 |
62 |
63 | /*---------------------------------------------------------------------------*/
64 | /* The rest is only relevant for the keyboard input handler */
65 | /*---------------------------------------------------------------------------*/
66 |
67 | #ifdef INCLUDE_KBD_TRANS_TABLES
68 | /*****************************************************************************/
69 | /* keyboard codeset 1 -> HIDX translation table */
70 | /*****************************************************************************/
71 | // A_00ac
72 | uint8_t PROGMEM kbd_ttbl_set1[0x80] =
73 | {
74 | KEY_UNASSIGNED, KEY_ESC, KEY_1, KEY_2, // 00..03
75 | KEY_3, KEY_4, KEY_5, KEY_6, // 04..07
76 | KEY_7, KEY_8, KEY_9, KEY_0, // 08..0B
77 | KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_TAB, // 0C..0F
78 | KEY_Q, KEY_W, KEY_E, KEY_R, // 10..13
79 | KEY_T, KEY_Y, KEY_U, KEY_I, // 14..17
80 | KEY_O, KEY_P, KEY_LEFT_BRACE, KEY_RIGHT_BRACE, // 18..1B
81 | KEY_ENTER, KEY_LCTRL, KEY_A, KEY_S, // 1C..1F
82 | KEY_D, KEY_F, KEY_G, KEY_H, // 20..23
83 | KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, // 24..27
84 | KEY_QUOTE, KEY_BACK_QUOTE, KEY_LSHIFT, KEY_BACKSLASH, // 28..2b
85 | KEY_Z, KEY_X, KEY_C, KEY_V, // 2c..2f
86 | KEY_B, KEY_N, KEY_M, KEY_COMMA, // 30..33
87 | KEY_PERIOD, KEY_SLASH, KEY_RSHIFT, KEY_PAD_ASTERIX, // 34..37
88 | KEY_LALT, KEY_SPACE, KEY_CAPS_LOCK, KEY_F1, // 38..3B
89 | KEY_F2, KEY_F3, KEY_F4, KEY_F5, // 3C..3F
90 | KEY_F6, KEY_F7, KEY_F8, KEY_F9, // 40..43
91 | KEY_F10, KEY_NUM_LOCK, KEY_SCROLL_LOCK, KEY_PAD_7, // 44..47
92 | KEY_PAD_8, KEY_PAD_9, KEY_PAD_MINUS, KEY_PAD_4, // 48..4B
93 | KEY_PAD_5, KEY_PAD_6, KEY_PAD_PLUS, KEY_PAD_1, // 4C..4F
94 | KEY_PAD_2, KEY_PAD_3, KEY_PAD_0, KEY_PAD_PERIOD, // 50..53
95 | KEY_EXTRA_SYSRQ, KEY_EXTRA_F8, KEY_EUROPE_2, KEY_F11, // 54..57
96 | KEY_F12, KEY_PAD_EQUALS, KEY_FAKE_01, KEY_EXTRA_PAD_PLUS, // 58..5B
97 | KEY_INTERNATIONAL_6, KEY_EXTRA_F1, KEY_EXTRA_F2, KEY_EXTRA_F3, // 5C..5F
98 | KEY_EXTRA_F4, KEY_EXTRA_F5, KEY_EXTRA_F6, KEY_EXTRA_F7, // 60..63
99 | KEY_F13, KEY_F14, KEY_F15, KEY_F16, // 64..67
100 | KEY_F17, KEY_F18, KEY_F19, KEY_F20, // 68..6B
101 | KEY_F21, KEY_F22, KEY_F23, KEY_FAKE_18, // 6C..6F
102 | KEY_INTERNATIONAL_2, KEY_EXTRA_LALT, KEY_EXTRA_RALT, KEY_INTERNATIONAL_1, // 70..73
103 | KEY_EXTRA_EUROPE_2, KEY_EXTRA_BACKSLASH, KEY_F24, KEY_LANG_4, // 74..77
104 | KEY_LANG_3, KEY_INTERNATIONAL_4, KEY_EXTRA_F9, KEY_INTERNATIONAL_5, // 78..7B
105 | KEY_EXTRA_INSERT, KEY_INTERNATIONAL_3, KEY_PAD_COMMA, KEY_EXTRA_F10 // 7C..7F
106 | };
107 |
108 | /*****************************************************************************/
109 | /* keyboard codeset 2 -> HIDX translation table */
110 | /*****************************************************************************/
111 | // A_012c
112 | uint8_t PROGMEM kbd_ttbl_set2[0x85] =
113 | {
114 | KEY_OVERRUN_ERROR, KEY_F9, KEY_UNASSIGNED, KEY_F5, // 00..03
115 | KEY_F3, KEY_F1, KEY_F2, KEY_F12, // 04..07
116 | KEY_F13, KEY_F10, KEY_F8, KEY_F6, // 08..0B
117 | KEY_F4, KEY_TAB, KEY_BACK_QUOTE, KEY_PAD_EQUALS, // 0C..0F
118 | KEY_F14, KEY_LALT, KEY_LSHIFT, KEY_INTERNATIONAL_2, // 10..13
119 | KEY_LCTRL, KEY_Q, KEY_1, KEY_FAKE_01, // 14..17
120 | KEY_F15, KEY_EXTRA_LALT, KEY_Z, KEY_S, // 18..1B
121 | KEY_A, KEY_W, KEY_2, KEY_EXTRA_PAD_PLUS, // 1C..1F
122 | KEY_F16, KEY_C, KEY_X, KEY_D, // 20..23
123 | KEY_E, KEY_4, KEY_3, KEY_INTERNATIONAL_6, // 24..27
124 | KEY_F17, KEY_SPACE, KEY_V, KEY_F, // 28..2B
125 | KEY_T, KEY_R, KEY_5, KEY_EXTRA_F1, // 2C..2F
126 | KEY_F18, KEY_N, KEY_B, KEY_H, // 30..33
127 | KEY_G, KEY_Y, KEY_6, KEY_EXTRA_F2, // 34..37
128 | KEY_F19, KEY_EXTRA_RALT, KEY_M, KEY_J, // 38..3B
129 | KEY_U, KEY_7, KEY_8, KEY_EXTRA_F3, // 3C..3F
130 | KEY_F20, KEY_COMMA, KEY_K, KEY_I, // 40..43
131 | KEY_O, KEY_0, KEY_9, KEY_EXTRA_F4, // 44..47
132 | KEY_F21, KEY_PERIOD, KEY_SLASH, KEY_L, // 48..4B
133 | KEY_SEMICOLON, KEY_P, KEY_MINUS, KEY_EXTRA_F5, // 4C..4F
134 | KEY_F22, KEY_INTERNATIONAL_1, KEY_QUOTE, KEY_EXTRA_EUROPE_2, // 50..53
135 | KEY_LEFT_BRACE, KEY_EQUAL, KEY_EXTRA_F6, KEY_F23, // 54..57
136 | KEY_CAPS_LOCK, KEY_RSHIFT, KEY_ENTER, KEY_RIGHT_BRACE, // 58..5B
137 | KEY_EXTRA_BACKSLASH, KEY_BACKSLASH, KEY_EXTRA_F7, KEY_F24, // 5C..5F
138 | KEY_EXTRA_F8, KEY_EUROPE_2, KEY_LANG_4, KEY_LANG_3, // 60..63
139 | KEY_INTERNATIONAL_4, KEY_EXTRA_F9, KEY_BACKSPACE, KEY_INTERNATIONAL_5, // 64..67
140 | KEY_EXTRA_INSERT, KEY_PAD_1, KEY_INTERNATIONAL_3, KEY_PAD_4, // 68..6B
141 | KEY_PAD_7, KEY_PAD_COMMA, KEY_EXTRA_F10, KEY_FAKE_18, // 6C..6F
142 | KEY_PAD_0, KEY_PAD_PERIOD, KEY_PAD_2, KEY_PAD_5, // 70..73
143 | KEY_PAD_6, KEY_PAD_8, KEY_ESC, KEY_NUM_LOCK, // 74..77
144 | KEY_F11, KEY_PAD_PLUS, KEY_PAD_3, KEY_PAD_MINUS, // 78..7B
145 | KEY_PAD_ASTERIX, KEY_PAD_9, KEY_SCROLL_LOCK, KEY_UNASSIGNED, // 7C..7F
146 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_F7, // 80..83
147 | KEY_EXTRA_SYSRQ // 84
148 | };
149 |
150 | /*****************************************************************************/
151 | /* keyboard codeset 4 (E0 + scan code) -> HIDX translation table */
152 | /*****************************************************************************/
153 | // A_01b1
154 | uint8_t PROGMEM kbd_ttbl_set2ex[0x7f] =
155 | {
156 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 00..03
157 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 04..07
158 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 08..0B
159 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 0C..0F
160 | KEY_MEDIA_WWW_SEARCH,KEY_RALT, KEY_UNASSIGNED, KEY_UNASSIGNED, // 10..13
161 | KEY_RCTRL, KEY_MEDIA_PREV_TRACK,KEY_UNASSIGNED, KEY_UNASSIGNED, // 14..17
162 | KEY_MEDIA_WWW_FAVORITES, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 18..1B
163 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_LGUI, // 1C..1F
164 | KEY_MEDIA_WWW_REFRESH,KEY_MEDIA_VOLUME_DOWN, KEY_UNASSIGNED, KEY_MEDIA_MUTE, // 20..23
165 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_RGUI, // 24..27
166 | KEY_MEDIA_WWW_STOP, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_MEDIA_CALCULATOR, // 28..2B
167 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_APP, // 2C..2F
168 | KEY_MEDIA_WWW_FORWARD, KEY_UNASSIGNED, KEY_MEDIA_VOLUME_UP, KEY_UNASSIGNED, // 30..33
169 | KEY_MEDIA_PLAY_PAUSE,KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_POWER, // 34..37
170 | KEY_MEDIA_WWW_BACK, KEY_UNASSIGNED, KEY_MEDIA_WWW_HOME, KEY_MEDIA_STOP, // 38..3B
171 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_SYSTEM_SLEEP, // 3C..3F
172 | KEY_MEDIA_MY_COMPUTER, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 40..43
173 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 44..47
174 | KEY_MEDIA_MAIL, KEY_UNASSIGNED, KEY_PAD_SLASH, KEY_UNASSIGNED, // 48..4B
175 | KEY_UNASSIGNED, KEY_MEDIA_NEXT_TRACK, KEY_UNASSIGNED, KEY_UNASSIGNED, // 4C..4F
176 | KEY_MEDIA_MEDIA_SELECT, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 50..53
177 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 54..57
178 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_PAD_ENTER, KEY_UNASSIGNED, // 58..5B
179 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_SYSTEM_WAKE, KEY_UNASSIGNED, // 5C..5F
180 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 60..63
181 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 64..67
182 | KEY_UNASSIGNED, KEY_END, KEY_UNASSIGNED, KEY_LEFT, // 68..6B
183 | KEY_HOME, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 6C..6F
184 | KEY_INSERT, KEY_DELETE, KEY_DOWN, KEY_UNASSIGNED, // 70..73
185 | KEY_RIGHT, KEY_UP, KEY_UNASSIGNED, KEY_UNASSIGNED, // 74..77
186 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_PAGE_DOWN, KEY_UNASSIGNED, // 78..7B
187 | KEY_PRINTSCREEN, KEY_PAGE_UP, KEY_PAUSE // 7C..7E
188 | };
189 |
190 | /*****************************************************************************/
191 | /* keyboard codeset 3 -> HIDX translation table */
192 | /*****************************************************************************/
193 | // A_0230
194 | uint8_t PROGMEM kbd_ttbl_set3[0x85] =
195 | {
196 | KEY_OVERRUN_ERROR, KEY_EXTRA_F9, KEY_UNASSIGNED, KEY_EXTRA_F5, // 00..03
197 | KEY_EXTRA_F3, KEY_EXTRA_F1, KEY_EXTRA_F2, KEY_F1, // 04..07
198 | KEY_F13, KEY_EXTRA_F10, KEY_EXTRA_F8, KEY_EXTRA_F6, // 08..0B
199 | KEY_EXTRA_F4, KEY_TAB, KEY_BACK_QUOTE, KEY_F2, // 0C..0F
200 | KEY_F14, KEY_LCTRL, KEY_LSHIFT, KEY_EUROPE_2, // 10..13
201 | KEY_CAPS_LOCK, KEY_Q, KEY_1, KEY_F3, // 14..17
202 | KEY_F15, KEY_LALT, KEY_Z, KEY_S, // 18..1B
203 | KEY_A, KEY_W, KEY_2, KEY_F4, // 1C..1F
204 | KEY_F16, KEY_C, KEY_X, KEY_D, // 20..23
205 | KEY_E, KEY_4, KEY_3, KEY_F5, // 24..27
206 | KEY_F17, KEY_SPACE, KEY_V, KEY_F, // 28..2B
207 | KEY_T, KEY_R, KEY_5, KEY_F6, // 2C..2F
208 | KEY_F18, KEY_N, KEY_B, KEY_H, // 30..33
209 | KEY_G, KEY_Y, KEY_6, KEY_F7, // 34..37
210 | KEY_F19, KEY_RALT, KEY_M, KEY_J, // 38..3B
211 | KEY_U, KEY_7, KEY_8, KEY_F8, // 3C..3F
212 | KEY_F20, KEY_COMMA, KEY_K, KEY_I, // 40..43
213 | KEY_O, KEY_0, KEY_9, KEY_F9, // 44..47
214 | KEY_F21, KEY_PERIOD, KEY_SLASH, KEY_L, // 48..4B
215 | KEY_SEMICOLON, KEY_P, KEY_MINUS, KEY_F10, // 4C..4F
216 | KEY_F22, KEY_INTERNATIONAL_1, KEY_QUOTE, KEY_EUROPE_1, // 50..53
217 | KEY_LEFT_BRACE, KEY_EQUAL, KEY_F11, KEY_F23, // 54..57
218 | KEY_RCTRL, KEY_RSHIFT, KEY_ENTER, KEY_RIGHT_BRACE, // 58..5B
219 | KEY_BACKSLASH, KEY_INTERNATIONAL_3, KEY_F12, KEY_F24, // 5C..5F
220 | KEY_DOWN, KEY_LEFT, KEY_LANG_4, KEY_UP, // 60..63
221 | KEY_DELETE, KEY_END, KEY_BACKSPACE, KEY_INSERT, // 64..67
222 | KEY_EXTRA_INSERT, KEY_PAD_1, KEY_RIGHT, KEY_PAD_4, // 68..6B
223 | KEY_PAD_7, KEY_PAGE_DOWN, KEY_HOME, KEY_PAGE_UP, // 6C..6F
224 | KEY_PAD_0, KEY_PAD_PERIOD, KEY_PAD_2, KEY_PAD_5, // 70..73
225 | KEY_PAD_6, KEY_PAD_8, KEY_ESC, KEY_NUM_LOCK, // 74..77
226 | KEY_EXTRA_PAD_PLUS, KEY_PAD_PLUS, KEY_PAD_3, KEY_PAD_MINUS, // 78..7B
227 | KEY_PAD_ASTERIX, KEY_PAD_9, KEY_SCROLL_LOCK, KEY_UNASSIGNED, // 7C..7F
228 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_EXTRA_F7, // 80..83
229 | KEY_EXTRA_SYSRQ // 84
230 | };
231 | #endif // defined(INCLUDE_KBD_TRANS_TABLES)
232 |
--------------------------------------------------------------------------------
/m32U4def.inc:
--------------------------------------------------------------------------------
1 | ;***** THIS IS A MACHINE GENERATED FILE - DO NOT EDIT ********************
2 | ;***** Created: 2011-02-09 12:03 ******* Source: ATmega32U4.xml **********
3 | ;*************************************************************************
4 | ;* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y
5 | ;*
6 | ;* Number : AVR000
7 | ;* File Name : "m32U4def.inc"
8 | ;* Title : Register/Bit Definitions for the ATmega32U4
9 | ;* Date : 2011-02-09
10 | ;* Version : 2.35
11 | ;* Support E-mail : avr@atmel.com
12 | ;* Target MCU : ATmega32U4
13 | ;*
14 | ;* DESCRIPTION
15 | ;* When including this file in the assembly program file, all I/O register
16 | ;* names and I/O register bit names appearing in the data book can be used.
17 | ;* In addition, the six registers forming the three data pointers X, Y and
18 | ;* Z have been assigned names XL - ZH. Highest RAM address for Internal
19 | ;* SRAM is also defined
20 | ;*
21 | ;* The Register names are represented by their hexadecimal address.
22 | ;*
23 | ;* The Register Bit names are represented by their bit number (0-7).
24 | ;*
25 | ;* Please observe the difference in using the bit names with instructions
26 | ;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc"
27 | ;* (skip if bit in register set/cleared). The following example illustrates
28 | ;* this:
29 | ;*
30 | ;* in r16,PORTB ;read PORTB latch
31 | ;* sbr r16,(1<
27 | #include
28 |
29 | #include "hwdefs.h"
30 | #include "print.h"
31 |
32 | void print_P(const char *s)
33 | {
34 | char c;
35 |
36 | while (1) {
37 | c = pgm_read_byte(s++);
38 | if (!c) break;
39 | if (c == '\n') usb_debug_putchar('\r');
40 | usb_debug_putchar(c);
41 | }
42 | }
43 |
44 | void phex1(unsigned char c)
45 | {
46 | usb_debug_putchar(c + ((c < 10) ? '0' : 'A' - 10));
47 | }
48 |
49 | void phex(unsigned char c)
50 | {
51 | phex1(c >> 4);
52 | phex1(c & 15);
53 | }
54 |
55 | void phex16(unsigned int i)
56 | {
57 | phex(i >> 8);
58 | phex(i);
59 | }
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/print.h:
--------------------------------------------------------------------------------
1 | #ifndef print_h__
2 | #define print_h__
3 |
4 | #include
5 | #include "usb_comm.h"
6 |
7 | // this macro allows you to write print("some text") and
8 | // the string is automatically placed into flash memory :)
9 | #define print(s) print_P(PSTR(s))
10 | #define pchar(c) usb_debug_putchar(c)
11 |
12 | void print_P(const char *s);
13 | void phex1(unsigned char c);
14 | void phex(unsigned char c);
15 | void phex16(unsigned int i);
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/processing.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************/
2 | /* processing.h : the processing part of Soarer's Converter */
3 | /*****************************************************************************/
4 |
5 | #ifndef _processing_h__
6 | #define _processing_h__
7 |
8 | #include
9 |
10 | #define PROTOCOL_VER 1
11 | #define PROTOCOL_SUBVER 0
12 | #define CODE_VER 1
13 | #define CODE_SUBVER 12
14 | #define SETTINGS_VER 1
15 | #define SETTINGS_SUBVER 1
16 |
17 | // Macro commands
18 |
19 | #define MCMD_PUSH_META 0x80 // PUSH_META modifier
20 | #define MCMD_PRESS 0x01 // PRESS
21 | #define MCMD_MAKE 0x02 // MAKE
22 | #define MCMD_BREAK 0x03 // BREAK
23 | #define MCMD_ASSIGN_META 0x04 // ASSIGN_META
24 | #define MCMD_SET_META 0x05 // SET_META
25 | #define MCMD_CLEAR_META 0x06 // CLEAR_META
26 | #define MCMD_TOGGLE_META 0x07 // TOGGLE_META
27 | #define MCMD_POP_META 0x08 // POP_META
28 | #define MCMD_POP_ALL_META 0x09 // POP_ALL_META
29 | #define MCMD_DELAY 0x0A // DELAY
30 | #define MCMD_CLEAR_ALL 0x0B // CLEAR_ALL
31 | #define MCMD_BOOT 0x0C // BOOT
32 |
33 | #ifdef __cplusplus
34 | extern "C" {
35 | #endif
36 |
37 | void setup_proc_kbd(uint8_t keyboard_codeset, uint16_t keyboard_id); // A_2b22
38 | uint8_t get_forced_keyboard_type(void); // A_2b7e
39 | uint8_t setup_processing(void); // A_2e28
40 | void rawhid_comm(void); // A_2f98
41 | uint8_t get_keyboard_leds(void); // A_341c
42 | uint8_t get_keyboard_protocol(void); // A_3422
43 | void proc_eeprom_mem_init(void); // A_3428
44 |
45 | void reset_macroproc(void); // A_3430
46 | void queue_reset_usb_data(void); // A_3444
47 | void incoming_keybreak(uint8_t keyid); // A_344a
48 | void incoming_keymake(uint8_t keyid); // A_3488
49 | void queue_key(uint8_t unk1, uint8_t hidx); // A_34dc
50 | void empty_key_queue(void); // A_3552
51 | void macro_tick(void); // A_355c
52 |
53 | #ifdef __cplusplus
54 | }
55 | #endif
56 |
57 | #endif /* defined(_processing_h__) */
58 |
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | EEPROM Layout:
2 | ==============
3 |
4 | Address Len Content
5 | 0000 2 "SC"
6 | 0002 2 Length of data area starting... somewhere yet undefined
7 | 0004 1 Settings version
8 | 0005 1 Settings sub-version (must be < 2)
9 | 0006 1 Predefined keyboard layout:
10 | Bits 0..3 : keyboard mode
11 | Bits 4..7: keyboard_codeset; if != 0
12 | (keyboard_codeset << 4) | keyboard_mode
13 | if keyboard_codeset is set, keyboard_mode is overruled:
14 | if keyboard_codeset == 1, keyboard mode is 2 else 1
15 | 0008 ? Start of configuration blocks
16 |
17 | Each configuration block starts with a header:
18 | 0000 1 Length
19 | 0001 1 Type Mask:
20 | Bit 2..0 : type (0=layers 1=remaps 2=macros)
21 | Bit 5..3 : select this is for(?check)
22 | Bit 6 : if set, header is followed by 1 byte bit set of codesets
23 | Bit 7 : if set, header (plus codesets byte if bit 6)
24 | is followed by 2 bytes keyboard ID
25 |
26 | Macro blocks contain a set of macros. Each macro has at least 5 bytes:
27 | 0000 1 HID code this is for
28 | 0001 1 Bit set of modifiers that must be set
29 | 0002 1 Bit set of modifiers that must be set OR clear
30 | (logic not completely understood yet - some additional mangling of upper nibble)
31 | 0003 1 Bit 0..5 : # macro commands for Make
32 | 0004 1 Bit 0..5 : # macro commands for Break
33 | Can contain a flag in bit 7; if set,
34 | the current modifier state is saved before executing the macro and restored afterwards.
35 | Can be suppressed by specifying norestoremeta.
36 | Soarer's scdis v1.10 has a bug here, BTW - it always shows "norestoremeta".
37 | This header is followed by (0003*2) bytes for the Make macro commands
38 | and (0003*2) bytes for the Break macro commands
39 | Each macro command consists of 2 bytes:
40 | 0000 1 macro command
41 | one of the following:
42 | 01 : PRESS
43 | 02 : MAKE
44 | 03 : BREAK
45 | 04 : ASSIGN_META
46 | 05 : SET_META
47 | 06 : CLEAR_META
48 | 07 : TOGGLE_META
49 | 08 : POP_META
50 | 09 : POP_ALL_META
51 | 0A : DELAY
52 | 0B : CLEAR_ALL
53 | 0C : BOOT
54 | 0001 1 argument (HID, modifier or other argument value, like delay in ms)
55 |
56 | Keyboard IDs (http://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html)
57 | ============
58 |
59 | Keyboards do report an ID as a reply to the command f2.
60 | (An XT keyboard does not reply, an AT keyboard only replies with an ACK.)
61 | An MF2 AT keyboard reports ID ab 83.
62 |
63 | Many short keyboards, like IBM ThinkPads, and Spacesaver keyboards, send ab 84.
64 |
65 | Several 122-key keyboards are reported to send ab 86.
66 | Here translated and untranslated values coincide.
67 | (Reports mention "122-Key Enhanced Keyboard", "standard 122-key keyboard",
68 | "122 Key Mainframe Interactive (MFI) Keyboard", "122-Key Host Connected Keyboard".)
69 |
70 | John Elliott reports on his IBM 1390876 page that this keyboard returns bf bf:
71 | When sent an identify command (0xF2), the keyboard returns the byte sequence 0xBF 0xBF.
72 | However, this can be changed.
73 | On the keyboard PCB is a 12-pin header, marked as 6 pairs of pins (B2-B7).
74 | These correspond to bits 5-0 of the second byte of the keyboard ID.
75 | Shorting a pair of pins sets that bit to zero.
76 | So placing a jumper on the B2 pair will change the keyboard ID to 0xBF 0x9F.
77 | Adjacent to this header is a space on the circuit board for an identical header,
78 | marked as pins A2-A7.
79 | Presumably these would have the same effect on the first byte of the keyboard ID.
80 |
81 | David Monro reports ab 85 for a NCD N-97 keyboard.
82 |
83 | Tim Clarke reports ab 85 (instead of the usual ab 86)
84 | for the "122-Key Host Connect(ed) Keyboard".
85 | He also reports: Also, when playing with my KVM problems Belkin gave me a
86 | 105-key Windows keyboard which Id.s itself as 18ABh.
87 |
88 | Linux 2.5.25 kernel source has 0xaca1 for a "NCD Sun layout keyboard".
89 | It also mentions 0xab02 and 0xab7f,
90 | but these arise as (mistaken) back translations from ab 41 and ab 54.
91 |
92 | Ralph Brown's Interrupt list mentions "old Japanese 'G', 'P', 'A' keyboards",
93 | with keyboard IDs ab 90, ab 91, ab 92.
94 | Here translated and untranslated versions coincide. ID ab 90 was also mentioned above.
95 |
--------------------------------------------------------------------------------
/salloc.c:
--------------------------------------------------------------------------------
1 | /*****************************************************************************/
2 | /* salloc.c : Soarer's special(?) memory allocation routines */
3 | /*****************************************************************************/
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include "hwdefs.h"
10 | #include "salloc.h"
11 |
12 | // gleaned from avr-libc's stdlib_private.h
13 | #define STACK_POINTER() ((char *)AVR_STACK_POINTER_REG)
14 | #define HEAP_MARGIN 32
15 |
16 | /*****************************************************************************/
17 | /* Global data */
18 | /*****************************************************************************/
19 |
20 | // provided by avr-gcc
21 | extern char __heap_start;
22 | extern char __heap_end;
23 |
24 | uint16_t data_0x0113 = 0x7fff; // 0x0113 UNUSED?
25 | char *__malloc_heap_end = &__heap_end; // 0x0115
26 | char *__brkval = &__heap_start; // 0x0117
27 |
28 | /*****************************************************************************/
29 | /* memfree : returns amount of free memory */
30 | /*****************************************************************************/
31 | // A_164a
32 | int16_t memfree(void)
33 | {
34 | char *memend = __malloc_heap_end;
35 | if (memend == 0)
36 | memend = STACK_POINTER() - HEAP_MARGIN;
37 | return memend - __brkval; // &A_03ab
38 | }
39 |
40 | /*****************************************************************************/
41 | /* memalloc : allocate a chunk of memory on the heap */
42 | /*****************************************************************************/
43 | // A_1670
44 | char *memalloc(int16_t nelem)
45 | {
46 | char *memend = __malloc_heap_end;
47 | char *retaddr;
48 |
49 | if (!memend)
50 | memend = STACK_POINTER() - HEAP_MARGIN;
51 | if (memend - __brkval < nelem)
52 | return 0;
53 |
54 | retaddr = __brkval;
55 | __brkval += nelem;
56 | return retaddr;
57 | }
58 |
59 | /*****************************************************************************/
60 | /* memreset : reset memory allocation */
61 | /*****************************************************************************/
62 | // A_16b2
63 | char *memreset(void)
64 | {
65 | __brkval = &__heap_start; // 0x0117 = 0x03ab;
66 | return __brkval;
67 | }
68 |
69 |
--------------------------------------------------------------------------------
/salloc.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************/
2 | /* salloc.h : Soarer's special(?) memory allocation routines */
3 | /*****************************************************************************/
4 |
5 | #ifndef _salloc_h__
6 | #define _salloc_h__
7 |
8 | #include
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | int16_t memfree(void); // A_164a
15 | char *memalloc(int16_t nelem); // A_1670
16 | char *memreset(void); // A_16b2
17 |
18 |
19 | #ifdef __cplusplus
20 | }
21 | #endif
22 |
23 | #endif // defined(_salloc_h__)
24 |
--------------------------------------------------------------------------------
/soarer.c:
--------------------------------------------------------------------------------
1 | /*****************************************************************************/
2 | /* Soarer.c : reverse-engineered from Soarer's Converter V1.12 */
3 | /*****************************************************************************/
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include "hwdefs.h"
13 | #include "soarer.h"
14 | #include "salloc.h"
15 | #include "usb_comm.h"
16 | #include "print.h"
17 | #include "processing.h"
18 |
19 | /*****************************************************************************/
20 | /* PS/2 definitions and scan code translation tables */
21 | /*****************************************************************************/
22 |
23 | #define INCLUDE_KBD_TRANS_TABLES
24 | #include "kbdtbls.h"
25 |
26 | /*****************************************************************************/
27 | /* Global data for this module */
28 | /*****************************************************************************/
29 |
30 | uint8_t keyboard_codeset = 4; // 0x0100
31 | // a hot candidate for PROGMEM ...
32 | uint8_t const kbd_pauseseq[8] = // 0x0101 pause key definition
33 | { 0xe1, 0x14, 0x77, 0xe1, 0xf0, 0x14, 0xf0, 0x77 };
34 | uint16_t keyboard_id = 0; // 0x120/0x121
35 | uint8_t kbd_breakcode = 0; // 0x0122 incoming scan code is preceded by BREAK (0xf0)
36 | uint8_t kbd_extended_scancode = 0; // 0x0123 incoming scan code is extended (E0 prefix)
37 | uint8_t kbd_extended2_scancode = 0; // 0x0124 incoming scan code is extended (E1 prefix = Pause)
38 | uint8_t prot_led_state = 0; // 0x0125 protocol / LED state
39 | uint8_t old_aux_key_bits = 0; // 0x0126
40 | uint8_t volatile aux_key_bits = 0; // 0x0127
41 | uint8_t keyboard_mode = 0; // 1 = AT/PS2, 2 = PC/XT, 3/4 forced // 0x0129
42 | uint8_t volatile kbd_rcvd_byte = 0; // 0x012a
43 | uint8_t volatile kbd_rcvd_state = 0; // 0x012b
44 | uint8_t volatile kbdcmd_to_send = 0; // 0x012e
45 | uint8_t volatile data_0x0133 = 0; // 0x0133
46 | uint32_t volatile timer0_counter = 0; // 0x0136
47 | uint16_t onboard_led_counter = 0; // 0x013a
48 | #ifdef OBLED2_CONFIG
49 | uint16_t onboard_led2_counter = 0;
50 | #endif
51 |
52 | /*****************************************************************************/
53 | /* Necessary prototypes used only in the module */
54 | /*****************************************************************************/
55 |
56 | void setup_aux_key_handler(void); // A_0c5c
57 | uint8_t get_aux_key_bits(void); // A_0c92
58 | void setup_timer1(uint16_t counter); // A_0c98
59 | void set_kbd_reset_pin(uint8_t bHigh); // A_0ce2
60 | void disable_extint1(void); // A_0d3e
61 | void enable_extint1_rising(void); // A_0d4a
62 | void init_kbd(void); // A_129a
63 | uint8_t send_kbd_command(uint8_t cmd, uint8_t timeout); // A_133c
64 | uint8_t fetch_kbd_byte(uint8_t *addr, uint8_t timeout); // A_13de
65 | uint8_t get_kbd_byte(uint8_t timeout); // A_1492
66 | uint8_t send_kbd_command_with_parm(uint8_t command, uint8_t cmdparm); // A_14c6
67 | uint8_t send_kbd_command_without_parm(uint8_t command); // A_1538
68 | void act_onboard_led(uint16_t counter); // A_1586
69 | #ifdef OBLED2_CONFIG
70 | void act_onboard_led2(uint16_t counter);
71 | #else
72 | #define act_onboard_led2(a)
73 | #endif
74 | void setup_timer0(void); // A_1592
75 |
76 | /*****************************************************************************/
77 | /* translate_scancode : translates incoming scan code based on kbd codeset */
78 | /*****************************************************************************/
79 | // A_0660
80 | uint8_t translate_scancode(uint8_t scancode, uint8_t bExtended)
81 | {
82 | switch (keyboard_codeset)
83 | {
84 | case 1:
85 | // A_067c
86 | if (scancode < sizeof(kbd_ttbl_set1))
87 | return pgm_read_byte(kbd_ttbl_set1 + scancode);
88 | break;
89 | case 4:
90 | // A_069c
91 | if (bExtended)
92 | {
93 | if (scancode < sizeof(kbd_ttbl_set2ex))
94 | return pgm_read_byte(kbd_ttbl_set2ex + scancode);
95 | else
96 | break;
97 | }
98 | // else fall thru to...
99 | case 2:
100 | // A_06b0
101 | if (scancode < sizeof(kbd_ttbl_set2))
102 | return pgm_read_byte(kbd_ttbl_set2 + scancode);
103 | break;
104 | case 3:
105 | // A_068c
106 | if (scancode < sizeof(kbd_ttbl_set3))
107 | return pgm_read_byte(kbd_ttbl_set3 + scancode);
108 | break;
109 | }
110 | return 0;
111 | }
112 |
113 | /*****************************************************************************/
114 | /* reset_kbdinstate : */
115 | /*****************************************************************************/
116 | // A_06c4
117 | void reset_kbdinstate(void)
118 | {
119 | reset_macroproc();
120 | queue_reset_usb_data();
121 | kbd_breakcode = 0; /* reset state flags */
122 | kbd_extended_scancode = 0;
123 | kbd_extended2_scancode = 0;
124 | }
125 |
126 | /*****************************************************************************/
127 | /* set_kbd_leds : sets the Teensy's keyboard LEDs */
128 | /*****************************************************************************/
129 | // A_06da
130 | void set_kbd_leds(uint8_t ledbits)
131 | {
132 | if (get_keyboard_protocol())
133 | LLED_ON(ledbits);
134 | else // if USB host set keybord protocol to 0
135 | LLED_OFF(ledbits);
136 | }
137 |
138 | /*****************************************************************************/
139 | /* incoming_kbd_breakcode : translates a scan code and passes it on */
140 | /*****************************************************************************/
141 | // A_071e
142 | void incoming_kbd_breakcode(uint8_t scancode, uint8_t bExtended)
143 | {
144 | incoming_keybreak(translate_scancode(scancode, bExtended));
145 | }
146 |
147 | /*****************************************************************************/
148 | /* incoming_kbd_makecode : translates a scan code and passes it on */
149 | /*****************************************************************************/
150 | // A_0724
151 | void incoming_kbd_makecode(uint8_t scancode, uint8_t bExtended)
152 | {
153 | incoming_keymake(translate_scancode(scancode, bExtended));
154 | }
155 |
156 | /*****************************************************************************/
157 | /* send_aux_key_changes : if there are changes in the aux key states, send'em*/
158 | /*****************************************************************************/
159 | // A_072a
160 | uint8_t send_aux_key_changes(void)
161 | {
162 | uint8_t cur_aux_key_bits = get_aux_key_bits();
163 | uint8_t chg_aux_key_bits = old_aux_key_bits ^ cur_aux_key_bits;
164 | int8_t i;
165 |
166 | if (!chg_aux_key_bits)
167 | return chg_aux_key_bits;
168 |
169 | // loop from auxkey_id=0xab..0xaf
170 | for (i = 0; i != 6; i++)
171 | {
172 | if ((chg_aux_key_bits >> i) & 1)
173 | {
174 | // internal IDs: $AB..$AF
175 | if ((cur_aux_key_bits >> i) & 1)
176 | //A_0778
177 | incoming_keybreak(KEY_AUX1 + i);
178 | else
179 | // A_0780
180 | incoming_keymake(KEY_AUX1 + i);
181 | }
182 | }
183 |
184 | old_aux_key_bits = cur_aux_key_bits;
185 | return 1;
186 | }
187 |
188 | /*****************************************************************************/
189 | /* main : main program function */
190 | /*****************************************************************************/
191 | // A_07a6
192 | int main(void)
193 | {
194 | uint8_t kbd_reset_pin_reset = 0; // R3
195 | uint8_t keyboard_determined = 0; // R8
196 | uint32_t t0ct_start; // R10-13
197 | uint32_t t0ct_cur;
198 | uint8_t kbd_byte_fetched;
199 | uint8_t newline_after_wait; // R5
200 | uint8_t resend_requested; // R9
201 | uint8_t new_pled_state; // R16
202 |
203 | #if 1
204 | uint8_t fetched_kbd_byte; // R28[1]
205 | #else
206 | // in the original, there's the following code sequence here:
207 | rcall A_07cc ; 0x7cc
208 | A_07cc:
209 | push R0
210 | in R28, SPL
211 | in R29, SPH
212 | // i.e., call yourself and then do it again.
213 | // Presumably means "reserve 4 bytes on stack"...
214 | #endif
215 |
216 | // set for unscaled clock (16MHz on all of the supported configurations)
217 | CPU_PRESCALE(0);
218 | OBLED_CONFIG;
219 | #ifdef OBLED2_CONFIG
220 | OBLED2_CONFIG;
221 | #endif
222 |
223 | set_kbd_leds(0); // init keyboard LEDs to out
224 | set_kbd_leds(7); // set all attached keyboard LEDs on
225 |
226 | setup_timer0();
227 | proc_eeprom_mem_init();
228 | init_kbd();
229 | setup_aux_key_handler();
230 | reset_kbdinstate();
231 | set_kbd_reset_pin(0);
232 |
233 | kbd_reset_pin_reset = 0;
234 | keyboard_determined = 0;
235 | resend_requested = 0;
236 | newline_after_wait = 0;
237 | t0ct_start = 0;
238 |
239 | // big fat main loop presumably starts here
240 | // A_080c
241 | while (1)
242 | {
243 | if (!kbd_reset_pin_reset)
244 | {
245 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
246 | t0ct_cur = timer0_counter;
247 | if (t0ct_cur > 500)
248 | {
249 | set_kbd_reset_pin(1);
250 | kbd_reset_pin_reset = 1;
251 | }
252 | }
253 |
254 | // A_0838
255 | if (!keyboard_determined)
256 | {
257 | // A_083e:
258 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
259 | t0ct_cur = timer0_counter;
260 | if (t0ct_cur > 3000)
261 | {
262 | // A_0860
263 | uint8_t forcedtype = get_forced_keyboard_type();
264 | if (forcedtype & 0x0f)
265 | {
266 | keyboard_codeset = forcedtype >> 4;
267 | if (keyboard_codeset)
268 | {
269 | if (keyboard_codeset == 1)
270 | // A_0878
271 | keyboard_mode = 2;
272 | else
273 | // A_087e
274 | keyboard_mode = 1;
275 | }
276 | else
277 | // A_886
278 | keyboard_mode = forcedtype;
279 | }
280 | else
281 | {
282 | // A_0890
283 | keyboard_codeset = 0;
284 | keyboard_id = 0;
285 | // send echo (kbd is expected to respond with 0xee)
286 | if (send_kbd_command(ATCMD_ECHO, 50) == 2)
287 | {
288 | // A_08a8
289 | get_kbd_byte(50); // get and ignore the response
290 | keyboard_mode = 1;
291 | if (!keyboard_codeset)
292 | {
293 | // A_08bc
294 | // send "Read ID" command (kbd is expected to respond with KBDM_ACK
295 | // followed by 2 bytes ID, 0xab 0x83 being standard PS/2)
296 | // A_08c8
297 | if (send_kbd_command(ATCMD_READID, 50) == 2 &&
298 | get_kbd_byte(50) == KBDM_ACK)
299 | {
300 | uint8_t kbdid1 /*R28+2*/, kbdid2 /*R28+3*/;
301 |
302 | // A_08d0
303 | if (fetch_kbd_byte(&kbdid1, 50) == 2)
304 | {
305 | // A_08dc
306 | if (fetch_kbd_byte(&kbdid2, 50) == 2)
307 | {
308 | // A_0900
309 | keyboard_id = ((uint16_t)(kbdid1) << 8) | kbdid2;
310 | // A_08ea
311 | // ABxx is an AT/PS2 variant, except for
312 | // 122-key host-connected keyboard (AB85)
313 | // (this, BTW, also covers the IBM AT keyboard (AB83),
314 | // which is really using codeset 2!)
315 | if (kbdid1 == 0xab && kbdid2 != 0x85)
316 | // A_08f4
317 | keyboard_codeset = 4;
318 | else
319 | // A_08fa
320 | keyboard_codeset = 3;
321 | }
322 | else
323 | {
324 | // A_0916:
325 | keyboard_codeset = 4;
326 | keyboard_id = kbdid1; // high part empty
327 | }
328 | }
329 | else
330 | // A_0924
331 | keyboard_codeset = 2;
332 | }
333 | }
334 | }
335 | else /* seems to be an XT keyboard */
336 | {
337 | // A_092a
338 | keyboard_mode = 2;
339 | keyboard_codeset = 1; /* so use scan code set 1 */
340 | }
341 | // A_0934
342 | if (!keyboard_codeset) /* in case of doubt */
343 | keyboard_codeset = 4; /* treat it as normal PS/2 */
344 | }
345 |
346 | // This seems to be the area where the EEPROM translation stuff is set up
347 | // A_0940
348 | setup_proc_kbd(keyboard_codeset, keyboard_id);
349 | setup_processing();
350 | if (keyboard_mode == 2) // if PC/XT keyboard
351 | {
352 | // A_095c
353 | disable_extint1(); // switch to int on rising clock flank
354 | enable_extint1_rising();
355 | }
356 | // A_0960
357 | if (keyboard_codeset == 3) // tell Terminal keyboards to send Make/Break
358 | // A_0968
359 | send_kbd_command_without_parm(ATCMD_SETAMKBK);
360 | // A_096c
361 | set_kbd_leds(0); // turn off keyboard LEDs
362 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
363 | t0ct_start = timer0_counter;
364 | #if 1
365 | print_P(PSTR("\n\nKeyboard ID: "));
366 | #else
367 | usb_debug_putchar('\n');
368 | usb_debug_putchar('\n');
369 | print_P(PSTR("Keyboard ID: "));
370 | #endif
371 | phex16(keyboard_id);
372 | #if 1
373 | print_P(PSTR("\nCode Set: "));
374 | #else
375 | usb_debug_putchar('\n');
376 | print_P(PSTR("Code Set: "));
377 | #endif
378 |
379 | #if 1
380 | // 12 bytes less code than the original ...
381 | switch (keyboard_codeset)
382 | {
383 | case 1 :
384 | case 2 :
385 | case 3 :
386 | phex1(keyboard_codeset);
387 | break;
388 | case 4 :
389 | print_P(PSTR("2 (extended)"));
390 | break;
391 | default :
392 | print_P(PSTR("unknown"));
393 | break;
394 | }
395 | #else
396 | if (keyboard_codeset == 2)
397 | // A_09d4
398 | usb_debug_putchar('2');
399 | else if (keyboard_codeset == 3)
400 | // A_09dc
401 | usb_debug_putchar('3');
402 | else if (keyboard_codeset == 4)
403 | // A_09e0
404 | print_P(PSTR("2 (extended)"));
405 | else if (keyboard_codeset == 1)
406 | // A_09d0
407 | usb_debug_putchar('1');
408 | else
409 | // A_09e6
410 | print_P(PSTR("unknown"));
411 | #endif
412 | //A_09ee
413 | if (keyboard_mode == 2)
414 | print_P(PSTR("\nMode: PC/XT\n\n"));
415 | else
416 | print_P(PSTR("\nMode: AT/PS2\n\n"));
417 | // A_0a04
418 | keyboard_determined = 1;
419 | }
420 | }
421 |
422 | // A_0a08:
423 | kbd_byte_fetched = fetch_kbd_byte(&fetched_kbd_byte, 0);
424 | #ifdef OBLED2_CONFIG // little "special" - blink LED2 on each incoming kbd byte
425 | if (kbd_byte_fetched == 2)
426 | act_onboard_led2(10);
427 | #endif
428 | if (keyboard_determined)
429 | {
430 | // A_0a16
431 | if (kbd_byte_fetched >= 2)
432 | {
433 | // A_0a1c
434 | if (kbd_byte_fetched == 2)
435 | {
436 | // A_0a22
437 | if (keyboard_codeset == 1) // if it's a PC/XT keyboard
438 | {
439 | // A_0a2c
440 | if (fetched_kbd_byte != 0xff) // buffer full?
441 | {
442 | // A_0a32
443 | if (fetched_kbd_byte & 0x80)
444 | incoming_kbd_breakcode(fetched_kbd_byte & 0x7f, 0);
445 | else
446 | // A_0a40
447 | incoming_kbd_makecode(fetched_kbd_byte, 0);
448 | }
449 | else
450 | {
451 | // A_0ace
452 | reset_kbdinstate();
453 | // print_P(PSTR("!BF "));
454 | act_onboard_led(5000);
455 | }
456 | // goto A_0b08;
457 | }
458 | else // if it's AT / PS/2
459 | {
460 | // A_0a46
461 | if (kbd_extended2_scancode) // if in pause key processing
462 | {
463 | // A_0a4e
464 | if (fetched_kbd_byte == kbd_pauseseq[kbd_extended2_scancode])
465 | {
466 | // A_0a5c
467 | kbd_extended2_scancode++;
468 | if (kbd_extended2_scancode == 3)
469 | // A_0a68
470 | incoming_kbd_makecode(0x7e, 1);
471 | else if (kbd_extended2_scancode == 8)
472 | {
473 | // A_0a76
474 | // PAUSE has no typematic repeat or break, so treat it as
475 | // "released" once the PAUSE sequence is complete
476 | incoming_kbd_breakcode(0x7e, 1);
477 | kbd_extended2_scancode = 0;
478 | }
479 | }
480 | else
481 | {
482 | // A_0a82
483 | if (kbd_extended2_scancode >= 3)
484 | incoming_kbd_breakcode(0x7e, 1);
485 | kbd_extended2_scancode = 0;
486 | // in this special case, continue examining the incoming code
487 | goto kbdnopause;
488 | }
489 | }
490 | else
491 | {
492 | // A_0a90
493 | kbdnopause: // can't seem to get rid of this (see above)
494 | switch (fetched_kbd_byte)
495 | {
496 | case KBDM_BUFOVR : // Buffer overflow
497 | #if 1 // not in original
498 | case KBDM_BUFOVR2 : // Key detection error or buffer overrun
499 | #endif
500 | // A_0ace
501 | reset_kbdinstate();
502 | // print_P(PSTR("!BO "));
503 | act_onboard_led(5000);
504 | break;
505 | case KBDM_BATOK : // BAT finished OK
506 | break;
507 | case KBDM_EXTENDED : // extended scan code?
508 | // A_0ab8
509 | kbd_extended_scancode = 1;
510 | break;
511 | case KBDM_EXTENDED2 : // Pause key sequence start
512 | // A_0ac0:
513 | kbd_extended2_scancode = 1;
514 | break;
515 | #if 1 // not in original
516 | case KBDM_ECHO : // Response to ECHO command
517 | // should never come in...
518 | break;
519 | #endif
520 | case KBDM_BREAK : // break code coming in
521 | // A_0ab0
522 | kbd_breakcode = 1;
523 | break;
524 | #if 1 // not in original
525 | case KBDM_ACK : // Command Acknowledgement
526 | // should never come in...
527 | break;
528 | #endif
529 | case KBDM_ERR : // Keyboard returned an error!
530 | #if 1 // not in original
531 | case KBDM_ERR2 :
532 | #endif
533 | // A_0ac8
534 | // print_P(PSTR("!ER "));
535 | act_onboard_led(10000);
536 | break;
537 | #if 1 // not in original, but SHOULD be...
538 | case KBDM_RESEND : // Resend last command byte
539 | break;
540 | #endif
541 | default : // any normal key
542 | // A_0ad8:
543 | if (kbd_breakcode)
544 | {
545 | // A_0ae0
546 | incoming_kbd_breakcode(fetched_kbd_byte, kbd_extended_scancode);
547 | kbd_breakcode = 0;
548 | kbd_extended_scancode = 0;
549 | }
550 | else
551 | {
552 | // A_0aee
553 | incoming_kbd_makecode(fetched_kbd_byte, kbd_extended_scancode);
554 | kbd_extended_scancode = 0;
555 | }
556 | break;
557 | }
558 | }
559 | }
560 |
561 | // A_0b08
562 | resend_requested = 0;
563 | }
564 | else // if (kbd_byte_fetched > 2)
565 | {
566 | // A_0afc
567 | send_kbd_command(ATCMD_RESEND, 50); // request resend of last byte
568 | resend_requested = 1;
569 | }
570 |
571 | // A_0b0a
572 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
573 | t0ct_start = timer0_counter;
574 | newline_after_wait = 1;
575 | }
576 |
577 | // A_0b26
578 | else if (!kbd_byte_fetched && !resend_requested)
579 | {
580 | // A_0b32
581 | new_pled_state = (get_keyboard_protocol() << 7) | get_keyboard_leds();
582 | if (new_pled_state != prot_led_state)
583 | {
584 | // A_0b50
585 | uint8_t num_lock = new_pled_state & 1;
586 | uint8_t caps_lock = (new_pled_state >> 1) & 1;
587 | uint8_t scroll_lock = (new_pled_state >> 2) & 1;
588 |
589 | uint8_t numscrollbits;
590 | // special code for IBM RT PC keyboard with inverted Num/Caps LED pos
591 | if (keyboard_id == KBDID_IBM_RT)
592 | // A_0b7c
593 | numscrollbits = (num_lock << 2) | (caps_lock << 1) | scroll_lock;
594 | else
595 | // A_0b8c:
596 | numscrollbits = (caps_lock << 2) | (num_lock << 1) | scroll_lock;
597 | // A_0b9a:
598 | send_kbd_command_with_parm(ATCMD_SETLEDS, numscrollbits);
599 | set_kbd_leds((scroll_lock << 2) | (num_lock << 1) | caps_lock);
600 | prot_led_state = new_pled_state;
601 | }
602 | }
603 | // A_0c08
604 | if (send_aux_key_changes())
605 | {
606 | // A_0bb4
607 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
608 | t0ct_start = timer0_counter;
609 | newline_after_wait = 1;
610 | }
611 | }
612 | // A_0bd0:
613 | if (newline_after_wait)
614 | {
615 | // A_0bd4:
616 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
617 | t0ct_cur = timer0_counter;
618 | if (t0ct_cur - t0ct_start >= 50)
619 | {
620 | usb_debug_putchar('\n');
621 | newline_after_wait = 0;
622 | }
623 | }
624 | rawhid_comm();
625 | } // end of big fat main loop
626 | }
627 |
628 | /*****************************************************************************/
629 | /* TIMER3_COMPA_vect : Timer/Counter3 Compare Match A */
630 | /*****************************************************************************/
631 | // A_0c10
632 | ISR(TIMER3_COMPA_vect)
633 | {
634 | // ticks once per ms
635 | // aux key bits must be stable for 10ms to be counted
636 | static uint8_t aux_key_timercounter = 10; // 0x0109
637 | static uint8_t tmr_aux_key_bits = 0; // 0x0128
638 |
639 | uint8_t newauxkeys = AUXK_GET; // retrieve new aux key states
640 | if (newauxkeys != tmr_aux_key_bits)
641 | {
642 | tmr_aux_key_bits = newauxkeys;
643 | aux_key_timercounter = 10;
644 | }
645 | if (aux_key_timercounter)
646 | {
647 | if (!--aux_key_timercounter)
648 | aux_key_bits = tmr_aux_key_bits;
649 | }
650 | }
651 |
652 | /*****************************************************************************/
653 | /* setup_aux_key_handler : sets up timer 3 for aux key checking */
654 | /*****************************************************************************/
655 | // A_0c5c
656 | void setup_aux_key_handler(void)
657 | {
658 | AUXK_CONFIG; // setup aux key port
659 |
660 | // Timer 3 ticks once per ms (F_CPU / 64 / 1000 = 250)
661 | TIMSK3 |= (1 << OCIE3A);
662 | OCR3AH = 0;
663 | OCR3AL = 250;
664 | TCCR3A = 0;
665 | TCCR3B = (1 << WGM32);
666 | TCCR3B |= (1 << CS31) | (1 << CS30);
667 | }
668 |
669 | /*****************************************************************************/
670 | /* get_aux_key_bits : returns current state of the aux keys */
671 | /*****************************************************************************/
672 | // A_0c92
673 | uint8_t get_aux_key_bits(void)
674 | {
675 | return aux_key_bits;
676 | }
677 |
678 | /*****************************************************************************/
679 | /* setup_timer1 : sets up timer/counter 1 for operation */
680 | /*****************************************************************************/
681 | // A_0c98
682 | void setup_timer1(uint16_t microseconds)
683 | {
684 | TCCR1B &= ~((1 << CS12)|(1 << CS11)|(1 << CS10)); // set timer 1 prescaler to 0
685 | TIMSK1 &= ~(1 << OCIE1A); // disable Timer/Counter1 Output Compare A Match interrupt
686 | TCNT1H = 0; // reset timer 1 counter
687 | TCNT1L = 0;
688 | TIFR1 = (1 << OCF1A); // clear Timer/Counter1 Output Compare A Match Flag
689 | if (microseconds)
690 | {
691 | // This works nicely at 16MHz, but would have to be changed for other speeds!
692 | microseconds *= 2;
693 | OCR1AH = (microseconds >> 8); // set up output compare value
694 | OCR1AL = (microseconds & 0xff);
695 | TIMSK1 |= (1 << OCIE1A); // enable Timer/Counter1 Output Compare A Match interrupt
696 | // This works nicely at 16MHz, but would have to be changed for other speeds!
697 | TCCR1B |= (1 << CS11); // Timer 1 Clock Source = Clock / 8
698 | }
699 | }
700 |
701 | /*****************************************************************************/
702 | /* set_kbd_reset_pin : sets up the keyboard reset pin */
703 | /*****************************************************************************/
704 | // A_0ce2
705 | void set_kbd_reset_pin(uint8_t bHigh)
706 | {
707 | if (bHigh)
708 | KBDR_HIGH;
709 | else
710 | KBDR_LOW;
711 | }
712 |
713 | /*****************************************************************************/
714 | /* set_kbd_data_pin : sets the keyboard Data pin */
715 | /*****************************************************************************/
716 | // A_0cf2
717 | void set_kbd_data_pin(uint8_t bHigh)
718 | {
719 | if (bHigh)
720 | KBDD_HIGH;
721 | else
722 | KBDD_LOW;
723 | }
724 |
725 | /*****************************************************************************/
726 | /* set_kbd_clock_pin : sets the clock line and waits for it */
727 | /*****************************************************************************/
728 | // A_0d02
729 | uint8_t set_kbd_clock_pin(uint8_t bHigh)
730 | {
731 | uint8_t oldmask = EIMSK; /* remember current ext.int mask */
732 | uint8_t i;
733 |
734 | EIMSK &= ~(1 << INT1); /* disable ext. interrupt 1 */
735 | _NOP();
736 | if (bHigh) /* if we need to set it to 1 */
737 | // A_0d0e
738 | KBDC_HIGH;
739 | else /* if we need to set it to 0 */
740 | // A_0d14
741 | KBDC_LOW;
742 |
743 | // A_0d18
744 | // wait until line is stable (?)
745 | for (i = 20; i > 0; i--) /* wait a little bit for it to happen*/
746 | {
747 | if (KBDC_GET0 == bHigh)
748 | break;
749 | }
750 | // A_0d2c
751 | EIFR = (1 << INTF1); /* clear ext.int.1 interrupt flag */
752 | if (oldmask & (1 << INT1)) /* if it was enabled before, */
753 | EIMSK |= (1 << INT1); /* re-enable it */
754 | else /* otherwise */
755 | EIMSK &= ~(1 << INT1); /* disable ext.int.1 */
756 | return EIMSK; /* pass back current ext.int.mask */
757 | }
758 |
759 | /*****************************************************************************/
760 | /* disable_extint1 : disable external interrrupt 1 */
761 | /*****************************************************************************/
762 | // A_0d3e
763 | void disable_extint1(void)
764 | {
765 | cli();
766 | EIMSK &= ~(1 << INT1); /* disable ext. interrupt 1 */
767 | EIFR = (1 << INTF1); /* clear ext.int.1 interrupt flag */
768 | sei();
769 | }
770 |
771 | /*****************************************************************************/
772 | /* enable_extint1_rising : enable external interrupt 1 on RISING edge */
773 | /*****************************************************************************/
774 | // A_0d4a
775 | void enable_extint1_rising(void)
776 | {
777 | cli();
778 | // The rising edge of INTn generates asynchronously an interrupt request.
779 | EICRA |= (1 << ISC11) | (1 << ISC10); /* set up ext. interrupt 1 */
780 | EIMSK |= (1 << INT1); /* enable ext. interrupt 1 */
781 | sei();
782 | }
783 |
784 | /*****************************************************************************/
785 | /* A_0d5c : */
786 | /*****************************************************************************/
787 | // A_0d5c
788 | uint8_t A_0d5c
789 | (
790 | uint8_t cmode // 0=from IRQ1/init_kbd, 1=timer 1, 2=from send_kbd_command
791 | )
792 | {
793 | static int8_t data_0x0111 = -1; // 0x0111
794 | static int8_t data_0x0112 = -1; // 0x0112
795 | uint8_t ps2clk; // PS/2 clock line state
796 |
797 | if (cmode)
798 | data_0x0112 = data_0x0111;
799 | ps2clk = KBDC_GET0; /* get PS/2 Clock line */
800 |
801 | // R24 = data_0x0112;
802 | if (data_0x0112 == -1)
803 | // A_0d7c
804 | data_0x0112 = 1 ^ ps2clk; /* save inverted clock line */
805 |
806 | // A_0d84
807 | switch (data_0x0112)
808 | {
809 | case 0 :
810 | // A_0d96
811 | if (!ps2clk)
812 | {
813 | // A_0dcc
814 | data_0x0112 = -1;
815 | return 4;
816 | }
817 | // A_0d9a
818 | setup_timer1(90); // set timer1 to 90 microseconds
819 | data_0x0111 = -2;
820 | data_0x0112 = 1;
821 | return 1;
822 | case 1 :
823 | // A_0dae
824 | if (ps2clk)
825 | {
826 | // A_0dcc
827 | data_0x0112 = -1;
828 | return 4;
829 | }
830 | // A_0db2
831 | setup_timer1(1000); // setup timer1 to 1 ms
832 | data_0x0111 = -1;
833 | data_0x0112 = 0;
834 | return 1;
835 | case -2 :
836 | // A_0dc8
837 | data_0x0112 = -1;
838 | return 2;
839 | default :
840 | // A_0d92
841 | return 1;
842 | }
843 | }
844 |
845 | /*****************************************************************************/
846 | /* pcxt_clockin : called for keyboard mode PC/XT */
847 | /*****************************************************************************/
848 | // A_0dd6
849 | void pcxt_clockin(uint8_t timer1)
850 | {
851 | static int8_t read_pcxt_nextstate = -2; // 0x010a
852 | static int8_t read_pcxt_state = 1; // 0x010b
853 | static uint8_t read_pcxt_shiftin = 0; // 0x012c
854 | static uint8_t read_pcxt_bits = 0; // 0x012d
855 | uint8_t b = KBDD_GET0; /* get PD0 (PS/2 Data line) */
856 |
857 | if (timer1)
858 | // A_0de0
859 | read_pcxt_state = read_pcxt_nextstate;
860 |
861 | // A_0de8
862 | switch (read_pcxt_state)
863 | {
864 | case -2:
865 | // A_0e7c
866 | b = 5;
867 | break;
868 | case 1 :
869 | // A_0e08
870 | read_pcxt_nextstate = -2;
871 | setup_timer1(1200); // setup timer1 to 1.2ms
872 | read_pcxt_bits = 0;
873 | read_pcxt_shiftin = 0;
874 | if (b)
875 | {
876 | // A_0e24
877 | read_pcxt_state = 2;
878 | return;
879 | }
880 | else
881 | b = 6;
882 | break;
883 | case 2 :
884 | // A_0e2c:
885 | read_pcxt_shiftin = (read_pcxt_shiftin >> 1) | (b << 7); // shift in data bit from the left
886 | if (++read_pcxt_bits != 8)
887 | return;
888 | // A_0e4c
889 | read_pcxt_nextstate = 3;
890 | setup_timer1(120); // set timer 1 to 120 microseconds
891 | read_pcxt_state = 3;
892 | return;
893 | case 3 :
894 | // A_0e5e:
895 | setup_timer1(0);
896 | kbd_rcvd_byte = read_pcxt_shiftin;
897 | b = 2;
898 | break;
899 |
900 | default:
901 | return;
902 | }
903 |
904 | // A_0e7e:
905 | setup_timer1(0);
906 | read_pcxt_state = 1;
907 | if (b != 2)
908 | // A_0e70
909 | {
910 | // print_P(PSTR("!RE "));
911 | act_onboard_led(3000);
912 | }
913 | kbd_rcvd_state = b;
914 | }
915 |
916 | /*****************************************************************************/
917 | /* atps2_clockout */
918 | /*****************************************************************************/
919 | // A_0e94
920 | uint8_t atps2_clockout
921 | (
922 | uint8_t fromt1 /* flag whether called from timer 1 */
923 | )
924 | {
925 | static uint8_t atps2_write_parity = 1; // 0x010c
926 | static int8_t atps2_write_t1state = -1; // 0x010d
927 | static int8_t atps2_write_state = -1; // 0x010e
928 | static uint8_t atps2_write_shiftout = 0; // 0x012f
929 | static int8_t atps2_write_bits = 0; // 0x0130
930 | uint8_t curbit; // R16
931 | uint8_t rc; // R17
932 |
933 | /* To write out a byte, the following has to be done
934 | ( from http://www.computer-engineering.org/ps2protocol/ )
935 | 1) Bring the Clock line low for at least 100 microseconds.
936 | 2) Bring the Data line low.
937 | 3) Release the Clock line.
938 | 4) Wait for the device to bring the Clock line low.
939 | 5) Set/reset the Data line to send the first data bit
940 | 6) Wait for the device to bring Clock high.
941 | 7) Wait for the device to bring Clock low.
942 | 8) Repeat steps 5-7 for the other seven data bits and the parity bit
943 | 9) Release the Data line.
944 | 10) Wait for the device to bring Data low.
945 | 11) Wait for the device to bring Clock low.
946 | 12) Wait for the device to release Data and Clock
947 | */
948 |
949 | if (atps2_write_state == -1) // setup to state 2
950 | atps2_write_state = 2;
951 | if (fromt1) // if coming from timer, switch to t1 state
952 | atps2_write_state = atps2_write_t1state;
953 |
954 | switch (atps2_write_state)
955 | {
956 | // Obviously, no states 0/1 in this one...
957 | // Has encoded the expected clock line state in bit 0
958 | case 2:
959 | // 1) Bring clock line low and wait for 200microseconds
960 | // A_0f0a
961 | atps2_write_shiftout = kbdcmd_to_send;
962 | atps2_write_bits = 8;
963 | atps2_write_parity = 1;
964 | atps2_write_t1state = 3;
965 | setup_timer1(200); // setup timer1 to 0.2ms
966 | set_kbd_clock_pin(0);
967 | break;
968 | case 3 :
969 | // 2) Bring data line low
970 | // 3) release the clock line
971 | // 4) wait up to 20ms for the device to bring the lock line low
972 | // A_0f30
973 | set_kbd_data_pin(0);
974 | set_kbd_clock_pin(1);
975 | atps2_write_t1state = -2;
976 | setup_timer1(20000); // setup timer1 to 20ms
977 | // fall thru to...
978 | case 4 :
979 | // A_0f44
980 | // Expect clock line to be high after request start
981 | atps2_write_state = 5;
982 | break;
983 | case 5 :
984 | // Send one of the 8 data bits
985 | // A_0f48
986 | curbit = atps2_write_shiftout & 1;
987 | set_kbd_data_pin(curbit);
988 | atps2_write_shiftout >>= 1;
989 | atps2_write_parity ^= curbit;
990 | if (--atps2_write_bits)
991 | atps2_write_state = 4;
992 | else
993 | atps2_write_state = 6;
994 | break;
995 | case 6 :
996 | // Expect clock line to be high after one of the data bits
997 | // A_0f7a
998 | atps2_write_state = 7;
999 | break;
1000 | case 7:
1001 | // 8) send out the parity bit
1002 | // A_0f7e
1003 | set_kbd_data_pin(atps2_write_parity);
1004 | atps2_write_bits--;
1005 | atps2_write_state = 8;
1006 | break;
1007 | case 8 :
1008 | // Expect clock line to be high after the parity bit
1009 | // A_0f92
1010 | atps2_write_state = 9;
1011 | break;
1012 | case 9 :
1013 | // 9) Release data line
1014 | // A_0f96
1015 | set_kbd_data_pin(1);
1016 | atps2_write_bits--;
1017 | atps2_write_state = 10;
1018 | break;
1019 | case 10 :
1020 | // Expect clock line to be high after 9)
1021 | // A_0fa8
1022 | atps2_write_state = 11;
1023 | break;
1024 | case 11 :
1025 | // sending done
1026 | // A_0fb0
1027 | setup_timer1(0); // reset timeout counter
1028 | if (KBDD_GET0) // data line is expected to be low now
1029 | rc = 9;
1030 | else
1031 | rc = 2;
1032 | // A_0fcc
1033 | set_kbd_data_pin(1); // release data line
1034 | atps2_write_state = -1;
1035 | #if 0
1036 | usb_debug_putchar('>');
1037 | phex(rc);
1038 | usb_debug_putchar(' ');
1039 | #endif
1040 | return rc;
1041 | case -2 :
1042 | // A_0fbe
1043 | // Something has gone wrong; the operation timed out
1044 | // atps2_write_bits is anything between 8 and -2 (0xfe)
1045 | rc = (atps2_write_bits << 4) | 0x05;
1046 | if (rc >= 2) // that is totally, totally BS IMO, since it's either <0 or >=5
1047 | {
1048 | set_kbd_data_pin(1); // release data line
1049 | atps2_write_state = -1;
1050 | return rc;
1051 | }
1052 | break;
1053 | }
1054 |
1055 | // A_0fd8
1056 | if (KBDC_GET0 == ((uint8_t)atps2_write_state & 1))
1057 | return 1;
1058 | else
1059 | {
1060 | // A_0ff8
1061 | set_kbd_data_pin(1);
1062 | atps2_write_state = -1;
1063 | // print_P(PSTR("!WC "));
1064 | act_onboard_led(3000);
1065 | return 4;
1066 | }
1067 | }
1068 |
1069 | /*****************************************************************************/
1070 | /* atps2_clockin : clock line transition from high to low or timer 1 */
1071 | /*****************************************************************************/
1072 | // A_1016
1073 | uint8_t atps2_clockin(uint8_t bReset)
1074 | {
1075 | static uint8_t read_atps2_parity = 1; // 0x010f
1076 | static int8_t read_atps2_state = -1; // 0x0110
1077 | static uint8_t read_atps2_shiftin = 0; // 0x0131
1078 | static uint8_t read_atps2_bits = 0; // 0x0132
1079 | uint8_t ps2clk = KBDC_GET0; // R15
1080 | uint8_t ps2data = KBDD_GET0; // R16 PS/2 data line
1081 |
1082 | /* AT / PS/2 read logic
1083 | ( from http://www.computer-engineering.org/ps2protocol/ )
1084 |
1085 | Bus idle state is high. When the keyboard wants to send information,
1086 | it first checks the Clock line to make sure it's at a high logic level.
1087 | If it's not, the host is inhibiting communication and the device must
1088 | buffer any to-be-sent data until the host releases Clock.
1089 | The Clock line must be continuously high for at least 50 microseconds
1090 | before the device can begin to transmit its data.
1091 |
1092 | The keyboard uses a serial protocol with 11-bit frames. These bits are:
1093 |
1094 | 1 start bit. This is always 0.
1095 | 8 data bits, least significant bit first.
1096 | 1 parity bit (odd parity).
1097 | 1 stop bit. This is always 1.
1098 |
1099 | The keyboard/mouse writes a bit on the Data line when Clock is high,
1100 | and it is read by the host when Clock is low.
1101 |
1102 | */
1103 |
1104 | if (bReset)
1105 | {
1106 | read_atps2_state = -1;
1107 | return 5;
1108 | }
1109 | // A_102e
1110 | if (read_atps2_state == -1)
1111 | read_atps2_state = 1;
1112 |
1113 | // A_103c
1114 | //ps2data = KBDD_GET0; // PS/2 Data line
1115 |
1116 | switch (read_atps2_state)
1117 | {
1118 | case 1 :
1119 | // A_106c
1120 | setup_timer1(1200); // setup timer1 to 1.2ms
1121 | read_atps2_bits = 0;
1122 | read_atps2_shiftin = 0;
1123 | read_atps2_parity = 1;
1124 | if (ps2data)
1125 | {
1126 | // A_1132
1127 | setup_timer1(0);
1128 | read_atps2_state = -1;
1129 | return 6;
1130 | }
1131 | read_atps2_state = 4;
1132 | break;
1133 | case 4 :
1134 | // A_1086
1135 | read_atps2_state = 5;
1136 | break;
1137 | case 5 :
1138 | // A_108a
1139 | read_atps2_shiftin = (ps2data << 7) | (read_atps2_shiftin >> 1); // shift in new bit
1140 | read_atps2_parity ^= ps2data;
1141 | if (++read_atps2_bits == 8)
1142 | read_atps2_state = 6;
1143 | else
1144 | read_atps2_state = 4;
1145 | break;
1146 | case 6 :
1147 | // A_10c2
1148 | read_atps2_state = 7;
1149 | break;
1150 | case 7 :
1151 | // A_10c6
1152 | if (read_atps2_parity != ps2data)
1153 | {
1154 | // A_1132:
1155 | setup_timer1(0);
1156 | read_atps2_state = -1;
1157 | return 7;
1158 | }
1159 | read_atps2_state = 8;
1160 | break;
1161 | case 8 :
1162 | // A_10d6
1163 | read_atps2_state = 9;
1164 | break;
1165 | case 9 :
1166 | // A_10da
1167 | if (ps2data)
1168 | {
1169 | kbd_rcvd_byte = read_atps2_shiftin;
1170 | keyboard_mode = 1;
1171 | setup_timer1(0);
1172 | read_atps2_state = -1;
1173 | return 2;
1174 | }
1175 | else
1176 | {
1177 | // A_10f0
1178 | // print_P(PSTR("!DL "));
1179 | act_onboard_led(3000);
1180 | setup_timer1(0);
1181 | read_atps2_state = -1;
1182 | return 8;
1183 | }
1184 | break;
1185 | }
1186 |
1187 | // A_10fa
1188 | if ((uint8_t)(read_atps2_state & 1) == ps2clk)
1189 | return 1;
1190 | else
1191 | {
1192 | // A_111a
1193 | read_atps2_state = -1;
1194 | // print_P(PSTR("!CE "));
1195 | act_onboard_led(3000);
1196 | return 4;
1197 | }
1198 | }
1199 |
1200 | /*****************************************************************************/
1201 | /* atps2_clock : called for keyboard modes 1,3,4 */
1202 | /*****************************************************************************/
1203 | // A_1142
1204 | void atps2_clock
1205 | (
1206 | uint8_t cmode // 0=from IRQ1/init_kbd, 1=timed out, 2=from send_kbd_command
1207 | )
1208 | {
1209 | static uint8_t data_0x0134 = 0; // 0x0134
1210 | static uint8_t data_0x0135 = 0; // 0x0135
1211 | uint8_t b; // little helper
1212 |
1213 | if (cmode == 2) // if called from send_kbd_command
1214 | {
1215 | if (keyboard_mode == 2)
1216 | {
1217 | data_0x0133 = 3;
1218 | return;
1219 | }
1220 | // A_1162
1221 | if (data_0x0135 == 1)
1222 | {
1223 | data_0x0135 = 3;
1224 | if (data_0x0133)
1225 | {
1226 | // print_P(PSTR("!X1 "));
1227 | act_onboard_led(3000);
1228 | }
1229 | // A_117e
1230 | data_0x0133 = 1;
1231 | cmode = 0;
1232 | }
1233 | else
1234 | {
1235 | // A_1188
1236 | data_0x0134 = 1;
1237 | return;
1238 | }
1239 | }
1240 |
1241 | // A_1190
1242 | // R15 = 1;
1243 | // R13 = 2;
1244 | // R14 = 3;
1245 |
1246 | // A_119c
1247 | while (1)
1248 | {
1249 | switch (data_0x0135)
1250 | {
1251 | case 0 :
1252 | // A_11b4
1253 | b = A_0d5c(cmode);
1254 | if (b < 2)
1255 | return;
1256 | // A_11be
1257 | else if (b == 2)
1258 | {
1259 | // A_11c2
1260 | if (data_0x0134 != 0)
1261 | {
1262 | data_0x0134 = 0;
1263 | if (data_0x0133 != 0)
1264 | {
1265 | // print_P(PSTR("!X2 "));
1266 | act_onboard_led(3000);
1267 | }
1268 | // A_11dc
1269 | data_0x0133 = 1;
1270 | data_0x0135 = 3;
1271 | cmode = 0;
1272 | }
1273 | else
1274 | {
1275 | // A_11e8
1276 | data_0x0135 = 1;
1277 | return;
1278 | }
1279 | }
1280 | break;
1281 | case 1 :
1282 | // A_11f0
1283 | if (KBDC_GET) // if PS/2 Clock line high
1284 | data_0x0135 = 0;
1285 | else
1286 | {
1287 | if (data_0x0133 != 0)
1288 | {
1289 | // print_P(PSTR("!X3 "));
1290 | act_onboard_led(3000);
1291 | }
1292 | // A_1202
1293 | kbd_rcvd_state = 1;
1294 | data_0x0135 = 2;
1295 | }
1296 | break;
1297 | case 2 :
1298 | // A_120c
1299 | b = atps2_clockin(cmode);
1300 | if (b < 2)
1301 | return;
1302 | else if (b != 2)
1303 | {
1304 | // print_P(PSTR("!X4 "));
1305 | act_onboard_led(3000);
1306 | }
1307 | // A_1220
1308 | kbd_rcvd_state = b;
1309 | data_0x0135 = 0;
1310 | break;
1311 | case 3 :
1312 | // A_1226
1313 | b = atps2_clockout(cmode);
1314 | if (b < 2)
1315 | return;
1316 | data_0x0133 = b;
1317 | data_0x0135 = 0;
1318 | break;
1319 | default :
1320 | return;
1321 | }
1322 | }
1323 | }
1324 |
1325 | /*****************************************************************************/
1326 | /* INT1_vect : external interrupt request 1 */
1327 | /*****************************************************************************/
1328 | // A_1244
1329 | ISR(INT1_vect)
1330 | {
1331 | if (keyboard_mode == 2) /* if PC/XT keyboard attached */
1332 | pcxt_clockin(0);
1333 | else /* if AT / PS/2 keyboard attached */
1334 | atps2_clock(0);
1335 | }
1336 |
1337 | /*****************************************************************************/
1338 | /* init_kbd : initializes external keyboard handling */
1339 | /*****************************************************************************/
1340 | // A_129a
1341 | void init_kbd(void)
1342 | {
1343 | cli(); /* disable interrupts */
1344 | set_kbd_clock_pin(1);
1345 | set_kbd_data_pin(1);
1346 | TCCR1A = 0; // normal port operation
1347 | TCCR1B = (1 << WGM12); // Timer/Counter mode CTC
1348 | // The falling edge of INT1 generates asynchronously an interrupt request
1349 | EICRA = (EICRA & ~((1 << ISC11) | (1 << ISC10))) | (1 << ISC10);
1350 | // Allow External Interrupt 1
1351 | EIMSK |= (1 << INT1);
1352 | atps2_clock(0);
1353 | sei(); /* allow interrupts */
1354 | }
1355 |
1356 | /*****************************************************************************/
1357 | /* TIMER1_COMPA_vect : Timer/Counter1 Compare Match A */
1358 | /*****************************************************************************/
1359 | // A_12c4
1360 | ISR(TIMER1_COMPA_vect)
1361 | {
1362 | TCCR1B &= ~((1 << COM1C0) | (1 << WGM11) | (1 << WGM10));
1363 | TIMSK1 &= ~(1 << OCIE1A);
1364 | _NOP();
1365 | TCNT1H = 0;
1366 | TCNT1L = 0;
1367 | TIFR1 = (1 << OCF1A);
1368 | if (keyboard_mode == 2) /* if PC / XT keyboard attached */
1369 | pcxt_clockin(1);
1370 | else /* if AT / PS/2 keyboard attached */
1371 | atps2_clock(1);
1372 | }
1373 |
1374 | /*****************************************************************************/
1375 | /* send_kbd_command : */
1376 | /*****************************************************************************/
1377 | // A_133c
1378 | uint8_t send_kbd_command(uint8_t cmd /*R24*/, uint8_t timeout/*R22*/)
1379 | {
1380 | uint32_t startcounter; // R14-17
1381 | uint8_t ret;
1382 |
1383 | if (keyboard_mode == 2) // not possible on PC/XT keyboards
1384 | return 0;
1385 |
1386 | act_onboard_led2(10); // little "special" - blink LED2 on each outgoing kbd byte
1387 |
1388 | // A1356
1389 | usb_debug_putchar('w');
1390 | phex(cmd);
1391 | usb_debug_putchar(' ');
1392 | // A_1362
1393 | cli();
1394 | kbdcmd_to_send = cmd;
1395 | data_0x0133 = 0;
1396 | atps2_clock(2);
1397 | sei();
1398 |
1399 | // A_1372
1400 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
1401 | startcounter = timer0_counter;
1402 |
1403 | // A_13c2
1404 | while (data_0x0133 < 2)
1405 | {
1406 | if (timeout)
1407 | {
1408 | uint32_t now;
1409 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
1410 | now = timer0_counter;
1411 | // A_1392
1412 | if (now - startcounter > timeout)
1413 | return 10;
1414 | }
1415 | }
1416 |
1417 | // A_13ca
1418 | ret = data_0x0133;
1419 | data_0x0133 = 0;
1420 | return ret;
1421 | }
1422 |
1423 | /*****************************************************************************/
1424 | /* fetch_kbd_byte : fetches a byte from PS/2 data line with timeout */
1425 | /*****************************************************************************/
1426 | // A_13de
1427 | uint8_t fetch_kbd_byte(uint8_t *addr, uint8_t timeout)
1428 | {
1429 | uint8_t b; // R13
1430 | uint32_t startcounter;
1431 |
1432 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
1433 | startcounter = timer0_counter;
1434 |
1435 | b = kbd_rcvd_state;
1436 | if (timeout)
1437 | {
1438 | while (b < 2)
1439 | {
1440 | uint32_t now;
1441 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
1442 | now = timer0_counter;
1443 | if (now - startcounter > timeout)
1444 | return b;
1445 | b = kbd_rcvd_state;
1446 | }
1447 | }
1448 | // A_144c
1449 | else if (b < 2)
1450 | return b;
1451 |
1452 | // A_1452
1453 | kbd_rcvd_state = 0;
1454 | if (b == 2)
1455 | {
1456 | usb_debug_putchar('r');
1457 | phex(kbd_rcvd_byte);
1458 | usb_debug_putchar(' ');
1459 | if (addr)
1460 | *addr = kbd_rcvd_byte;
1461 | }
1462 | else
1463 | {
1464 | usb_debug_putchar('R');
1465 | phex(b);
1466 | usb_debug_putchar(' ');
1467 | }
1468 |
1469 | return b;
1470 | }
1471 |
1472 | /*****************************************************************************/
1473 | /* get_kbd_byte */
1474 | /*****************************************************************************/
1475 | // A_1492
1476 | uint8_t get_kbd_byte(uint8_t timeout)
1477 | {
1478 | uint8_t kbdbyte; // allocated on stack
1479 | uint8_t ret = fetch_kbd_byte(&kbdbyte, timeout);
1480 | if (ret != 2)
1481 | {
1482 | kbdbyte = 0;
1483 | usb_debug_putchar('R');
1484 | usb_debug_putchar('1');
1485 | phex(ret);
1486 | }
1487 | return kbdbyte;
1488 | }
1489 |
1490 | /*****************************************************************************/
1491 | /* send_kbd_command_with_parm : sends a squence of 2 commands with ACK wait */
1492 | /*****************************************************************************/
1493 | // A_14c6
1494 | uint8_t send_kbd_command_with_parm(uint8_t command, uint8_t cmdparm)
1495 | {
1496 | uint8_t i;
1497 | uint8_t rc;
1498 |
1499 | if (keyboard_mode == 2)
1500 | return 0;
1501 | // A_14da:
1502 | for (i = 3; i > 0; i--) /* 3 tries */
1503 | {
1504 | rc = send_kbd_command(command, 50);
1505 | if (rc == 2)
1506 | {
1507 | // A_14e8
1508 | rc = get_kbd_byte(50);
1509 | if (rc == KBDM_ACK) // if not an ACK
1510 | {
1511 | // A_14f2
1512 | rc = send_kbd_command(cmdparm, 50);
1513 | if (rc == 2)
1514 | {
1515 | // A_14fe
1516 | rc = get_kbd_byte(50);
1517 | if (rc == KBDM_ACK)
1518 | // A_1508
1519 | return 1;
1520 | else
1521 | {
1522 | // A_150c:
1523 | usb_debug_putchar('!');
1524 | usb_debug_putchar('!');
1525 | }
1526 | }
1527 | else
1528 | {
1529 | // A_1514
1530 | usb_debug_putchar('W');
1531 | usb_debug_putchar('2');
1532 | }
1533 | }
1534 | else
1535 | {
1536 | // A_150c:
1537 | usb_debug_putchar('!');
1538 | usb_debug_putchar('!');
1539 | }
1540 | }
1541 | else
1542 | {
1543 | // A_151c:
1544 | usb_debug_putchar('W');
1545 | usb_debug_putchar('1');
1546 | }
1547 |
1548 | // A_1524:
1549 | phex(rc);
1550 | }
1551 | return 0;
1552 | }
1553 |
1554 | /*****************************************************************************/
1555 | /* send_kbd_command_without_parm : sends a single-byte AT/PS2 command */
1556 | /*****************************************************************************/
1557 | // A_1538
1558 | uint8_t send_kbd_command_without_parm(uint8_t command)
1559 | {
1560 | // R15 = command;
1561 | uint8_t i; // R16;
1562 | uint8_t rc; // R17;
1563 | if (keyboard_mode == 2) /* not for PC / XT keyboards */
1564 | return 0;
1565 |
1566 | for (i = 3; i > 0; i--)
1567 | {
1568 | // A_154a:
1569 | rc = send_kbd_command(command, 50);
1570 | if (rc == 2)
1571 | {
1572 | // A_1556
1573 | rc = get_kbd_byte(50);
1574 | if (rc == KBDM_ACK)
1575 | return 1;
1576 | else
1577 | {
1578 | // A_1564
1579 | usb_debug_putchar('!');
1580 | usb_debug_putchar('!');
1581 | }
1582 | }
1583 | else
1584 | {
1585 | // A_156c
1586 | usb_debug_putchar('W');
1587 | usb_debug_putchar('0');
1588 | }
1589 | // A_1574
1590 | phex(rc);
1591 | }
1592 |
1593 | return 0;
1594 | }
1595 |
1596 | /*****************************************************************************/
1597 | /* act_onboard_led : turns on the onboard LED */
1598 | /*****************************************************************************/
1599 | // A_1586
1600 | void act_onboard_led(uint16_t counter)
1601 | {
1602 | onboard_led_counter = counter;
1603 | OBLED_ON;
1604 | }
1605 |
1606 | /*****************************************************************************/
1607 | /* act_onboard_led2 : turns on the onboard LED 2 */
1608 | /*****************************************************************************/
1609 | #ifdef OBLED2_CONFIG
1610 | void act_onboard_led2(uint16_t counter)
1611 | {
1612 | onboard_led2_counter = counter;
1613 | OBLED2_ON;
1614 | }
1615 | #endif
1616 |
1617 | /*****************************************************************************/
1618 | /* setup_timer0 : */
1619 | /*****************************************************************************/
1620 | // A_1592
1621 | void setup_timer0(void)
1622 | {
1623 | TIMSK0 |= (1 << OCIE0A); // Enable Compare/Match A Interrupt
1624 | // (F_CPU / 64) / 1000 for 16MHz
1625 | OCR0A = 250; // With Prescaler/64, this gives 1 tick per ms
1626 | TCCR0A = (1 << WGM01); // Clear Timer on Compare Match mode
1627 | TCCR0B = 0; // Stop Timer 0
1628 | // Run Timer 0 with Prescaler/64
1629 | TCCR0B |= ((1 << CS00) | (1 << CS01));
1630 | }
1631 |
1632 | /*****************************************************************************/
1633 | /* TIMER0_COMPA_vect : Timer/Counter0 Compare Match A */
1634 | /*****************************************************************************/
1635 | // A_15ae
1636 | ISR(TIMER0_COMPA_vect)
1637 | {
1638 | // Ticks once per ms
1639 | static uint8_t volatile in_macro_tick = 0; // 0x013c recursion protection
1640 |
1641 | timer0_counter++;
1642 | // A_15f6
1643 | if (onboard_led_counter)
1644 | onboard_led_counter--;
1645 | else
1646 | OBLED_OFF; /* turn off onboard LED */
1647 |
1648 | #ifdef OBLED2_CONFIG
1649 | if (onboard_led2_counter)
1650 | onboard_led2_counter--;
1651 | else
1652 | OBLED2_OFF; /* turn off onboard LED 2 */
1653 | #endif
1654 |
1655 | // A_1610
1656 | if (in_macro_tick == 0)
1657 | {
1658 | in_macro_tick = 1;
1659 | sei();
1660 | macro_tick();
1661 | in_macro_tick = 0;
1662 | }
1663 | }
1664 |
--------------------------------------------------------------------------------
/soarer.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************/
2 | /* Soarer.h : main routine and support functions */
3 | /*****************************************************************************/
4 |
5 | #ifndef _soarer_h_
6 | #define _soarer_h_
7 |
8 | #include
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | extern uint32_t volatile timer0_counter; // 0x0136
15 |
16 | #ifdef __cplusplus
17 | }
18 | #endif
19 |
20 | #endif // defined _soarer_h_
21 |
--------------------------------------------------------------------------------
/usb_comm.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************/
2 | /* usb_comm.h : USB communication handling for hardware USB AVRs */
3 | /*****************************************************************************/
4 |
5 | #ifndef _usb_comm_h__
6 | #define _usb_comm_h__
7 |
8 | #include
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | extern uint8_t keyboard_protocol; // 0x0119
15 | extern uint8_t volatile usb_suspended; // 0x013d
16 | extern uint8_t volatile usb_resuming; // 0x013e
17 | extern uint8_t keyboard_modifier_keys; // 0x0140
18 | extern uint8_t volatile keyboard_leds; // 0x0141
19 |
20 |
21 | uint8_t reset_usb_keyboard_data(void); // A_16c0
22 | void usb_init(void); // A_16ee // initialize everything
23 | void usb_remote_wakeup(void); // A_172a
24 | uint8_t usb_keyboard_press(uint8_t keyid); // A_174c
25 | uint8_t usb_keyboard_release(uint8_t keyid); // A_1848
26 | uint8_t usb_keyboard_send(uint8_t flagset); // A_192e
27 | int8_t usb_debug_putchar(uint8_t c); // A_1a62 // transmit a character
28 |
29 | int8_t usb_rawhid_recv(uint8_t *buffer, uint8_t timeout); // A_2254
30 | int8_t usb_rawhid_send(const uint8_t *buffer, uint8_t timeout); // A_22b0
31 |
32 | uint8_t usb_configured(void); // is the USB port configured
33 | void usb_debug_flush_output(void); // immediately transmit any buffered output
34 |
35 | #define USB_DEBUG_HID
36 |
37 | #ifdef __cplusplus
38 | }
39 | #endif
40 |
41 | #endif /* defined(_usb_comm_h__) */
42 |
--------------------------------------------------------------------------------