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