Changeset d59d0bb in mainline for uspace/lib/usbhid/src/hidparser.c


Ignore:
Timestamp:
2011-05-12T09:16:30Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
97cb542
Parents:
9e195e2c (diff), 9be8669 (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 to HID parser from maklf

File:
1 edited

Legend:

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

    r9e195e2c rd59d0bb  
    6969
    7070
     71/** Returns size of report of specified report id and type in items
     72 *
     73 * @param parser Opaque report parser structure
     74 * @param report_id
     75 * @param type
     76 * @return Number of items in specified report
     77 */
     78size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id,
     79                           usb_hid_report_type_t type)
     80{
     81        usb_hid_report_description_t *report_des;
     82
     83        if(report == NULL) {
     84                return 0;
     85        }
     86
     87        report_des = usb_hid_report_find_description (report, report_id, type);
     88        if(report_des == NULL){
     89                return 0;
     90        }
     91        else {
     92                return report_des->item_length;
     93        }
     94}
    7195
    7296
     
    87111        usb_hid_report_description_t *report_des;
    88112        usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT;
    89 
     113       
    90114        if(report == NULL) {
    91115                return EINVAL;
     
    114138                                // array
    115139                                item->value = usb_hid_translate_data(item, data);
    116                             item->usage = (item->value - item->physical_minimum) + item->usage_minimum;
     140               
     141                                item->usage = USB_HID_EXTENDED_USAGE(item->usages[item->value - item->physical_minimum]);
     142                                item->usage_page = USB_HID_EXTENDED_USAGE_PAGE(item->usages[item->value - item->physical_minimum]);                             
     143
     144                                usb_hid_report_set_last_item (item->collection_path,
     145                                                              USB_HID_TAG_CLASS_GLOBAL,
     146                                                              item->usage_page);
     147                                usb_hid_report_set_last_item (item->collection_path,
     148                                                              USB_HID_TAG_CLASS_LOCAL,
     149                                                              item->usage);
     150                               
    117151                        }
    118152                        else {
     
    123157                list_item = list_item->next;
    124158        }
    125            
     159       
    126160        return EOK;
    127161       
     
    206240}
    207241
    208 /**
    209  * Returns number of items in input report which are accessible by given usage path
    210  *
    211  * @param parser Opaque report descriptor structure
    212  * @param path Usage path specification
    213  * @param flags Usage path comparison flags
    214  * @return Number of items in input report
    215  */
    216 size_t usb_hid_report_input_length(const usb_hid_report_t *report,
    217         usb_hid_report_path_t *path, int flags)
    218 {       
    219        
    220         size_t ret = 0;
    221 
    222         if(report == NULL) {
    223                 return 0;
    224         }
    225 
    226         usb_hid_report_description_t *report_des;
    227         report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_INPUT);
    228         if(report_des == NULL) {
    229                 return 0;
    230         }
    231 
    232         link_t *field_it = report_des->report_items.next;
    233         usb_hid_report_field_t *field;
    234         while(field_it != &report_des->report_items) {
    235 
    236                 field = list_get_instance(field_it, usb_hid_report_field_t, link);
    237                 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
    238                        
    239                         usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
    240                         if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {
    241                                 ret++;
    242                         }
    243                         usb_hid_report_remove_last_item (field->collection_path);
    244                 }
    245                
    246                 field_it = field_it->next;
    247         }
    248 
    249         return ret;
    250         }
    251 
    252242/*** OUTPUT API **/
    253243
     
    304294}
    305295
    306 /** Returns size of output for given usage path
    307  *
    308  * @param parser Opaque report parser structure
    309  * @param path Usage path specified which items will be thought for the output
    310  * @param flags Flags of usage path structure comparison
    311  * @return Number of items matching the given usage path
    312  */
    313 size_t usb_hid_report_output_size(usb_hid_report_t *report,
    314                                   usb_hid_report_path_t *path, int flags)
    315 {
    316         size_t ret = 0;
    317         usb_hid_report_description_t *report_des;
    318 
    319         if(report == NULL) {
    320                 return 0;
    321         }
    322 
    323         report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_OUTPUT);
    324         if(report_des == NULL){
    325                 return 0;
    326         }
    327        
    328         link_t *field_it = report_des->report_items.next;
    329         usb_hid_report_field_t *field;
    330         while(field_it != &report_des->report_items) {
    331 
    332                 field = list_get_instance(field_it, usb_hid_report_field_t, link);
    333                 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0){
    334                         usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
    335                         if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {
    336                                 ret++;
    337                         }
    338                         usb_hid_report_remove_last_item (field->collection_path);
    339                 }
    340                
    341                 field_it = field_it->next;
    342         }
    343 
    344         return ret;
    345        
    346 }
    347 
    348296/** Makes the output report buffer for data given in the report structure
    349297 *
     
    385333                report_item = list_get_instance(item, usb_hid_report_field_t, link);
    386334
    387                         if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) {
     335                usb_log_debug("OUTPUT ITEM usage(%x), value(%x)\n", report_item->usage, report_item->value);
     336               
     337                if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) {
    388338                                       
    389                                 // array
    390                                 value = usb_hid_translate_data_reverse(report_item, report_item->value);
    391                                 offset = report_item->offset;
    392                                 length = report_item->size;
    393                         }
    394                         else {
    395                                 // variable item
    396                                 value  = usb_hid_translate_data_reverse(report_item, report_item->value);
    397                                 offset = report_item->offset;
    398                                 length = report_item->size;
    399                         }
    400 
    401                         if((offset/8) == ((offset+length-1)/8)) {
    402                                 // je to v jednom bytu
    403                                 if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) {
    404                                         break; // TODO ErrorCode
     339                        // array
     340                        value = usb_hid_translate_data_reverse(report_item, report_item->value);
     341                        offset = report_item->offset;
     342                        length = report_item->size;
     343                }
     344                else {
     345                        // variable item
     346                        value  = usb_hid_translate_data_reverse(report_item, report_item->value);
     347                        offset = report_item->offset;
     348                        length = report_item->size;
     349                }
     350
     351                usb_log_debug("\ttranslated value: %x\n", value);
     352
     353                if((offset/8) == ((offset+length-1)/8)) {
     354                        // je to v jednom bytu
     355                        if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) {
     356                                break; // TODO ErrorCode
     357                        }
     358                        size_t shift = 8 - offset%8 - length;
     359                        value = value << shift;                                                 
     360                        value = value & (((1 << length)-1) << shift);
     361                               
     362                        uint8_t mask = 0;
     363                        mask = 0xff - (((1 << length) - 1) << shift);
     364                        buffer[offset/8] = (buffer[offset/8] & mask) | value;
     365                }
     366                else {
     367                        int i = 0;
     368                        uint8_t mask = 0;
     369                        for(i = (offset/8); i <= ((offset+length-1)/8); i++) {
     370                                if(i == (offset/8)) {
     371                                        tmp_value = value;
     372                                        tmp_value = tmp_value & ((1 << (8-(offset%8)))-1);                             
     373                                        tmp_value = tmp_value << (offset%8);
     374       
     375                                        mask = ~(((1 << (8-(offset%8)))-1) << (offset%8));
     376                                        buffer[i] = (buffer[i] & mask) | tmp_value;                     
    405377                                }
    406 
    407                                 size_t shift = 8 - offset%8 - length;
    408 
    409                                 value = value << shift;                                                 
    410                                 value = value & (((1 << length)-1) << shift);
     378                                else if (i == ((offset + length -1)/8)) {
     379                                       
     380                                        value = value >> (length - ((offset + length) % 8));
     381                                        value = value & ((1 << (length - ((offset + length) % 8))) - 1);
    411382                               
    412                                 uint8_t mask = 0;
    413                                 mask = 0xff - (((1 << length) - 1) << shift);
    414                                 buffer[offset/8] = (buffer[offset/8] & mask) | value;
    415                         }
    416                         else {
    417                                 int i = 0;
    418                                 uint8_t mask = 0;
    419                                 for(i = (offset/8); i <= ((offset+length-1)/8); i++) {
    420                                         if(i == (offset/8)) {
    421                                                 tmp_value = value;
    422                                                 tmp_value = tmp_value & ((1 << (8-(offset%8)))-1);                             
    423                                                 tmp_value = tmp_value << (offset%8);
    424        
    425                                                 mask = ~(((1 << (8-(offset%8)))-1) << (offset%8));
    426                                                 buffer[i] = (buffer[i] & mask) | tmp_value;                     
    427                                         }
    428                                         else if (i == ((offset + length -1)/8)) {
    429                                                
    430                                                 value = value >> (length - ((offset + length) % 8));
    431                                                 value = value & ((1 << (length - ((offset + length) % 8))) - 1);
    432                                
    433                                                 mask = (1 << (length - ((offset + length) % 8))) - 1;
    434                                                 buffer[i] = (buffer[i] & mask) | value;
    435                                         }
    436                                         else {
    437                                                 buffer[i] = value & (0xFF << i);
    438                                         }
     383                                        mask = (1 << (length - ((offset + length) % 8))) - 1;
     384                                        buffer[i] = (buffer[i] & mask) | value;
    439385                                }
    440                         }
    441 
     386                                else {
     387                                        buffer[i] = value & (0xFF << i);
     388                                }
     389                        }
     390                }
    442391
    443392                // reset value
     
    472421        }
    473422       
    474 
    475         if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0)) {
    476 
    477                 // variable item
    478                 if(item->physical_maximum == item->physical_minimum){
    479                     resolution = 1;
    480                 }
    481                 else {
    482                     resolution = (item->logical_maximum - item->logical_minimum) /
    483                         ((item->physical_maximum - item->physical_minimum) *
    484                         (usb_pow(10,(item->unit_exponent))));
    485                 }
    486 
    487                 ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum;
    488         }
    489         else {
    490                 // bitmapa
    491                 if(value == 0) {
    492                         ret = 0;
    493                 }
    494                 else {
    495                         size_t bitmap_idx = (value - item->usage_minimum);
    496                         ret = 1 << bitmap_idx;
    497                 }
    498         }
    499 
     423        // variable item
     424        if(item->physical_maximum == item->physical_minimum){
     425            resolution = 1;
     426        }
     427        else {
     428            resolution = (item->logical_maximum - item->logical_minimum) /
     429                ((item->physical_maximum - item->physical_minimum) *
     430                (usb_pow(10,(item->unit_exponent))));
     431        }
     432
     433        ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum;
     434        usb_log_debug("\tvalue(%x), resolution(%x), phymin(%x) logmin(%x), ret(%x)\n", value, resolution, item->physical_minimum, item->logical_minimum, ret);
     435       
    500436        if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
    501437                return USB_HID_INT32_TO_UINT32(ret, item->size);
    502438        }
    503         return (int32_t)ret;
     439        return (int32_t)0 + ret;
    504440}
    505441
Note: See TracChangeset for help on using the changeset viewer.