Changeset 021351c in mainline
- Timestamp:
- 2011-03-08T20:01:03Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5050d9e
- Parents:
- 8e9becf6 (diff), 8bec4d1 (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. - Location:
- uspace/lib/usb
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/classes/hid_report_items.h
r8e9becf6 r021351c 42 42 #define USB_HID_REPORT_TAG_INPUT 0x8 43 43 #define USB_HID_REPORT_TAG_OUTPUT 0x9 44 #define USB_HID_REPORT_TAG_FEATURE 0x A45 #define USB_HID_REPORT_TAG_COLLECTION 0x B44 #define USB_HID_REPORT_TAG_FEATURE 0xB 45 #define USB_HID_REPORT_TAG_COLLECTION 0xA 46 46 #define USB_HID_REPORT_TAG_END_COLLECTION 0xC 47 47 -
uspace/lib/usb/include/usb/classes/hidparser.h
r8e9becf6 r021351c 76 76 int32_t size; 77 77 int32_t count; 78 int32_t offset; 78 size_t offset; 79 int32_t delimiter; 79 80 80 81 int32_t unit_exponent; -
uspace/lib/usb/src/hidparser.c
r8e9becf6 r021351c 36 36 #include <errno.h> 37 37 #include <stdio.h> 38 #include <adt/list.h>39 38 #include <malloc.h> 40 39 #include <mem.h> 41 42 #define USB_HID_NEW_REPORT_ITEM 0 43 44 45 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, uint8_t *data, size_t item_size, 40 #include <usb/debug.h> 41 42 #define USB_HID_NEW_REPORT_ITEM 1 43 #define USB_HID_NO_ACTION 2 44 #define USB_HID_UNKNOWN_TAG -99 45 46 #define BAD_HACK_USAGE_PAGE 0x07 47 48 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 46 49 usb_hid_report_item_t *report_item); 47 int usb_hid_report_parse_main_tag(uint8_t tag, uint8_t *data, size_t item_size,50 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 48 51 usb_hid_report_item_t *report_item); 49 int usb_hid_report_parse_global_tag(uint8_t tag, uint8_t *data, size_t item_size,52 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 50 53 usb_hid_report_item_t *report_item); 51 int usb_hid_report_parse_local_tag(uint8_t tag, uint8_t *data, size_t item_size,54 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 52 55 usb_hid_report_item_t *report_item); 53 56 … … 55 58 int usb_hid_report_reset_local_items(); 56 59 void usb_hid_free_report_list(link_t *head); 57 int32_t usb_hid_report_tag_data_int32(uint8_t *data, size_t size); 60 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size); 61 inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset); 62 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j); 63 int usb_pow(int a, int b); 64 65 int usb_pow(int a, int b) 66 { 67 switch(b) { 68 case 0: 69 return 1; 70 break; 71 case 1: 72 return a; 73 break; 74 default: 75 return a * usb_pow(a, b-1); 76 break; 77 } 78 } 79 58 80 /** 59 81 * … … 89 111 usb_hid_report_item_t *report_item=0; 90 112 usb_hid_report_item_t *new_report_item; 113 114 size_t offset=0; 91 115 92 116 … … 95 119 } 96 120 link_initialize(&(report_item->link)); 97 98 while(i<size){ 99 121 122 while(i<size){ 100 123 if(!USB_HID_ITEM_IS_LONG(data[i])){ 124 125 if((i+USB_HID_ITEM_SIZE(data[i]))>= size){ 126 return -1; // TODO ERROR CODE 127 } 128 101 129 tag = USB_HID_ITEM_TAG(data[i]); 102 130 item_size = USB_HID_ITEM_SIZE(data[i]); 103 131 class = USB_HID_ITEM_TAG_CLASS(data[i]); 104 105 ret = usb_hid_report_parse_tag(tag,class, 106 (uint8_t *)(data + sizeof(uint8_t)*(i+1)), 132 133 usb_log_debug2( 134 "i(%u) data(%X) value(%X): TAG %u, class %u, size %u - ", i, 135 data[i], usb_hid_report_tag_data_int32(data+i+1,item_size), 136 tag, class, item_size); 137 138 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 107 139 item_size,report_item); 140 usb_log_debug2("ret: %u\n", ret); 108 141 switch(ret){ 109 142 case USB_HID_NEW_REPORT_ITEM: 110 143 // store report item to report and create the new one 111 printf("\nNEW REPORT ITEM: %X",tag); 144 usb_log_debug("\nNEW REPORT ITEM: %X",tag); 145 146 report_item->offset = offset; 147 offset += report_item->count * report_item->size; 148 112 149 switch(tag) { 113 150 case USB_HID_REPORT_TAG_INPUT: 114 printf(" - INPUT\n");151 usb_log_debug(" - INPUT\n"); 115 152 list_append(&(report_item->link), &(parser->input)); 116 153 break; 117 154 case USB_HID_REPORT_TAG_OUTPUT: 118 printf(" - OUTPUT\n");155 usb_log_debug(" - OUTPUT\n"); 119 156 list_append(&(report_item->link), &(parser->output)); 120 157 121 158 break; 122 159 case USB_HID_REPORT_TAG_FEATURE: 123 printf(" - FEATURE\n");160 usb_log_debug(" - FEATURE\n"); 124 161 list_append(&(report_item->link), &(parser->feature)); 125 162 break; 126 163 default: 127 printf("\tjump over\n");164 usb_log_debug("\tjump over - tag %X\n", tag); 128 165 break; 129 166 } … … 148 185 149 186 default: 150 // nothing special to do 187 // nothing special to do 151 188 break; 152 189 } … … 163 200 } 164 201 165 166 return EOK;167 }168 169 /** Parse and act upon a HID report.170 *171 * @see usb_hid_parse_report_descriptor172 *173 * @param parser Opaque HID report parser structure.174 * @param data Data for the report.175 * @param callbacks Callbacks for report actions.176 * @param arg Custom argument (passed through to the callbacks).177 * @return Error code.178 */179 int usb_hid_parse_report(const usb_hid_report_parser_t *parser,180 const uint8_t *data, size_t size,181 const usb_hid_report_in_callbacks_t *callbacks, void *arg)182 {183 int i;184 185 /* main parsing loop */186 while(0){187 }188 189 190 uint8_t keys[6];191 192 for (i = 0; i < 6; ++i) {193 keys[i] = data[i];194 }195 196 callbacks->keyboard(keys, 6, 0, arg);197 198 202 return EOK; 199 203 } … … 268 272 * @return Code of action to be done next 269 273 */ 270 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, uint8_t *data, size_t item_size,274 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 271 275 usb_hid_report_item_t *report_item) 272 276 { 277 int ret; 278 273 279 switch(class){ 274 280 case USB_HID_TAG_CLASS_MAIN: 275 281 276 if( usb_hid_report_parse_main_tag(tag,data,item_size,report_item) == EOK) {282 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item)) == EOK) { 277 283 return USB_HID_NEW_REPORT_ITEM; 278 284 } 279 285 else { 280 286 /*TODO process the error */ 281 return -1;287 return ret; 282 288 } 283 289 break; … … 291 297 break; 292 298 default: 293 return -1; /* TODO ERROR CODE - UNKNOWN TAG CODE */299 return USB_HID_NO_ACTION; 294 300 } 295 301 } … … 305 311 */ 306 312 307 int usb_hid_report_parse_main_tag(uint8_t tag, uint8_t *data, size_t item_size,313 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 308 314 usb_hid_report_item_t *report_item) 309 315 { … … 313 319 case USB_HID_REPORT_TAG_OUTPUT: 314 320 case USB_HID_REPORT_TAG_FEATURE: 315 report_item->item_flags = *data; 316 return USB_HID_NEW_REPORT_ITEM;321 report_item->item_flags = *data; 322 return EOK; 317 323 break; 318 324 319 325 case USB_HID_REPORT_TAG_COLLECTION: 320 326 // TODO 327 return USB_HID_NO_ACTION; 321 328 break; 322 329 323 330 case USB_HID_REPORT_TAG_END_COLLECTION: 324 331 /* should be ignored */ 332 return USB_HID_NO_ACTION; 325 333 break; 326 334 default: 327 return -1; //TODO ERROR CODE335 return USB_HID_NO_ACTION; 328 336 } 329 337 … … 341 349 */ 342 350 343 int usb_hid_report_parse_global_tag(uint8_t tag, uint8_t *data, size_t item_size,351 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 344 352 usb_hid_report_item_t *report_item) 345 353 { … … 383 391 384 392 default: 385 return -1; //TODO ERROR CODE INVALID GLOBAL TAG393 return USB_HID_NO_ACTION; 386 394 } 387 395 … … 398 406 * @return Error code 399 407 */ 400 int usb_hid_report_parse_local_tag(uint8_t tag, uint8_t *data, size_t item_size,408 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 401 409 usb_hid_report_item_t *report_item) 402 410 { … … 429 437 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 430 438 report_item->string_maximum = usb_hid_report_tag_data_int32(data,item_size); 431 break; 432 /* 439 break; 433 440 case USB_HID_REPORT_TAG_DELIMITER: 434 441 report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size); 435 442 break; 436 */443 437 444 default: 438 return -1; //TODO ERROR CODE INVALID LOCAL TAG NOW IS ONLY UNSUPPORTED445 return USB_HID_NO_ACTION; 439 446 } 440 447 … … 449 456 * @return Converted int32 number 450 457 */ 451 int32_t usb_hid_report_tag_data_int32( uint8_t *data, size_t size)458 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size) 452 459 { 453 460 unsigned int i; … … 479 486 return; 480 487 } 481 482 483 printf("\tHEAD %p\n",head); 488 484 489 for(item = head->next; item != head; item = item->next) { 485 490 … … 492 497 printf("\tUSAGE: %X\n", report_item->usage); 493 498 printf("\tUSAGE PAGE: %X\n", report_item->usage_page); 499 printf("\tLOGMIN: %X\n", report_item->logical_minimum); 500 printf("\tLOGMAX: %X\n", report_item->logical_maximum); 501 printf("\tPHYMIN: %X\n", report_item->physical_minimum); 502 printf("\tPHYMAX: %X\n", report_item->physical_maximum); 494 503 printf("\n"); 495 504 … … 563 572 return; 564 573 } 574 575 /** Parse and act upon a HID report. 576 * 577 * @see usb_hid_parse_report_descriptor 578 * 579 * @param parser Opaque HID report parser structure. 580 * @param data Data for the report. 581 * @param callbacks Callbacks for report actions. 582 * @param arg Custom argument (passed through to the callbacks). 583 * @return Error code. 584 */ 585 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 586 const uint8_t *data, size_t size, 587 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 588 { 589 /* 590 * 591 * only key codes (usage page 0x07) will be processed 592 * other usages will be ignored 593 */ 594 link_t *list_item; 595 usb_hid_report_item_t *item; 596 uint8_t *keys; 597 size_t key_count=0; 598 size_t i=0; 599 size_t j=0; 600 601 // get the size of result keycodes array 602 list_item = parser->input.next; 603 while(list_item != &(parser->input)) { 604 605 item = list_get_instance(list_item, usb_hid_report_item_t, link); 606 if(item->usage_page == BAD_HACK_USAGE_PAGE) { 607 key_count += item->count; 608 } 609 610 list_item = list_item->next; 611 } 612 613 614 if(!(keys = malloc(sizeof(uint8_t) * key_count))){ 615 return ENOMEM; 616 } 617 618 // read data 619 list_item = parser->input.next; 620 while(list_item != &(parser->input)) { 621 622 item = list_get_instance(list_item, usb_hid_report_item_t, link); 623 if(item->usage_page == BAD_HACK_USAGE_PAGE) { 624 for(j=0; j<(size_t)(item->count); j++) { 625 keys[i++] = usb_hid_translate_data(item, data,j); 626 } 627 } 628 list_item = list_item->next; 629 } 630 631 callbacks->keyboard(keys, key_count, 0, arg); 632 633 free(keys); 634 return EOK; 635 636 } 637 638 639 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j) 640 { 641 int resolution; 642 int offset; 643 int part_size; 644 645 int32_t value; 646 int32_t mask; 647 const uint8_t *foo; 648 649 // now only common numbers llowed 650 if(item->size > 32) { 651 return 0; 652 } 653 654 if((item->physical_minimum == 0) && (item->physical_maximum ==0)) { 655 item->physical_minimum = item->logical_minimum; 656 item->physical_maximum = item->logical_maximum; 657 } 658 659 resolution = (item->logical_maximum - item->logical_minimum) / ((item->physical_maximum - item->physical_minimum) * (usb_pow(10,(item->unit_exponent)))); 660 offset = item->offset + (j * item->size); 661 662 // FIXME 663 if((offset/8) != ((offset+item->size)/8)) { 664 usb_log_debug2("offset %d\n", offset); 665 666 part_size = ((offset+item->size)%8); 667 usb_log_debug2("part size %d\n",part_size); 668 669 // the higher one 670 foo = data+(offset/8); 671 mask = ((1 << (item->size-part_size))-1); 672 value = (*foo & mask) << part_size; 673 674 usb_log_debug2("hfoo %x\n", *foo); 675 usb_log_debug2("hmaska %x\n", mask); 676 usb_log_debug2("hval %d\n", value); 677 678 // the lower one 679 foo = data+((offset+item->size)/8); 680 mask = ((1 << part_size)-1) << (8-part_size); 681 value += ((*foo & mask) >> (8-part_size)); 682 683 usb_log_debug2("lfoo %x\n", *foo); 684 usb_log_debug2("lmaska %x\n", mask); 685 usb_log_debug2("lval %d\n", ((*foo & mask) >> (8-(item->size-part_size)))); 686 usb_log_debug2("val %d\n", value); 687 688 689 } 690 else { 691 foo = data+(offset/8); 692 mask = ((1 << item->size)-1) << (8-((offset%8)+item->size)); 693 value = (*foo & mask) >> (8-((offset%8)+item->size)); 694 695 usb_log_debug2("offset %d\n", offset); 696 usb_log_debug2("foo %x\n", *foo); 697 usb_log_debug2("maska %x\n", mask); 698 usb_log_debug2("val %d\n", value); 699 } 700 701 usb_log_debug2("---\n\n"); 702 703 return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum); 704 705 } 565 706 /** 566 707 * @}
Note:
See TracChangeset
for help on using the changeset viewer.