Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset ec6ab88 in mainline


Ignore:
Timestamp:
2010-12-12T12:27:46Z (11 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master
Children:
a1ca50b3
Parents:
5174c62 (diff), 8365533 (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 branch lelian/hidd into development

Location:
uspace
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/virtusbkbd/Makefile

    r5174c62 rec6ab88  
    3333
    3434LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBUSBVIRT_PREFIX)/libusbvirt.a
    35 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX)
     35EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX) -I$(LIBDRV_PREFIX)/include
    3636
    3737SOURCES = \
  • uspace/drv/usbkbd/main.c

    r5174c62 rec6ab88  
    2828#include <usb/usbdrv.h>
    2929#include <driver.h>
     30#include <ipc/driver.h>
    3031#include <errno.h>
     32#include <fibril.h>
     33#include <usb/classes/hid.h>
     34#include <usb/classes/hidparser.h>
     35#include <usb/devreq.h>
    3136
    3237#define BUFFER_SIZE 32
    33 
    34 /* Call this periodically to check keyboard status changes. */
    35 static void poll_keyboard(device_t *dev)
     38#define NAME "usbkbd"
     39
     40static const usb_endpoint_t CONTROL_EP = 0;
     41
     42/*
     43 * Callbacks for parser
     44 */
     45static void usbkbd_process_keycodes(const uint16_t *key_codes, size_t count,
     46                                    void *arg)
     47{
     48
     49}
     50
     51/*
     52 * Kbd functions
     53 */
     54static int usbkbd_get_descriptors()
     55{
     56        // copy-pasted:
     57       
     58        /* Prepare the setup packet. */
     59        usb_device_request_setup_packet_t setup_packet = {
     60                .request_type = 128,
     61                .request = USB_DEVREQ_GET_DESCRIPTOR,
     62                .index = 0,
     63                .length = sizeof(usb_standard_device_descriptor_t)
     64        };
     65       
     66        setup_packet.value_high = USB_DESCTYPE_DEVICE;
     67        setup_packet.value_low = 0;
     68
     69        /* Prepare local descriptor. */
     70        size_t actually_transferred = 0;
     71        usb_standard_device_descriptor_t descriptor_tmp;
     72
     73        /* Perform the control read transaction. */
     74        int rc = usb_drv_psync_control_read(phone, target,
     75            &setup_packet, sizeof(setup_packet),
     76            &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred);
     77
     78        if (rc != EOK) {
     79                return rc;
     80        }
     81       
     82        // end of copy-paste
     83}
     84
     85static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev)
     86{
     87        usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)malloc(
     88                        sizeof(usb_hid_dev_kbd_t));
     89
     90        if (kbd_dev == NULL) {
     91                fprintf(stderr, NAME ": No memory!\n");
     92                return NULL;
     93        }
     94
     95        kbd_dev->device = dev;
     96
     97        // get phone to my HC and save it as my parent's phone
     98        // TODO: maybe not a good idea if DDF will use parent_phone
     99        kbd_dev->device->parent_phone = usb_drv_hc_connect(dev, 0);
     100
     101        kbd_dev->address = usb_drv_get_my_address(dev->parent_phone,
     102            dev);
     103
     104        // doesn't matter now that we have no address
     105//      if (kbd_dev->address < 0) {
     106//              fprintf(stderr, NAME ": No device address!\n");
     107//              free(kbd_dev);
     108//              return NULL;
     109//      }
     110
     111        // default endpoint
     112        kbd_dev->default_ep = CONTROL_EP;
     113
     114        // TODO: get descriptors
     115        usbkbd_get_descriptors();
     116        // TODO: parse descriptors and save endpoints
     117
     118        return kbd_dev;
     119}
     120
     121static void usbkbd_process_interrupt_in(usb_hid_dev_kbd_t *kbd_dev,
     122                                        uint8_t *buffer, size_t actual_size)
     123{
     124        /*
     125         * here, the parser will be called, probably with some callbacks
     126         * now only take last 6 bytes and process, i.e. send to kbd
     127         */
     128
     129        usb_hid_report_in_callbacks_t *callbacks =
     130            (usb_hid_report_in_callbacks_t *)malloc(
     131                sizeof(usb_hid_report_in_callbacks_t));
     132        callbacks->keyboard = usbkbd_process_keycodes;
     133
     134        usb_hid_parse_report(kbd_dev->parser, buffer, callbacks, NULL);
     135}
     136
     137static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev)
    36138{
    37139        int rc;
    38140        usb_handle_t handle;
    39         char buffer[BUFFER_SIZE];
     141        uint8_t buffer[BUFFER_SIZE];
    40142        size_t actual_size;
    41         usb_endpoint_t poll_endpoint = 1;
    42 
    43         usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,
    44             dev);
    45         if (my_address < 0) {
    46                 return;
    47         }
     143        //usb_endpoint_t poll_endpoint = 1;
     144
     145//      usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,
     146//          dev);
     147//      if (my_address < 0) {
     148//              return;
     149//      }
    48150
    49151        usb_target_t poll_target = {
    50                 .address = my_address,
    51                 .endpoint = poll_endpoint
     152                .address = kbd_dev->address,
     153                .endpoint = kbd_dev->default_ep
    52154        };
    53155
    54         rc = usb_drv_async_interrupt_in(dev->parent_phone, poll_target,
    55             buffer, BUFFER_SIZE, &actual_size, &handle);
    56         if (rc != EOK) {
    57                 return;
    58         }
    59 
    60         rc = usb_drv_async_wait_for(handle);
    61         if (rc != EOK) {
    62                 return;
    63         }
    64 
    65         /*
    66          * If the keyboard answered with NAK, it returned no data.
    67          * This implies that no change happened since last query.
    68          */
    69         if (actual_size == 0) {
    70                 return;
    71         }
    72 
    73         /*
    74          * Process pressed keys.
    75          */
    76 }
    77 
    78 static int add_kbd_device(device_t *dev)
     156        while (true) {
     157                rc = usb_drv_async_interrupt_in(kbd_dev->device->parent_phone,
     158                    poll_target, buffer, BUFFER_SIZE, &actual_size, &handle);
     159
     160                if (rc != EOK) {
     161                        continue;
     162                }
     163
     164                rc = usb_drv_async_wait_for(handle);
     165                if (rc != EOK) {
     166                        continue;
     167                }
     168
     169                /*
     170                 * If the keyboard answered with NAK, it returned no data.
     171                 * This implies that no change happened since last query.
     172                 */
     173                if (actual_size == 0) {
     174                        continue;
     175                }
     176
     177                /*
     178                 * TODO: Process pressed keys.
     179                 */
     180                usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size);
     181        }
     182
     183        // not reached
     184        assert(0);
     185}
     186
     187static int usbkbd_fibril_device(void *arg)
     188{
     189        printf("!!! USB device fibril\n");
     190
     191        if (arg == NULL) {
     192                printf("No device!\n");
     193                return -1;
     194        }
     195
     196        device_t *dev = (device_t *)arg;
     197
     198        // initialize device (get and process descriptors, get address, etc.)
     199        usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev);
     200
     201        usbkbd_poll_keyboard(kbd_dev);
     202
     203        return EOK;
     204}
     205
     206static int usbkbd_add_device(device_t *dev)
    79207{
    80208        /* For now, fail immediately. */
    81         return ENOTSUP;
     209        //return ENOTSUP;
    82210
    83211        /*
    84212         * When everything is okay, connect to "our" HC.
    85          */
    86         int phone = usb_drv_hc_connect(dev, 0);
    87         if (phone < 0) {
    88                 /*
    89                  * Connecting to HC failed, roll-back and announce
    90                  * failure.
    91                  */
    92                 return phone;
    93         }
    94 
    95         dev->parent_phone = phone;
    96 
    97         /*
    98          * Just for fun ;-).
    99          */
    100         poll_keyboard(dev);
     213         *
     214         * Not supported yet, skip..
     215         */
     216//      int phone = usb_drv_hc_connect(dev, 0);
     217//      if (phone < 0) {
     218//              /*
     219//               * Connecting to HC failed, roll-back and announce
     220//               * failure.
     221//               */
     222//              return phone;
     223//      }
     224
     225//      dev->parent_phone = phone;
     226
     227        /*
     228         * Create new fibril for handling this keyboard
     229         */
     230        fid_t fid = fibril_create(usbkbd_fibril_device, dev);
     231        if (fid == 0) {
     232                printf("%s: failed to start fibril for HID device\n", NAME);
     233                return ENOMEM;
     234        }
     235        fibril_add_ready(fid);
    101236
    102237        /*
     
    107242
    108243static driver_ops_t kbd_driver_ops = {
    109         .add_device = add_kbd_device,
     244        .add_device = usbkbd_add_device,
    110245};
    111246
    112247static driver_t kbd_driver = {
    113         .name = "usbkbd",
     248        .name = NAME,
    114249        .driver_ops = &kbd_driver_ops
    115250};
  • uspace/lib/usb/include/usb/classes/hid.h

    r5174c62 rec6ab88  
    3636#define LIBUSB_HID_H_
    3737
     38#include <usb/usb.h>
     39#include <driver.h>
     40#include <usb/classes/hidparser.h>
     41
    3842/** USB/HID device requests. */
    3943typedef enum {
     
    5458} usb_hid_protocol_t;
    5559
     60/**
     61 * @brief USB/HID keyboard device type.
     62 *
     63 * Quite dummy right now.
     64 */
     65typedef struct {
     66        device_t *device;
     67        usb_address_t address;
     68        usb_endpoint_t default_ep;
     69        usb_hid_report_parser_t *parser;
     70} usb_hid_dev_kbd_t;
     71
    5672#endif
    5773/**
  • uspace/lib/usb/include/usb/classes/hidparser.h

    r5174c62 rec6ab88  
    5050         * @param arg Custom argument.
    5151         */
    52         void (*keyboard)(const uint32_t *key_codes, size_t count, void *arg);
     52        void (*keyboard)(const uint16_t *key_codes, size_t count, void *arg);
    5353} usb_hid_report_in_callbacks_t;
    5454
  • uspace/lib/usb/src/hidparser.c

    r5174c62 rec6ab88  
    6262    const usb_hid_report_in_callbacks_t *callbacks, void *arg)
    6363{
    64         return ENOTSUP;
     64        int i;
     65       
     66        // TODO: parse report
     67       
     68        uint16_t keys[6];
     69       
     70        for (i = 0; i < 6; ++i) {
     71                keys[i] = data[i];
     72        }
     73       
     74        callbacks->keyboard(keys, 6, arg);
    6575}
    6676
Note: See TracChangeset for help on using the changeset viewer.