]>
git.gir.st - tmk_keyboard.git/blob - protocol/iwrap/iwrap.c
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 /* host driver for Bulegiga iWRAP */
21 * Hardware UART Software UART BlueTooth
22 * PC=====UART=======AVR=====SUART====iWRAP(BT12)-----------PC
24 * - Hardware UART for Debug Console to communicate iWRAP
25 * - Software UART for iWRAP control to send keyboard/mouse data
30 #include <avr/interrupt.h>
31 #include <util/delay.h>
36 #include "host_driver.h"
41 /* iWRAP MUX mode utils. 3.10 HID raw mode(iWRAP_HID_Application_Note.pdf) */
42 #define MUX_HEADER(LINK, LENGTH) do { \
43 xmit(0xbf); /* SOF */ \
44 xmit(LINK); /* Link */ \
45 xmit(0x00); /* Flags */ \
46 xmit(LENGTH); /* Length */ \
48 #define MUX_FOOTER(LINK) xmit(LINK^0xff)
51 static uint8_t connected
= 0;
52 //static uint8_t channel = 1;
55 #define MUX_BUF_SIZE 64
56 static char buf
[MUX_BUF_SIZE
];
57 static uint8_t snd_pos
= 0;
59 #define MUX_RCV_BUF_SIZE 256
60 static char rcv_buf
[MUX_RCV_BUF_SIZE
];
61 static uint8_t rcv_head
= 0;
62 static uint8_t rcv_tail
= 0;
66 static void rcv_enq(char c
)
68 uint8_t next
= (rcv_head
+ 1) % MUX_RCV_BUF_SIZE
;
69 if (next
!= rcv_tail
) {
70 rcv_buf
[rcv_head
] = c
;
75 static char rcv_deq(void)
78 if (rcv_head
!= rcv_tail
) {
79 c
= rcv_buf
[rcv_tail
++];
80 rcv_tail
%= MUX_RCV_BUF_SIZE
;
86 static char rcv_peek(void)
88 if (rcv_head == rcv_tail)
90 return rcv_buf[rcv_tail];
94 static void rcv_clear(void)
96 rcv_tail
= rcv_head
= 0;
100 ISR(PCINT1_vect
, ISR_BLOCK
) // recv() runs away in case of ISR_NOBLOCK
102 if ((SUART_IN_PIN
& (1<<SUART_IN_BIT
)))
105 static volatile uint8_t mux_state
= 0xff;
106 static volatile uint8_t mux_link
= 0xff;
136 /*------------------------------------------------------------------*
137 * iWRAP communication
138 *------------------------------------------------------------------*/
139 void iwrap_init(void)
141 // reset iWRAP if in already MUX mode after AVR software-reset
143 iwrap_mux_send("RESET");
145 iwrap_send("\r\nSET CONTROL MUX 1\r\n");
147 iwrap_check_connection();
150 void iwrap_mux_send(const char *s
)
153 MUX_HEADER(0xff, strlen((char *)s
));
158 void iwrap_send(const char *s
)
165 void iwrap_buf_add(uint8_t c
)
167 // need space for '\0'
168 if (snd_pos
< MUX_BUF_SIZE
-1)
172 void iwrap_buf_del(void)
178 void iwrap_buf_send(void)
185 void iwrap_call(void)
189 iwrap_mux_send("SET BT PAIR");
192 p
= rcv_buf
+ rcv_tail
;
193 while (!strncmp(p
, "SET BT PAIR", 11)) {
195 strncpy(p
, "CALL", 4);
196 strncpy(p
+22, " 11 HID\n\0", 9);
199 // TODO: skip to next line
224 iwrap_check_connection();
227 void iwrap_kill(void)
230 iwrap_mux_send("LIST");
233 while ((c
= rcv_deq()) && c
!= '\n') ;
234 if (strncmp(rcv_buf
+ rcv_tail
, "LIST ", 5)) {
235 print("no connection to kill.\n");
238 // skip 10 'space' chars
239 for (uint8_t i
= 10; i
; i
--)
240 while ((c
= rcv_deq()) && c
!= ' ') ;
242 char *p
= rcv_buf
+ rcv_tail
- 5;
243 strncpy(p
, "KILL ", 5);
244 strncpy(p
+ 22, "\n\0", 2);
249 iwrap_check_connection();
252 void iwrap_unpair(void)
254 iwrap_mux_send("SET BT PAIR");
257 char *p
= rcv_buf
+ rcv_tail
;
258 if (!strncmp(p
, "SET BT PAIR", 11)) {
259 strncpy(p
+29, "\n\0", 2);
265 void iwrap_sleep(void)
267 iwrap_mux_send("SLEEP");
270 void iwrap_sniff(void)
274 void iwrap_subrate(void)
278 bool iwrap_failed(void)
280 if (strncmp(rcv_buf
, "SYNTAX ERROR", 12))
286 uint8_t iwrap_connected(void)
291 uint8_t iwrap_check_connection(void)
293 iwrap_mux_send("LIST");
296 if (strncmp(rcv_buf
, "LIST ", 5) || !strncmp(rcv_buf
, "LIST 0", 6))
304 /*------------------------------------------------------------------*
306 *------------------------------------------------------------------*/
307 static uint8_t keyboard_leds(void);
308 static void send_keyboard(report_keyboard_t
*report
);
309 static void send_mouse(report_mouse_t
*report
);
310 static void send_system(uint16_t data
);
311 static void send_consumer(uint16_t data
);
313 static host_driver_t driver
= {
321 host_driver_t
*iwrap_driver(void)
326 static uint8_t keyboard_leds(void) {
330 static void send_keyboard(report_keyboard_t
*report
)
332 if (!iwrap_connected() && !iwrap_check_connection()) return;
333 MUX_HEADER(0x01, 0x0c);
334 // HID raw mode header
336 xmit(0x0a); // Length
337 xmit(0xa1); // DATA(Input)
338 xmit(0x01); // Report ID
340 xmit(0x00); // reserved byte(always 0)
341 xmit(report
->keys
[0]);
342 xmit(report
->keys
[1]);
343 xmit(report
->keys
[2]);
344 xmit(report
->keys
[3]);
345 xmit(report
->keys
[4]);
346 xmit(report
->keys
[5]);
350 static void send_mouse(report_mouse_t
*report
)
352 #if defined(MOUSEKEY_ENABLE) || defined(PS2_MOUSE_ENABLE)
353 if (!iwrap_connected() && !iwrap_check_connection()) return;
354 MUX_HEADER(0x01, 0x09);
355 // HID raw mode header
357 xmit(0x07); // Length
358 xmit(0xa1); // DATA(Input)
359 xmit(0x02); // Report ID
360 xmit(report
->buttons
);
369 static void send_system(uint16_t data
)
374 static void send_consumer(uint16_t data
)
376 #ifdef EXTRAKEY_ENABLE
377 static uint16_t last_data
= 0;
382 if (!iwrap_connected() && !iwrap_check_connection()) return;
383 if (data
== last_data
) return;
386 // 3.10 HID raw mode(iWRAP_HID_Application_Note.pdf)
397 case TRANSPORT_PLAY_PAUSE
:
400 case TRANSPORT_NEXT_TRACK
:
403 case TRANSPORT_PREV_TRACK
:
409 case TRANSPORT_EJECT
:
445 case AL_LOCAL_BROWSER
:
451 case TRANSPORT_RECORD
:
454 case TRANSPORT_REWIND
:
459 MUX_HEADER(0x01, 0x07);
461 xmit(0x05); // Length
462 xmit(0xa1); // DATA(Input)
463 xmit(0x03); // Report ID