1 /*---------------------------------------------------------------------------*
2 Project: Revolution Low-Level Sync USB keyboard demo
3 File: kbdLowLevelSync.c
4
5 Copyright 2007 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: kbdLowLevelSync.c,v $
14 Revision 1.12.6.1 2009/10/14 10:03:27 iwai_yuma
15 Rool back into StackB.
16
17 Revision 1.10 2007/10/08 18:44:55 henrch
18 per API change
19
20 Revision 1.9 2007/10/03 22:48:01 henrch
21 changed to use new KBD / HID lib
22
23 Revision 1.8 2007/07/13 23:37:18 carlmu
24 Changed from TrySetLeds to KBDSetLedsRetry.
25
26 Revision 1.7 2007/06/21 22:46:50 carlmu
27 Updated for KBD 1.4 API (changed LED handling).
28
29 Revision 1.6 2007/05/05 01:56:57 carlmu
30 Changes for 0.8 API
31
32 Revision 1.5 2007/04/17 23:55:57 carlmu
33 Updated for 0.5 API.
34
35 Revision 1.4 2007/04/10 18:34:05 carlmu
36 Changed for compatibility with 0.4 API.
37
38 Revision 1.3 2007/04/02 19:12:17 carlmu
39 Set callback functions modified for new return value.
40
41 Revision 1.2 2007/03/29 22:38:01 carlmu
42 Added multiple channel support.
43
44 Revision 1.1 2007/03/28 00:18:25 carlmu
45 Initial version.
46
47
48 $NoKeywords: $
49 *---------------------------------------------------------------------------*/
50
51 /*
52 Example simple keyboard application to output the low-level API HID code
53 to the console. Uses the synchronous keyboard API.
54 */
55
56 #include <demo.h>
57 #include <revolution/kbd.h>
58
59 static u8 __kbd_mem[KBD_MEM_SIZE];
60
61
62 //-----------------------------------------------------------------------------
63
64 #define KBD_CALL(_fn_call) \
65 if ((_fn_call) != KBD_SUCCESS) { \
66 OSReport ("KBD error: calling %s @ %s:%i\n", \
67 #_fn_call, __FILE__, __LINE__); \
68 }
69
70 //-----------------------------------------------------------------------------
71
72 static void
kbdAppAttach(KBDDevEvent * kde)73 kbdAppAttach (KBDDevEvent *kde) {
74 OSReport ("kbd app: keyboard added on channel %d\n", kde->channel);
75 // for demo purposes, enable NumLock on newly attached keyboard
76 KBDSetModState(kde->channel, KBD_MS_NUM_LOCK);
77 KBDSetLedsRetry(kde->channel, KBD_LED_NUM_LOCK);
78 }
79
80
81 static void
kbdAppDetach(KBDDevEvent * kde)82 kbdAppDetach (KBDDevEvent *kde) {
83 OSReport ("kbd app: keyboard removed on channel %d\n", kde->channel);
84 }
85
86
87 static void
kbdAppKeyEvent(KBDKeyEvent * kke)88 kbdAppKeyEvent (KBDKeyEvent *kke) {
89 if (KBD_KEY_MODE_REPEAT(kke->mode)) {
90 return;
91 }
92
93 if (KBD_KEY_MODE_UP(kke->mode))
94 OSReport ("\t\t\thid code: 0x%02x ^ up (chan %d)\n", kke->hid, kke->channel);
95 else
96 OSReport ("hid code: 0x%02x v down (chan %d)\n", kke->hid, kke->channel);
97
98 // check for CapsLock, NumLock, or ScrollLock (handle LEDs)
99 if (kke->hid == KBD_HID_Caps_Lock ||
100 kke->hid == KBD_HID_Keypad_Num_Lock ||
101 kke->unicode == KBK_Scroll_Lock) {
102
103 KBDModState ms;
104 KBDLedState leds;
105
106 // First compute the new LED state
107 KBDGetModState(kke->channel, &ms);
108
109 leds = (KBDLedState)
110 (((ms & KBD_MS_NUM_LOCK) == KBD_MS_NUM_LOCK) * KBD_LED_NUM_LOCK |
111 ((ms & KBD_MS_CAPS_LOCK) == KBD_MS_CAPS_LOCK) * KBD_LED_CAPS_LOCK |
112 ((ms & KBD_MS_SCROLL_LOCK) == KBD_MS_SCROLL_LOCK) * KBD_LED_SCROLL_LOCK);
113
114 KBDSetLedsRetry(kke->channel, leds);
115 }
116 }
117
118 extern void hid_open_async(void);
119 extern void hid_close_async(void);
120
main(void)121 int main(void) {
122 KBDKeyEvent kevent;
123 KBDChannel ch;
124 KBDEc rc;
125
126 DEMOInit (NULL);
127
128 hid_open_async();
129
130 OSReport ("\n\n");
131 OSReport ("************************************************\n");
132 OSReport ("kbdLowLevelSync Low-level Sync keyboard demo\n");
133 OSReport ("************************************************\n");
134 OSReport ("Attach a USB keyboard and press some keys.\n");
135 OSReport ("Use a GameCube controller plugged into port 1.\n");
136 OSReport ("Right Trigger: sleeps for 5 seconds (to test overflow)\n");
137 OSReport ("\n");
138
139 KBD_CALL (KBDInit(&__kbd_mem, kbdAppAttach, kbdAppDetach, 0));
140
141 // One of these MUST be called after calling KBDInit.
142 // It's okay to call more than one.
143 KBDInitRegionUS();
144 KBDInitRegionJP();
145 KBDInitRegionEU();
146
147 while (1) {
148
149 DEMOPadRead();
150
151 if ( DEMOPadGetButtonDown(0) & PAD_TRIGGER_R ) {
152 OSSleepSeconds(5);
153 }
154
155 // poll all keyboard channels
156 for(ch=0; ch<KBD_MAX_CHANNELS; ch++) {
157 KBDChanStatus cstat;
158
159 // see if keyboard is connected
160 KBD_CALL(KBDGetChannelStatus (ch, &cstat));
161 if (cstat == KBD_CS_OK) {
162
163 // call KBDGetKey until queue is empty or error
164 do {
165 rc=KBDGetKey(ch, &kevent);
166 if (rc != KBD_SUCCESS) break;
167
168 if (kevent.hid == KBD_HID_OVERFLOW) {
169 OSReport("KBD queue overflowed!\n");
170 continue;
171 }
172 if (kevent.hid == KBD_HID_NONE) {
173 break;
174 }
175 // process event
176 kbdAppKeyEvent(&kevent);
177 } while (1);
178 }
179 }
180
181 OSYieldThread();
182
183 }
184
185 hid_close_async();
186
187 OSShutdownSystem(); // Never reached!
188
189 return 0;
190 }
191
192
193