Changeset aec2ad4 in mainline for uspace/drv/usbhid/main.c
- Timestamp:
- 2011-02-04T11:48:33Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 103a3626
- Parents:
- ba5ab09 (diff), 3597dab (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/main.c
rba5ab09 raec2ad4 1 1 /* 2 2 * Copyright (c) 2010 Vojtech Horky 3 * Copyright (c) 2011 Lubos Slovak 3 4 * All rights reserved. 4 5 * … … 26 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 */ 29 28 30 /** @addtogroup drvusbhid 29 31 * @{ 30 32 */ 33 /** 34 * @file 35 * Main routines of USB HID driver. 36 */ 37 31 38 #include <usb/usbdrv.h> 32 39 #include <driver.h> … … 36 43 #include <io/console.h> 37 44 #include <errno.h> 45 #include <str_error.h> 38 46 #include <fibril.h> 39 47 #include <usb/classes/hid.h> 40 48 #include <usb/classes/hidparser.h> 41 #include <usb/ devreq.h>49 #include <usb/request.h> 42 50 #include <usb/descriptor.h> 51 #include <io/console.h> 52 #include "hid.h" 43 53 #include "descparser.h" 44 54 #include "descdump.h" 55 #include "conv.h" 56 #include "layout.h" 45 57 46 58 #define BUFFER_SIZE 32 47 #define NAME "usb kbd"59 #define NAME "usbhid" 48 60 49 61 #define GUESSED_POLL_ENDPOINT 1 … … 91 103 92 104 /* 105 * TODO: Move somewhere else 106 */ 107 /* 108 #define BYTES_PER_LINE 12 109 110 static void dump_buffer(const char *msg, const uint8_t *buffer, size_t length) 111 { 112 printf("%s\n", msg); 113 114 size_t i; 115 for (i = 0; i < length; i++) { 116 printf(" 0x%02X", buffer[i]); 117 if (((i > 0) && (((i+1) % BYTES_PER_LINE) == 0)) 118 || (i + 1 == length)) { 119 printf("\n"); 120 } 121 } 122 } 123 */ 124 /* 125 * Copy-paste from srv/hid/kbd/generic/kbd.c 126 */ 127 128 /** Currently active modifiers. 129 * 130 * TODO: put to device? 131 */ 132 static unsigned mods = KM_NUM_LOCK; 133 134 /** Currently pressed lock keys. We track these to tackle autorepeat. 135 * 136 * TODO: put to device? 137 */ 138 static unsigned lock_keys; 139 140 #define NUM_LAYOUTS 3 141 142 static layout_op_t *layout[NUM_LAYOUTS] = { 143 &us_qwerty_op, 144 &us_dvorak_op, 145 &cz_op 146 }; 147 148 static int active_layout = 0; 149 150 static void kbd_push_ev(int type, unsigned int key) 151 { 152 console_event_t ev; 153 unsigned mod_mask; 154 155 // TODO: replace by our own parsing?? or are the key codes identical?? 156 switch (key) { 157 case KC_LCTRL: mod_mask = KM_LCTRL; break; 158 case KC_RCTRL: mod_mask = KM_RCTRL; break; 159 case KC_LSHIFT: mod_mask = KM_LSHIFT; break; 160 case KC_RSHIFT: mod_mask = KM_RSHIFT; break; 161 case KC_LALT: mod_mask = KM_LALT; break; 162 case KC_RALT: mod_mask = KM_RALT; break; 163 default: mod_mask = 0; break; 164 } 165 166 if (mod_mask != 0) { 167 if (type == KEY_PRESS) 168 mods = mods | mod_mask; 169 else 170 mods = mods & ~mod_mask; 171 } 172 173 switch (key) { 174 case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break; 175 case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break; 176 case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break; 177 default: mod_mask = 0; break; 178 } 179 180 if (mod_mask != 0) { 181 if (type == KEY_PRESS) { 182 /* 183 * Only change lock state on transition from released 184 * to pressed. This prevents autorepeat from messing 185 * up the lock state. 186 */ 187 mods = mods ^ (mod_mask & ~lock_keys); 188 lock_keys = lock_keys | mod_mask; 189 190 /* Update keyboard lock indicator lights. */ 191 // TODO 192 //kbd_ctl_set_ind(mods); 193 } else { 194 lock_keys = lock_keys & ~mod_mask; 195 } 196 } 197 /* 198 printf("type: %d\n", type); 199 printf("mods: 0x%x\n", mods); 200 printf("keycode: %u\n", key); 201 */ 202 203 if (type == KEY_PRESS && (mods & KM_LCTRL) && 204 key == KC_F1) { 205 active_layout = 0; 206 layout[active_layout]->reset(); 207 return; 208 } 209 210 if (type == KEY_PRESS && (mods & KM_LCTRL) && 211 key == KC_F2) { 212 active_layout = 1; 213 layout[active_layout]->reset(); 214 return; 215 } 216 217 if (type == KEY_PRESS && (mods & KM_LCTRL) && 218 key == KC_F3) { 219 active_layout = 2; 220 layout[active_layout]->reset(); 221 return; 222 } 223 224 ev.type = type; 225 ev.key = key; 226 ev.mods = mods; 227 228 ev.c = layout[active_layout]->parse_ev(&ev); 229 230 printf("Sending key %d to the console\n", ev.key); 231 assert(console_callback_phone != -1); 232 async_msg_4(console_callback_phone, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c); 233 } 234 /* 235 * End of copy-paste 236 */ 237 238 /* 239 * TODO: 240 * 1) key press / key release - how does the keyboard notify about release? 241 * 2) layouts (use the already defined), not important now 242 * 3) 243 */ 244 245 /* 93 246 * Callbacks for parser 94 247 */ 95 248 static void usbkbd_process_keycodes(const uint8_t *key_codes, size_t count, 96 249 uint8_t modifiers, void *arg) 97 250 { 98 251 printf("Got keys: "); … … 100 253 for (i = 0; i < count; ++i) { 101 254 printf("%d ", key_codes[i]); 255 // TODO: Key press / release 256 257 // TODO: NOT WORKING 258 unsigned int key = usbkbd_parse_scancode(key_codes[i]); 259 kbd_push_ev(KEY_PRESS, key); 102 260 } 103 261 printf("\n"); … … 122 280 123 281 // get the descriptor from the device 124 int rc = usb_drv_req_get_descriptor(kbd_dev->device->parent_phone, 125 kbd_dev->address, USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT, 126 0, i, kbd_dev->conf->interfaces[i].report_desc, length, 282 int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe, 283 USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT, 284 i, 0, 285 kbd_dev->conf->interfaces[i].report_desc, length, 127 286 &actual_size); 128 287 … … 145 304 usb_standard_configuration_descriptor_t config_desc; 146 305 147 int rc = usb_drv_req_get_bare_configuration_descriptor( 148 kbd_dev->device->parent_phone, kbd_dev->address, 0, &config_desc); 306 int rc; 307 rc = usb_request_get_bare_configuration_descriptor(&kbd_dev->ctrl_pipe, 308 0, &config_desc); 149 309 150 310 if (rc != EOK) { … … 160 320 size_t transferred = 0; 161 321 // get full configuration descriptor 162 rc = usb_ drv_req_get_full_configuration_descriptor(163 kbd_dev->device->parent_phone, kbd_dev->address,0, descriptors,322 rc = usb_request_get_full_configuration_descriptor(&kbd_dev->ctrl_pipe, 323 0, descriptors, 164 324 config_desc.total_length, &transferred); 165 325 … … 208 368 static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev) 209 369 { 370 int rc; 371 210 372 usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)calloc(1, 211 373 sizeof(usb_hid_dev_kbd_t)); … … 218 380 kbd_dev->device = dev; 219 381 220 // get phone to my HC and save it as my parent's phone 221 // TODO: maybe not a good idea if DDF will use parent_phone 222 int rc = kbd_dev->device->parent_phone = usb_drv_hc_connect_auto(dev, 0); 223 if (rc < 0) { 224 printf("Problem setting phone to HC.\n"); 225 free(kbd_dev); 226 return NULL; 227 } 228 229 rc = kbd_dev->address = usb_drv_get_my_address(dev->parent_phone, dev); 230 if (rc < 0) { 231 printf("Problem getting address of the device.\n"); 232 free(kbd_dev); 233 return NULL; 234 } 235 236 // doesn't matter now that we have no address 237 // if (kbd_dev->address < 0) { 238 // fprintf(stderr, NAME ": No device address!\n"); 239 // free(kbd_dev); 240 // return NULL; 241 // } 242 243 // default endpoint 244 kbd_dev->poll_endpoint = GUESSED_POLL_ENDPOINT; 245 382 /* 383 * Initialize the backing connection to the host controller. 384 */ 385 rc = usb_device_connection_initialize_from_device(&kbd_dev->wire, dev); 386 if (rc != EOK) { 387 printf("Problem initializing connection to device: %s.\n", 388 str_error(rc)); 389 goto error_leave; 390 } 391 392 /* 393 * Initialize device pipes. 394 */ 395 rc = usb_endpoint_pipe_initialize_default_control(&kbd_dev->ctrl_pipe, 396 &kbd_dev->wire); 397 if (rc != EOK) { 398 printf("Failed to initialize default control pipe: %s.\n", 399 str_error(rc)); 400 goto error_leave; 401 } 402 403 rc = usb_endpoint_pipe_initialize(&kbd_dev->poll_pipe, &kbd_dev->wire, 404 GUESSED_POLL_ENDPOINT, USB_TRANSFER_INTERRUPT, USB_DIRECTION_IN); 405 if (rc != EOK) { 406 printf("Failed to initialize interrupt in pipe: %s.\n", 407 str_error(rc)); 408 goto error_leave; 409 } 410 246 411 /* 247 412 * will need all descriptors: 248 * 1) choose one configuration from configuration descriptors 413 * 1) choose one configuration from configuration descriptors 249 414 * (set it to the device) 250 415 * 2) set endpoints from endpoint descriptors … … 252 417 253 418 // TODO: get descriptors, parse descriptors and save endpoints 419 usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe); 254 420 usbkbd_process_descriptors(kbd_dev); 421 usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe); 255 422 256 423 return kbd_dev; 424 425 error_leave: 426 free(kbd_dev); 427 return NULL; 257 428 } 258 429 … … 267 438 //usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks, 268 439 // NULL); 269 printf("Calling usb_hid_boot_keyboard_input_report()...\n)"); 270 usb_hid_boot_keyboard_input_report(buffer, actual_size, callbacks, NULL); 440 printf("Calling usb_hid_boot_keyboard_input_report() with size %zu\n", 441 actual_size); 442 //dump_buffer("bufffer: ", buffer, actual_size); 443 int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, callbacks, 444 NULL); 445 if (rc != EOK) { 446 printf("Error in usb_hid_boot_keyboard_input_report(): %d\n", rc); 447 } 271 448 } 272 449 273 450 static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev) 274 451 { 275 return; 276 277 int rc; 278 usb_handle_t handle; 452 int rc, sess_rc; 279 453 uint8_t buffer[BUFFER_SIZE]; 280 454 size_t actual_size; 281 //usb_endpoint_t poll_endpoint = 1; 282 283 // usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone, 284 // dev); 285 // if (my_address < 0) { 286 // return; 287 // } 288 289 usb_target_t poll_target = { 290 .address = kbd_dev->address, 291 .endpoint = kbd_dev->poll_endpoint 292 }; 455 456 printf("Polling keyboard...\n"); 293 457 294 458 while (true) { 295 async_usleep(1000 * 1000); 296 rc = usb_drv_async_interrupt_in(kbd_dev->device->parent_phone, 297 poll_target, buffer, BUFFER_SIZE, &actual_size, &handle); 459 async_usleep(1000 * 1000 * 2); 460 461 sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->poll_pipe); 462 if (sess_rc != EOK) { 463 printf("Failed to start a session: %s.\n", 464 str_error(sess_rc)); 465 continue; 466 } 467 468 rc = usb_endpoint_pipe_read(&kbd_dev->poll_pipe, buffer, 469 BUFFER_SIZE, &actual_size); 470 sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->poll_pipe); 298 471 299 472 if (rc != EOK) { 473 printf("Error polling the keyboard: %s.\n", 474 str_error(rc)); 300 475 continue; 301 476 } 302 477 303 rc = usb_drv_async_wait_for(handle); 304 if (rc != EOK) { 478 if (sess_rc != EOK) { 479 printf("Error closing session: %s.\n", 480 str_error(sess_rc)); 305 481 continue; 306 482 } … … 311 487 */ 312 488 if (actual_size == 0) { 489 printf("Keyboard returned NAK\n"); 313 490 continue; 314 491 } … … 317 494 * TODO: Process pressed keys. 318 495 */ 496 printf("Calling usbkbd_process_interrupt_in()\n"); 319 497 usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size); 320 498 } … … 337 515 // initialize device (get and process descriptors, get address, etc.) 338 516 usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev); 517 if (kbd_dev == NULL) { 518 printf("Error while initializing device.\n"); 519 return -1; 520 } 339 521 340 522 usbkbd_poll_keyboard(kbd_dev);
Note:
See TracChangeset
for help on using the changeset viewer.