Ignore:
File:
1 edited

Legend:

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

    rb7fd2a0 r5a6cc679  
    4040#include <usb/debug.h>
    4141#include <assert.h>
     42#include <bitops.h>
     43#include <macros.h>
    4244
    4345
     
    199201int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data)
    200202{
    201         int resolution;
    202         int offset;
    203         int part_size;
    204        
    205         int32_t value = 0;
    206         int32_t mask = 0;
    207         const uint8_t *foo = 0;
    208 
    209203        /* now only short tags are allowed */
    210204        if (item->size > 32) {
     
    214208        if ((item->physical_minimum == 0) && (item->physical_maximum == 0)) {
    215209                item->physical_minimum = item->logical_minimum;
    216                 item->physical_maximum = item->logical_maximum;                 
    217         }
    218        
    219 
     210                item->physical_maximum = item->logical_maximum;
     211        }
     212
     213        int resolution;
    220214        if (item->physical_maximum == item->physical_minimum) {
    221215            resolution = 1;
    222216        } else {
    223             resolution = (item->logical_maximum - item->logical_minimum) / 
    224                 ((item->physical_maximum - item->physical_minimum) * 
     217            resolution = (item->logical_maximum - item->logical_minimum) /
     218                ((item->physical_maximum - item->physical_minimum) *
    225219                (usb_pow(10, (item->unit_exponent))));
    226220        }
    227221
    228         offset = item->offset;
    229         // FIXME
    230         if ((size_t) (offset / 8) != (size_t) ((offset+item->size - 1) / 8)) {
    231                
    232                 part_size = 0;
    233 
    234                 size_t i = 0;
    235                 for (i = (size_t) (offset / 8);
    236                     i <= (size_t) (offset + item->size - 1) / 8; i++) {
    237                         if (i == (size_t) (offset / 8)) {
    238                                 /* the higher one */
    239                                 part_size = 8 - (offset % 8);
    240                                 foo = data + i;
    241                                 mask =  ((1 << (item->size - part_size)) - 1);
    242                                 value = (*foo & mask);
    243                         } else if (i == ((offset + item->size - 1) / 8)) {
    244                                 /* the lower one */
    245                                 foo = data + i;
    246                                 mask = ((1 << (item->size - part_size)) - 1) <<
    247                                     (8 - (item->size - part_size));
    248 
    249                                 value = (((*foo & mask) >> (8 -
    250                                     (item->size - part_size))) << part_size) +
    251                                     value;
    252                         } else {
    253                                 value = (*(data + 1) << (part_size + 8)) +
    254                                     value;
    255                                 part_size += 8;
    256                         }
    257                 }
    258         } else {               
    259                 foo = data + (offset / 8);
    260                 mask = ((1 << item->size) - 1) <<
    261                     (8 - ((offset % 8) + item->size));
    262                 value = (*foo & mask) >> (8 - ((offset % 8) + item->size));
     222        int32_t value = 0;
     223
     224        /* First, skip all bytes we don't care */
     225        data += item->offset / 8;
     226
     227        int bits = item->size;
     228        int taken = 0;
     229
     230        /* Than we take the higher bits from the LSB */
     231        const unsigned bit_offset = item->offset % 8;
     232        const int lsb_bits = min(bits, 8);
     233
     234        value |= (*data >> bit_offset) & BIT_RRANGE(uint8_t, lsb_bits);
     235        bits -= lsb_bits;
     236        taken += lsb_bits;
     237        data++;
     238
     239        /* Then there may be bytes, which we take as a whole. */
     240        while (bits > 8) {
     241                value |= *data << taken;
     242                taken += 8;
     243                bits -= 8;
     244                data++;
     245        }
     246
     247        /* And, finally, lower bits from HSB. */
     248        if (bits > 0) {
     249                value |= (*data & BIT_RRANGE(uint8_t, bits)) << taken;
    263250        }
    264251
     
    366353                length = report_item->size;
    367354               
    368                 usb_log_debug("\ttranslated value: %x\n", value);
     355                usb_log_debug("\ttranslated value: %x", value);
    369356
    370357                if ((offset / 8) == ((offset + length - 1) / 8)) {
     
    437424
    438425        if (USB_HID_ITEM_FLAG_CONSTANT(item->item_flags)) {
    439                 ret = item->logical_minimum;
     426                return item->logical_minimum;
    440427        }
    441428
Note: See TracChangeset for help on using the changeset viewer.