2 Copyright 2011 Jun Wako <wakojun@gmail.com>
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.
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.
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/>.
18 #include <avr/interrupt.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>
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);
48 static void set_prr(void)
54 //power_timer0_disable(); // used in timer.c
56 power_timer1_disable();
57 power_timer2_disable();
62 static void pullup_pins(void)
64 // DDRs are set to 0(input) by default.
82 static void disable_vusb(void)
84 // disable interrupt & disconnect to prevent host from enumerating
85 USB_INTR_ENABLE &= ~(1 << USB_INTR_ENABLE_BIT);
86 usbDeviceDisconnect();
89 static void enable_vusb(void)
91 USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
95 static void init_vusb(void)
101 /* fake USB disconnect for > 250 ms */
109 void change_driver(host_driver_t *driver)
111 host_clear_keyboard_report();
112 host_swap_keyboard_report();
113 host_clear_keyboard_report();
114 host_send_keyboard_report();
116 host_set_driver(driver);
120 static bool sleeping = false;
121 static bool insomniac = false; // TODO: should be false for power saving
122 static uint16_t last_timer = 0;
127 clock_prescale_set(clock_div_1);
130 // power saving: the result is worse than nothing... why?
139 print("\nSend BREAK for UART Console Commands.\n");
141 // TODO: move to iWRAP/suart file
142 print("suart init\n");
144 // PC4: Tx Output IDLE(Hi)
147 // PC5: Rx Input(pull-up)
150 // suart receive interrut(PC5/PCINT13)
154 host_set_driver(iwrap_driver());
156 print("iwrap_init()\n");
160 last_timer = timer_read();
163 if (host_get_driver() == vusb_driver())
168 if (host_get_driver() == vusb_driver())
169 vusb_transfer_keyboard();
171 if (matrix_is_modified() || console()) {
172 last_timer = timer_read();
174 } else if (!sleeping && timer_elapsed(last_timer) > 4000) {
176 iwrap_check_connection();
179 if (host_get_driver() == iwrap_driver()) {
180 if (sleeping && !insomniac) {
181 _delay_ms(1); // wait for UART to send
189 static void sleep(uint8_t term)
191 WD_SET(WD_IRQ, term);
194 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
209 static bool console(void)
211 // Send to Bluetoot module WT12
212 static bool breaked = false;
213 if (!uart_available())
220 case 0x00: // BREAK signal
222 print("break(? for help): ");
247 uint8_t command_extra()
249 return console_command(key2asc(host_get_first_key()));
252 static uint8_t console_command(uint8_t c)
257 print("\nCommands for Bluetooth(WT12/iWRAP):\n");
258 print("r: reset. software reset by watchdog\n");
259 print("i: insomniac. prevent KB from sleeping\n");
260 print("c: iwrap_call. CALL for BT connection.\n");
262 print("u: USB mode. switch to USB.\n");
263 print("w: BT mode. switch to Bluetooth.\n");
265 print("k: kill first connection.\n");
266 print("Del: unpair first pairing.\n");
274 insomniac = !insomniac;
276 print("insomniac\n");
278 print("not insomniac\n");
281 print("iwrap_call()\n");
288 change_driver(vusb_driver());
291 // disable suart receive interrut(PC5/PCINT13)
292 PCMSK1 &= ~(0b00100000);
293 PCICR &= ~(0b00000010);
296 print("iWRAP mode\n");
297 change_driver(iwrap_driver());
299 // enable suart receive interrut(PC5/PCINT13)
300 PCMSK1 |= 0b00100000;
316 // convert keycode into ascii charactor
317 static uint8_t key2asc(uint8_t key)
320 case KC_A: return 'a';
321 case KC_B: return 'b';
322 case KC_C: return 'c';
323 case KC_D: return 'd';
324 case KC_E: return 'e';
325 case KC_F: return 'f';
326 case KC_G: return 'g';
327 case KC_H: return 'h';
328 case KC_I: return 'i';
329 case KC_J: return 'j';
330 case KC_K: return 'k';
331 case KC_L: return 'l';
332 case KC_M: return 'm';
333 case KC_N: return 'n';
334 case KC_O: return 'o';
335 case KC_P: return 'p';
336 case KC_Q: return 'q';
337 case KC_R: return 'r';
338 case KC_S: return 's';
339 case KC_T: return 't';
340 case KC_U: return 'u';
341 case KC_V: return 'v';
342 case KC_W: return 'w';
343 case KC_X: return 'x';
344 case KC_Y: return 'y';
345 case KC_Z: return 'z';
346 case KC_1: return '1';
347 case KC_2: return '2';
348 case KC_3: return '3';
349 case KC_4: return '4';
350 case KC_5: return '5';
351 case KC_6: return '6';
352 case KC_7: return '7';
353 case KC_8: return '8';
354 case KC_9: return '9';
355 case KC_0: return '0';
356 case KC_ENTER: return '\n';
357 case KC_ESCAPE: return 0x1B;
358 case KC_BSPACE: return '\b';
359 case KC_TAB: return '\t';
360 case KC_SPACE: return ' ';
361 case KC_MINUS: return '-';
362 case KC_EQUAL: return '=';
363 case KC_LBRACKET: return '[';
364 case KC_RBRACKET: return ']';
365 case KC_BSLASH: return '\\';
366 case KC_NONUS_HASH: return '\\';
367 case KC_SCOLON: return ';';
368 case KC_QUOTE: return '\'';
369 case KC_GRAVE: return '`';
370 case KC_COMMA: return ',';
371 case KC_DOT: return '.';
372 case KC_SLASH: return '/';
373 default: return 0x00;