diff options
Diffstat (limited to 'vusb')
| -rw-r--r-- | vusb/main.c | 99 | ||||
| -rw-r--r-- | vusb/vusb.c (renamed from vusb/host.c) | 207 | ||||
| -rw-r--r-- | vusb/vusb.h (renamed from vusb/host_vusb.h) | 10 |
3 files changed, 180 insertions, 136 deletions
diff --git a/vusb/main.c b/vusb/main.c new file mode 100644 index 000000000..1bf9035b3 --- /dev/null +++ b/vusb/main.c | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | /* Name: main.c | ||
| 2 | * Project: hid-mouse, a very simple HID example | ||
| 3 | * Author: Christian Starkjohann | ||
| 4 | * Creation Date: 2008-04-07 | ||
| 5 | * Tabsize: 4 | ||
| 6 | * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH | ||
| 7 | * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) | ||
| 8 | * This Revision: $Id: main.c 790 2010-05-30 21:00:26Z cs $ | ||
| 9 | */ | ||
| 10 | #include <stdint.h> | ||
| 11 | #include <avr/interrupt.h> | ||
| 12 | #include <avr/wdt.h> | ||
| 13 | #include <avr/sleep.h> | ||
| 14 | #include <util/delay.h> | ||
| 15 | #include "usbdrv.h" | ||
| 16 | #include "oddebug.h" | ||
| 17 | #include "vusb.h" | ||
| 18 | #include "keyboard.h" | ||
| 19 | #include "host.h" | ||
| 20 | #include "timer.h" | ||
| 21 | #include "uart.h" | ||
| 22 | #include "debug.h" | ||
| 23 | |||
| 24 | |||
| 25 | #define UART_BAUD_RATE 115200 | ||
| 26 | |||
| 27 | |||
| 28 | /* This is from main.c of USBaspLoader */ | ||
| 29 | static void initForUsbConnectivity(void) | ||
| 30 | { | ||
| 31 | uint8_t i = 0; | ||
| 32 | |||
| 33 | usbInit(); | ||
| 34 | /* enforce USB re-enumerate: */ | ||
| 35 | usbDeviceDisconnect(); /* do this while interrupts are disabled */ | ||
| 36 | while(--i){ /* fake USB disconnect for > 250 ms */ | ||
| 37 | wdt_reset(); | ||
| 38 | _delay_ms(1); | ||
| 39 | } | ||
| 40 | usbDeviceConnect(); | ||
| 41 | sei(); | ||
| 42 | } | ||
| 43 | |||
| 44 | int main(void) | ||
| 45 | { | ||
| 46 | bool suspended = false; | ||
| 47 | #if USB_COUNT_SOF | ||
| 48 | uint16_t last_timer = timer_read(); | ||
| 49 | #endif | ||
| 50 | |||
| 51 | CLKPR = 0x80, CLKPR = 0; | ||
| 52 | #ifndef PS2_USE_USART | ||
| 53 | uart_init(UART_BAUD_RATE); | ||
| 54 | #endif | ||
| 55 | |||
| 56 | debug_enable = true; | ||
| 57 | print_enable = true; | ||
| 58 | |||
| 59 | debug("keyboard_init()\n"); | ||
| 60 | keyboard_init(); | ||
| 61 | host_set_driver(vusb_driver()); | ||
| 62 | |||
| 63 | debug("initForUsbConnectivity()\n"); | ||
| 64 | initForUsbConnectivity(); | ||
| 65 | |||
| 66 | debug("main loop\n"); | ||
| 67 | while (1) { | ||
| 68 | #if USB_COUNT_SOF | ||
| 69 | if (usbSofCount != 0) { | ||
| 70 | suspended = false; | ||
| 71 | usbSofCount = 0; | ||
| 72 | last_timer = timer_read(); | ||
| 73 | } else { | ||
| 74 | // Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1) | ||
| 75 | if (timer_elapsed(last_timer) > 5) { | ||
| 76 | suspended = true; | ||
| 77 | /* | ||
| 78 | uart_putchar('S'); | ||
| 79 | _delay_ms(1); | ||
| 80 | cli(); | ||
| 81 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); | ||
| 82 | sleep_enable(); | ||
| 83 | sleep_bod_disable(); | ||
| 84 | sei(); | ||
| 85 | sleep_cpu(); | ||
| 86 | sleep_disable(); | ||
| 87 | _delay_ms(10); | ||
| 88 | uart_putchar('W'); | ||
| 89 | */ | ||
| 90 | } | ||
| 91 | } | ||
| 92 | #endif | ||
| 93 | if (!suspended) | ||
| 94 | usbPoll(); | ||
| 95 | keyboard_proc(); | ||
| 96 | if (!suspended) | ||
| 97 | vusb_transfer_keyboard(); | ||
| 98 | } | ||
| 99 | } | ||
diff --git a/vusb/host.c b/vusb/vusb.c index 8cd38d0b3..638611f32 100644 --- a/vusb/host.c +++ b/vusb/vusb.c | |||
| @@ -16,133 +16,69 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #include <stdint.h> | 18 | #include <stdint.h> |
| 19 | #include <avr/interrupt.h> | ||
| 20 | #include "usbdrv.h" | 19 | #include "usbdrv.h" |
| 21 | #include "usbconfig.h" | 20 | #include "usbconfig.h" |
| 22 | #include "print.h" | ||
| 23 | #include "usb_keycodes.h" | ||
| 24 | #include "host.h" | 21 | #include "host.h" |
| 25 | #include "host_vusb.h" | 22 | #include "report.h" |
| 23 | #include "print.h" | ||
| 26 | #include "debug.h" | 24 | #include "debug.h" |
| 25 | #include "host_driver.h" | ||
| 26 | #include "vusb.h" | ||
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | static report_keyboard_t report0; | 29 | static uint8_t vusb_keyboard_leds = 0; |
| 30 | static report_keyboard_t report1; | 30 | static uint8_t vusb_idle_rate = 0; |
| 31 | report_keyboard_t *keyboard_report = &report0; | ||
| 32 | report_keyboard_t *keyboard_report_prev = &report1; | ||
| 33 | |||
| 34 | static uint8_t keyboard_leds = 0; | ||
| 35 | static uchar idleRate = 0; | ||
| 36 | |||
| 37 | uint8_t host_keyboard_leds(void) | ||
| 38 | { | ||
| 39 | return keyboard_leds; | ||
| 40 | } | ||
| 41 | |||
| 42 | |||
| 43 | /*------------------------------------------------------------------* | ||
| 44 | * Keyboard report operations | ||
| 45 | *------------------------------------------------------------------*/ | ||
| 46 | void host_add_key(uint8_t code) | ||
| 47 | { | ||
| 48 | int8_t i = 0; | ||
| 49 | int8_t empty = -1; | ||
| 50 | for (; i < REPORT_KEYS; i++) { | ||
| 51 | if (keyboard_report_prev->keys[i] == code) { | ||
| 52 | keyboard_report->keys[i] = code; | ||
| 53 | break; | ||
| 54 | } | ||
| 55 | if (empty == -1 && keyboard_report_prev->keys[i] == KB_NO && keyboard_report->keys[i] == KB_NO) { | ||
| 56 | empty = i; | ||
| 57 | } | ||
| 58 | } | ||
| 59 | if (i == REPORT_KEYS && empty != -1) { | ||
| 60 | keyboard_report->keys[empty] = code; | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | void host_add_mod_bit(uint8_t mod) | ||
| 65 | { | ||
| 66 | keyboard_report->mods |= mod; | ||
| 67 | } | ||
| 68 | |||
| 69 | void host_set_mods(uint8_t mods) | ||
| 70 | { | ||
| 71 | keyboard_report->mods = mods; | ||
| 72 | } | ||
| 73 | |||
| 74 | void host_add_code(uint8_t code) | ||
| 75 | { | ||
| 76 | if (IS_MOD(code)) { | ||
| 77 | host_add_mod_bit(MOD_BIT(code)); | ||
| 78 | } else { | ||
| 79 | host_add_key(code); | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | void host_swap_keyboard_report(void) | ||
| 84 | { | ||
| 85 | uint8_t sreg = SREG; | ||
| 86 | cli(); | ||
| 87 | report_keyboard_t *tmp = keyboard_report_prev; | ||
| 88 | keyboard_report_prev = keyboard_report; | ||
| 89 | keyboard_report = tmp; | ||
| 90 | SREG = sreg; | ||
| 91 | } | ||
| 92 | 31 | ||
| 93 | void host_clear_keyboard_report(void) | 32 | /* Keyboard report send buffer */ |
| 94 | { | 33 | #define KBUF_SIZE 16 |
| 95 | keyboard_report->mods = 0; | 34 | static report_keyboard_t kbuf[KBUF_SIZE]; |
| 96 | for (int8_t i = 0; i < REPORT_KEYS; i++) { | 35 | static uint8_t kbuf_head = 0; |
| 97 | keyboard_report->keys[i] = 0; | 36 | static uint8_t kbuf_tail = 0; |
| 98 | } | ||
| 99 | } | ||
| 100 | 37 | ||
| 101 | uint8_t host_has_anykey(void) | ||
| 102 | { | ||
| 103 | uint8_t cnt = 0; | ||
| 104 | for (int i = 0; i < REPORT_KEYS; i++) { | ||
| 105 | if (keyboard_report->keys[i]) | ||
| 106 | cnt++; | ||
| 107 | } | ||
| 108 | return cnt; | ||
| 109 | } | ||
| 110 | 38 | ||
| 111 | uint8_t host_get_first_key(void) | 39 | /* transfer keyboard report from buffer */ |
| 40 | void vusb_transfer_keyboard(void) | ||
| 112 | { | 41 | { |
| 113 | #ifdef USB_NKRO_ENABLE | 42 | if (usbInterruptIsReady()) { |
| 114 | if (keyboard_nkro) { | 43 | if (kbuf_head != kbuf_tail) { |
| 115 | uint8_t i = 0; | 44 | usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t)); |
| 116 | for (; i < REPORT_KEYS && !keyboard_report->keys[i]; i++) | 45 | kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE; |
| 117 | ; | 46 | } |
| 118 | return i<<3 | biton(keyboard_report->keys[i]); | ||
| 119 | } | 47 | } |
| 120 | #endif | ||
| 121 | return keyboard_report->keys[0]; | ||
| 122 | } | 48 | } |
| 123 | 49 | ||
| 124 | 50 | ||
| 125 | /*------------------------------------------------------------------* | 51 | /*------------------------------------------------------------------* |
| 126 | * Keyboard report send buffer | 52 | * Host driver |
| 127 | *------------------------------------------------------------------*/ | 53 | *------------------------------------------------------------------*/ |
| 128 | #define KBUF_SIZE 16 | 54 | static uint8_t keyboard_leds(void); |
| 129 | static report_keyboard_t kbuf[KBUF_SIZE]; | 55 | static void send_keyboard(report_keyboard_t *report); |
| 130 | static uint8_t kbuf_head = 0; | 56 | static void send_mouse(report_mouse_t *report); |
| 131 | static uint8_t kbuf_tail = 0; | 57 | static void send_system(uint16_t data); |
| 58 | static void send_consumer(uint16_t data); | ||
| 59 | |||
| 60 | static host_driver_t driver = { | ||
| 61 | keyboard_leds, | ||
| 62 | send_keyboard, | ||
| 63 | send_mouse, | ||
| 64 | send_system, | ||
| 65 | send_consumer | ||
| 66 | }; | ||
| 132 | 67 | ||
| 133 | void host_vusb_keyboard_send(void) | 68 | host_driver_t *vusb_driver(void) |
| 134 | { | 69 | { |
| 135 | if (usbInterruptIsReady() && kbuf_head != kbuf_tail) { | 70 | return &driver; |
| 136 | usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t)); | ||
| 137 | kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE; | ||
| 138 | } | ||
| 139 | } | 71 | } |
| 140 | 72 | ||
| 141 | void host_send_keyboard_report(void) | 73 | static uint8_t keyboard_leds(void) { |
| 74 | return vusb_keyboard_leds; | ||
| 75 | } | ||
| 76 | |||
| 77 | static void send_keyboard(report_keyboard_t *report) | ||
| 142 | { | 78 | { |
| 143 | uint8_t next = (kbuf_head + 1) % KBUF_SIZE; | 79 | uint8_t next = (kbuf_head + 1) % KBUF_SIZE; |
| 144 | if (next != kbuf_tail) { | 80 | if (next != kbuf_tail) { |
| 145 | kbuf[kbuf_head] = *keyboard_report; | 81 | kbuf[kbuf_head] = *report; |
| 146 | kbuf_head = next; | 82 | kbuf_head = next; |
| 147 | } else { | 83 | } else { |
| 148 | debug("kbuf: full\n"); | 84 | debug("kbuf: full\n"); |
| @@ -150,20 +86,15 @@ void host_send_keyboard_report(void) | |||
| 150 | } | 86 | } |
| 151 | 87 | ||
| 152 | 88 | ||
| 153 | #if defined(MOUSEKEY_ENABLE) || defined(PS2_MOUSE_ENABLE) | 89 | static void send_mouse(report_mouse_t *report) |
| 154 | void host_mouse_send(report_mouse_t *report) | ||
| 155 | { | 90 | { |
| 156 | report->report_id = REPORT_ID_MOUSE; | 91 | report->report_id = REPORT_ID_MOUSE; |
| 157 | if (usbInterruptIsReady3()) { | 92 | if (usbInterruptIsReady3()) { |
| 158 | usbSetInterrupt3((void *)report, sizeof(*report)); | 93 | usbSetInterrupt3((void *)report, sizeof(*report)); |
| 159 | } else { | ||
| 160 | debug("Int3 not ready\n"); | ||
| 161 | } | 94 | } |
| 162 | } | 95 | } |
| 163 | #endif | ||
| 164 | 96 | ||
| 165 | #ifdef USB_EXTRA_ENABLE | 97 | static void send_system(uint16_t data) |
| 166 | void host_system_send(uint16_t data) | ||
| 167 | { | 98 | { |
| 168 | // Not need static? | 99 | // Not need static? |
| 169 | static uint8_t report[] = { REPORT_ID_SYSTEM, 0, 0 }; | 100 | static uint8_t report[] = { REPORT_ID_SYSTEM, 0, 0 }; |
| @@ -171,12 +102,10 @@ void host_system_send(uint16_t data) | |||
| 171 | report[2] = (data>>8)&0xFF; | 102 | report[2] = (data>>8)&0xFF; |
| 172 | if (usbInterruptIsReady3()) { | 103 | if (usbInterruptIsReady3()) { |
| 173 | usbSetInterrupt3((void *)&report, sizeof(report)); | 104 | usbSetInterrupt3((void *)&report, sizeof(report)); |
| 174 | } else { | ||
| 175 | debug("Int3 not ready\n"); | ||
| 176 | } | 105 | } |
| 177 | } | 106 | } |
| 178 | 107 | ||
| 179 | void host_consumer_send(uint16_t data) | 108 | static void send_consumer(uint16_t data) |
| 180 | { | 109 | { |
| 181 | static uint16_t last_data = 0; | 110 | static uint16_t last_data = 0; |
| 182 | if (data == last_data) return; | 111 | if (data == last_data) return; |
| @@ -188,11 +117,8 @@ void host_consumer_send(uint16_t data) | |||
| 188 | report[2] = (data>>8)&0xFF; | 117 | report[2] = (data>>8)&0xFF; |
| 189 | if (usbInterruptIsReady3()) { | 118 | if (usbInterruptIsReady3()) { |
| 190 | usbSetInterrupt3((void *)&report, sizeof(report)); | 119 | usbSetInterrupt3((void *)&report, sizeof(report)); |
| 191 | } else { | ||
| 192 | debug("Int3 not ready\n"); | ||
| 193 | } | 120 | } |
| 194 | } | 121 | } |
| 195 | #endif | ||
| 196 | 122 | ||
| 197 | 123 | ||
| 198 | 124 | ||
| @@ -213,32 +139,36 @@ usbRequest_t *rq = (void *)data; | |||
| 213 | 139 | ||
| 214 | if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */ | 140 | if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */ |
| 215 | if(rq->bRequest == USBRQ_HID_GET_REPORT){ | 141 | if(rq->bRequest == USBRQ_HID_GET_REPORT){ |
| 216 | debug(" GET_REPORT"); | 142 | debug("GET_REPORT:"); |
| 217 | /* we only have one report type, so don't look at wValue */ | 143 | /* we only have one report type, so don't look at wValue */ |
| 218 | usbMsgPtr = (void *)keyboard_report_prev; | 144 | usbMsgPtr = (void *)keyboard_report_prev; |
| 219 | return sizeof(*keyboard_report_prev); | 145 | return sizeof(*keyboard_report_prev); |
| 220 | }else if(rq->bRequest == USBRQ_HID_GET_IDLE){ | 146 | }else if(rq->bRequest == USBRQ_HID_GET_IDLE){ |
| 221 | debug(" GET_IDLE: "); | 147 | debug("GET_IDLE: "); |
| 222 | debug_hex(idleRate); | 148 | //debug_hex(vusb_idle_rate); |
| 223 | usbMsgPtr = &idleRate; | 149 | usbMsgPtr = &vusb_idle_rate; |
| 224 | return 1; | 150 | return 1; |
| 225 | }else if(rq->bRequest == USBRQ_HID_SET_IDLE){ | 151 | }else if(rq->bRequest == USBRQ_HID_SET_IDLE){ |
| 226 | idleRate = rq->wValue.bytes[1]; | 152 | vusb_idle_rate = rq->wValue.bytes[1]; |
| 227 | debug(" SET_IDLE: "); | 153 | debug("SET_IDLE: "); |
| 228 | debug_hex(idleRate); | 154 | debug_hex(vusb_idle_rate); |
| 229 | }else if(rq->bRequest == USBRQ_HID_SET_REPORT){ | 155 | }else if(rq->bRequest == USBRQ_HID_SET_REPORT){ |
| 230 | //debug(" SET_REPORT: "); | 156 | debug("SET_REPORT: "); |
| 157 | // Report Type: 0x02(Out)/ReportID: 0x00(none) && Interface: 0(keyboard) | ||
| 231 | if (rq->wValue.word == 0x0200 && rq->wIndex.word == 0) { | 158 | if (rq->wValue.word == 0x0200 && rq->wIndex.word == 0) { |
| 159 | debug("SET_LED: "); | ||
| 232 | last_req.kind = SET_LED; | 160 | last_req.kind = SET_LED; |
| 233 | last_req.len = rq->wLength.word; | 161 | last_req.len = rq->wLength.word; |
| 234 | } | 162 | } |
| 235 | return USB_NO_MSG; // to get data in usbFunctionWrite | 163 | return USB_NO_MSG; // to get data in usbFunctionWrite |
| 164 | } else { | ||
| 165 | debug("UNKNOWN:"); | ||
| 236 | } | 166 | } |
| 237 | debug("\n"); | ||
| 238 | }else{ | 167 | }else{ |
| 239 | debug("VENDOR\n"); | 168 | debug("VENDOR:"); |
| 240 | /* no vendor specific requests implemented */ | 169 | /* no vendor specific requests implemented */ |
| 241 | } | 170 | } |
| 171 | debug("\n"); | ||
| 242 | return 0; /* default for not implemented requests: return no data back to host */ | 172 | return 0; /* default for not implemented requests: return no data back to host */ |
| 243 | } | 173 | } |
| 244 | 174 | ||
| @@ -249,8 +179,10 @@ uchar usbFunctionWrite(uchar *data, uchar len) | |||
| 249 | } | 179 | } |
| 250 | switch (last_req.kind) { | 180 | switch (last_req.kind) { |
| 251 | case SET_LED: | 181 | case SET_LED: |
| 252 | //debug("SET_LED\n"); | 182 | debug("SET_LED: "); |
| 253 | keyboard_leds = data[0]; | 183 | debug_hex(data[0]); |
| 184 | debug("\n"); | ||
| 185 | vusb_keyboard_leds = data[0]; | ||
| 254 | last_req.len = 0; | 186 | last_req.len = 0; |
| 255 | return 1; | 187 | return 1; |
| 256 | break; | 188 | break; |
| @@ -484,13 +416,14 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) | |||
| 484 | { | 416 | { |
| 485 | usbMsgLen_t len = 0; | 417 | usbMsgLen_t len = 0; |
| 486 | 418 | ||
| 419 | /* | ||
| 487 | debug("usbFunctionDescriptor: "); | 420 | debug("usbFunctionDescriptor: "); |
| 488 | debug_hex(rq->bmRequestType); debug(" "); | 421 | debug_hex(rq->bmRequestType); debug(" "); |
| 489 | debug_hex(rq->bRequest); debug(" "); | 422 | debug_hex(rq->bRequest); debug(" "); |
| 490 | debug_hex16(rq->wValue.word); debug(" "); | 423 | debug_hex16(rq->wValue.word); debug(" "); |
| 491 | debug_hex16(rq->wIndex.word); debug(" "); | 424 | debug_hex16(rq->wIndex.word); debug(" "); |
| 492 | debug_hex16(rq->wLength.word); debug("\n"); | 425 | debug_hex16(rq->wLength.word); debug("\n"); |
| 493 | 426 | */ | |
| 494 | switch (rq->wValue.bytes[1]) { | 427 | switch (rq->wValue.bytes[1]) { |
| 495 | #if USB_CFG_DESCR_PROPS_CONFIGURATION | 428 | #if USB_CFG_DESCR_PROPS_CONFIGURATION |
| 496 | case USBDESCR_CONFIG: | 429 | case USBDESCR_CONFIG: |
| @@ -499,8 +432,16 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) | |||
| 499 | break; | 432 | break; |
| 500 | #endif | 433 | #endif |
| 501 | case USBDESCR_HID: | 434 | case USBDESCR_HID: |
| 502 | usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 18); | 435 | switch (rq->wValue.bytes[0]) { |
| 503 | len = 9; | 436 | case 0: |
| 437 | usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 9 + 9); | ||
| 438 | len = 9; | ||
| 439 | break; | ||
| 440 | case 1: | ||
| 441 | usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 9 + (9 + 9 + 7) + 9); | ||
| 442 | len = 9; | ||
| 443 | break; | ||
| 444 | } | ||
| 504 | break; | 445 | break; |
| 505 | case USBDESCR_HID_REPORT: | 446 | case USBDESCR_HID_REPORT: |
| 506 | /* interface index */ | 447 | /* interface index */ |
| @@ -516,6 +457,6 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) | |||
| 516 | } | 457 | } |
| 517 | break; | 458 | break; |
| 518 | } | 459 | } |
| 519 | debug("desc len: "); debug_hex(len); debug("\n"); | 460 | //debug("desc len: "); debug_hex(len); debug("\n"); |
| 520 | return len; | 461 | return len; |
| 521 | } | 462 | } |
diff --git a/vusb/host_vusb.h b/vusb/vusb.h index be9886e88..5accf233b 100644 --- a/vusb/host_vusb.h +++ b/vusb/vusb.h | |||
| @@ -15,9 +15,13 @@ 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/>. | 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #ifndef HOST_VUSB_H | 18 | #ifndef VUSB_H |
| 19 | #define HOST_VUSB_H | 19 | #define VUSB_H |
| 20 | 20 | ||
| 21 | void host_vusb_keyboard_send(void); | 21 | #include "host_driver.h" |
| 22 | |||
| 23 | |||
| 24 | host_driver_t *vusb_driver(void); | ||
| 25 | void vusb_transfer_keyboard(void); | ||
| 22 | 26 | ||
| 23 | #endif | 27 | #endif |
