Changeset 021351c in mainline


Ignore:
Timestamp:
2011-03-08T20:01:03Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
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.
Message:

Merged changes from branch maklf

Location:
uspace/lib/usb
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/include/usb/classes/hid_report_items.h

    r8e9becf6 r021351c  
    4242#define USB_HID_REPORT_TAG_INPUT                        0x8
    4343#define USB_HID_REPORT_TAG_OUTPUT                       0x9
    44 #define USB_HID_REPORT_TAG_FEATURE                      0xA
    45 #define USB_HID_REPORT_TAG_COLLECTION           0xB
     44#define USB_HID_REPORT_TAG_FEATURE                      0xB
     45#define USB_HID_REPORT_TAG_COLLECTION           0xA
    4646#define USB_HID_REPORT_TAG_END_COLLECTION       0xC
    4747
  • uspace/lib/usb/include/usb/classes/hidparser.h

    r8e9becf6 r021351c  
    7676        int32_t size;
    7777        int32_t count;
    78         int32_t offset;
     78        size_t offset;
     79        int32_t delimiter;
    7980
    8081        int32_t unit_exponent;
  • uspace/lib/usb/src/hidparser.c

    r8e9becf6 r021351c  
    3636#include <errno.h>
    3737#include <stdio.h>
    38 #include <adt/list.h>
    3938#include <malloc.h>
    4039#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
     48int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    4649                             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,
     50int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    4851                             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,
     52int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    5053                             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,
     54int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    5255                             usb_hid_report_item_t *report_item);
    5356
     
    5558int usb_hid_report_reset_local_items();
    5659void usb_hid_free_report_list(link_t *head);
    57 int32_t usb_hid_report_tag_data_int32(uint8_t *data, size_t size);
     60int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size);
     61inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset);
     62int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j);
     63int usb_pow(int a, int b);
     64
     65int 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
    5880/**
    5981 *
     
    89111        usb_hid_report_item_t *report_item=0;
    90112        usb_hid_report_item_t *new_report_item;
     113
     114        size_t offset=0;
    91115       
    92116
     
    95119        }
    96120        link_initialize(&(report_item->link)); 
    97        
    98         while(i<size){
    99                
     121
     122        while(i<size){ 
    100123                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                       
    101129                        tag = USB_HID_ITEM_TAG(data[i]);
    102130                        item_size = USB_HID_ITEM_SIZE(data[i]);
    103131                        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,
    107139                                                 item_size,report_item);
     140                        usb_log_debug2("ret: %u\n", ret);
    108141                        switch(ret){
    109142                                case USB_HID_NEW_REPORT_ITEM:
    110143                                        // 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                                       
    112149                                        switch(tag) {
    113150                                                case USB_HID_REPORT_TAG_INPUT:
    114                                                         printf(" - INPUT\n");
     151                                                        usb_log_debug(" - INPUT\n");
    115152                                                        list_append(&(report_item->link), &(parser->input));
    116153                                                        break;
    117154                                                case USB_HID_REPORT_TAG_OUTPUT:
    118                                                         printf(" - OUTPUT\n");
     155                                                        usb_log_debug(" - OUTPUT\n");
    119156                                                                list_append(&(report_item->link), &(parser->output));
    120157
    121158                                                        break;
    122159                                                case USB_HID_REPORT_TAG_FEATURE:
    123                                                         printf(" - FEATURE\n");
     160                                                        usb_log_debug(" - FEATURE\n");
    124161                                                                list_append(&(report_item->link), &(parser->feature));
    125162                                                        break;
    126163                                                default:
    127                                                     printf("\tjump over\n");
     164                                                    usb_log_debug("\tjump over - tag %X\n", tag);
    128165                                                    break;
    129166                                        }
     
    148185                                       
    149186                                default:
    150                                         // nothing special to do
     187                                        // nothing special to do                                       
    151188                                        break;
    152189                        }
     
    163200        }
    164201       
    165 
    166         return EOK;
    167 }
    168 
    169 /** Parse and act upon a HID report.
    170  *
    171  * @see usb_hid_parse_report_descriptor
    172  *
    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 
    198202        return EOK;
    199203}
     
    268272 * @return Code of action to be done next
    269273 */
    270 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, uint8_t *data, size_t item_size,
     274int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    271275                             usb_hid_report_item_t *report_item)
    272276{       
     277        int ret;
     278       
    273279        switch(class){
    274280                case USB_HID_TAG_CLASS_MAIN:
    275281
    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) {
    277283                                return USB_HID_NEW_REPORT_ITEM;
    278284                        }
    279285                        else {
    280286                                /*TODO process the error */
    281                                 return -1;
     287                                return ret;
    282288                           }
    283289                        break;
     
    291297                        break;
    292298                default:
    293                         return -1; /* TODO ERROR CODE - UNKNOWN TAG CODE */
     299                        return USB_HID_NO_ACTION;
    294300        }
    295301}
     
    305311 */
    306312
    307 int usb_hid_report_parse_main_tag(uint8_t tag, uint8_t *data, size_t item_size,
     313int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    308314                             usb_hid_report_item_t *report_item)
    309315{
     
    313319                case USB_HID_REPORT_TAG_OUTPUT:
    314320                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;                     
    317323                        break;
    318324                       
    319325                case USB_HID_REPORT_TAG_COLLECTION:
    320326                        // TODO
     327                        return USB_HID_NO_ACTION;
    321328                        break;
    322329                       
    323330                case USB_HID_REPORT_TAG_END_COLLECTION:
    324331                        /* should be ignored */
     332                        return USB_HID_NO_ACTION;
    325333                        break;
    326334                default:
    327                         return -1; //TODO ERROR CODE
     335                        return USB_HID_NO_ACTION;
    328336        }
    329337
     
    341349 */
    342350
    343 int usb_hid_report_parse_global_tag(uint8_t tag, uint8_t *data, size_t item_size,
     351int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    344352                             usb_hid_report_item_t *report_item)
    345353{
     
    383391                       
    384392                default:
    385                         return -1; //TODO ERROR CODE INVALID GLOBAL TAG
     393                        return USB_HID_NO_ACTION;
    386394        }
    387395       
     
    398406 * @return Error code
    399407 */
    400 int usb_hid_report_parse_local_tag(uint8_t tag, uint8_t *data, size_t item_size,
     408int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    401409                             usb_hid_report_item_t *report_item)
    402410{
     
    429437                case USB_HID_REPORT_TAG_STRING_MAXIMUM:
    430438                        report_item->string_maximum = usb_hid_report_tag_data_int32(data,item_size);
    431                         break;
    432 /*                     
     439                        break;                 
    433440                case USB_HID_REPORT_TAG_DELIMITER:
    434441                        report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size);
    435442                        break;
    436 */             
     443               
    437444                default:
    438                         return -1; //TODO ERROR CODE INVALID LOCAL TAG NOW IS ONLY UNSUPPORTED
     445                        return USB_HID_NO_ACTION;
    439446        }
    440447       
     
    449456 * @return Converted int32 number
    450457 */
    451 int32_t usb_hid_report_tag_data_int32(uint8_t *data, size_t size)
     458int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size)
    452459{
    453460        unsigned int i;
     
    479486            return;
    480487        }
    481 
    482        
    483         printf("\tHEAD %p\n",head);
     488       
    484489        for(item = head->next; item != head; item = item->next) {
    485490               
     
    492497                printf("\tUSAGE: %X\n", report_item->usage);
    493498                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);                               
    494503                printf("\n");           
    495504
     
    563572        return;
    564573}
     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 */
     585int 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
     639int 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}
    565706/**
    566707 * @}
Note: See TracChangeset for help on using the changeset viewer.