Changeset fad14d7 in mainline


Ignore:
Timestamp:
2011-03-05T18:08:35Z (14 years ago)
Author:
Matej Klonfar <maklf@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
767da0a
Parents:
b7d9606
Message:

Basic report descriptor imlementation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/src/hidparser.c

    rb7d9606 rfad14d7  
    3333 * @brief HID parser implementation.
    3434 */
     35
     36
    3537#include <usb/classes/hidparser.h>
    3638#include <errno.h>
     
    3840#include <malloc.h>
    3941#include <mem.h>
    40 #include <assert.h>
    4142#include <usb/debug.h>
     43
    4244
    4345#define USB_HID_NEW_REPORT_ITEM 1
     
    4547#define USB_HID_UNKNOWN_TAG             -99
    4648
     49#define BAD_HACK_USAGE_PAGE             0x07
    4750
    4851int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
     
    6063int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size);
    6164inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset);
     65int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j);
     66int usb_pow(int a, int b);
     67
     68int usb_pow(int a, int b)
     69{
     70        switch(b) {
     71                case 0:
     72                        return 1;
     73                        break;
     74                case 1:
     75                        return a;
     76                        break;
     77                default:
     78                        return a * usb_pow(a, b-1);
     79                        break;
     80        }
     81}
     82
    6283/**
    6384 *
     
    120141                        ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    121142                                                 item_size,report_item);
    122                         printf("ret: %u\n", ret);
     143                        usb_log_debug2("ret: %u\n", ret);
    123144                        switch(ret){
    124145                                case USB_HID_NEW_REPORT_ITEM:
     
    127148
    128149                                        report_item->offset = offset;
    129                                         offset = usb_hid_count_item_offset(report_item, offset);
     150                                        offset += report_item->count * report_item->size;
     151                                       
    130152                                        switch(tag) {
    131153                                                case USB_HID_REPORT_TAG_INPUT:
     
    185207}
    186208
    187 /** Parse and act upon a HID report.
    188  *
    189  * @see usb_hid_parse_report_descriptor
    190  *
    191  * @param parser Opaque HID report parser structure.
    192  * @param data Data for the report.
    193  * @param callbacks Callbacks for report actions.
    194  * @param arg Custom argument (passed through to the callbacks).
    195  * @return Error code.
    196  */
    197 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    198     const uint8_t *data, size_t size,
    199     const usb_hid_report_in_callbacks_t *callbacks, void *arg)
    200 {
    201         int i;
    202        
    203         /* main parsing loop */
    204         while(0){
    205         }
    206        
    207        
    208         uint8_t keys[6];
    209        
    210         for (i = 0; i < 6; ++i) {
    211                 keys[i] = data[i];
    212         }
    213        
    214         callbacks->keyboard(keys, 6, 0, arg);
    215 
    216         return EOK;
    217 }
    218 
    219209
    220210/**
     
    582572}
    583573
    584 inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset)
    585 {
    586         return offset += (report_item->count * report_item->size);
     574/** Parse and act upon a HID report.
     575 *
     576 * @see usb_hid_parse_report_descriptor
     577 *
     578 * @param parser Opaque HID report parser structure.
     579 * @param data Data for the report.
     580 * @param callbacks Callbacks for report actions.
     581 * @param arg Custom argument (passed through to the callbacks).
     582 * @return Error code.
     583 */
     584int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
     585    const uint8_t *data, size_t size,
     586    const usb_hid_report_in_callbacks_t *callbacks, void *arg)
     587{
     588        /*
     589         *
     590         * only key codes (usage page 0x07) will be processed
     591         * other usages will be ignored
     592         */
     593        link_t *list_item;
     594        usb_hid_report_item_t *item;
     595        uint8_t *keys;
     596        size_t key_count=0;
     597        size_t i=0;
     598        size_t j=0;
     599
     600        // get the size of result keycodes array
     601        list_item = parser->input.next;   
     602        while(list_item != &(parser->input)) {
     603
     604                item = list_get_instance(list_item, usb_hid_report_item_t, link);
     605                if(item->usage_page == BAD_HACK_USAGE_PAGE) {
     606                        key_count += item->count;
     607                }
     608
     609                list_item = list_item->next;
     610        }
     611
     612       
     613        if(!(keys = malloc(sizeof(uint8_t) * key_count))){
     614                return ENOMEM;
     615        }
     616
     617        // read data           
     618        list_item = parser->input.next;   
     619        while(list_item != &(parser->input)) {
     620
     621                item = list_get_instance(list_item, usb_hid_report_item_t, link);
     622                if(item->usage_page == BAD_HACK_USAGE_PAGE) {
     623                        for(j=0; j<(size_t)(item->count); j++) {
     624                                keys[i++] = usb_hid_translate_data(item, data,j);
     625                        }
     626                }
     627                list_item = list_item->next;
     628        }
     629
     630        callbacks->keyboard(keys, key_count, 0, arg);
     631           
     632        free(keys);     
     633        return EOK;
     634       
     635}
     636
     637
     638int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j)
     639{
     640        int resolution;
     641        int offset;
     642        int part_size;
     643       
     644        int32_t value;
     645        int32_t mask;
     646        const uint8_t *foo;
     647       
     648        // now only common numbers llowed
     649        if(item->size > 32) {
     650                return 0;
     651        }
     652
     653        if((item->physical_minimum == 0) && (item->physical_maximum ==0)) {
     654                item->physical_minimum = item->logical_minimum;
     655                item->physical_maximum = item->logical_maximum;         
     656        }
     657
     658        resolution = (item->logical_maximum - item->logical_minimum) / ((item->physical_maximum - item->physical_minimum) * (usb_pow(10,(item->unit_exponent))));
     659        offset = item->offset + (j * item->size);
     660       
     661        // FIXME
     662        if((offset/8) != ((offset+item->size)/8)) {
     663                usb_log_debug2("offset %d\n", offset);
     664               
     665                part_size = ((offset+item->size)%8);
     666                usb_log_debug2("part size %d\n",part_size);
     667
     668                // the higher one
     669                foo = data+(offset/8);
     670                mask =  ((1 << (item->size-part_size))-1);
     671                value = (*foo & mask) << part_size;
     672
     673                usb_log_debug2("hfoo %x\n", *foo);
     674                usb_log_debug2("hmaska %x\n",  mask);
     675                usb_log_debug2("hval %d\n", value);             
     676
     677                // the lower one
     678                foo = data+((offset+item->size)/8);
     679                mask =  ((1 << part_size)-1) << (8-part_size);
     680                value += ((*foo & mask) >> (8-part_size));
     681
     682                usb_log_debug2("lfoo %x\n", *foo);
     683                usb_log_debug2("lmaska %x\n",  mask);
     684                usb_log_debug2("lval %d\n", ((*foo & mask) >> (8-(item->size-part_size))));             
     685                usb_log_debug2("val %d\n", value);
     686               
     687               
     688        }
     689        else {         
     690                foo = data+(offset/8);
     691                mask =  ((1 << item->size)-1) << (8-((offset%8)+item->size));
     692                value = (*foo & mask) >> (8-((offset%8)+item->size));
     693
     694                usb_log_debug2("offset %d\n", offset);
     695                usb_log_debug2("foo %x\n", *foo);
     696                usb_log_debug2("maska %x\n",  mask);
     697                usb_log_debug2("val %d\n", value);                             
     698        }
     699
     700        usb_log_debug2("---\n\n");
     701
     702        return (int)(((value - item->physical_minimum) / resolution) + item->logical_minimum);
     703       
    587704}
    588705/**
Note: See TracChangeset for help on using the changeset viewer.