]> git.gir.st - tmk_keyboard.git/blob - protocol/iwrap/main.c
Fix projects for new keycodes
[tmk_keyboard.git] / protocol / iwrap / main.c
1 /*
2 Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include <stdint.h>
18 #include <avr/interrupt.h>
19 #include <avr/io.h>
20 //#include <avr/wdt.h>
21 #include "wd.h" // in order to use watchdog in interrupt mode
22 #include <avr/sleep.h>
23 #include <util/delay.h>
24 #include <avr/power.h>
25 #include "keyboard.h"
26 #include "matrix.h"
27 #include "host.h"
28 #include "iwrap.h"
29 #ifdef HOST_VUSB
30 # include "vusb.h"
31 # include "usbdrv.h"
32 #endif
33 #include "uart.h"
34 #include "suart.h"
35 #include "timer.h"
36 #include "debug.h"
37 #include "keycode.h"
38 #include "command.h"
39
40
41 static void sleep(uint8_t term);
42 static bool console(void);
43 static uint8_t console_command(uint8_t c);
44 static uint8_t key2asc(uint8_t key);
45
46
47 /*
48 static void set_prr(void)
49 {
50 power_adc_disable();
51 power_spi_disable();
52 power_twi_disable();
53 #ifndef TIMER_H
54 //power_timer0_disable(); // used in timer.c
55 #endif
56 power_timer1_disable();
57 power_timer2_disable();
58 }
59 */
60
61 /*
62 static void pullup_pins(void)
63 {
64 // DDRs are set to 0(input) by default.
65 #ifdef PORTA
66 PORTA = 0xFF;
67 #endif
68 PORTB = 0xFF;
69 PORTC = 0xFF;
70 PORTD = 0xFF;
71 #ifdef PORTE
72 PORTE = 0xFF;
73 #endif
74 #ifdef PORTE
75 PORTF = 0xFF;
76 #endif
77 }
78 */
79
80
81 #ifdef HOST_VUSB
82 static void disable_vusb(void)
83 {
84 // disable interrupt & disconnect to prevent host from enumerating
85 USB_INTR_ENABLE &= ~(1 << USB_INTR_ENABLE_BIT);
86 usbDeviceDisconnect();
87 }
88
89 static void enable_vusb(void)
90 {
91 USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
92 usbDeviceConnect();
93 }
94
95 static void init_vusb(void)
96 {
97 uint8_t i = 0;
98
99 usbInit();
100 disable_vusb();
101 /* fake USB disconnect for > 250 ms */
102 while(--i){
103 _delay_ms(1);
104 }
105 enable_vusb();
106 }
107 #endif
108
109 void change_driver(host_driver_t *driver)
110 {
111 host_clear_keyboard_report();
112 host_swap_keyboard_report();
113 host_clear_keyboard_report();
114 host_send_keyboard_report();
115 _delay_ms(1000);
116 host_set_driver(driver);
117 }
118
119
120 static bool sleeping = false;
121 static bool insomniac = false; // TODO: should be false for power saving
122 static uint16_t last_timer = 0;
123
124 int main(void)
125 {
126 MCUSR = 0;
127 clock_prescale_set(clock_div_1);
128 WD_SET(WD_OFF);
129
130 // power saving: the result is worse than nothing... why?
131 //pullup_pins();
132 //set_prr();
133
134 print_enable = true;
135 debug_enable = false;
136
137 #ifdef HOST_VUSB
138 disable_vusb();
139 #endif
140 uart_init(115200);
141 keyboard_init();
142 print("\nSend BREAK for UART Console Commands.\n");
143
144 // TODO: move to iWRAP/suart file
145 print("suart init\n");
146 // suart init
147 // PC4: Tx Output IDLE(Hi)
148 PORTC |= (1<<4);
149 DDRC |= (1<<4);
150 // PC5: Rx Input(pull-up)
151 PORTC |= (1<<5);
152 DDRC &= ~(1<<5);
153 // suart receive interrut(PC5/PCINT13)
154 PCMSK1 = 0b00100000;
155 PCICR = 0b00000010;
156
157 host_set_driver(iwrap_driver());
158
159 print("iwrap_init()\n");
160 iwrap_init();
161 iwrap_call();
162
163 last_timer = timer_read();
164 while (true) {
165 #ifdef HOST_VUSB
166 if (host_get_driver() == vusb_driver())
167 usbPoll();
168 #endif
169 keyboard_task();
170 #ifdef HOST_VUSB
171 if (host_get_driver() == vusb_driver())
172 vusb_transfer_keyboard();
173 #endif
174 if (matrix_is_modified() || console()) {
175 last_timer = timer_read();
176 sleeping = false;
177 } else if (!sleeping && timer_elapsed(last_timer) > 4000) {
178 sleeping = true;
179 iwrap_check_connection();
180 }
181
182 if (host_get_driver() == iwrap_driver()) {
183 if (sleeping && !insomniac) {
184 _delay_ms(1); // wait for UART to send
185 iwrap_sleep();
186 sleep(WDTO_60MS);
187 }
188 }
189 }
190 }
191
192 static void sleep(uint8_t term)
193 {
194 WD_SET(WD_IRQ, term);
195
196 cli();
197 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
198 sleep_enable();
199 sleep_bod_disable();
200 sei();
201 sleep_cpu();
202 sleep_disable();
203
204 WD_SET(WD_OFF);
205 }
206
207 ISR(WDT_vect)
208 {
209 // wake up
210 }
211
212 static bool console(void)
213 {
214 // Send to Bluetoot module WT12
215 static bool breaked = false;
216 if (!uart_available())
217 return false;
218 else {
219 uint8_t c;
220 c = uart_getchar();
221 uart_putchar(c);
222 switch (c) {
223 case 0x00: // BREAK signal
224 if (!breaked) {
225 print("break(? for help): ");
226 breaked = true;
227 }
228 break;
229 case '\r':
230 uart_putchar('\n');
231 iwrap_buf_send();
232 break;
233 case '\b':
234 iwrap_buf_del();
235 break;
236 default:
237 if (breaked) {
238 print("\n");
239 console_command(c);
240 breaked = false;
241 } else {
242 iwrap_buf_add(c);
243 }
244 break;
245 }
246 return true;
247 }
248 }
249
250 uint8_t command_extra()
251 {
252 return console_command(key2asc(host_get_first_key()));
253 }
254
255 static uint8_t console_command(uint8_t c)
256 {
257 switch (c) {
258 case 'h':
259 case '?':
260 print("\nCommands for Bluetooth(WT12/iWRAP):\n");
261 print("r: reset. software reset by watchdog\n");
262 print("i: insomniac. prevent KB from sleeping\n");
263 print("c: iwrap_call. CALL for BT connection.\n");
264 #ifdef HOST_VUSB
265 print("u: USB mode. switch to USB.\n");
266 print("w: BT mode. switch to Bluetooth.\n");
267 #endif
268 print("k: kill first connection.\n");
269 print("Del: unpair first pairing.\n");
270 print("\n");
271 return 0;
272 case 'r':
273 print("reset\n");
274 WD_AVR_RESET();
275 return 1;
276 case 'i':
277 insomniac = !insomniac;
278 if (insomniac)
279 print("insomniac\n");
280 else
281 print("not insomniac\n");
282 return 1;
283 case 'c':
284 print("iwrap_call()\n");
285 iwrap_call();
286 return 1;
287 #ifdef HOST_VUSB
288 case 'u':
289 print("USB mode\n");
290 init_vusb();
291 change_driver(vusb_driver());
292 //iwrap_kill();
293 //iwrap_sleep();
294 // disable suart receive interrut(PC5/PCINT13)
295 PCMSK1 &= ~(0b00100000);
296 PCICR &= ~(0b00000010);
297 return 1;
298 case 'w':
299 print("iWRAP mode\n");
300 change_driver(iwrap_driver());
301 disable_vusb();
302 // enable suart receive interrut(PC5/PCINT13)
303 PCMSK1 |= 0b00100000;
304 PCICR |= 0b00000010;
305 return 1;
306 #endif
307 case 'k':
308 print("kill\n");
309 iwrap_kill();
310 return 1;
311 case 0x7F: // DELETE
312 print("unpair\n");
313 iwrap_unpair();
314 return 1;
315 }
316 return 0;
317 }
318
319 // convert keycode into ascii charactor
320 static uint8_t key2asc(uint8_t key)
321 {
322 switch (key) {
323 case KC_A: return 'a';
324 case KC_B: return 'b';
325 case KC_C: return 'c';
326 case KC_D: return 'd';
327 case KC_E: return 'e';
328 case KC_F: return 'f';
329 case KC_G: return 'g';
330 case KC_H: return 'h';
331 case KC_I: return 'i';
332 case KC_J: return 'j';
333 case KC_K: return 'k';
334 case KC_L: return 'l';
335 case KC_M: return 'm';
336 case KC_N: return 'n';
337 case KC_O: return 'o';
338 case KC_P: return 'p';
339 case KC_Q: return 'q';
340 case KC_R: return 'r';
341 case KC_S: return 's';
342 case KC_T: return 't';
343 case KC_U: return 'u';
344 case KC_V: return 'v';
345 case KC_W: return 'w';
346 case KC_X: return 'x';
347 case KC_Y: return 'y';
348 case KC_Z: return 'z';
349 case KC_1: return '1';
350 case KC_2: return '2';
351 case KC_3: return '3';
352 case KC_4: return '4';
353 case KC_5: return '5';
354 case KC_6: return '6';
355 case KC_7: return '7';
356 case KC_8: return '8';
357 case KC_9: return '9';
358 case KC_0: return '0';
359 case KC_ENTER: return '\n';
360 case KC_ESCAPE: return 0x1B;
361 case KC_BSPACE: return '\b';
362 case KC_TAB: return '\t';
363 case KC_SPACE: return ' ';
364 case KC_MINUS: return '-';
365 case KC_EQUAL: return '=';
366 case KC_LBRACKET: return '[';
367 case KC_RBRACKET: return ']';
368 case KC_BSLASH: return '\\';
369 case KC_NONUS_HASH: return '\\';
370 case KC_SCOLON: return ';';
371 case KC_QUOTE: return '\'';
372 case KC_GRAVE: return '`';
373 case KC_COMMA: return ',';
374 case KC_DOT: return '.';
375 case KC_SLASH: return '/';
376 default: return 0x00;
377 }
378 }
Imprint / Impressum