aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/protocol/iwrap/iwrap.c
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/protocol/iwrap/iwrap.c')
-rw-r--r--tmk_core/protocol/iwrap/iwrap.c420
1 files changed, 0 insertions, 420 deletions
diff --git a/tmk_core/protocol/iwrap/iwrap.c b/tmk_core/protocol/iwrap/iwrap.c
deleted file mode 100644
index 4d0ca5756..000000000
--- a/tmk_core/protocol/iwrap/iwrap.c
+++ /dev/null
@@ -1,420 +0,0 @@
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
18/* host driver for Bulegiga iWRAP */
19/* Bluegiga BT12
20 * Connections
21 * Hardware UART Software UART BlueTooth
22 * PC=====UART=======AVR=====SUART====iWRAP(BT12)-----------PC
23 *
24 * - Hardware UART for Debug Console to communicate iWRAP
25 * - Software UART for iWRAP control to send keyboard/mouse data
26 */
27
28#include <stdint.h>
29#include <string.h>
30#include <avr/interrupt.h>
31#include <util/delay.h>
32#include "keycode.h"
33#include "suart.h"
34#include "uart.h"
35#include "report.h"
36#include "host_driver.h"
37#include "iwrap.h"
38#include "print.h"
39
40/* iWRAP MUX mode utils. 3.10 HID raw mode(iWRAP_HID_Application_Note.pdf) */
41#define MUX_HEADER(LINK, LENGTH) \
42 do { \
43 xmit(0xbf); /* SOF */ \
44 xmit(LINK); /* Link */ \
45 xmit(0x00); /* Flags */ \
46 xmit(LENGTH); /* Length */ \
47 } while (0)
48#define MUX_FOOTER(LINK) xmit(LINK ^ 0xff)
49
50static uint8_t connected = 0;
51// static uint8_t channel = 1;
52
53/* iWRAP buffer */
54#define MUX_BUF_SIZE 64
55static char buf[MUX_BUF_SIZE];
56static uint8_t snd_pos = 0;
57
58#define MUX_RCV_BUF_SIZE 256
59static char rcv_buf[MUX_RCV_BUF_SIZE];
60static uint8_t rcv_head = 0;
61static uint8_t rcv_tail = 0;
62
63/* receive buffer */
64static void rcv_enq(char c) {
65 uint8_t next = (rcv_head + 1) % MUX_RCV_BUF_SIZE;
66 if (next != rcv_tail) {
67 rcv_buf[rcv_head] = c;
68 rcv_head = next;
69 }
70}
71
72static char rcv_deq(void) {
73 char c = 0;
74 if (rcv_head != rcv_tail) {
75 c = rcv_buf[rcv_tail++];
76 rcv_tail %= MUX_RCV_BUF_SIZE;
77 }
78 return c;
79}
80
81/*
82static char rcv_peek(void)
83{
84 if (rcv_head == rcv_tail)
85 return 0;
86 return rcv_buf[rcv_tail];
87}
88*/
89
90static void rcv_clear(void) { rcv_tail = rcv_head = 0; }
91
92/* iWRAP response */
93ISR(PCINT1_vect, ISR_BLOCK) // recv() runs away in case of ISR_NOBLOCK
94{
95 if ((SUART_IN_PIN & (1 << SUART_IN_BIT))) return;
96
97 static volatile uint8_t mux_state = 0xff;
98 static volatile uint8_t mux_link = 0xff;
99 uint8_t c = recv();
100 switch (mux_state) {
101 case 0xff: // SOF
102 if (c == 0xbf) mux_state--;
103 break;
104 case 0xfe: // Link
105 mux_state--;
106 mux_link = c;
107 break;
108 case 0xfd: // Flags
109 mux_state--;
110 break;
111 case 0xfc: // Length
112 mux_state = c;
113 break;
114 case 0x00:
115 mux_state = 0xff;
116 mux_link = 0xff;
117 break;
118 default:
119 if (mux_state--) {
120 uart_putchar(c);
121 rcv_enq(c);
122 }
123 }
124}
125
126/*------------------------------------------------------------------*
127 * iWRAP communication
128 *------------------------------------------------------------------*/
129void iwrap_init(void) {
130 // reset iWRAP if in already MUX mode after AVR software-reset
131 iwrap_send("RESET");
132 iwrap_mux_send("RESET");
133 _delay_ms(3000);
134 iwrap_send("\r\nSET CONTROL MUX 1\r\n");
135 _delay_ms(500);
136 iwrap_check_connection();
137}
138
139void iwrap_mux_send(const char *s) {
140 rcv_clear();
141 MUX_HEADER(0xff, strlen((char *)s));
142 iwrap_send(s);
143 MUX_FOOTER(0xff);
144}
145
146void iwrap_send(const char *s) {
147 while (*s) xmit(*s++);
148}
149
150/* send buffer */
151void iwrap_buf_add(uint8_t c) {
152 // need space for '\0'
153 if (snd_pos < MUX_BUF_SIZE - 1) buf[snd_pos++] = c;
154}
155
156void iwrap_buf_del(void) {
157 if (snd_pos) snd_pos--;
158}
159
160void iwrap_buf_send(void) {
161 buf[snd_pos] = '\0';
162 snd_pos = 0;
163 iwrap_mux_send(buf);
164}
165
166void iwrap_call(void) {
167 char *p;
168
169 iwrap_mux_send("SET BT PAIR");
170 _delay_ms(500);
171
172 p = rcv_buf + rcv_tail;
173 while (!strncmp(p, "SET BT PAIR", 11)) {
174 p += 7;
175 strncpy(p, "CALL", 4);
176 strncpy(p + 22, " 11 HID\n\0", 9);
177 print_S(p);
178 iwrap_mux_send(p);
179 // TODO: skip to next line
180 p += 57;
181
182 DEBUG_LED_CONFIG;
183 DEBUG_LED_ON;
184 _delay_ms(500);
185 DEBUG_LED_OFF;
186 _delay_ms(500);
187 DEBUG_LED_ON;
188 _delay_ms(500);
189 DEBUG_LED_OFF;
190 _delay_ms(500);
191 DEBUG_LED_ON;
192 _delay_ms(500);
193 DEBUG_LED_OFF;
194 _delay_ms(500);
195 DEBUG_LED_ON;
196 _delay_ms(500);
197 DEBUG_LED_OFF;
198 _delay_ms(500);
199 DEBUG_LED_ON;
200 _delay_ms(500);
201 DEBUG_LED_OFF;
202 _delay_ms(500);
203 }
204 iwrap_check_connection();
205}
206
207void iwrap_kill(void) {
208 char c;
209 iwrap_mux_send("LIST");
210 _delay_ms(500);
211
212 while ((c = rcv_deq()) && c != '\n')
213 ;
214 if (strncmp(rcv_buf + rcv_tail, "LIST ", 5)) {
215 print("no connection to kill.\n");
216 return;
217 }
218 // skip 10 'space' chars
219 for (uint8_t i = 10; i; i--)
220 while ((c = rcv_deq()) && c != ' ')
221 ;
222
223 char *p = rcv_buf + rcv_tail - 5;
224 strncpy(p, "KILL ", 5);
225 strncpy(p + 22, "\n\0", 2);
226 print_S(p);
227 iwrap_mux_send(p);
228 _delay_ms(500);
229
230 iwrap_check_connection();
231}
232
233void iwrap_unpair(void) {
234 iwrap_mux_send("SET BT PAIR");
235 _delay_ms(500);
236
237 char *p = rcv_buf + rcv_tail;
238 if (!strncmp(p, "SET BT PAIR", 11)) {
239 strncpy(p + 29, "\n\0", 2);
240 print_S(p);
241 iwrap_mux_send(p);
242 }
243}
244
245void iwrap_sleep(void) { iwrap_mux_send("SLEEP"); }
246
247void iwrap_sniff(void) {}
248
249void iwrap_subrate(void) {}
250
251bool iwrap_failed(void) {
252 if (strncmp(rcv_buf, "SYNTAX ERROR", 12))
253 return true;
254 else
255 return false;
256}
257
258uint8_t iwrap_connected(void) { return connected; }
259
260uint8_t iwrap_check_connection(void) {
261 iwrap_mux_send("LIST");
262 _delay_ms(100);
263
264 if (strncmp(rcv_buf, "LIST ", 5) || !strncmp(rcv_buf, "LIST 0", 6))
265 connected = 0;
266 else
267 connected = 1;
268 return connected;
269}
270
271/*------------------------------------------------------------------*
272 * Host driver
273 *------------------------------------------------------------------*/
274static uint8_t keyboard_leds(void);
275static void send_keyboard(report_keyboard_t *report);
276static void send_mouse(report_mouse_t *report);
277static void send_system(uint16_t data);
278static void send_consumer(uint16_t data);
279
280static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
281
282host_driver_t *iwrap_driver(void) { return &driver; }
283
284static uint8_t keyboard_leds(void) { return 0; }
285
286static void send_keyboard(report_keyboard_t *report) {
287 if (!iwrap_connected() && !iwrap_check_connection()) return;
288 MUX_HEADER(0x01, 0x0c);
289 // HID raw mode header
290 xmit(0x9f);
291 xmit(0x0a); // Length
292 xmit(0xa1); // DATA(Input)
293 xmit(0x01); // Report ID
294 xmit(report->mods);
295 xmit(0x00); // reserved byte(always 0)
296 xmit(report->keys[0]);
297 xmit(report->keys[1]);
298 xmit(report->keys[2]);
299 xmit(report->keys[3]);
300 xmit(report->keys[4]);
301 xmit(report->keys[5]);
302 MUX_FOOTER(0x01);
303}
304
305static void send_mouse(report_mouse_t *report) {
306#if defined(MOUSEKEY_ENABLE) || defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE)
307 if (!iwrap_connected() && !iwrap_check_connection()) return;
308 MUX_HEADER(0x01, 0x09);
309 // HID raw mode header
310 xmit(0x9f);
311 xmit(0x07); // Length
312 xmit(0xa1); // DATA(Input)
313 xmit(0x02); // Report ID
314 xmit(report->buttons);
315 xmit(report->x);
316 xmit(report->y);
317 xmit(report->v);
318 xmit(report->h);
319 MUX_FOOTER(0x01);
320#endif
321}
322
323static void send_system(uint16_t data) { /* not supported */
324}
325
326static void send_consumer(uint16_t data) {
327#ifdef EXTRAKEY_ENABLE
328 static uint16_t last_data = 0;
329 uint8_t bits1 = 0;
330 uint8_t bits2 = 0;
331 uint8_t bits3 = 0;
332
333 if (!iwrap_connected() && !iwrap_check_connection()) return;
334 if (data == last_data) return;
335 last_data = data;
336
337 // 3.10 HID raw mode(iWRAP_HID_Application_Note.pdf)
338 switch (data) {
339 case AUDIO_VOL_UP:
340 bits1 = 0x01;
341 break;
342 case AUDIO_VOL_DOWN:
343 bits1 = 0x02;
344 break;
345 case AUDIO_MUTE:
346 bits1 = 0x04;
347 break;
348 case TRANSPORT_PLAY_PAUSE:
349 bits1 = 0x08;
350 break;
351 case TRANSPORT_NEXT_TRACK:
352 bits1 = 0x10;
353 break;
354 case TRANSPORT_PREV_TRACK:
355 bits1 = 0x20;
356 break;
357 case TRANSPORT_STOP:
358 bits1 = 0x40;
359 break;
360 case TRANSPORT_EJECT:
361 bits1 = 0x80;
362 break;
363 case AL_EMAIL:
364 bits2 = 0x01;
365 break;
366 case AC_SEARCH:
367 bits2 = 0x02;
368 break;
369 case AC_BOOKMARKS:
370 bits2 = 0x04;
371 break;
372 case AC_HOME:
373 bits2 = 0x08;
374 break;
375 case AC_BACK:
376 bits2 = 0x10;
377 break;
378 case AC_FORWARD:
379 bits2 = 0x20;
380 break;
381 case AC_STOP:
382 bits2 = 0x40;
383 break;
384 case AC_REFRESH:
385 bits2 = 0x80;
386 break;
387 case AL_CC_CONFIG:
388 bits3 = 0x01;
389 break;
390 case AL_CALCULATOR:
391 bits3 = 0x04;
392 break;
393 case AL_LOCK:
394 bits3 = 0x08;
395 break;
396 case AL_LOCAL_BROWSER:
397 bits3 = 0x10;
398 break;
399 case AC_MINIMIZE:
400 bits3 = 0x20;
401 break;
402 case TRANSPORT_RECORD:
403 bits3 = 0x40;
404 break;
405 case TRANSPORT_REWIND:
406 bits3 = 0x80;
407 break;
408 }
409
410 MUX_HEADER(0x01, 0x07);
411 xmit(0x9f);
412 xmit(0x05); // Length
413 xmit(0xa1); // DATA(Input)
414 xmit(0x03); // Report ID
415 xmit(bits1);
416 xmit(bits2);
417 xmit(bits3);
418 MUX_FOOTER(0x01);
419#endif
420}