From 3493c1c0878db2b2c367fcdd9e69e4dcc104cad6 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Tue, 30 Aug 2016 04:02:27 +0200 Subject: fix bmRequestType field - use of defines Signed-off-by: Amir Hammad --- src/usbh_core.c | 8 ++++---- src/usbh_driver_ac_midi.c | 2 +- src/usbh_driver_gp_xbox.c | 2 +- src/usbh_driver_hub.c | 24 ++++++++++++------------ 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/usbh_core.c b/src/usbh_core.c index e1076cd..5e35da9 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -337,7 +337,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ struct usb_setup_data setup_data; - setup_data.bmRequestType = 0b10000000; + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; setup_data.wValue = USB_DT_DEVICE << 8; setup_data.wIndex = 0; @@ -394,7 +394,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ dev->packet_size_max0 = ddt->bMaxPacketSize0; struct usb_setup_data setup_data; - setup_data.bmRequestType = 0b10000000; + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; setup_data.wValue = USB_DT_CONFIGURATION << 8; setup_data.wIndex = 0; @@ -457,7 +457,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ (struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE]; struct usb_setup_data setup_data; LOG_PRINTF("WRITE: LEN: %d", cdt->wTotalLength); - setup_data.bmRequestType = 0b10000000; + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; setup_data.wValue = USB_DT_CONFIGURATION << 8; setup_data.wIndex = 0; @@ -573,7 +573,7 @@ void device_enumeration_start(usbh_device_t *dev) struct usb_setup_data setup_data; - setup_data.bmRequestType = 0b00000000; + setup_data.bmRequestType = USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; setup_data.bRequest = USB_REQ_SET_ADDRESS; setup_data.wValue = address; setup_data.wIndex = 0; diff --git a/src/usbh_driver_ac_midi.c b/src/usbh_driver_ac_midi.c index 413875f..205c2a2 100644 --- a/src/usbh_driver_ac_midi.c +++ b/src/usbh_driver_ac_midi.c @@ -300,7 +300,7 @@ static void midi_poll(void *drvdata, uint32_t t_us) //~ LOG_PRINTF("CFGVAL: %d\n", dev->config_val); struct usb_setup_data setup_data; - setup_data.bmRequestType = 0b00000000; + setup_data.bmRequestType = USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; setup_data.bRequest = USB_REQ_SET_CONFIGURATION; setup_data.wValue = midi->buffer[0]; setup_data.wIndex = 0; diff --git a/src/usbh_driver_gp_xbox.c b/src/usbh_driver_gp_xbox.c index 01cebb5..1bc2498 100644 --- a/src/usbh_driver_gp_xbox.c +++ b/src/usbh_driver_gp_xbox.c @@ -364,7 +364,7 @@ static void poll(void *drvdata, uint32_t time_curr_us) { struct usb_setup_data setup_data; - setup_data.bmRequestType = 0b00000000; + setup_data.bmRequestType = USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; setup_data.bRequest = USB_REQ_SET_CONFIGURATION; setup_data.wValue = gp_xbox->configuration_value; setup_data.wIndex = 0; diff --git a/src/usbh_driver_hub.c b/src/usbh_driver_hub.c index a7448f5..29335a7 100644 --- a/src/usbh_driver_hub.c +++ b/src/usbh_driver_hub.c @@ -179,9 +179,9 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) struct usb_setup_data setup_data; // If regular port event, else hub event if (port) { - setup_data.bmRequestType = 0b10100011; + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT; } else { - setup_data.bmRequestType = 0b10100000; + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE; } setup_data.bRequest = USB_REQ_GET_STATUS; @@ -246,7 +246,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) struct usb_setup_data setup_data; hub->desc_len = hub->device[0]->packet_size_max0; - setup_data.bmRequestType = 0b10100000; + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE; setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; setup_data.wValue = 0x29<<8; setup_data.wIndex = 0; @@ -297,7 +297,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) struct usb_setup_data setup_data; hub->desc_len = hub_descriptor->head.bDescLength; - setup_data.bmRequestType = 0b10100000; + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE; setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; setup_data.wValue = 0x29<<8; setup_data.wIndex = 0; @@ -361,7 +361,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) struct usb_setup_data setup_data; LOG_PRINTF("[!%d!]",hub->index); - setup_data.bmRequestType = 0b00100011; + setup_data.bmRequestType = USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT; setup_data.bRequest = HUB_REQ_SET_FEATURE; setup_data.wValue = HUB_FEATURE_PORT_POWER; setup_data.wIndex = hub->index; @@ -400,7 +400,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) { struct usb_setup_data setup_data; - setup_data.bmRequestType = 0b10100000; + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE; setup_data.bRequest = USB_REQ_GET_STATUS; setup_data.wValue = 0; setup_data.wIndex = 0; @@ -445,7 +445,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) { struct usb_setup_data setup_data; - setup_data.bmRequestType = 0b10100011; + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT; setup_data.bRequest = USB_REQ_GET_STATUS; setup_data.wValue = 0; setup_data.wIndex = ++hub->index; @@ -564,7 +564,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) // clear feature C_PORT_CONNECTION struct usb_setup_data setup_data; - setup_data.bmRequestType = 0b00100011; + setup_data.bmRequestType = USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT; setup_data.bRequest = HUB_REQ_CLEAR_FEATURE; setup_data.wValue = HUB_FEATURE_C_PORT_CONNECTION; setup_data.wIndex = port; @@ -580,7 +580,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) // Reset processing is complete, enumerate device struct usb_setup_data setup_data; - setup_data.bmRequestType = 0b00100011; + setup_data.bmRequestType = USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT; setup_data.bRequest = HUB_REQ_CLEAR_FEATURE; setup_data.wValue = HUB_FEATURE_C_PORT_RESET; setup_data.wIndex = port; @@ -622,7 +622,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) if ((stc) & (1<buffer[0]); struct usb_setup_data setup_data; - setup_data.bmRequestType = 0b00000000; + setup_data.bmRequestType = USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; setup_data.bRequest = USB_REQ_SET_CONFIGURATION; setup_data.wValue = hub->buffer[0]; setup_data.wIndex = 0; -- cgit From e0fbb799bd0dcf8592d08d6a8734e0afcb7e2b81 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Thu, 1 Sep 2016 10:38:18 +0200 Subject: usbh_core refactor Signed-off-by: Amir Hammad --- include/driver/usbh_device_driver.h | 19 +++- src/usbh_core.c | 182 ++++++++++++++++++++---------------- 2 files changed, 118 insertions(+), 83 deletions(-) diff --git a/include/driver/usbh_device_driver.h b/include/driver/usbh_device_driver.h index bace1ef..6dd53c3 100644 --- a/include/driver/usbh_device_driver.h +++ b/include/driver/usbh_device_driver.h @@ -61,6 +61,23 @@ enum USBH_CONTROL_TYPE { USBH_CONTROL_TYPE_DATA }; +enum USBH_ENUM_STATE { + USBH_ENUM_STATE_SET_ADDRESS, + USBH_ENUM_STATE_FIRST = USBH_ENUM_STATE_SET_ADDRESS, + USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ, + USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ_COMPLETE, + USBH_ENUM_STATE_DEVICE_DT_READ_SETUP, + USBH_ENUM_STATE_DEVICE_DT_READ, + USBH_ENUM_STATE_DEVICE_DT_READ_COMPLETE, + USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ_SETUP, + USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ, + USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ_COMPLETE, + USBH_ENUM_STATE_CONFIGURATION_DT_READ_SETUP, + USBH_ENUM_STATE_CONFIGURATION_DT_READ, + USBH_ENUM_STATE_CONFIGURATION_DT_READ_COMPLETE, + USBH_ENUM_STATE_FIND_DRIVER, +}; + /** * @brief The _usbh_device struct * @@ -77,7 +94,7 @@ struct _usbh_device { enum USBH_SPEED speed; /// state used for enumeration purposes - uint8_t state; + enum USBH_ENUM_STATE state; /// toggle bit uint8_t toggle0; diff --git a/src/usbh_core.c b/src/usbh_core.c index 5e35da9..cd631a4 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -172,10 +172,9 @@ void usbh_init(const void *low_level_drivers[], const usbh_dev_driver_t * const usbh_data.lld_drivers = (const usbh_low_level_driver_t **)low_level_drivers; usbh_data.dev_drivers = device_drivers; - // TODO: init structures uint32_t k = 0; while (usbh_data.lld_drivers[k]) { - LOG_PRINTF("DRIVER %d\n", k); + LOG_PRINTF("Initialization low-level driver with index=%d\n", k); usbh_device_t * usbh_device = ((usbh_generic_data_t *)(usbh_data.lld_drivers[k])->driver_data)->usbh_device; @@ -186,7 +185,6 @@ void usbh_init(const void *low_level_drivers[], const usbh_dev_driver_t * const usbh_device[i].drv = 0; usbh_device[i].drvdata = 0; } - LOG_PRINTF("DRIVER %d", k); usbh_data.lld_drivers[k]->init(usbh_data.lld_drivers[k]->driver_data); k++; @@ -289,17 +287,22 @@ usbh_device_t *usbh_get_free_device(const usbh_device_t *dev) return 0; } -static void device_enumeration_terminate(usbh_device_t *dev) +static void device_enumeration_finish(usbh_device_t *dev) { reset_enumeration(); - dev->state = 0; + dev->state = USBH_ENUM_STATE_FIRST; +} + +static void device_enumeration_terminate(usbh_device_t *dev) +{ dev->address = -1; + device_enumeration_finish(dev); } -/* Do not call this function directly, - * only via callback passing into low-level function - * If you must, call it carefully ;) - */ +#define CONTINUE_WITH(en) \ + dev->state = en;\ + device_enumerate(dev, cb_data); + static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) { const usbh_low_level_driver_t *lld = dev->lld; @@ -308,12 +311,12 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ uint8_t state_start = dev->state; // Detection of hang // LOG_PRINTF("\nSTATE: %d\n", state); switch (dev->state) { - case 1: + case USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ: { switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: - dev->state++; - LOG_PRINTF("::%d::", dev->address); + dev->state = USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ_COMPLETE; + LOG_PRINTF("Assigning address: %d\n", usbh_data.address_temporary); device_xfer_control_read(0, 0, device_enumerate, dev); break; @@ -327,14 +330,27 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ } break; - case 2: + case USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ_COMPLETE: switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: if (dev->address == 0) { dev->address = usbh_data.address_temporary; - LOG_PRINTF("ADDR: %d\n", dev->address); + LOG_PRINTF("Assigned address: %d\n", dev->address); } + CONTINUE_WITH(USBH_ENUM_STATE_DEVICE_DT_READ_SETUP); + break; + case USBH_PACKET_CALLBACK_STATUS_EFATAL: + case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + device_enumeration_terminate(dev); + ERROR(cb_data.status); + break; + } + break; + + case USBH_ENUM_STATE_DEVICE_DT_READ_SETUP: + { struct usb_setup_data setup_data; setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; @@ -343,36 +359,24 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ setup_data.wIndex = 0; setup_data.wLength = USB_DT_DEVICE_SIZE; - dev->state++; + dev->state = USBH_ENUM_STATE_DEVICE_DT_READ; device_xfer_control_write_setup(&setup_data, sizeof(setup_data), device_enumerate, dev); - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - device_enumeration_terminate(dev); - ERROR(cb_data.status); - break; } break; - case 3: + + case USBH_ENUM_STATE_DEVICE_DT_READ: { switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: - dev->state++; + dev->state = USBH_ENUM_STATE_DEVICE_DT_READ_COMPLETE; device_xfer_control_read(&usbh_buffer[0], USB_DT_DEVICE_SIZE, device_enumerate, dev); break; case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - dev->state = 2; - - // WARNING: Recursion - // .. but should work - cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK; - device_enumerate(dev, cb_data); + CONTINUE_WITH(USBH_ENUM_STATE_DEVICE_DT_READ_SETUP); break; case USBH_PACKET_CALLBACK_STATUS_EFATAL: @@ -384,7 +388,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ } break; - case 4: + case USBH_ENUM_STATE_DEVICE_DT_READ_COMPLETE: { switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: @@ -392,17 +396,9 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ struct usb_device_descriptor *ddt = (struct usb_device_descriptor *)&usbh_buffer[0]; dev->packet_size_max0 = ddt->bMaxPacketSize0; - struct usb_setup_data setup_data; - - setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; - setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; - setup_data.wValue = USB_DT_CONFIGURATION << 8; - setup_data.wIndex = 0; - setup_data.wLength = ddt->bMaxPacketSize0;//USB_DT_CONFIGURATION_SIZE; - - dev->state++; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), - device_enumerate, dev); + LOG_PRINTF("Found device with vid=0x%04x pid=0x%04x\n", ddt->idVendor, ddt->idProduct); + LOG_PRINTF("class=0x%02x subclass=0x%02x protocol=0x%02x\n", ddt->bDeviceClass, ddt->bDeviceSubClass, ddt->bDeviceProtocol); + CONTINUE_WITH(USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ_SETUP) } break; @@ -411,12 +407,10 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ struct usb_device_descriptor *ddt = (struct usb_device_descriptor *)&usbh_buffer[0]; dev->packet_size_max0 = ddt->bMaxPacketSize0; - dev->state = 2; - - // WARNING: Recursion - // .. but should work - cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK; - device_enumerate(dev, cb_data); + CONTINUE_WITH(USBH_ENUM_STATE_DEVICE_DT_READ_SETUP); + } else { + device_enumeration_terminate(dev); + ERROR(cb_data.status); } break; @@ -429,11 +423,27 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ } break; - case 5: + case USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ_SETUP: + { + struct usb_setup_data setup_data; + + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_DEVICE; + setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; + setup_data.wValue = USB_DT_CONFIGURATION << 8; + setup_data.wIndex = 0; + setup_data.wLength = dev->packet_size_max0; + + dev->state = USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ; + device_xfer_control_write_setup(&setup_data, sizeof(setup_data), + device_enumerate, dev); + } + break; + + case USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ: { switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: - dev->state++; + dev->state = USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ_COMPLETE; device_xfer_control_read(&usbh_buffer[USB_DT_DEVICE_SIZE], dev->packet_size_max0, device_enumerate, dev); break; @@ -448,38 +458,20 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ } break; - case 6: + case USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ_COMPLETE: { switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: - { - struct usb_config_descriptor *cdt = - (struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE]; - struct usb_setup_data setup_data; - LOG_PRINTF("WRITE: LEN: %d", cdt->wTotalLength); - setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; - setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; - setup_data.wValue = USB_DT_CONFIGURATION << 8; - setup_data.wIndex = 0; - setup_data.wLength = cdt->wTotalLength; - - dev->state++; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), - device_enumerate, dev); - } + CONTINUE_WITH(USBH_ENUM_STATE_CONFIGURATION_DT_READ_SETUP); break; case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: if (cb_data.transferred_length >= USB_DT_CONFIGURATION_SIZE) { struct usb_config_descriptor *cdt = (struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE]; - if (cb_data.transferred_length <= cdt->wTotalLength) { - dev->state = 8; - - // WARNING: Recursion - // .. but should work - cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK; - device_enumerate(dev, cb_data); + if (cb_data.transferred_length == cdt->wTotalLength) { + LOG_PRINTF("Configuration descriptor read complete. length: %d\n", cdt->wTotalLength); + CONTINUE_WITH(USBH_ENUM_STATE_FIND_DRIVER); } } break; @@ -493,14 +485,32 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ } break; - case 7: + case USBH_ENUM_STATE_CONFIGURATION_DT_READ_SETUP: + { + struct usb_config_descriptor *cdt = + (struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE]; + struct usb_setup_data setup_data; + LOG_PRINTF("Getting complete configuration descriptor of length: %d bytes\n", cdt->wTotalLength); + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_DEVICE; + setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; + setup_data.wValue = USB_DT_CONFIGURATION << 8; + setup_data.wIndex = 0; + setup_data.wLength = cdt->wTotalLength; + + dev->state = USBH_ENUM_STATE_CONFIGURATION_DT_READ; + device_xfer_control_write_setup(&setup_data, sizeof(setup_data), + device_enumerate, dev); + } + break; + + case USBH_ENUM_STATE_CONFIGURATION_DT_READ: { switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: { struct usb_config_descriptor *cdt = (struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE]; - dev->state++; + dev->state = USBH_ENUM_STATE_CONFIGURATION_DT_READ_COMPLETE; device_xfer_control_read(&usbh_buffer[USB_DT_DEVICE_SIZE], cdt->wTotalLength, device_enumerate, dev); } @@ -516,18 +526,16 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ } break; - case 8: + case USBH_ENUM_STATE_CONFIGURATION_DT_READ_COMPLETE: { switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: { struct usb_config_descriptor *cdt = (struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE]; - LOG_PRINTF("TOTAL_LENGTH: %d\n", cdt->wTotalLength); - device_register(usbh_buffer, cdt->wTotalLength + USB_DT_DEVICE_SIZE, dev); - dev->state++; + LOG_PRINTF("Configuration descriptor read complete. length: %d\n", cdt->wTotalLength); + CONTINUE_WITH(USBH_ENUM_STATE_FIND_DRIVER); - reset_enumeration(); } break; @@ -542,6 +550,16 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ } break; + case USBH_ENUM_STATE_FIND_DRIVER: + { + struct usb_config_descriptor *cdt = + (struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE]; + device_register(usbh_buffer, cdt->wTotalLength + USB_DT_DEVICE_SIZE, dev); + + device_enumeration_finish(dev); + } + break; + default: LOG_PRINTF("Error: Unknown state "__FILE__"/%d\n", __LINE__); break; @@ -555,7 +573,6 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ void device_enumeration_start(usbh_device_t *dev) { set_enumeration(); - dev->state = 1; // save address uint8_t address = dev->address; @@ -571,6 +588,7 @@ void device_enumeration_start(usbh_device_t *dev) LOG_PRINTF("\n\n\n ENUMERATION OF DEVICE@%d STARTED \n\n", address); + dev->state = USBH_ENUM_STATE_SET_ADDRESS; struct usb_setup_data setup_data; setup_data.bmRequestType = USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; -- cgit From 4aa69b4eaf44757aa71997e4a59f0889ea6e23f4 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Thu, 1 Sep 2016 14:16:17 +0200 Subject: make usbh_packet->data of union type out: const void * in: void * Signed-off-by: Amir Hammad --- include/driver/usbh_device_driver.h | 9 ++++++--- src/usbh_core.c | 10 +++++----- src/usbh_driver_ac_midi.c | 4 ++-- src/usbh_driver_gp_xbox.c | 2 +- src/usbh_driver_hid_mouse.c | 2 +- src/usbh_driver_hub.c | 2 +- src/usbh_lld_stm32f4.c | 8 ++++---- 7 files changed, 20 insertions(+), 17 deletions(-) diff --git a/include/driver/usbh_device_driver.h b/include/driver/usbh_device_driver.h index 6dd53c3..76e2619 100644 --- a/include/driver/usbh_device_driver.h +++ b/include/driver/usbh_device_driver.h @@ -129,7 +129,10 @@ typedef void (*usbh_packet_callback_t)(usbh_device_t *dev, usbh_packet_callback_ struct _usbh_packet { /// pointer to data - void *data; + union { + const void *out; + void *in; + } data; /// length of the data (up to 1023) uint16_t datalen; @@ -234,8 +237,8 @@ void usbh_write(usbh_device_t *dev, const usbh_packet_t *packet); /* Helper functions used by device drivers */ void device_xfer_control_read(void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev); -void device_xfer_control_write_setup(void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev); -void device_xfer_control_write_data(void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev); +void device_xfer_control_write_setup(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev); +void device_xfer_control_write_data(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev); END_DECLS diff --git a/src/usbh_core.c b/src/usbh_core.c index cd631a4..60baf64 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -196,11 +196,11 @@ void usbh_init(const void *low_level_drivers[], const usbh_dev_driver_t * const * NEW ENUMERATE * */ -void device_xfer_control_write_setup(void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev) +void device_xfer_control_write_setup(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev) { usbh_packet_t packet; - packet.data = data; + packet.data.out = data; packet.datalen = datalen; packet.address = dev->address; packet.endpoint_address = 0; @@ -216,11 +216,11 @@ void device_xfer_control_write_setup(void *data, uint16_t datalen, usbh_packet_c LOG_PRINTF("WR-setup@device...%d \n", dev->address); } -void device_xfer_control_write_data(void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev) +void device_xfer_control_write_data(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev) { usbh_packet_t packet; - packet.data = data; + packet.data.out = data; packet.datalen = datalen; packet.address = dev->address; packet.endpoint_address = 0; @@ -240,7 +240,7 @@ void device_xfer_control_read(void *data, uint16_t datalen, usbh_packet_callback { usbh_packet_t packet; - packet.data = data; + packet.data.in = data; packet.datalen = datalen; packet.address = dev->address; packet.endpoint_address = 0; diff --git a/src/usbh_driver_ac_midi.c b/src/usbh_driver_ac_midi.c index 205c2a2..cea40df 100644 --- a/src/usbh_driver_ac_midi.c +++ b/src/usbh_driver_ac_midi.c @@ -242,7 +242,7 @@ static void read_midi_in(void *drvdata, const uint8_t nextstate) usbh_packet_t packet; packet.address = midi->usbh_device->address; - packet.data = &midi->buffer[0]; + packet.data.in = &midi->buffer[0]; packet.datalen = midi->endpoint_in_maxpacketsize; packet.endpoint_address = midi->endpoint_in_address; packet.endpoint_size_max = midi->endpoint_in_maxpacketsize; @@ -362,7 +362,7 @@ void usbh_midi_write(uint8_t device_id, const void *data, uint32_t length, midi_ midi->sending = true; midi->write_callback_user = callback; - midi->write_packet.data = (void*)data; // it is safe cast since we are writing and function usbh_write cannot modify data + midi->write_packet.data.out = data; midi->write_packet.datalen = length; midi->write_packet.address = dev->address; midi->write_packet.endpoint_address = midi->endpoint_out_address; diff --git a/src/usbh_driver_gp_xbox.c b/src/usbh_driver_gp_xbox.c index 1bc2498..f52621a 100644 --- a/src/usbh_driver_gp_xbox.c +++ b/src/usbh_driver_gp_xbox.c @@ -326,7 +326,7 @@ static void read_gp_xbox_in(gp_xbox_device_t *gp_xbox) usbh_packet_t packet; packet.address = gp_xbox->usbh_device->address; - packet.data = &gp_xbox->buffer[0]; + packet.data.in = &gp_xbox->buffer[0]; packet.datalen = gp_xbox->endpoint_in_maxpacketsize; packet.endpoint_address = gp_xbox->endpoint_in_address; packet.endpoint_size_max = gp_xbox->endpoint_in_maxpacketsize; diff --git a/src/usbh_driver_hid_mouse.c b/src/usbh_driver_hid_mouse.c index 9d438a9..b52392f 100644 --- a/src/usbh_driver_hid_mouse.c +++ b/src/usbh_driver_hid_mouse.c @@ -214,7 +214,7 @@ static void read_mouse_in(void *drvdata) usbh_packet_t packet; packet.address = mouse->usbh_device->address; - packet.data = &mouse->buffer[0]; + packet.data.in = &mouse->buffer[0]; packet.datalen = mouse->endpoint_in_maxpacketsize; packet.endpoint_address = mouse->endpoint_in_address; packet.endpoint_size_max = mouse->endpoint_in_maxpacketsize; diff --git a/src/usbh_driver_hub.c b/src/usbh_driver_hub.c index 29335a7..1beed01 100644 --- a/src/usbh_driver_hub.c +++ b/src/usbh_driver_hub.c @@ -738,7 +738,7 @@ static void read_ep1(void *drvdata) usbh_packet_t packet; packet.address = hub->device[0]->address; - packet.data = hub->buffer; + packet.data.in = hub->buffer; packet.datalen = hub->endpoint_in_maxpacketsize; packet.endpoint_address = hub->endpoint_in_address; packet.endpoint_size_max = hub->endpoint_in_maxpacketsize; diff --git a/src/usbh_lld_stm32f4.c b/src/usbh_lld_stm32f4.c index 9e81c09..08000a2 100644 --- a/src/usbh_lld_stm32f4.c +++ b/src/usbh_lld_stm32f4.c @@ -295,7 +295,7 @@ static void write(void *drvdata, const usbh_packet_t *packet) packet->endpoint_type == USBH_ENDPOINT_TYPE_BULK) { volatile uint32_t *fifo = &REBASE_CH(OTG_FIFO, channel) + RX_FIFO_SIZE; - const uint32_t * buf32 = packet->data; + const uint32_t * buf32 = packet->data.out; int i; LOG_PRINTF("\nSending[%d]: ", packet->datalen); for(i = packet->datalen; i >= 4; i-=4) { @@ -317,7 +317,7 @@ static void write(void *drvdata, const usbh_packet_t *packet) } else { volatile uint32_t *fifo = &REBASE_CH(OTG_FIFO, channel) + RX_FIFO_SIZE + TX_NP_FIFO_SIZE; - const uint32_t * buf32 = packet->data; + const uint32_t * buf32 = packet->data.out; int i; for(i = packet->datalen; i > 0; i-=4) { *fifo++ = *buf32++; @@ -334,7 +334,7 @@ static void rxflvl_handle(void *drvdata) uint8_t channel = rxstsp&0xf; uint32_t len = (rxstsp>>4) & 0x1ff; if ((rxstsp&OTG_GRXSTSP_PKTSTS_MASK) == OTG_GRXSTSP_PKTSTS_IN) { - uint8_t *data = channels[channel].packet.data; + uint8_t *data = channels[channel].packet.data.in; uint32_t *buf32 = (uint32_t *)&data[channels[channel].data_index]; int32_t i; @@ -366,7 +366,7 @@ static void rxflvl_handle(void *drvdata) uint32_t i; LOG_PRINTF("\nDATA: "); for (i = 0; i < channels[channel].data_index; i++) { - uint8_t *data = channels[channel].packet.data; + uint8_t *data = channels[channel].packet.data.in; LOG_PRINTF("%02X ", data[i]); } #endif -- cgit From 28ccd32608bb3daf0f8137eb1521f382f69d120d Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Thu, 1 Sep 2016 16:07:48 +0200 Subject: core: adjust search for the device driver in finding compatibility there are 3 steps how to find out whether the provided device driver supports currently inserted device. 1. compare fields in the driver info structure If there is a match (all CHECK_PARTIAL_COMPATIBILITY() macros return true), we proceed to step 2. If all device drivers are searched, but none is compatible -> that means no device driver is available for currently inserted device. 2. try to call driver's init function. If it return non-null pointer to data we may proceed to the step 3. Otherwise, we continue in the loop handling step 1. 3. call analyze descriptor for all descriptors. When it returns true, it means success and that the driver supports current device. From now on poll function is allowed to be called. If all descriptors were provided to the analyze_descriptor method and it still returns false, it means device driver is not initialized and should not be used with this device. Signed-off-by: Amir Hammad --- src/usbh_core.c | 57 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/usbh_core.c b/src/usbh_core.c index 60baf64..d6f6ff4 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -53,7 +53,7 @@ static bool enumeration(void) /** * */ -static const usbh_dev_driver_t *find_driver(const usbh_dev_driver_info_t * device_info) +static bool find_driver(usbh_device_t *dev, const usbh_dev_driver_info_t * device_info) { #define CHECK_PARTIAL_COMPATIBILITY(what) \ @@ -63,7 +63,6 @@ static const usbh_dev_driver_t *find_driver(const usbh_dev_driver_info_t * devic continue;\ } - int i = 0; while (usbh_data.dev_drivers[i]) { @@ -77,9 +76,16 @@ static const usbh_dev_driver_t *find_driver(const usbh_dev_driver_info_t * devic CHECK_PARTIAL_COMPATIBILITY(idVendor); CHECK_PARTIAL_COMPATIBILITY(idProduct); - return usbh_data.dev_drivers[i]; + dev->drv = usbh_data.dev_drivers[i]; + dev->drvdata = dev->drv->init(dev); + if (!dev->drvdata) { + LOG_PRINTF("Unable to initialize device driver at index %d\n", i); + i++; + continue; + } + return true; } - return 0; + return false; #undef CHECK_PARTIAL_COMPATIBILITY } @@ -122,14 +128,26 @@ static void device_register(void *descriptors, uint16_t descriptors_len, usbh_de device_info.ifaceClass = iface->bInterfaceClass; device_info.ifaceSubClass = iface->bInterfaceSubClass; device_info.ifaceProtocol = iface->bInterfaceProtocol; - const usbh_dev_driver_t *driver = find_driver(&device_info); - if (driver) { - dev->drv = driver; - dev->drvdata = dev->drv->init(dev); - if (!dev->drvdata) { - LOG_PRINTF("CANT TOUCH THIS"); + if (find_driver(dev, &device_info)) { + int k = 0; + while (k < descriptors_len) { + desc_len = buf[k]; + void *drvdata = dev->drvdata; + LOG_PRINTF("[%d]", buf[k+1]); + if (dev->drv->analyze_descriptor(drvdata, &buf[k])) { + LOG_PRINTF("Device Initialized\n"); + return; + } + + if (desc_len == 0) { + LOG_PRINTF("Problem occured while parsing complete configuration descriptor"); + return; + } + k += desc_len; } - break; + LOG_PRINTF("Device driver isn't compatible with this device\n"); + } else { + LOG_PRINTF("No compatible driver has been found for interface #%d\n", iface->bInterfaceNumber); } } break; @@ -142,23 +160,6 @@ static void device_register(void *descriptors, uint16_t descriptors_len, usbh_de return; } i += desc_len; - - } - - if (dev->drv && dev->drvdata) { - // analyze descriptors - LOG_PRINTF("ANALYZE"); - i = 0; - while (i < descriptors_len) { - desc_len = buf[i]; - void *drvdata = dev->drvdata; - LOG_PRINTF("[%d]",buf[i+1]); - if (dev->drv->analyze_descriptor(drvdata, &buf[i])) { - LOG_PRINTF("Device Initialized\n"); - return; - } - i += desc_len; - } } LOG_PRINTF("Device NOT Initialized\n"); } -- cgit From ed70a1efa3335b6bf64c8c6a6f5be4dc25bdd9b7 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Fri, 9 Sep 2016 18:36:38 +0200 Subject: Switch to cmake build system * use tinyprintf * ability to configure project via ccmake Signed-off-by: Amir Hammad --- CMakeLists.txt | 94 +++++++ DEVICE_DRIVER_HOWTO | 3 - Makefile | 267 ------------------ README.md | 159 ++++++----- build/.gitignore | 1 + cmake/doc.cmake | 6 + cmake/openocd_flash.cmake | 18 ++ cmake/toolchain.cmake | 15 ++ compileDemo.sh | 2 - config.mk | 4 - include/driver/usbh_device_driver.h | 1 - include/usbh_config.h | 6 - libopencm3_stm32f4.ld | 32 --- libusbhost_stm32f4.ld | 32 +++ src/CMakeLists.txt | 61 +++++ src/demo.c | 7 +- src/tinyprintf.c | 521 ++++++++++++++++++++++++++++++++++++ src/tinyprintf.h | 186 +++++++++++++ src/usart_helpers.c | 39 +-- src/usart_helpers.h | 1 - 20 files changed, 1043 insertions(+), 412 deletions(-) create mode 100644 CMakeLists.txt delete mode 100644 DEVICE_DRIVER_HOWTO delete mode 100644 Makefile create mode 100644 cmake/doc.cmake create mode 100644 cmake/openocd_flash.cmake create mode 100644 cmake/toolchain.cmake delete mode 100755 compileDemo.sh delete mode 100644 config.mk delete mode 100644 libopencm3_stm32f4.ld create mode 100644 libusbhost_stm32f4.ld create mode 100644 src/CMakeLists.txt create mode 100644 src/tinyprintf.c create mode 100644 src/tinyprintf.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b97355d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,94 @@ +cmake_minimum_required (VERSION 2.6) + +# initialize compiler +include (cmake/toolchain.cmake) + +# initialize flashing +include (cmake/openocd_flash.cmake) + +# initilize doc +include (cmake/doc.cmake) + +project (libusbhost C) + +# Declare cached variables + +set (USE_STM32F4_FS TRUE CACHE BOOL "Use USB full speed (FS) host periphery") +set (USE_STM32F4_HS TRUE CACHE BOOL "Use USB high speed (HS) host periphery") +set (USE_USART_DEBUG TRUE CACHE BOOL "Use debug uart output") + +# Set compiler and linker flags + +set (FP_FLAGS + "-mfloat-abi=hard -mfpu=fpv4-sp-d16 -mfp16-format=alternative" +) + +set (ARCH_FLAGS + "-mthumb -mcpu=cortex-m4 ${FP_FLAGS}" +) +set (COMMON_FLAGS + "-O2 -g -Wextra -Wshadow -Wredundant-decls -fno-common -ffunction-sections -fdata-sections" +) + +set (CMAKE_C_FLAGS + "${COMMON_FLAGS} ${ARCH_FLAGS} -Wstrict-prototypes -Wmissing-prototypes -Wimplicit-function-declaration" +) + +set (CMAKE_CXX_FLAGS + "${COMMON_FLAGS} ${ARCH_FLAGS} -Weffc++" +) + +# C preprocessor flags +set (CPP_FLAGS + " -MD -Wall -Wundef" +) + +add_definitions (${CPP_FLAGS}) + +# set platform +add_definitions (-DSTM32F4) + +set (CMAKE_EXE_LINKER_FLAGS + "--static -nostartfiles -T${CMAKE_SOURCE_DIR}/libusbhost_stm32f4.ld -Wl,-Map=FIXME_ONE.map -Wl,--gc-sections -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group" +) + +include_directories (${CMAKE_SOURCE_DIR}/include) + +function (init_libopencm3) + include_directories (${CMAKE_SOURCE_DIR}/libopencm3/include) + link_directories (${CMAKE_SOURCE_DIR}/libopencm3/lib) + set (LIBOPENCM3_LIB opencm3_stm32f4 PARENT_SCOPE) + execute_process ( + COMMAND sh "${CMAKE_SOURCE_DIR}/initRepo.sh" + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_QUIET + ) +endfunction (init_libopencm3) + +message (STATUS "Initializing repository") +init_libopencm3 () +message (STATUS "Repository initialized") + +# Process cached varibles +message (STATUS "Setuping build") +if (USE_STM32F4_FS) + message (STATUS "... Using USB full speed (FS) host periphery") + add_definitions (-DUSE_STM32F4_USBH_DRIVER_FS) +endif (USE_STM32F4_FS) + +if (USE_STM32F4_HS) + message (STATUS "... Using USB high speed (HS) host periphery") + add_definitions (-DUSE_STM32F4_USBH_DRIVER_HS) +endif (USE_STM32F4_HS) + +if (USE_USART_DEBUG) + message (STATUS "... Using debug uart output") + add_definitions (-DUSART_DEBUG) +endif (USE_USART_DEBUG) +message (STATUS "Setup done") + +add_custom_target (README.md + SOURCES README.md +) + +add_subdirectory (src) diff --git a/DEVICE_DRIVER_HOWTO b/DEVICE_DRIVER_HOWTO deleted file mode 100644 index e26c9f1..0000000 --- a/DEVICE_DRIVER_HOWTO +++ /dev/null @@ -1,3 +0,0 @@ -TODO - -See usbh_driver*.c in src directory for example of device drivers. diff --git a/Makefile b/Makefile deleted file mode 100644 index 350e42a..0000000 --- a/Makefile +++ /dev/null @@ -1,267 +0,0 @@ -## -## This file is part of the libusbhost project. -## Imported and adopted from libopencm3 project. -## -## Copyright (C) 2009 Uwe Hermann -## Copyright (C) 2010 Piotr Esden-Tempski -## Copyright (C) 2013 Frantisek Burian -## Copyright (C) 2014 Amir Hammad -## -## This library is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## This library is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with this library. If not, see . -## - -BINARY = demo -BINARY := $(addprefix build/, demo) -LIBUSBHOSTNAME = usbhost - -LIBUSBHOST := $(addprefix build/lib, $(LIBUSBHOSTNAME)) -LIBNAME = opencm3_stm32f4 -DEFS = -DSTM32F4 - -# load user config -include config.mk -DEFS += $(USER_CONFIG) - -ifdef USART_DEBUG -DEFS += -DUSART_DEBUG -endif - -DEFS += -Iinclude -LDSCRIPT = lib$(LIBNAME).ld - -SRCDIR = src -OPENCM3_DIR ?= ./libopencm3 -FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mfp16-format=alternative -ARCH_FLAGS = -mthumb -mcpu=cortex-m4 $(FP_FLAGS) - -################################################################################ -# OpenOCD specific variables - -OOCD ?= openocd -OOCD_INTERFACE ?= stlink-v2 -OOCD_BOARD ?= stm32f4discovery - -################################################################################ -# Black Magic Probe specific variables -# Set the BMP_PORT to a serial port and then BMP is used for flashing -BMP_PORT ?= - -################################################################################ -# texane/stlink specific variables -#STLINK_PORT ?= :4242 - -# Be silent per default, but 'make V=1' will show all compiler calls. -ifneq ($(V),1) -Q := @ -NULL := 2>/dev/null -endif - -############################################################################### -# Executables - -PREFIX ?= arm-none-eabi - -CC := $(PREFIX)-gcc -CXX := $(PREFIX)-g++ -LD := $(PREFIX)-gcc -AR := $(PREFIX)-ar -AS := $(PREFIX)-as -OBJCOPY := $(PREFIX)-objcopy -OBJDUMP := $(PREFIX)-objdump -GDB := $(PREFIX)-gdb -STFLASH = $(shell which st-flash) -STYLECHECK := /checkpatch.pl -STYLECHECKFLAGS := --no-tree -f --terse --mailback -STYLECHECKFILES := $(shell find . -name '*.[ch]') - - -############################################################################### -# Source files - -LDSCRIPT ?= $(BINARY).ld - - -SRCS := $(sort $(notdir $(wildcard $(SRCDIR)/*.c))) -OBJSDEMO := $(patsubst %.c, build/%.o ,$(SRCS)) -SRCS := $(sort $(notdir $(wildcard $(SRCDIR)/*.cpp))) -OBJSDEMO += $(patsubst %.cpp, build/%.o ,$(SRCS)) -OBJS = $(filter-out $(BINARY).o, $(OBJSDEMO)) - -ifndef USART_DEBUG -OBJS := $(filter-out build/usart_helpers.o, $(OBJS)) -OBJSDEMO := $(filter-out build/usart_helpers.o, $(OBJSDEMO)) -else -$(info compiling with DEBUG functions) -endif - - -INCLUDE_DIR = $(OPENCM3_DIR)/include -LIB_DIR = $(OPENCM3_DIR)/lib -SCRIPT_DIR = $(OPENCM3_DIR)/scripts - -############################################################################### -# C flags - -CFLAGS += -Ofast -g -CFLAGS += -Wextra -Wshadow -Wimplicit-function-declaration -CFLAGS += -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes -CFLAGS += -fno-common -ffunction-sections -fdata-sections - -############################################################################### -# C++ flags - -CXXFLAGS += -Ofast -g -CXXFLAGS += -Wextra -Wshadow -Wredundant-decls -Weffc++ -CXXFLAGS += -fno-common -ffunction-sections -fdata-sections - -############################################################################### -# C & C++ preprocessor common flags - -CPPFLAGS += -MD -CPPFLAGS += -Wall -Wundef -CPPFLAGS += -I$(INCLUDE_DIR) $(DEFS) - -############################################################################### -# Linker flags - -LDFLAGS += --static -nostartfiles -LDFLAGS += -L$(LIB_DIR) -LDFLAGS += -T$(LDSCRIPT) -LDFLAGS += -Wl,-Map=build/$*.map -LDFLAGS += -Wl,--gc-sections -ifeq ($(V),99) -LDFLAGS += -Wl,--print-gc-sections -endif - -############################################################################### -# Used libraries - -LDLIBS += -l$(LIBNAME) -LDLIBS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group - -############################################################################### -############################################################################### -############################################################################### - -.SUFFIXES: .elf .bin .hex .srec .list .map .images -.SECONDEXPANSION: -.SECONDARY: - - -all: elf bin lib -doc: - doxygen - -elf: $(BINARY).elf -bin: $(BINARY).bin -hex: $(BINARY).hex -srec: $(BINARY).srec -list: $(BINARY).list -lib: $(LIBUSBHOST).a -images: $(BINARY).images -flash: $(BINARY).flash - -%.images: %.bin %.hex %.srec %.list %.map - @#printf "*** $* images generated ***\n" - -%.bin: %.elf - @printf " OBJCOPY $(*).bin\n" - $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin - -%.hex: %.elf - @#printf " OBJCOPY $(*).hex\n" - $(Q)$(OBJCOPY) -Oihex $(*).elf $(*).hex - -%.srec: %.elf - @#printf " OBJCOPY $(*).srec\n" - $(Q)$(OBJCOPY) -Osrec $(*).elf $(*).srec - -%.list: %.elf - @#printf " OBJDUMP $(*).list\n" - $(Q)$(OBJDUMP) -S $(*).elf > $(*).list - --include $(OBJSDEMO:.o=.d) -build/%.elf build/%.map: $(OBJSDEMO) $(LDSCRIPT) - @printf " LD $(*).elf\n" - $(Q)$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJSDEMO) $(LDLIBS) -o build/$*.elf - -build/%.o:$(SRCDIR)/%.c - @printf " CC $(*).c\n" - $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $(SRCDIR)/$*.c - -build/%.o: $(SRCDIR)/%.cxx - @printf " CXX $(*).cxx\n" - $(Q)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $(SRCDIR)/$(*).cxx - -build/%.o: $(SRCDIR)/%.cpp - @printf " CXX $(*).cpp\n" - $(Q)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $(SRCDIR)/$(*).cpp -$(LIB_DIR)/lib$(LIBNAME).a: - -clean: - @#printf " CLEAN\n" - @rm -f build/* - - -%.stlink-flash: %.bin - @printf " FLASH $<\n" - $(Q)$(STFLASH) write $(*).bin 0x8000000 - -ifeq ($(STLINK_PORT),) -ifeq ($(BMP_PORT),) -ifeq ($(OOCD_SERIAL),) -%.flash: %.hex - @printf " FLASH $<\n" - @# IMPORTANT: Don't use "resume", only "reset" will work correctly! - $(Q)$(OOCD) -f interface/$(OOCD_INTERFACE).cfg \ - -f board/$(OOCD_BOARD).cfg \ - -c "init" -c "reset init" \ - -c "flash write_image erase $(*).hex" \ - -c "reset" \ - -c "shutdown" $(NULL) -else -%.flash: %.hex - @printf " FLASH $<\n" - @# IMPORTANT: Don't use "resume", only "reset" will work correctly! - $(Q)$(OOCD) -f interface/$(OOCD_INTERFACE).cfg \ - -f board/$(OOCD_BOARD).cfg \ - -c "ft2232_serial $(OOCD_SERIAL)" \ - -c "init" -c "reset init" \ - -c "flash write_image erase $(*).hex" \ - -c "reset" \ - -c "shutdown" $(NULL) -endif -else -%.flash: %.elf - @printf " GDB $(*).elf (flash)\n" - $(Q)$(GDB) --batch \ - -ex 'target extended-remote $(BMP_PORT)' \ - -x $(SCRIPT_DIR)/black_magic_probe_flash.scr \ - $(*).elf -endif -else -%.flash: %.elf - @printf " GDB $(*).elf (flash)\n" - $(Q)$(GDB) --batch \ - -ex 'target extended-remote $(STLINK_PORT)' \ - -x $(SCRIPT_DIR)/stlink_flash.scr \ - $(*).elf -endif - -.PHONY: images clean stylecheck styleclean elf bin hex srec list testing doc - --include $(OBJS:.o=.d) -build/lib$(LIBUSBHOSTNAME).a: $(OBJS) - @printf " LIB $@\n" - $(Q)$(AR) rcs $@ $(OBJS) diff --git a/README.md b/README.md index 3d5df3f..d23b425 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,104 @@ -###General Information +##General Information +[Link to the official repository](http://github.com/libusbhost/libusbhost) -**This library is in an active development.** -**WARNING**: None of its features are considered stable ! +###Objectives -This library implement usb host driver allowing users use -or write device drivers, which functionality -is abstracted of low level implementation. - -Main objectives are: - provide open-source(Lesser GPL3) usb host library for embedded devices -- execution speed: This library doesn't use blocking sleep, +- execution speed. This library doesn't use blocking sleep, making low overhead on runtime performance -- uses static allocation for all its buffers, -so no allocation and reallocation is affecting performance -(possibility of memory fragmentation. execution time indeterminism), -so no malloc(), realloc(), free(). -- written in C, with the support to use it with C++. -- does not depend on any Operating System. Library libopencm3 is used for testing purposes and to get proper defines. -So no runtime dependency is on this library. +- use static allocation for all of its buffers. +This means no allocation and reallocation is affecting performance +(possibility of memory fragmentation. execution time indeterminism). No malloc(), realloc(), free() +- do not depend on any operating system +### Supported hardware +- stm32f4discovery -Currently supported devices (yet tested) are: -* stm32f407 (stm32f4 Discovery) +### Supported device drivers -Native device drivers (mostly for demonstration purposes): - HUB - Gamepad - XBox compatible Controller - mouse (draft: only displays raw data) - USB MIDI devices (raw data + note on/off) -###Practical info - -!!! Do not forget to invoke "make clean" before new build when defines change(_TODO: remove this warning and fix the Makefile_) - - -**How to initialize repository** - -> ./initRepo.sh - -fetch libopencm3 submodule and compile needed libraries - -**How to generate documentation** - -> make doc - -**How to compile demo** - -Edit usbh_config.h to configure the library (By default Full speed OTG periphery on stm32f4 is supported) - - -> ./compileDemo.sh - -compiles demo, that can be flashed into stm32f4 Discovery platform and debug by USART - - -**How to upload firmware (FLASH) to stm32f4 Discovery** - -> sudo make flash - - -**How to view debug data** - -connect uart to USART6 pins on gpios: GPIOC6(TX - data), GPIOC7(RX - not used) -configure uart baud on PC side to 921600 with 1 stop bit, no parity, 8bit data, no handshake - - -**How to compile library only** - -> make lib - -**libusbhost.a** is built without usart debug support -(check compileDemo.sh for hint on how to compile with debug) - - -###Contact -Amir Hammad - *amir.hammad@hotmail.com* - -**Library is maintained there** -> http://github.com/libusbhost/libusbhost - +## Steps to compile library and demo +### Prerequisities +Make sure the following prerequisities are installed to be able to compile this library +- **git** for libopencm3 submodule fetch +- **gcc-arm-none-eabi** toolchain for cross compilation +- **cmake** +- **ccmake** (optional) +- **openocd** (optional) + +### Basic setup +1. go to build directory located in the root of the project +> cd build + +2. compile demo and the library with the default options set +> cmake .. && make + +Executable demo is placed into `build/demo.hex`. +Library is placed into `build/src/libusbhost.a`. + +### Advanced setup +*cmake* initial cache variables + + + + + + + + + + + + + + + + + + + +
Cache variableValueDescription
USE_STM32F4_FSTRUEEnable STM32F4 Full Speed USB host peripheral
USE_STM32F4_HSTRUEEnable STM32F4 High Speed USB host peripheral
USE_USART_DEBUGTRUEEnable writing of the debug information to USART6
OOCD_INTERFACE"stlink-v2"Interface configuration file used by the openocd
OOCD_BOARD"stm32f4discovery"Board configuration file used by the openocd
+You can alter these by issuing the following commands in the build directory + +- Graphical user interface +> ccmake .. + +- Command line interface +> cmake .. -D{VARIABLE}={VALUE} + +### Flashing +If the *openocd* is installed, `make flash` executed in the build directory +flashes the `build/demo.hex` to the stm32f4discovery board. + +### Reading debug output +The following table represents the configuration of the debug output + + + + + + + + + + + + + + + + +
GPIOGPIOC6
USART peripheryUSART6
FunctionUART TX
Baud rate921600
Uart mode8N1
+ +## License + +The libusbhost code is released under the terms of the GNU Lesser General +Public License (LGPL), version 3 or later. + +See COPYING.GPL3 and COPYING.LGPL3 for details. diff --git a/build/.gitignore b/build/.gitignore index e69de29..72e8ffc 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -0,0 +1 @@ +* diff --git a/cmake/doc.cmake b/cmake/doc.cmake new file mode 100644 index 0000000..76336a8 --- /dev/null +++ b/cmake/doc.cmake @@ -0,0 +1,6 @@ +add_custom_target (doc + COMMAND doxygen + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "output is generted in the ${CMAKE_SOURCE_DIR}/doc" + SOURCES Doxyfile +) diff --git a/cmake/openocd_flash.cmake b/cmake/openocd_flash.cmake new file mode 100644 index 0000000..5c92c49 --- /dev/null +++ b/cmake/openocd_flash.cmake @@ -0,0 +1,18 @@ +find_program (OOCD openocd DOC "openocd executable") + +set (OOCD_INTERFACE stlink-v2 CACHE STRING "interface config file used for openocd flashing") +set (OOCD_BOARD stm32f4discovery CACHE STRING "board config file used for openocd flashing") +if (OOCD) + message (STATUS "OpenOCD found: ${OOCD}") + message (STATUS "... interface: ${OOCD_INTERFACE}") + message (STATUS "... board: ${OOCD_BOARD}") + add_custom_target (flash + COMMAND sh -c '${OOCD} -f interface/${OOCD_INTERFACE}.cfg + -f board/${OOCD_BOARD}.cfg + -c "init" -c "reset init" + -c "flash write_image erase $" + -c "reset" + -c "shutdown" ' + DEPENDS demo + ) +endif (OOCD) diff --git a/cmake/toolchain.cmake b/cmake/toolchain.cmake new file mode 100644 index 0000000..b6e2af7 --- /dev/null +++ b/cmake/toolchain.cmake @@ -0,0 +1,15 @@ +set (_CMAKE_TOOLCHAIN_PREFIX "arm-none-eabi-" CACHE STRING "toolchain prefix") +set (_CMAKE_TOOLCHAIN_LOCATION "" CACHE STRING "toolchain location hint") + +set (CMAKE_SYSTEM_NAME Generic) +set (CMAKE_C_COMPILER_WORKS 1) +set (CMAKE_CXX_COMPILER_WORKS 1) +set (CMAKE_C_FLAGS "") +set (CMAKE_CXX_FLAGS "") +set (BUILD_SHARED_LIBS OFF) +find_program (CMAKE_C_COMPILER NAMES ${_CMAKE_TOOLCHAIN_PREFIX}gcc HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) +find_program (CMAKE_C_COMPILER NAMES ${_CMAKE_TOOLCHAIN_PREFIX}g++ HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) +find_program (CMAKE_OBJCOPY NAMES ${_CMAKE_TOOLCHAIN_PREFIX}objcopy HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) +find_program (CMAKE_SIZE NAMES ${_CMAKE_TOOLCHAIN_PREFIX}size HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) + + diff --git a/compileDemo.sh b/compileDemo.sh deleted file mode 100755 index 7731473..0000000 --- a/compileDemo.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -USART_DEBUG=1 OPENCM3_DIR=libopencm3 make all diff --git a/config.mk b/config.mk deleted file mode 100644 index 3ba462b..0000000 --- a/config.mk +++ /dev/null @@ -1,4 +0,0 @@ - - -USER_CONFIG = - diff --git a/include/driver/usbh_device_driver.h b/include/driver/usbh_device_driver.h index 76e2619..eca8928 100644 --- a/include/driver/usbh_device_driver.h +++ b/include/driver/usbh_device_driver.h @@ -240,7 +240,6 @@ void device_xfer_control_read(void *data, uint16_t datalen, usbh_packet_callback void device_xfer_control_write_setup(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev); void device_xfer_control_write_data(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev); - END_DECLS #endif diff --git a/include/usbh_config.h b/include/usbh_config.h index 7bf800b..4fa38cb 100644 --- a/include/usbh_config.h +++ b/include/usbh_config.h @@ -59,10 +59,4 @@ #error USBH_MAX_DEVICES > 127 #endif -// Uncomment to enable OTG_HS support - low level driver -// #define USE_STM32F4_USBH_DRIVER_HS - -// Uncomment to enable OTG_FS support - low level driver -#define USE_STM32F4_USBH_DRIVER_FS - #endif diff --git a/libopencm3_stm32f4.ld b/libopencm3_stm32f4.ld deleted file mode 100644 index 46a80f2..0000000 --- a/libopencm3_stm32f4.ld +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * Copyright (C) 2011 Stephen Caudle - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for ST STM32F4DISCOVERY (STM32F407VG, 1024K flash, 128K RAM). */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K -} - -/* Include the common ld script. */ -INCLUDE ./libopencm3/lib/libopencm3_stm32f4.ld - diff --git a/libusbhost_stm32f4.ld b/libusbhost_stm32f4.ld new file mode 100644 index 0000000..b814cc2 --- /dev/null +++ b/libusbhost_stm32f4.ld @@ -0,0 +1,32 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for ST STM32F4DISCOVERY (STM32F407VG, 1024K flash, 128K RAM). */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f4.ld + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..3165b51 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,61 @@ +if (USE_USART_DEBUG) + set (USART_HELPERS + usart_helpers.c + tinyprintf.c + ) +else (USE_USART_DEBUG) + set (USART_HELPERS "") +endif (USE_USART_DEBUG) + +set (inc ${CMAKE_SOURCE_DIR}/include) + +add_library (usbhost + ${USART_HELPERS} + ${inc}/usbh_core.h + ${inc}/usbh_driver_ac_midi.h + ${inc}/usbh_driver_gp_xbox.h + ${inc}/usbh_driver_hid_mouse.h + ${inc}/usbh_driver_hub.h + ${inc}/usbh_lld_stm32f4.h + ${inc}/driver/usbh_device_driver.h + + usbh_core.c + usbh_driver_ac_midi.c + usbh_driver_ac_midi_private.h + usbh_driver_gp_xbox.c + usbh_driver_hid_mouse.c + usbh_driver_hub.c + usbh_driver_hub_private.h + usbh_lld_stm32f4.c +) + +target_link_libraries (usbhost + ${LIBOPENCM3_LIB} +) + +add_executable (demo + demo.c +) + +target_link_libraries (demo + usbhost +) + +add_custom_command (TARGET demo + POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -Oihex $ ${CMAKE_BINARY_DIR}/demo.hex + COMMENT "Generating output files: ${CMAKE_BINARY_DIR}/demo.hex" +) + +add_custom_command (TARGET demo + POST_BUILD + COMMAND ${CMAKE_SIZE} $ + COMMENT "Calculating size of the binary" +) + +add_custom_command (TARGET usbhost + POST_BUILD + COMMENT "Calculating size of the library" + COMMAND ${CMAKE_SIZE} $ +) + diff --git a/src/demo.c b/src/demo.c index 5d829ac..3fedbd9 100644 --- a/src/demo.c +++ b/src/demo.c @@ -215,8 +215,13 @@ int main(void) * Pass array of supported device drivers */ const void *lld_drivers[] = { +#ifdef USE_STM32F4_USBH_DRIVER_FS usbh_lld_stm32f4_driver_fs, // Make sure USE_STM32F4_USBH_DRIVER_FS is defined in usbh_config.h -// usbh_lld_stm32f4_driver_hs, // Make sure USE_STM32F4_USBH_DRIVER_HS is defined in usbh_config.h +#endif + +#ifdef USE_STM32F4_USBH_DRIVER_HS + usbh_lld_stm32f4_driver_hs, // Make sure USE_STM32F4_USBH_DRIVER_HS is defined in usbh_config.h +#endif 0 }; usbh_init(lld_drivers, device_drivers); diff --git a/src/tinyprintf.c b/src/tinyprintf.c new file mode 100644 index 0000000..bb22700 --- /dev/null +++ b/src/tinyprintf.c @@ -0,0 +1,521 @@ +/* +File: tinyprintf.c + +Copyright (C) 2004 Kustaa Nyholm + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "tinyprintf.h" + + +/* + * Configuration + */ + +/* Enable long int support */ +#define PRINTF_LONG_SUPPORT + +/* Enable long long int support (implies long int support) */ +#define PRINTF_LONG_LONG_SUPPORT + +/* Enable %z (size_t) support */ +#define PRINTF_SIZE_T_SUPPORT + +/* + * Configuration adjustments + */ +#ifdef PRINTF_SIZE_T_SUPPORT +#include +#endif + +#ifdef PRINTF_LONG_LONG_SUPPORT +# define PRINTF_LONG_SUPPORT +#endif + +/* __SIZEOF___ defined at least by gcc */ +#ifdef __SIZEOF_POINTER__ +# define SIZEOF_POINTER __SIZEOF_POINTER__ +#endif +#ifdef __SIZEOF_LONG_LONG__ +# define SIZEOF_LONG_LONG __SIZEOF_LONG_LONG__ +#endif +#ifdef __SIZEOF_LONG__ +# define SIZEOF_LONG __SIZEOF_LONG__ +#endif +#ifdef __SIZEOF_INT__ +# define SIZEOF_INT __SIZEOF_INT__ +#endif + +#ifdef __GNUC__ +# define _TFP_GCC_NO_INLINE_ __attribute__ ((noinline)) +#else +# define _TFP_GCC_NO_INLINE_ +#endif + +/* + * Implementation + */ +struct param { + char lz:1; /**< Leading zeros */ + char alt:1; /**< alternate form */ + char uc:1; /**< Upper case (for base16 only) */ + char align_left:1; /**< 0 == align right (default), 1 == align left */ + unsigned int width; /**< field width */ + char sign; /**< The sign to display (if any) */ + unsigned int base; /**< number base (e.g.: 8, 10, 16) */ + char *bf; /**< Buffer to output */ +}; + + +#ifdef PRINTF_LONG_LONG_SUPPORT +static void _TFP_GCC_NO_INLINE_ ulli2a( + unsigned long long int num, struct param *p) +{ + int n = 0; + unsigned long long int d = 1; + char *bf = p->bf; + while (num / d >= p->base) + d *= p->base; + while (d != 0) { + int dgt = num / d; + num %= d; + d /= p->base; + if (n || dgt > 0 || d == 0) { + *bf++ = dgt + (dgt < 10 ? '0' : (p->uc ? 'A' : 'a') - 10); + ++n; + } + } + *bf = 0; +} + +static void lli2a(long long int num, struct param *p) +{ + if (num < 0) { + num = -num; + p->sign = '-'; + } + ulli2a(num, p); +} +#endif + +#ifdef PRINTF_LONG_SUPPORT +static void uli2a(unsigned long int num, struct param *p) +{ + int n = 0; + unsigned long int d = 1; + char *bf = p->bf; + while (num / d >= p->base) + d *= p->base; + while (d != 0) { + int dgt = num / d; + num %= d; + d /= p->base; + if (n || dgt > 0 || d == 0) { + *bf++ = dgt + (dgt < 10 ? '0' : (p->uc ? 'A' : 'a') - 10); + ++n; + } + } + *bf = 0; +} + +static void li2a(long num, struct param *p) +{ + if (num < 0) { + num = -num; + p->sign = '-'; + } + uli2a(num, p); +} +#endif + +static void ui2a(unsigned int num, struct param *p) +{ + int n = 0; + unsigned int d = 1; + char *bf = p->bf; + while (num / d >= p->base) + d *= p->base; + while (d != 0) { + int dgt = num / d; + num %= d; + d /= p->base; + if (n || dgt > 0 || d == 0) { + *bf++ = dgt + (dgt < 10 ? '0' : (p->uc ? 'A' : 'a') - 10); + ++n; + } + } + *bf = 0; +} + +static void i2a(int num, struct param *p) +{ + if (num < 0) { + num = -num; + p->sign = '-'; + } + ui2a(num, p); +} + +static int a2d(char ch) +{ + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + else if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 10; + else + return -1; +} + +static char a2u(char ch, const char **src, int base, unsigned int *nump) +{ + const char *p = *src; + unsigned int num = 0; + int digit; + while ((digit = a2d(ch)) >= 0) { + if (digit > base) + break; + num = num * base + digit; + ch = *p++; + } + *src = p; + *nump = num; + return ch; +} + +static void putchw(void *putp, putcf putf, struct param *p) +{ + char ch; + int n = p->width; + char *bf = p->bf; + + /* Number of filling characters */ + while (*bf++ && n > 0) + n--; + if (p->sign) + n--; + if (p->alt && p->base == 16) + n -= 2; + else if (p->alt && p->base == 8) + n--; + + /* Fill with space to align to the right, before alternate or sign */ + if (!p->lz && !p->align_left) { + while (n-- > 0) + putf(putp, ' '); + } + + /* print sign */ + if (p->sign) + putf(putp, p->sign); + + /* Alternate */ + if (p->alt && p->base == 16) { + putf(putp, '0'); + putf(putp, (p->uc ? 'X' : 'x')); + } else if (p->alt && p->base == 8) { + putf(putp, '0'); + } + + /* Fill with zeros, after alternate or sign */ + if (p->lz) { + while (n-- > 0) + putf(putp, '0'); + } + + /* Put actual buffer */ + bf = p->bf; + while ((ch = *bf++)) + putf(putp, ch); + + /* Fill with space to align to the left, after string */ + if (!p->lz && p->align_left) { + while (n-- > 0) + putf(putp, ' '); + } +} + +void tfp_format(void *putp, putcf putf, const char *fmt, va_list va) +{ + struct param p; +#ifdef PRINTF_LONG_SUPPORT + char bf[23]; /* long = 64b on some architectures */ +#else + char bf[12]; /* int = 32b on some architectures */ +#endif + char ch; + p.bf = bf; + + while ((ch = *(fmt++))) { + if (ch != '%') { + putf(putp, ch); + } else { +#ifdef PRINTF_LONG_SUPPORT + char lng = 0; /* 1 for long, 2 for long long */ +#endif + /* Init parameter struct */ + p.lz = 0; + p.alt = 0; + p.width = 0; + p.align_left = 0; + p.sign = 0; + + /* Flags */ + while ((ch = *(fmt++))) { + switch (ch) { + case '-': + p.align_left = 1; + continue; + case '0': + p.lz = 1; + continue; + case '#': + p.alt = 1; + continue; + default: + break; + } + break; + } + + /* Width */ + if (ch >= '0' && ch <= '9') { + ch = a2u(ch, &fmt, 10, &(p.width)); + } + + /* We accept 'x.y' format but don't support it completely: + * we ignore the 'y' digit => this ignores 0-fill + * size and makes it == width (ie. 'x') */ + if (ch == '.') { + p.lz = 1; /* zero-padding */ + /* ignore actual 0-fill size: */ + do { + ch = *(fmt++); + } while ((ch >= '0') && (ch <= '9')); + } + +#ifdef PRINTF_SIZE_T_SUPPORT +# ifdef PRINTF_LONG_SUPPORT + if (ch == 'z') { + ch = *(fmt++); + if (sizeof(size_t) == sizeof(unsigned long int)) + lng = 1; +# ifdef PRINTF_LONG_LONG_SUPPORT + else if (sizeof(size_t) == sizeof(unsigned long long int)) + lng = 2; +# endif + } else +# endif +#endif + +#ifdef PRINTF_LONG_SUPPORT + if (ch == 'l') { + ch = *(fmt++); + lng = 1; +#ifdef PRINTF_LONG_LONG_SUPPORT + if (ch == 'l') { + ch = *(fmt++); + lng = 2; + } +#endif + } +#endif + switch (ch) { + case 0: + goto abort; + case 'u': + p.base = 10; +#ifdef PRINTF_LONG_SUPPORT +#ifdef PRINTF_LONG_LONG_SUPPORT + if (2 == lng) + ulli2a(va_arg(va, unsigned long long int), &p); + else +#endif + if (1 == lng) + uli2a(va_arg(va, unsigned long int), &p); + else +#endif + ui2a(va_arg(va, unsigned int), &p); + putchw(putp, putf, &p); + break; + case 'd': + case 'i': + p.base = 10; +#ifdef PRINTF_LONG_SUPPORT +#ifdef PRINTF_LONG_LONG_SUPPORT + if (2 == lng) + lli2a(va_arg(va, long long int), &p); + else +#endif + if (1 == lng) + li2a(va_arg(va, long int), &p); + else +#endif + i2a(va_arg(va, int), &p); + putchw(putp, putf, &p); + break; +#ifdef SIZEOF_POINTER + case 'p': + p.alt = 1; +# if defined(SIZEOF_INT) && SIZEOF_POINTER <= SIZEOF_INT + lng = 0; +# elif defined(SIZEOF_LONG) && SIZEOF_POINTER <= SIZEOF_LONG + lng = 1; +# elif defined(SIZEOF_LONG_LONG) && SIZEOF_POINTER <= SIZEOF_LONG_LONG + lng = 2; +# endif +#endif + case 'x': + case 'X': + p.base = 16; + p.uc = (ch == 'X')?1:0; +#ifdef PRINTF_LONG_SUPPORT +#ifdef PRINTF_LONG_LONG_SUPPORT + if (2 == lng) + ulli2a(va_arg(va, unsigned long long int), &p); + else +#endif + if (1 == lng) + uli2a(va_arg(va, unsigned long int), &p); + else +#endif + ui2a(va_arg(va, unsigned int), &p); + putchw(putp, putf, &p); + break; + case 'o': + p.base = 8; + ui2a(va_arg(va, unsigned int), &p); + putchw(putp, putf, &p); + break; + case 'c': + putf(putp, (char)(va_arg(va, int))); + break; + case 's': + p.bf = va_arg(va, char *); + putchw(putp, putf, &p); + p.bf = bf; + break; + case '%': + putf(putp, ch); + default: + break; + } + } + } + abort:; +} + +#if TINYPRINTF_DEFINE_TFP_PRINTF +static putcf stdout_putf; +static void *stdout_putp; + +void init_printf(void *putp, putcf putf) +{ + stdout_putf = putf; + stdout_putp = putp; +} + +void tfp_printf(char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + tfp_format(stdout_putp, stdout_putf, fmt, va); + va_end(va); +} +#endif + +#if TINYPRINTF_DEFINE_TFP_SPRINTF +struct _vsnprintf_putcf_data +{ + size_t dest_capacity; + char *dest; + size_t num_chars; +}; + +static void _vsnprintf_putcf(void *p, char c) +{ + struct _vsnprintf_putcf_data *data = (struct _vsnprintf_putcf_data*)p; + if (data->num_chars < data->dest_capacity) + data->dest[data->num_chars] = c; + data->num_chars ++; +} + +int tfp_vsnprintf(char *str, size_t size, const char *format, va_list ap) +{ + struct _vsnprintf_putcf_data data; + + if (size < 1) + return 0; + + data.dest = str; + data.dest_capacity = size-1; + data.num_chars = 0; + tfp_format(&data, _vsnprintf_putcf, format, ap); + + if (data.num_chars < data.dest_capacity) + data.dest[data.num_chars] = '\0'; + else + data.dest[data.dest_capacity] = '\0'; + + return data.num_chars; +} + +int tfp_snprintf(char *str, size_t size, const char *format, ...) +{ + va_list ap; + int retval; + + va_start(ap, format); + retval = tfp_vsnprintf(str, size, format, ap); + va_end(ap); + return retval; +} + +struct _vsprintf_putcf_data +{ + char *dest; + size_t num_chars; +}; + +static void _vsprintf_putcf(void *p, char c) +{ + struct _vsprintf_putcf_data *data = (struct _vsprintf_putcf_data*)p; + data->dest[data->num_chars++] = c; +} + +int tfp_vsprintf(char *str, const char *format, va_list ap) +{ + struct _vsprintf_putcf_data data; + data.dest = str; + data.num_chars = 0; + tfp_format(&data, _vsprintf_putcf, format, ap); + data.dest[data.num_chars] = '\0'; + return data.num_chars; +} + +int tfp_sprintf(char *str, const char *format, ...) +{ + va_list ap; + int retval; + + va_start(ap, format); + retval = tfp_vsprintf(str, format, ap); + va_end(ap); + return retval; +} +#endif diff --git a/src/tinyprintf.h b/src/tinyprintf.h new file mode 100644 index 0000000..a769f4a --- /dev/null +++ b/src/tinyprintf.h @@ -0,0 +1,186 @@ +/* +File: tinyprintf.h + +Copyright (C) 2004 Kustaa Nyholm + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +This library is really just two files: 'tinyprintf.h' and 'tinyprintf.c'. + +They provide a simple and small (+400 loc) printf functionality to +be used in embedded systems. + +I've found them so useful in debugging that I do not bother with a +debugger at all. + +They are distributed in source form, so to use them, just compile them +into your project. + +Two printf variants are provided: printf and the 'sprintf' family of +functions ('snprintf', 'sprintf', 'vsnprintf', 'vsprintf'). + +The formats supported by this implementation are: +'c' 'd' 'i' 'o' 'p' 'u' 's' 'x' 'X'. + +Zero padding and field width are also supported. + +If the library is compiled with 'PRINTF_SUPPORT_LONG' defined, then +the long specifier is also supported. Note that this will pull in some +long math routines (pun intended!) and thus make your executable +noticeably longer. Likewise with 'PRINTF_LONG_LONG_SUPPORT' for the +long long specifier, and with 'PRINTF_SIZE_T_SUPPORT' for the size_t +specifier. + +The memory footprint of course depends on the target CPU, compiler and +compiler options, but a rough guesstimate (based on a H8S target) is about +1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space. +Not too bad. Your mileage may vary. By hacking the source code you can +get rid of some hundred bytes, I'm sure, but personally I feel the balance of +functionality and flexibility versus code size is close to optimal for +many embedded systems. + +To use the printf, you need to supply your own character output function, +something like : + +void putc ( void* p, char c) +{ + while (!SERIAL_PORT_EMPTY) ; + SERIAL_PORT_TX_REGISTER = c; +} + +Before you can call printf, you need to initialize it to use your +character output function with something like: + +init_printf(NULL,putc); + +Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc', +the NULL (or any pointer) you pass into the 'init_printf' will eventually be +passed to your 'putc' routine. This allows you to pass some storage space (or +anything really) to the character output function, if necessary. +This is not often needed but it was implemented like that because it made +implementing the sprintf function so neat (look at the source code). + +The code is re-entrant, except for the 'init_printf' function, so it is safe +to call it from interrupts too, although this may result in mixed output. +If you rely on re-entrancy, take care that your 'putc' function is re-entrant! + +The printf and sprintf functions are actually macros that translate to +'tfp_printf' and 'tfp_sprintf' when 'TINYPRINTF_OVERRIDE_LIBC' is set +(default). Setting it to 0 makes it possible to use them along with +'stdio.h' printf's in a single source file. When +'TINYPRINTF_OVERRIDE_LIBC' is set, please note that printf/sprintf are +not function-like macros, so if you have variables or struct members +with these names, things will explode in your face. Without variadic +macros this is the best we can do to wrap these function. If it is a +problem, just give up the macros and use the functions directly, or +rename them. + +It is also possible to avoid defining tfp_printf and/or tfp_sprintf by +clearing 'TINYPRINTF_DEFINE_TFP_PRINTF' and/or +'TINYPRINTF_DEFINE_TFP_SPRINTF' to 0. This allows for example to +export only tfp_format, which is at the core of all the other +functions. + +For further details see source code. + +regs Kusti, 23.10.2004 +*/ + +#ifndef __TFP_PRINTF__ +#define __TFP_PRINTF__ + +#include + +/* Global configuration */ + +/* Set this to 0 if you do not want to provide tfp_printf */ +#ifndef TINYPRINTF_DEFINE_TFP_PRINTF +# define TINYPRINTF_DEFINE_TFP_PRINTF 1 +#endif + +/* Set this to 0 if you do not want to provide + tfp_sprintf/snprintf/vsprintf/vsnprintf */ +#ifndef TINYPRINTF_DEFINE_TFP_SPRINTF +# define TINYPRINTF_DEFINE_TFP_SPRINTF 1 +#endif + +/* Set this to 0 if you do not want tfp_printf and + tfp_{vsn,sn,vs,s}printf to be also available as + printf/{vsn,sn,vs,s}printf */ +#ifndef TINYPRINTF_OVERRIDE_LIBC +# define TINYPRINTF_OVERRIDE_LIBC 1 +#endif + +/* Optional external types dependencies */ + +#if TINYPRINTF_DEFINE_TFP_SPRINTF +# include /* size_t */ +#endif + +/* Declarations */ + +#ifdef __GNUC__ +# define _TFP_SPECIFY_PRINTF_FMT(fmt_idx,arg1_idx) \ + __attribute__((format (printf, fmt_idx, arg1_idx))) +#else +# define _TFP_SPECIFY_PRINTF_FMT(fmt_idx,arg1_idx) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*putcf) (void *, char); + +/* + 'tfp_format' really is the central function for all tinyprintf. For + each output character after formatting, the 'putf' callback is + called with 2 args: + - an arbitrary void* 'putp' param defined by the user and + passed unmodified from 'tfp_format', + - the character. + The 'tfp_printf' and 'tfp_sprintf' functions simply define their own + callback and pass to it the right 'putp' it is expecting. +*/ +void tfp_format(void *putp, putcf putf, const char *fmt, va_list va); + +#if TINYPRINTF_DEFINE_TFP_SPRINTF +int tfp_vsnprintf(char *str, size_t size, const char *fmt, va_list ap); +int tfp_snprintf(char *str, size_t size, const char *fmt, ...) \ + _TFP_SPECIFY_PRINTF_FMT(3, 4); +int tfp_vsprintf(char *str, const char *fmt, va_list ap); +int tfp_sprintf(char *str, const char *fmt, ...) \ + _TFP_SPECIFY_PRINTF_FMT(2, 3); +# if TINYPRINTF_OVERRIDE_LIBC +# define vsnprintf tfp_vsnprintf +# define snprintf tfp_snprintf +# define vsprintf tfp_vsprintf +# define sprintf tfp_sprintf +# endif +#endif + +#if TINYPRINTF_DEFINE_TFP_PRINTF +void init_printf(void *putp, putcf putf); +void tfp_printf(char *fmt, ...) _TFP_SPECIFY_PRINTF_FMT(1, 2); +# if TINYPRINTF_OVERRIDE_LIBC +# define printf tfp_printf +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/usart_helpers.c b/src/usart_helpers.c index 5a9aa03..fc32333 100644 --- a/src/usart_helpers.c +++ b/src/usart_helpers.c @@ -22,14 +22,15 @@ #include "usart_helpers.h" +#define TINYPRINTF_OVERRIDE_LIBC 0 +#define TINYPRINTF_DEFINE_TFP_SPRINTF 0 +#include "tinyprintf.h" #include #include #include #include #include -#include - #define USART_FIFO_OUT_SIZE (4096) uint8_t usart_fifo_out_data[USART_FIFO_OUT_SIZE]; @@ -103,35 +104,22 @@ static void usart_fifo_in_push(uint8_t aData) usart_fifo_in_len++; } - -static void usart_write(const char * data, uint32_t len) +static void putf(void *arg, char c) { - uint32_t i; - for(i = 0; i < len; i++) - { - usart_fifo_push(data[i]); - } + //unused argument + (void)arg; + + usart_fifo_push(c); } + void usart_printf(const char *str, ...) { va_list va; va_start(va, str); - usart_vprintf(str, va); + tfp_format(NULL, putf, str, va); va_end(va); - -} - -void usart_vprintf(const char *str, va_list va) -{ - char databuffer[128]; - int i = vsnprintf(databuffer, 128, str, va); - if (i > 0) { - usart_write(databuffer, i); - } } - - void usart_init(uint32_t arg_usart, uint32_t baudrate) { usart_set_baudrate(arg_usart, baudrate); @@ -145,6 +133,7 @@ void usart_init(uint32_t arg_usart, uint32_t baudrate) usart_enable(arg_usart); usart = arg_usart; } + void usart_interrupt(void) { if (usart_get_interrupt_source(usart, USART_SR_RXNE)) { @@ -230,9 +219,7 @@ void usart_call_cmd(struct usart_commands * commands) LOG_PRINTF("#2"); return; } - //~ for (i = 0; i < command_len; i++) { - //~ LOG_PRINTF("%c", command[i]); - //~ } + i=0; while(commands[i].cmd != NULL) { if (!strcmp((char*)command, (char*)commands[i].cmd)) { @@ -243,7 +230,7 @@ void usart_call_cmd(struct usart_commands * commands) commands[i].callback(&command[command_argindex]); } } - usart_write("\n>>",4); + LOG_PRINTF("\n>>"); command_len = 0; command_argindex = 0; return; diff --git a/src/usart_helpers.h b/src/usart_helpers.h index d36f689..e62f67d 100644 --- a/src/usart_helpers.h +++ b/src/usart_helpers.h @@ -38,7 +38,6 @@ struct usart_commands{ #ifdef USART_DEBUG void usart_init(uint32_t usart, uint32_t baudrate); void usart_printf(const char *str, ...); -void usart_vprintf(const char *str, va_list va); void usart_fifo_send(void); void usart_call_cmd(struct usart_commands * commands); -- cgit From 3d68ea280790351d0320fc4e712c51b820a5522a Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Fri, 9 Sep 2016 18:37:22 +0200 Subject: make hid_mouse driver generic HID driver + keyboard support + SET_REPORT commands - usually leds on keyboards (WIP) - missing parsing of HID report descriptor Signed-off-by: Amir Hammad --- README.md | 2 +- include/usbh_config.h | 8 +- include/usbh_driver_hid.h | 85 +++++++ include/usbh_driver_hid_mouse.h | 53 ---- src/CMakeLists.txt | 4 +- src/demo.c | 26 +- src/usbh_driver_hid.c | 537 ++++++++++++++++++++++++++++++++++++++++ src/usbh_driver_hid_mouse.c | 298 ---------------------- 8 files changed, 648 insertions(+), 365 deletions(-) create mode 100644 include/usbh_driver_hid.h delete mode 100644 include/usbh_driver_hid_mouse.h create mode 100644 src/usbh_driver_hid.c delete mode 100644 src/usbh_driver_hid_mouse.c diff --git a/README.md b/README.md index d23b425..a823eaf 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This means no allocation and reallocation is affecting performance - HUB - Gamepad - XBox compatible Controller -- mouse (draft: only displays raw data) +- Generic Human Interface driver: mouse, keyboard (raw data) - USB MIDI devices (raw data + note on/off) ## Steps to compile library and demo diff --git a/include/usbh_config.h b/include/usbh_config.h index 4fa38cb..8146ffb 100644 --- a/include/usbh_config.h +++ b/include/usbh_config.h @@ -38,10 +38,10 @@ // Set this wisely #define BUFFER_ONE_BYTES (2048) -// MOUSE -#define USBH_HID_MOUSE_MAX_DEVICES (2) - -#define USBH_HID_MOUSE_BUFFER (32) +// HID class devices +#define USBH_HID_MAX_DEVICES (2) +#define USBH_HID_BUFFER (256) +#define USBH_HID_REPORT_BUFFER (4) // MIDI // Maximal number of midi devices connected to whatever hub diff --git a/include/usbh_driver_hid.h b/include/usbh_driver_hid.h new file mode 100644 index 0000000..8155d82 --- /dev/null +++ b/include/usbh_driver_hid.h @@ -0,0 +1,85 @@ +/* + * This file is part of the libusbhost library + * hosted at http://github.com/libusbhost/libusbhost + * + * Copyright (C) 2016 Amir Hammad + * + * + * libusbhost is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + */ + +#ifndef USBH_DRIVER_HID_ +#define USBH_DRIVER_HID_ + +#include "usbh_core.h" + +#include + +BEGIN_DECLS + +struct _hid_mouse_config { + /** + * @brief this is called when some data is read when polling the device + * @param device_id handle of HID device + * @param data pointer to the data + * @param length count of bytes in the data + * + * TODO: make better interface that provides data contained in the report descriptor + * + */ + void (*hid_in_message_handler)(uint8_t device_id, const uint8_t *data, uint32_t length); +}; +typedef struct _hid_mouse_config hid_config_t; + +/** + * @brief hid_mouse_driver_init initialization routine - this will initialize internal structures of this device driver + * @param config + * @see hid_mouse_config_t + */ +void hid_driver_init(const hid_config_t *config); + +/** + * @brief hid_set_report + * @param device_id handle of HID device + * @returns true on success, false otherwise + */ +bool hid_set_report(uint8_t device_id, uint8_t val); + +enum HID_TYPE { + HID_TYPE_NONE, + HID_TYPE_MOUSE, + HID_TYPE_KEYBOARD, +}; + +/** + * @brief hid_get_type + * @param device_id handle of HID device + * @return type of attached HID + * @see enum HID_TYPE + */ +enum HID_TYPE hid_get_type(uint8_t device_id); + +/** + * @brief hid_is_connected + * @param device_id handle of HID device + * @return true if the device with device_id is connected + */ +bool hid_is_connected(uint8_t device_id); + +extern const usbh_dev_driver_t usbh_hid_driver; + +END_DECLS + +#endif diff --git a/include/usbh_driver_hid_mouse.h b/include/usbh_driver_hid_mouse.h deleted file mode 100644 index 4a9f0d3..0000000 --- a/include/usbh_driver_hid_mouse.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of the libusbhost library - * hosted at http://github.com/libusbhost/libusbhost - * - * Copyright (C) 2015 Amir Hammad - * - * - * libusbhost is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * - */ - -#ifndef USBH_DRIVER_HID_MOUSE_ -#define USBH_DRIVER_HID_MOUSE_ - -#include "usbh_core.h" - -#include - -BEGIN_DECLS - -struct _hid_mouse_config { - /** - * @brief this is called when some data is read when polling the device - * @param device_id - * @param data pointer to the data (only 4 bytes are valid!) - */ - void (*mouse_in_message_handler)(uint8_t device_id, const uint8_t *data); -}; -typedef struct _hid_mouse_config hid_mouse_config_t; - -/** - * @brief hid_mouse_driver_init initialization routine - this will initialize internal structures of this device driver - * @param config - * @see hid_mouse_config_t - */ -void hid_mouse_driver_init(const hid_mouse_config_t *config); - -extern const usbh_dev_driver_t usbh_hid_mouse_driver; - -END_DECLS - -#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3165b51..f8478f6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,7 +14,7 @@ add_library (usbhost ${inc}/usbh_core.h ${inc}/usbh_driver_ac_midi.h ${inc}/usbh_driver_gp_xbox.h - ${inc}/usbh_driver_hid_mouse.h + ${inc}/usbh_driver_hid.h ${inc}/usbh_driver_hub.h ${inc}/usbh_lld_stm32f4.h ${inc}/driver/usbh_device_driver.h @@ -23,7 +23,7 @@ add_library (usbhost usbh_driver_ac_midi.c usbh_driver_ac_midi_private.h usbh_driver_gp_xbox.c - usbh_driver_hid_mouse.c + usbh_driver_hid.c usbh_driver_hub.c usbh_driver_hub_private.h usbh_lld_stm32f4.c diff --git a/src/demo.c b/src/demo.c index 3fedbd9..995e68c 100644 --- a/src/demo.c +++ b/src/demo.c @@ -23,7 +23,7 @@ #include "usart_helpers.h" /// provides LOG_PRINTF macros used for debugging #include "usbh_core.h" /// provides usbh_init() and usbh_poll() #include "usbh_lld_stm32f4.h" /// provides low level usb host driver for stm32f4 platform -#include "usbh_driver_hid_mouse.h" /// provides usb device driver Human Interface Device - type mouse +#include "usbh_driver_hid.h" /// provides generic usb device driver for Human Interface Device (HID) #include "usbh_driver_hub.h" /// provides usb full speed hub driver (Low speed devices on hub are not supported) #include "usbh_driver_gp_xbox.h" /// provides usb device driver for Gamepad: Microsoft XBOX compatible Controller #include "usbh_driver_ac_midi.h" /// provides usb device driver for midi class devices @@ -116,7 +116,7 @@ static void gpio_setup(void) static const usbh_dev_driver_t *device_drivers[] = { &usbh_hub_driver, - &usbh_hid_mouse_driver, + &usbh_hid_driver, &usbh_gp_xbox_driver, &usbh_midi_driver, 0 @@ -148,17 +148,29 @@ static const gp_xbox_config_t gp_xbox_config = { .notify_disconnected = &gp_xbox_disconnected }; -static void mouse_in_message_handler(uint8_t device_id, const uint8_t *data) +static void hid_in_message_handler(uint8_t device_id, const uint8_t *data, uint32_t length) { (void)device_id; (void)data; + if (length < 4) { + LOG_PRINTF("data too short, type=%d\n", hid_get_type(device_id)); + return; + } + // print only first 4 bytes, since every mouse should have at least these four set. // Report descriptors are not read by driver for now, so we do not know what each byte means - LOG_PRINTF("MOUSE EVENT %02X %02X %02X %02X \n", data[0], data[1], data[2], data[3]); + LOG_PRINTF("HID EVENT %02X %02X %02X %02X \n", data[0], data[1], data[2], data[3]); + if (hid_get_type(device_id) == HID_TYPE_KEYBOARD) { + static int x = 0; + if (x != data[2]) { + x = data[2]; + hid_set_report(device_id, x); + } + } } -static const hid_mouse_config_t mouse_config = { - .mouse_in_message_handler = &mouse_in_message_handler +static const hid_config_t hid_config = { + .hid_in_message_handler = &hid_in_message_handler }; static void midi_in_message_handler(int device_id, uint8_t *data) @@ -200,7 +212,7 @@ int main(void) * * Pass configuration struct where the callbacks are defined */ - hid_mouse_driver_init(&mouse_config); + hid_driver_init(&hid_config); hub_driver_init(); gp_xbox_driver_init(&gp_xbox_config); midi_driver_init(&midi_config); diff --git a/src/usbh_driver_hid.c b/src/usbh_driver_hid.c new file mode 100644 index 0000000..21fa262 --- /dev/null +++ b/src/usbh_driver_hid.c @@ -0,0 +1,537 @@ +/* + * This file is part of the libusbhost library + * hosted at http://github.com/libusbhost/libusbhost + * + * Copyright (C) 2016 Amir Hammad + * + * + * libusbhost is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + */ + +#include "usbh_core.h" +#include "driver/usbh_device_driver.h" +#include "usbh_driver_hid.h" +#include "usart_helpers.h" + +#include +#include +#include + +#define USB_HID_SET_REPORT 0x09 +#define USB_HID_SET_IDLE 0x0A + +enum STATES { + STATE_INACTIVE, + STATE_READING_REQUEST, + STATE_READING_COMPLETE_AND_CHECK_REPORT, + STATE_SET_REPORT_EMPTY_READ, + STATE_SET_CONFIGURATION_REQUEST, + STATE_SET_CONFIGURATION_EMPTY_READ, + STATE_GET_REPORT_DESCRIPTOR_READ_SETUP,// configuration is complete at this point. We write request + STATE_GET_REPORT_DESCRIPTOR_READ, + STATE_GET_REPORT_DESCRIPTOR_READ_COMPLETE,// after the read finishes, we parse that descriptor + STATE_SET_IDLE, + STATE_SET_IDLE_COMPLETE, +}; + +enum REPORT_STATE { + REPORT_STATE_NULL, + REPORT_STATE_READY, + REPORT_STATE_WRITE_PENDING, + REPORT_STATE_WRITE_PENDING_DATA, + REPORT_STATE_EMPTY_READ, +}; + +struct _hid_device { + usbh_device_t *usbh_device; + uint8_t buffer[USBH_HID_BUFFER]; + uint16_t endpoint_in_maxpacketsize; + uint8_t endpoint_in_address; + enum STATES state_next; + uint8_t endpoint_in_toggle; + uint8_t device_id; + uint8_t configuration_value; + uint16_t report0_length; + enum REPORT_STATE report_state; + uint8_t report_data[USBH_HID_REPORT_BUFFER]; + uint8_t report_data_length; + enum HID_TYPE hid_type; + uint8_t interface_number; +}; +typedef struct _hid_device hid_device_t; + +struct hid_report_decriptor { + struct usb_hid_descriptor header; + struct _report_descriptor_info { + uint8_t bDescriptorType; + uint16_t wDescriptorLength; + } __attribute__((packed)) report_descriptors_info[]; +} __attribute__((packed)); + +static hid_device_t hid_device[USBH_HID_MAX_DEVICES]; +static hid_config_t hid_config; + +static bool initialized = false; + +void hid_driver_init(const hid_config_t *config) +{ + uint32_t i; + + initialized = true; + + hid_config = *config; + for (i = 0; i < USBH_HID_MAX_DEVICES; i++) { + hid_device[i].state_next = STATE_INACTIVE; + } +} + +static void *init(void *usbh_dev) +{ + if (!initialized) { + LOG_PRINTF("\n%s/%d : driver not initialized\r\n", __FILE__, __LINE__); + return 0; + } + + uint32_t i; + hid_device_t *drvdata = 0; + + // find free data space for HID device + for (i = 0; i < USBH_HID_MAX_DEVICES; i++) { + if (hid_device[i].state_next == STATE_INACTIVE) { + drvdata = &hid_device[i]; + drvdata->device_id = i; + drvdata->endpoint_in_address = 0; + drvdata->endpoint_in_toggle = 0; + drvdata->report0_length = 0; + drvdata->usbh_device = (usbh_device_t *)usbh_dev; + drvdata->report_state = REPORT_STATE_NULL; + drvdata->hid_type = HID_TYPE_NONE; + break; + } + } + + return drvdata; +} + +static void parse_report_descriptor(hid_device_t *hid, const uint8_t *buffer, uint32_t length) +{ + // TODO + // Do some parsing! + // add some checks + hid->report_state = REPORT_STATE_READY; + + // TODO: parse this from buffer! + hid->report_data_length = 1; + (void)buffer; + (void)length; +} + +/** + * Returns true if all needed data are parsed + */ +static bool analyze_descriptor(void *drvdata, void *descriptor) +{ + hid_device_t *hid = (hid_device_t *)drvdata; + uint8_t desc_type = ((uint8_t *)descriptor)[1]; + switch (desc_type) { + case USB_DT_CONFIGURATION: + { + const struct usb_config_descriptor * cfg = (const struct usb_config_descriptor*)descriptor; + hid->configuration_value = cfg->bConfigurationValue; + } + break; + + case USB_DT_DEVICE: + { + const struct usb_device_descriptor *devDesc = (const struct usb_device_descriptor *)descriptor; + (void)devDesc; + } + break; + + case USB_DT_INTERFACE: + { + const struct usb_interface_descriptor *ifDesc = (const struct usb_interface_descriptor *)descriptor; + if (ifDesc->bInterfaceProtocol == 0x01) { + hid->hid_type = HID_TYPE_KEYBOARD; + hid->interface_number = ifDesc->bInterfaceNumber; + } else if (ifDesc->bInterfaceProtocol == 0x02) { + hid->hid_type = HID_TYPE_MOUSE; + hid->interface_number = ifDesc->bInterfaceNumber; + } + } + break; + + case USB_DT_ENDPOINT: + { + const struct usb_endpoint_descriptor *ep = (const struct usb_endpoint_descriptor *)descriptor; + if ((ep->bmAttributes&0x03) == USB_ENDPOINT_ATTR_INTERRUPT) { + uint8_t epaddr = ep->bEndpointAddress; + if (epaddr & (1<<7)) { + hid->endpoint_in_address = epaddr&0x7f; + if (ep->wMaxPacketSize < USBH_HID_BUFFER) { + hid->endpoint_in_maxpacketsize = ep->wMaxPacketSize; + } else { + hid->endpoint_in_maxpacketsize = USBH_HID_BUFFER; + } + } + } + } + break; + + case USB_DT_HID: + { + const struct hid_report_decriptor *desc = (const struct hid_report_decriptor *)descriptor; + if (desc->header.bNumDescriptors > 0 && desc->report_descriptors_info[0].bDescriptorType == USB_DT_REPORT) { + hid->report0_length = desc->report_descriptors_info[0].wDescriptorLength; + } + } + break; + + default: + break; + } + + if (hid->endpoint_in_address && hid->report0_length) { + hid->state_next = STATE_SET_CONFIGURATION_REQUEST; + return true; + } + + return false; +} + +static void report_event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) +{ + hid_device_t *hid = (hid_device_t *)dev->drvdata; + switch (hid->report_state) { + case REPORT_STATE_WRITE_PENDING: + switch (cb_data.status) { + case USBH_PACKET_CALLBACK_STATUS_OK: + hid->report_state = REPORT_STATE_WRITE_PENDING_DATA; + + device_xfer_control_write_data(hid->report_data, hid->report_data_length, report_event, dev); + break; + + case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + case USBH_PACKET_CALLBACK_STATUS_EFATAL: + case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + ERROR(cb_data.status); + hid->state_next = STATE_INACTIVE; + break; + } + break; + + case REPORT_STATE_WRITE_PENDING_DATA: + switch (cb_data.status) { + case USBH_PACKET_CALLBACK_STATUS_OK: + hid->report_state = REPORT_STATE_EMPTY_READ; + device_xfer_control_read(0, 0, report_event, dev); + LOG_PRINTF("reading empty\n"); + break; + + case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + case USBH_PACKET_CALLBACK_STATUS_EFATAL: + case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + ERROR(cb_data.status); + hid->state_next = STATE_INACTIVE; + break; + } + break; + + + case REPORT_STATE_EMPTY_READ: + switch (cb_data.status) { + case USBH_PACKET_CALLBACK_STATUS_OK: + hid->report_state = REPORT_STATE_READY; + break; + + case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + case USBH_PACKET_CALLBACK_STATUS_EFATAL: + case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + ERROR(cb_data.status); + hid->state_next = STATE_INACTIVE; + break; + } + break; + default: + break; + } +} + +static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) +{ + hid_device_t *hid = (hid_device_t *)dev->drvdata; + + switch (hid->state_next) { + case STATE_READING_COMPLETE_AND_CHECK_REPORT: + { + switch (cb_data.status) { + case USBH_PACKET_CALLBACK_STATUS_OK: + case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + if (hid_config.hid_in_message_handler) { + hid_config.hid_in_message_handler(hid->device_id, hid->buffer, cb_data.transferred_length); + } + hid->state_next = STATE_READING_REQUEST; + break; + + case USBH_PACKET_CALLBACK_STATUS_EFATAL: + case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + ERROR(cb_data.status); + hid->state_next = STATE_INACTIVE; + break; + } + } + break; + + case STATE_SET_CONFIGURATION_EMPTY_READ: + { + LOG_PRINTF("|empty packet read|"); + switch (cb_data.status) { + case USBH_PACKET_CALLBACK_STATUS_OK: + hid->state_next = STATE_GET_REPORT_DESCRIPTOR_READ_SETUP; + device_xfer_control_read(0, 0, event, dev); + break; + + case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + case USBH_PACKET_CALLBACK_STATUS_EFATAL: + case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + ERROR(cb_data.status); + hid->state_next = STATE_INACTIVE; + break; + } + } + break; + + case STATE_GET_REPORT_DESCRIPTOR_READ_SETUP: + { + switch (cb_data.status) { + case USBH_PACKET_CALLBACK_STATUS_OK: + case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + { + hid->endpoint_in_toggle = 0; + // We support only the first report descriptor with index 0 + + // limit the size of the report descriptor! + if (hid->report0_length > USBH_HID_BUFFER) { + hid->report0_length = USBH_HID_BUFFER; + } + + struct usb_setup_data setup_data; + + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_INTERFACE; + setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; + setup_data.wValue = USB_DT_REPORT << 8; + setup_data.wIndex = 0; + setup_data.wLength = hid->report0_length; + + hid->state_next = STATE_GET_REPORT_DESCRIPTOR_READ; + device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + + } + break; + + case USBH_PACKET_CALLBACK_STATUS_EFATAL: + case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + ERROR(cb_data.status); + hid->state_next = STATE_INACTIVE; + break; + } + } + break; + + case STATE_GET_REPORT_DESCRIPTOR_READ: + { + switch (cb_data.status) { + case USBH_PACKET_CALLBACK_STATUS_OK: + hid->state_next = STATE_GET_REPORT_DESCRIPTOR_READ_COMPLETE; + device_xfer_control_read(hid->buffer, hid->report0_length, event, dev); + break; + + case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + case USBH_PACKET_CALLBACK_STATUS_EFATAL: + case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + ERROR(cb_data.status); + hid->state_next = STATE_INACTIVE; + break; + } + } + break; + + + case STATE_GET_REPORT_DESCRIPTOR_READ_COMPLETE: // read complete, SET_IDLE to 0 + { + switch (cb_data.status) { + case USBH_PACKET_CALLBACK_STATUS_OK: + LOG_PRINTF("READ REPORT COMPLETE \n"); + hid->state_next = STATE_READING_REQUEST; + hid->endpoint_in_toggle = 0; + + parse_report_descriptor(hid, hid->buffer, cb_data.transferred_length); + break; + + case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + case USBH_PACKET_CALLBACK_STATUS_EFATAL: + case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + ERROR(cb_data.status); + hid->state_next = STATE_INACTIVE; + break; + } + } + break; + + default: + break; + } +} + + +static void read_hid_in_endpoint(void *drvdata) +{ + hid_device_t *hid = (hid_device_t *)drvdata; + usbh_packet_t packet; + + packet.address = hid->usbh_device->address; + packet.data.in = &hid->buffer[0]; + packet.datalen = hid->endpoint_in_maxpacketsize; + packet.endpoint_address = hid->endpoint_in_address; + packet.endpoint_size_max = hid->endpoint_in_maxpacketsize; + packet.endpoint_type = USBH_ENDPOINT_TYPE_INTERRUPT; + packet.speed = hid->usbh_device->speed; + packet.callback = event; + packet.callback_arg = hid->usbh_device; + packet.toggle = &hid->endpoint_in_toggle; + + hid->state_next = STATE_READING_COMPLETE_AND_CHECK_REPORT; + usbh_read(hid->usbh_device, &packet); +} + +/** + * @param time_curr_us - monotically rising time + * unit is microseconds + * @see usbh_poll() + */ +static void poll(void *drvdata, uint32_t time_curr_us) +{ + (void)time_curr_us; + + hid_device_t *hid = (hid_device_t *)drvdata; + usbh_device_t *dev = hid->usbh_device; + switch (hid->state_next) { + case STATE_READING_REQUEST: + { + read_hid_in_endpoint(drvdata); + } + break; + + case STATE_SET_CONFIGURATION_REQUEST: + { + struct usb_setup_data setup_data; + + setup_data.bmRequestType = USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; + setup_data.bRequest = USB_REQ_SET_CONFIGURATION; + setup_data.wValue = hid->configuration_value; + setup_data.wIndex = 0; + setup_data.wLength = 0; + + hid->state_next = STATE_SET_CONFIGURATION_EMPTY_READ; + + device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + } + break; + + default: + // do nothing - probably transfer is in progress + break; + } +} + +static void remove(void *drvdata) +{ + hid_device_t *hid = (hid_device_t *)drvdata; + hid->state_next = STATE_INACTIVE; + hid->endpoint_in_address = 0; +} + +bool hid_set_report(uint8_t device_id, uint8_t val) +{ + if (device_id >= USBH_HID_MAX_DEVICES) { + LOG_PRINTF("invalid device id"); + return false; + } + + hid_device_t *hid = &hid_device[device_id]; + if (hid->report_state != REPORT_STATE_READY) { + LOG_PRINTF("reporting is not ready\n"); + // store and update afterwards + return false; + } + + if (hid->report_data_length == 0) { + LOG_PRINTF("reporting is not available (report len=0)\n"); + return false; + } + + struct usb_setup_data setup_data; + setup_data.bmRequestType = USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE; + setup_data.bRequest = USB_HID_SET_REPORT; + setup_data.wValue = 0x02 << 8; + setup_data.wIndex = hid->interface_number; + setup_data.wLength = hid->report_data_length; + + hid->report_data[0] = val; + + hid->report_state = REPORT_STATE_WRITE_PENDING; + device_xfer_control_write_setup(&setup_data, sizeof(setup_data), report_event, hid->usbh_device); + return true; +} + +bool hid_is_connected(uint8_t device_id) +{ + if (device_id >= USBH_HID_MAX_DEVICES) { + LOG_PRINTF("is connected: invalid device id"); + return false; + } + return hid_device[device_id].state_next == STATE_INACTIVE; +} + + +enum HID_TYPE hid_get_type(uint8_t device_id) +{ + if (hid_is_connected(device_id)) { + return HID_TYPE_NONE; + } + return hid_device[device_id].hid_type; +} + +static const usbh_dev_driver_info_t driver_info = { + .deviceClass = -1, + .deviceSubClass = -1, + .deviceProtocol = -1, + .idVendor = -1, + .idProduct = -1, + .ifaceClass = 0x03, // HID class + .ifaceSubClass = -1, + .ifaceProtocol = -1, // Do not care +}; + +const usbh_dev_driver_t usbh_hid_driver = { + .init = init, + .analyze_descriptor = analyze_descriptor, + .poll = poll, + .remove = remove, + .info = &driver_info +}; + + + diff --git a/src/usbh_driver_hid_mouse.c b/src/usbh_driver_hid_mouse.c deleted file mode 100644 index b52392f..0000000 --- a/src/usbh_driver_hid_mouse.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * This file is part of the libusbhost library - * hosted at http://github.com/libusbhost/libusbhost - * - * Copyright (C) 2015 Amir Hammad - * - * - * libusbhost is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * - */ - -#include "usbh_core.h" -#include "driver/usbh_device_driver.h" -#include "usbh_driver_hid_mouse.h" -#include "usart_helpers.h" - -#include - -enum STATES { - STATE_INACTIVE, - STATE_READING_COMPLETE, - STATE_READING_REQUEST, - STATE_SET_CONFIGURATION_REQUEST, - STATE_SET_CONFIGURATION_EMPTY_READ, - STATE_SET_CONFIGURATION_COMPLETE -}; - -struct _hid_mouse_device { - usbh_device_t *usbh_device; - uint8_t buffer[USBH_HID_MOUSE_BUFFER]; - uint16_t endpoint_in_maxpacketsize; - uint8_t endpoint_in_address; - enum STATES state_next; - uint8_t endpoint_in_toggle; - uint8_t device_id; - uint8_t configuration_value; -}; -typedef struct _hid_mouse_device hid_mouse_device_t; - -static hid_mouse_device_t mouse_device[USBH_HID_MOUSE_MAX_DEVICES]; -static const hid_mouse_config_t *mouse_config; - - - - -#include - -static bool initialized = false; - -void hid_mouse_driver_init(const hid_mouse_config_t *config) -{ - uint32_t i; - - initialized = true; - - mouse_config = config; - for (i = 0; i < USBH_HID_MOUSE_MAX_DEVICES; i++) { - mouse_device[i].state_next = STATE_INACTIVE; - } -} - -/** - * - * - */ -static void *init(void *usbh_dev) -{ - if (!initialized) { - LOG_PRINTF("\n%s/%d : driver not initialized\n", __FILE__, __LINE__); - return 0; - } - - uint32_t i; - hid_mouse_device_t *drvdata = 0; - - // find free data space for mouse device - for (i = 0; i < USBH_HID_MOUSE_MAX_DEVICES; i++) { - if (mouse_device[i].state_next == STATE_INACTIVE) { - drvdata = &mouse_device[i]; - drvdata->device_id = i; - drvdata->endpoint_in_address = 0; - drvdata->endpoint_in_toggle = 0; - drvdata->usbh_device = (usbh_device_t *)usbh_dev; - break; - } - } - - return drvdata; -} - -/** - * Returns true if all needed data are parsed - */ -static bool analyze_descriptor(void *drvdata, void *descriptor) -{ - hid_mouse_device_t *mouse = (hid_mouse_device_t *)drvdata; - uint8_t desc_type = ((uint8_t *)descriptor)[1]; - switch (desc_type) { - case USB_DT_CONFIGURATION: - { - struct usb_config_descriptor *cfg = (struct usb_config_descriptor*)descriptor; - mouse->configuration_value = cfg->bConfigurationValue; - } - break; - case USB_DT_DEVICE: - break; - case USB_DT_INTERFACE: - break; - case USB_DT_ENDPOINT: - { - struct usb_endpoint_descriptor *ep = (struct usb_endpoint_descriptor*)descriptor; - if ((ep->bmAttributes&0x03) == USB_ENDPOINT_ATTR_INTERRUPT) { - uint8_t epaddr = ep->bEndpointAddress; - if (epaddr & (1<<7)) { - mouse->endpoint_in_address = epaddr&0x7f; - if (ep->wMaxPacketSize < USBH_HID_MOUSE_BUFFER) { - mouse->endpoint_in_maxpacketsize = ep->wMaxPacketSize; - } else { - mouse->endpoint_in_maxpacketsize = USBH_HID_MOUSE_BUFFER; - } - } - - if (mouse->endpoint_in_address) { - mouse->state_next = STATE_SET_CONFIGURATION_REQUEST; - return true; - } - } - } - break; - // TODO Class Specific descriptors - default: - break; - } - return false; -} - -static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) -{ - hid_mouse_device_t *mouse = (hid_mouse_device_t *)dev->drvdata; - switch (mouse->state_next) { - case STATE_READING_COMPLETE: - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - mouse->state_next = STATE_READING_REQUEST; - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - ERROR(cb_data.status); - mouse->state_next = STATE_INACTIVE; - break; - } - } - break; - - case STATE_SET_CONFIGURATION_EMPTY_READ: - { - LOG_PRINTF("|empty packet read|"); - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - mouse->state_next = STATE_SET_CONFIGURATION_COMPLETE; - device_xfer_control_read(0, 0, event, dev); - break; - - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - ERROR(cb_data.status); - mouse->state_next = STATE_INACTIVE; - break; - } - } - break; - case STATE_SET_CONFIGURATION_COMPLETE: // Configured - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - mouse->state_next = STATE_READING_REQUEST; - mouse->endpoint_in_toggle = 0; - LOG_PRINTF("\nMOUSE CONFIGURED\n"); - break; - - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - ERROR(cb_data.status); - mouse->state_next = STATE_INACTIVE; - break; - } - } - break; - default: - break; - } -} - - -static void read_mouse_in(void *drvdata) -{ - hid_mouse_device_t *mouse = (hid_mouse_device_t *)drvdata; - usbh_packet_t packet; - - packet.address = mouse->usbh_device->address; - packet.data.in = &mouse->buffer[0]; - packet.datalen = mouse->endpoint_in_maxpacketsize; - packet.endpoint_address = mouse->endpoint_in_address; - packet.endpoint_size_max = mouse->endpoint_in_maxpacketsize; - packet.endpoint_type = USBH_ENDPOINT_TYPE_INTERRUPT; - packet.speed = mouse->usbh_device->speed; - packet.callback = event; - packet.callback_arg = mouse->usbh_device; - packet.toggle = &mouse->endpoint_in_toggle; - - mouse->state_next = STATE_READING_COMPLETE; - usbh_read(mouse->usbh_device, &packet); - - // LOG_PRINTF("@MOUSE EP1 | \n"); - -} - -/** - * @param time_curr_us - monotically rising time - * unit is microseconds - * @see usbh_poll() - */ -static void poll(void *drvdata, uint32_t time_curr_us) -{ - (void)time_curr_us; - - hid_mouse_device_t *mouse = (hid_mouse_device_t *)drvdata; - usbh_device_t *dev = mouse->usbh_device; - switch (mouse->state_next) { - case STATE_READING_REQUEST: - { - read_mouse_in(drvdata); - } - break; - - case STATE_SET_CONFIGURATION_REQUEST: - { - struct usb_setup_data setup_data; - - setup_data.bmRequestType = 0b00000000; - setup_data.bRequest = USB_REQ_SET_CONFIGURATION; - setup_data.wValue = mouse->configuration_value; - setup_data.wIndex = 0; - setup_data.wLength = 0; - - mouse->state_next = STATE_SET_CONFIGURATION_EMPTY_READ; - - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); - } - break; - - default: - // do nothing - probably transfer is in progress - break; - } -} - -static void remove(void *drvdata) -{ - hid_mouse_device_t *mouse = (hid_mouse_device_t *)drvdata; - mouse->state_next = STATE_INACTIVE; - mouse->endpoint_in_address = 0; -} - -static const usbh_dev_driver_info_t driver_info = { - .deviceClass = -1, - .deviceSubClass = -1, - .deviceProtocol = -1, - .idVendor = -1, - .idProduct = -1, - .ifaceClass = 0x03, - .ifaceSubClass = -1, - .ifaceProtocol = 0x02 -}; - -const usbh_dev_driver_t usbh_hid_mouse_driver = { - .init = init, - .analyze_descriptor = analyze_descriptor, - .poll = poll, - .remove = remove, - .info = &driver_info -}; -- cgit From 1d08641a15eef8fb0590113c96e3f985f7e32a23 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Sat, 3 Sep 2016 17:55:44 +0200 Subject: Added travis.yml and badge Signed-off-by: Amir Hammad --- .travis.yml | 17 +++++++++++++++++ README.md | 1 + 2 files changed, 18 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..f453c85 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,17 @@ +language: c +compiler: + - gcc +before_install: + - sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded + - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key 6D1D8367A3421AFB + - sudo apt-get update -o Dir::Etc::sourcelist="sources.list.d/terry_guo-gcc-arm-embedded-precise.list" -o Dir::Etc::sourceparts="-" -o APT::Get::List-Cleanup="0" + - sudo apt-get install gcc-arm-none-eabi +script: + - cd build && cmake $FLAGS_matrix .. && make + +env: + matrix: + - FLAGS_matrix="-DUSE_USART_DEBUG=FALSE -DUSE_STM32F4_HS=TRUE -DUSE_STM32F4_FS=TRUE" + - FLAGS_matrix="-DUSE_USART_DEBUG=TRUE -DUSE_STM32F4_HS=TRUE -DUSE_STM32F4_FS=TRUE" + - FLAGS_matrix="-DUSE_USART_DEBUG=TRUE -DUSE_STM32F4_HS=FALSE -DUSE_STM32F4_FS=TRUE" + - FLAGS_matrix="-DUSE_USART_DEBUG=TRUE -DUSE_STM32F4_HS=TRUE -DUSE_STM32F4_FS=FALSE" diff --git a/README.md b/README.md index a823eaf..4608e7e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Build Status](https://travis-ci.org/libusbhost/libusbhost.svg?branch=master)](https://travis-ci.org/libusbhost/libusbhost) ##General Information [Link to the official repository](http://github.com/libusbhost/libusbhost) -- cgit From a75535e52b9500a82cd0e9aebe6a987b68390895 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Mon, 5 Sep 2016 20:10:17 +0200 Subject: core: Simplify device removes Signed-off-by: Amir Hammad --- src/usbh_core.c | 24 +++++++++++++----------- src/usbh_driver_hub.c | 16 ++-------------- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/src/usbh_core.c b/src/usbh_core.c index d6f6ff4..dbdec0c 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -50,6 +50,16 @@ static bool enumeration(void) return usbh_data.enumeration_run; } +static void device_remove(usbh_device_t *dev) +{ + if (dev->drv && dev->drvdata) { + dev->drv->remove(dev->drvdata); + } + dev->address = -1; + dev->drv = 0; + dev->drvdata = 0; +} + /** * */ @@ -146,6 +156,7 @@ static void device_register(void *descriptors, uint16_t descriptors_len, usbh_de k += desc_len; } LOG_PRINTF("Device driver isn't compatible with this device\n"); + device_remove(dev); } else { LOG_PRINTF("No compatible driver has been found for interface #%d\n", iface->bInterfaceNumber); } @@ -630,18 +641,9 @@ void usbh_poll(uint32_t time_curr_us) case USBH_POLL_STATUS_DEVICE_DISCONNECTED: { - // Device disconnected - if (usbh_device[0].drv && usbh_device[0].drvdata) { - usbh_device[0].drv->remove(usbh_device[0].drvdata); - } - usbh_device[0].drv = 0; - usbh_device[0].drvdata = 0; - uint32_t i; - for (i = 1; i < USBH_MAX_DEVICES; i++) { - usbh_device[i].address = -1; - usbh_device[i].drv = 0; - usbh_device[i].drvdata = 0; + for (i = 0; i < USBH_MAX_DEVICES; i++) { + device_remove(&usbh_device[i]); } } break; diff --git a/src/usbh_driver_hub.c b/src/usbh_driver_hub.c index 1beed01..c185b6a 100644 --- a/src/usbh_driver_hub.c +++ b/src/usbh_driver_hub.c @@ -835,23 +835,11 @@ static void remove(void *drvdata) hub_device_t *hub = (hub_device_t *)drvdata; uint8_t i; - // Call fast... to avoid polling hub->state = 0; hub->endpoint_in_address = 0; hub->busy = 0; - for (i = 1; i < USBH_HUB_MAX_DEVICES + 1; i++) { - if (hub->device[i]) { - if (hub->device[i]->drv && hub->device[i]->drvdata) { - if (hub->device[i]->drv->remove != remove) { - LOG_PRINTF("\t\t\t\tHUB REMOVE %d\n",hub->device[i]->address); - hub->device[i]->drv->remove(hub->device[i]->drvdata); - } - } - hub->device[i] = 0; - } - hub->device[0]->drv = 0; - hub->device[0]->drvdata = 0; - hub->device[0] = 0; + for (i = 0; i < USBH_HUB_MAX_DEVICES + 1; i++) { + hub->device[i] = 0; } } -- cgit From 58fec7a17ceb6814d64e702e7829556c3ece01e4 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Mon, 5 Sep 2016 19:48:56 +0200 Subject: Drop need for the set configuration request in dev drivers Signed-off-by: Amir Hammad --- include/driver/usbh_device_driver.h | 3 ++ src/usbh_core.c | 58 +++++++++++++++++++++++++- src/usbh_driver_ac_midi.c | 44 +++++--------------- src/usbh_driver_gp_xbox.c | 66 +++++------------------------- src/usbh_driver_hid.c | 81 +++++++------------------------------ src/usbh_driver_hub.c | 72 +++++++++------------------------ 6 files changed, 112 insertions(+), 212 deletions(-) diff --git a/include/driver/usbh_device_driver.h b/include/driver/usbh_device_driver.h index eca8928..c70715b 100644 --- a/include/driver/usbh_device_driver.h +++ b/include/driver/usbh_device_driver.h @@ -75,6 +75,9 @@ enum USBH_ENUM_STATE { USBH_ENUM_STATE_CONFIGURATION_DT_READ_SETUP, USBH_ENUM_STATE_CONFIGURATION_DT_READ, USBH_ENUM_STATE_CONFIGURATION_DT_READ_COMPLETE, + USBH_ENUM_STATE_SET_CONFIGURATION_SETUP, + USBH_ENUM_STATE_SET_CONFIGURATION_EMPTY_READ, + USBH_ENUM_STATE_SET_CONFIGURATION_COMPLETE, USBH_ENUM_STATE_FIND_DRIVER, }; diff --git a/src/usbh_core.c b/src/usbh_core.c index dbdec0c..7071281 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -483,7 +483,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ (struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE]; if (cb_data.transferred_length == cdt->wTotalLength) { LOG_PRINTF("Configuration descriptor read complete. length: %d\n", cdt->wTotalLength); - CONTINUE_WITH(USBH_ENUM_STATE_FIND_DRIVER); + CONTINUE_WITH(USBH_ENUM_STATE_SET_CONFIGURATION_SETUP); } } break; @@ -546,7 +546,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ struct usb_config_descriptor *cdt = (struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE]; LOG_PRINTF("Configuration descriptor read complete. length: %d\n", cdt->wTotalLength); - CONTINUE_WITH(USBH_ENUM_STATE_FIND_DRIVER); + CONTINUE_WITH(USBH_ENUM_STATE_SET_CONFIGURATION_SETUP); } break; @@ -562,6 +562,60 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ } break; + case USBH_ENUM_STATE_SET_CONFIGURATION_SETUP: + { + struct usb_config_descriptor *cdt = + (struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE]; + + struct usb_setup_data setup_data; + + setup_data.bmRequestType = USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; + setup_data.bRequest = USB_REQ_SET_CONFIGURATION; + setup_data.wValue = cdt->bConfigurationValue; + setup_data.wIndex = 0; + setup_data.wLength = 0; + + dev->state = USBH_ENUM_STATE_SET_CONFIGURATION_EMPTY_READ; + + device_xfer_control_write_setup(&setup_data, sizeof(setup_data), device_enumerate, dev); + } + break; + + case USBH_ENUM_STATE_SET_CONFIGURATION_EMPTY_READ: + { + switch (cb_data.status) { + case USBH_PACKET_CALLBACK_STATUS_OK: + dev->state = USBH_ENUM_STATE_SET_CONFIGURATION_COMPLETE; + device_xfer_control_read(0, 0, device_enumerate, dev); + break; + + case USBH_PACKET_CALLBACK_STATUS_EFATAL: + case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + device_enumeration_terminate(dev); + ERROR(cb_data.status); + break; + } + } + break; + + case USBH_ENUM_STATE_SET_CONFIGURATION_COMPLETE: + { + switch (cb_data.status) { + case USBH_PACKET_CALLBACK_STATUS_OK: + CONTINUE_WITH(USBH_ENUM_STATE_FIND_DRIVER); + break; + + case USBH_PACKET_CALLBACK_STATUS_EFATAL: + case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + device_enumeration_terminate(dev); + ERROR(cb_data.status); + break; + } + } + break; + case USBH_ENUM_STATE_FIND_DRIVER: { struct usb_config_descriptor *cdt = diff --git a/src/usbh_driver_ac_midi.c b/src/usbh_driver_ac_midi.c index cea40df..87da03b 100644 --- a/src/usbh_driver_ac_midi.c +++ b/src/usbh_driver_ac_midi.c @@ -206,30 +206,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t status) LOG_PRINTF("\n CAN'T TOUCH THIS... ignoring data\n"); } break; - case 2: - { - LOG_PRINTF("|empty packet read|"); - if (status.status == USBH_PACKET_CALLBACK_STATUS_OK) { - midi->state++; - device_xfer_control_read(0, 0, event, dev); - } - } - break; - case 3: // Configured - { - if (status.status == USBH_PACKET_CALLBACK_STATUS_OK) { - midi->state = 100; - - midi->endpoint_in_toggle = 0; - LOG_PRINTF("\nMIDI CONFIGURED\n"); - // Notify user - if (midi_config->notify_connected) { - midi_config->notify_connected(midi->device_id); - } - } - } - break; default: break; } @@ -265,7 +242,6 @@ static void midi_poll(void *drvdata, uint32_t t_us) (void)drvdata; midi_device_t *midi = drvdata; - usbh_device_t *dev = midi->usbh_device; switch (midi->state) { /// Upon configuration, some controllers send additional error data @@ -276,11 +252,13 @@ static void midi_poll(void *drvdata, uint32_t t_us) midi->state = 101; } break; + case 101: { read_midi_in(drvdata, 102); } break; + case 102: { // if elapsed MIDI initial delay microseconds @@ -289,6 +267,7 @@ static void midi_poll(void *drvdata, uint32_t t_us) } } break; + case 25: { read_midi_in(drvdata, 26); @@ -297,18 +276,15 @@ static void midi_poll(void *drvdata, uint32_t t_us) case 1: { - //~ LOG_PRINTF("CFGVAL: %d\n", dev->config_val); - struct usb_setup_data setup_data; + midi->state = 100; - setup_data.bmRequestType = USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; - setup_data.bRequest = USB_REQ_SET_CONFIGURATION; - setup_data.wValue = midi->buffer[0]; - setup_data.wIndex = 0; - setup_data.wLength = 0; + midi->endpoint_in_toggle = 0; + LOG_PRINTF("\nMIDI CONFIGURED\n"); - midi->state++; - - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + // Notify user + if (midi_config->notify_connected) { + midi_config->notify_connected(midi->device_id); + } } break; } diff --git a/src/usbh_driver_gp_xbox.c b/src/usbh_driver_gp_xbox.c index f52621a..92f61b5 100644 --- a/src/usbh_driver_gp_xbox.c +++ b/src/usbh_driver_gp_xbox.c @@ -30,11 +30,9 @@ enum STATES { STATE_INACTIVE, - STATE_READING_COMPLETE, + STATE_INITIAL, STATE_READING_REQUEST, - STATE_SET_CONFIGURATION_REQUEST, - STATE_SET_CONFIGURATION_EMPTY_READ, - STATE_SET_CONFIGURATION_COMPLETE + STATE_READING_COMPLETE, }; #define GP_XBOX_CORRECT_TRANSFERRED_LENGTH 20 @@ -132,7 +130,7 @@ static bool analyze_descriptor(void *drvdata, void *descriptor) } if (gp_xbox->endpoint_in_address) { - gp_xbox->state_next = STATE_SET_CONFIGURATION_REQUEST; + gp_xbox->state_next = STATE_INITIAL; return true; } } @@ -268,45 +266,6 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } break; - case STATE_SET_CONFIGURATION_EMPTY_READ: - { - LOG_PRINTF("|empty packet read|"); - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - gp_xbox->state_next = STATE_SET_CONFIGURATION_COMPLETE; - device_xfer_control_read(0, 0, event, dev); - break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - ERROR(cb_data.status); - gp_xbox->state_next = STATE_INACTIVE; - break; - } - } - break; - case STATE_SET_CONFIGURATION_COMPLETE: // Configured - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - gp_xbox->state_next = STATE_READING_REQUEST; - gp_xbox->endpoint_in_toggle = 0; - LOG_PRINTF("\ngp_xbox CONFIGURED\n"); - if (gp_xbox_config->notify_connected) { - gp_xbox_config->notify_connected(gp_xbox->device_id); - } - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - ERROR(cb_data.status); - gp_xbox->state_next = STATE_INACTIVE; - break; - } - } - break; - case STATE_INACTIVE: { LOG_PRINTF("XBOX inactive"); @@ -360,19 +319,14 @@ static void poll(void *drvdata, uint32_t time_curr_us) } break; - case STATE_SET_CONFIGURATION_REQUEST: + case STATE_INITIAL: { - struct usb_setup_data setup_data; - - setup_data.bmRequestType = USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; - setup_data.bRequest = USB_REQ_SET_CONFIGURATION; - setup_data.wValue = gp_xbox->configuration_value; - setup_data.wIndex = 0; - setup_data.wLength = 0; - - gp_xbox->state_next = STATE_SET_CONFIGURATION_EMPTY_READ; - - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + gp_xbox->state_next = STATE_READING_REQUEST; + gp_xbox->endpoint_in_toggle = 0; + LOG_PRINTF("\ngp_xbox CONFIGURED\n"); + if (gp_xbox_config->notify_connected) { + gp_xbox_config->notify_connected(gp_xbox->device_id); + } } break; diff --git a/src/usbh_driver_hid.c b/src/usbh_driver_hid.c index 21fa262..b9b95d7 100644 --- a/src/usbh_driver_hid.c +++ b/src/usbh_driver_hid.c @@ -37,8 +37,6 @@ enum STATES { STATE_READING_REQUEST, STATE_READING_COMPLETE_AND_CHECK_REPORT, STATE_SET_REPORT_EMPTY_READ, - STATE_SET_CONFIGURATION_REQUEST, - STATE_SET_CONFIGURATION_EMPTY_READ, STATE_GET_REPORT_DESCRIPTOR_READ_SETUP,// configuration is complete at this point. We write request STATE_GET_REPORT_DESCRIPTOR_READ, STATE_GET_REPORT_DESCRIPTOR_READ_COMPLETE,// after the read finishes, we parse that descriptor @@ -204,7 +202,7 @@ static bool analyze_descriptor(void *drvdata, void *descriptor) } if (hid->endpoint_in_address && hid->report0_length) { - hid->state_next = STATE_SET_CONFIGURATION_REQUEST; + hid->state_next = STATE_GET_REPORT_DESCRIPTOR_READ_SETUP; return true; } @@ -294,62 +292,6 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } break; - case STATE_SET_CONFIGURATION_EMPTY_READ: - { - LOG_PRINTF("|empty packet read|"); - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - hid->state_next = STATE_GET_REPORT_DESCRIPTOR_READ_SETUP; - device_xfer_control_read(0, 0, event, dev); - break; - - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - ERROR(cb_data.status); - hid->state_next = STATE_INACTIVE; - break; - } - } - break; - - case STATE_GET_REPORT_DESCRIPTOR_READ_SETUP: - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - { - hid->endpoint_in_toggle = 0; - // We support only the first report descriptor with index 0 - - // limit the size of the report descriptor! - if (hid->report0_length > USBH_HID_BUFFER) { - hid->report0_length = USBH_HID_BUFFER; - } - - struct usb_setup_data setup_data; - - setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_INTERFACE; - setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; - setup_data.wValue = USB_DT_REPORT << 8; - setup_data.wIndex = 0; - setup_data.wLength = hid->report0_length; - - hid->state_next = STATE_GET_REPORT_DESCRIPTOR_READ; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); - - } - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - ERROR(cb_data.status); - hid->state_next = STATE_INACTIVE; - break; - } - } - break; - case STATE_GET_REPORT_DESCRIPTOR_READ: { switch (cb_data.status) { @@ -434,18 +376,25 @@ static void poll(void *drvdata, uint32_t time_curr_us) } break; - case STATE_SET_CONFIGURATION_REQUEST: + case STATE_GET_REPORT_DESCRIPTOR_READ_SETUP: { + hid->endpoint_in_toggle = 0; + // We support only the first report descriptor with index 0 + + // limit the size of the report descriptor! + if (hid->report0_length > USBH_HID_BUFFER) { + hid->report0_length = USBH_HID_BUFFER; + } + struct usb_setup_data setup_data; - setup_data.bmRequestType = USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; - setup_data.bRequest = USB_REQ_SET_CONFIGURATION; - setup_data.wValue = hid->configuration_value; + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_INTERFACE; + setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; + setup_data.wValue = USB_DT_REPORT << 8; setup_data.wIndex = 0; - setup_data.wLength = 0; - - hid->state_next = STATE_SET_CONFIGURATION_EMPTY_READ; + setup_data.wLength = hid->report0_length; + hid->state_next = STATE_GET_REPORT_DESCRIPTOR_READ; device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); } break; diff --git a/src/usbh_driver_hub.c b/src/usbh_driver_hub.c index c185b6a..4fbe643 100644 --- a/src/usbh_driver_hub.c +++ b/src/usbh_driver_hub.c @@ -86,13 +86,6 @@ static bool analyze_descriptor(void *drvdata, void *descriptor) hub_device_t *hub = (hub_device_t *)drvdata; uint8_t desc_type = ((uint8_t *)descriptor)[1]; switch (desc_type) { - case USB_DT_CONFIGURATION: - { - struct usb_config_descriptor *cfg = (struct usb_config_descriptor*)descriptor; - hub->buffer[0] = cfg->bConfigurationValue; - } - break; - case USB_DT_ENDPOINT: { struct usb_endpoint_descriptor *ep = (struct usb_endpoint_descriptor *)descriptor; @@ -110,7 +103,6 @@ static bool analyze_descriptor(void *drvdata, void *descriptor) case USB_DT_HUB: { struct usb_hub_descriptor *desc = (struct usb_hub_descriptor *)descriptor; - //~ hub->ports_num = desc->head.bNbrPorts; if ( desc->head.bNbrPorts <= USBH_HUB_MAX_DEVICES) { hub->ports_num = desc->head.bNbrPorts; } else { @@ -231,42 +223,6 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } break; - case 3: // Get HUB Descriptor write - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - if (hub->ports_num) { - hub->index = 0; - hub->state = 6; - LOG_PRINTF("No need to get HUB DESC\n"); - event(dev, cb_data); - } else { - hub->endpoint_in_toggle = 0; - - struct usb_setup_data setup_data; - hub->desc_len = hub->device[0]->packet_size_max0; - - setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE; - setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; - setup_data.wValue = 0x29<<8; - setup_data.wIndex = 0; - setup_data.wLength = hub->desc_len; - - hub->state++; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); - LOG_PRINTF("DO Need to get HUB DESC\n"); - } - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - ERROR(cb_data.status); - break; - } - } - break; - case 4: // Get HUB Descriptor read { switch (cb_data.status) { @@ -779,19 +735,27 @@ static void poll(void *drvdata, uint32_t time_curr_us) case 1: { - LOG_PRINTF("CFGVAL: %d\n", hub->buffer[0]); - struct usb_setup_data setup_data; + if (hub->ports_num) { + hub->index = 0; + hub->state = 6; + LOG_PRINTF("No need to get HUB DESC\n"); + event(dev, (usbh_packet_callback_data_t){0, 0}); + } else { + hub->endpoint_in_toggle = 0; - setup_data.bmRequestType = USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; - setup_data.bRequest = USB_REQ_SET_CONFIGURATION; - setup_data.wValue = hub->buffer[0]; - setup_data.wIndex = 0; - setup_data.wLength = 0; + struct usb_setup_data setup_data; + hub->desc_len = hub->device[0]->packet_size_max0; - hub->state = EMPTY_PACKET_READ_STATE; - hub->state_after_empty_read = 3; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE; + setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; + setup_data.wValue = 0x29 << 8; + setup_data.wIndex = 0; + setup_data.wLength = hub->desc_len; + hub->state = 4; + device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + LOG_PRINTF("DO Need to get HUB DESC\n"); + } } break; case 100: -- cgit From 6d9ee8e9a63208e83adddfe1eeccf7461297dc1b Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Mon, 5 Sep 2016 20:16:30 +0200 Subject: add DISABLE_LOW_LEVEL ifdef in hub device driver Signed-off-by: Amir Hammad --- src/usbh_driver_hub.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/usbh_driver_hub.c b/src/usbh_driver_hub.c index 4fbe643..b1b37e5 100644 --- a/src/usbh_driver_hub.c +++ b/src/usbh_driver_hub.c @@ -638,6 +638,8 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } if ((sts & (1<<(HUB_FEATURE_PORT_LOWSPEED))) && !(sts & (1<<(HUB_FEATURE_PORT_HIGHSPEED)))) { +#define DISABLE_LOW_SPEED +#ifdef DISABLE_LOW_SPEED LOG_PRINTF("Low speed device"); // Disable Low speed device immediately @@ -655,6 +657,12 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) hub->current_port = CURRENT_PORT_NONE; device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); +#else + hub->device[port]->speed = USBH_SPEED_LOW; + LOG_PRINTF("Low speed device"); + hub->timestamp_us = hub->time_curr_us; + hub->state = 100; // schedule wait for 500ms +#endif } else if (!(sts & (1<<(HUB_FEATURE_PORT_LOWSPEED))) && !(sts & (1<<(HUB_FEATURE_PORT_HIGHSPEED)))) { hub->device[port]->speed = USBH_SPEED_FULL; -- cgit From c4e6f3b55b03b29b9f6ac269c4ce591944cb8cab Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Mon, 5 Sep 2016 21:21:02 +0200 Subject: core: add helper state machine for control read/write Signed-off-by: Amir Hammad --- include/driver/usbh_device_driver.h | 51 +++++++++++++------- src/usbh_core.c | 95 +++++++++++++++++++++++++++++++++---- 2 files changed, 122 insertions(+), 24 deletions(-) diff --git a/include/driver/usbh_device_driver.h b/include/driver/usbh_device_driver.h index c70715b..f32457b 100644 --- a/include/driver/usbh_device_driver.h +++ b/include/driver/usbh_device_driver.h @@ -26,6 +26,7 @@ #include "usbh_config.h" #include "usbh_core.h" +#include #include BEGIN_DECLS @@ -64,8 +65,6 @@ enum USBH_CONTROL_TYPE { enum USBH_ENUM_STATE { USBH_ENUM_STATE_SET_ADDRESS, USBH_ENUM_STATE_FIRST = USBH_ENUM_STATE_SET_ADDRESS, - USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ, - USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ_COMPLETE, USBH_ENUM_STATE_DEVICE_DT_READ_SETUP, USBH_ENUM_STATE_DEVICE_DT_READ, USBH_ENUM_STATE_DEVICE_DT_READ_COMPLETE, @@ -81,6 +80,38 @@ enum USBH_ENUM_STATE { USBH_ENUM_STATE_FIND_DRIVER, }; +enum USBH_CONTROL_STATE { + USBH_CONTROL_STATE_NONE, + USBH_CONTROL_STATE_SETUP, + USBH_CONTROL_STATE_DATA, + USBH_CONTROL_STATE_STATUS, +}; + +typedef struct _usbh_device usbh_device_t; + +struct _usbh_packet_callback_data { + /// status - it is used for reporting of the errors + enum USBH_PACKET_CALLBACK_STATUS status; + + /// count of bytes that has been actually transferred + uint32_t transferred_length; +}; +typedef struct _usbh_packet_callback_data usbh_packet_callback_data_t; + +typedef void (*usbh_packet_callback_t)(usbh_device_t *dev, usbh_packet_callback_data_t status); + +struct _usbh_control { + enum USBH_CONTROL_STATE state; + usbh_packet_callback_t callback; + union { + const void *out; + void *in; + } data; + uint16_t data_length; + struct usb_setup_data setup_data; +}; +typedef struct _usbh_control usbh_control_t; + /** * @brief The _usbh_device struct * @@ -98,6 +129,7 @@ struct _usbh_device { /// state used for enumeration purposes enum USBH_ENUM_STATE state; + usbh_control_t control; /// toggle bit uint8_t toggle0; @@ -119,17 +151,6 @@ struct _usbh_device { }; typedef struct _usbh_device usbh_device_t; -struct _usbh_packet_callback_data { - /// status - it is used for reporting of the errors - enum USBH_PACKET_CALLBACK_STATUS status; - - /// count of bytes that has been actually transferred - uint32_t transferred_length; -}; -typedef struct _usbh_packet_callback_data usbh_packet_callback_data_t; - -typedef void (*usbh_packet_callback_t)(usbh_device_t *dev, usbh_packet_callback_data_t status); - struct _usbh_packet { /// pointer to data union { @@ -239,9 +260,7 @@ void usbh_read(usbh_device_t *dev, usbh_packet_t *packet); void usbh_write(usbh_device_t *dev, const usbh_packet_t *packet); /* Helper functions used by device drivers */ -void device_xfer_control_read(void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev); -void device_xfer_control_write_setup(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev); -void device_xfer_control_write_data(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev); +void device_control(usbh_device_t *dev, usbh_packet_callback_t callback, const struct usb_setup_data *setup_data, void *data); END_DECLS diff --git a/src/usbh_core.c b/src/usbh_core.c index 7071281..4e0f112 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -28,6 +28,8 @@ #include #include +#include + static struct { bool enumeration_run; const usbh_low_level_driver_t * const *lld_drivers; @@ -204,11 +206,7 @@ void usbh_init(const void *low_level_drivers[], const usbh_dev_driver_t * const } -/* - * NEW ENUMERATE - * - */ -void device_xfer_control_write_setup(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev) +static void device_xfer_control_write_setup(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev) { usbh_packet_t packet; @@ -228,7 +226,7 @@ void device_xfer_control_write_setup(const void *data, uint16_t datalen, usbh_pa LOG_PRINTF("WR-setup@device...%d \n", dev->address); } -void device_xfer_control_write_data(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev) +static void device_xfer_control_write_data(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev) { usbh_packet_t packet; @@ -248,7 +246,7 @@ void device_xfer_control_write_data(const void *data, uint16_t datalen, usbh_pac LOG_PRINTF("WR-data@device...%d \n", dev->address); } -void device_xfer_control_read(void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev) +static void device_xfer_control_read(void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev) { usbh_packet_t packet; @@ -268,6 +266,85 @@ void device_xfer_control_read(void *data, uint16_t datalen, usbh_packet_callback } +static void control_state_machine(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) +{ + switch (dev->control.state) { + case USBH_CONTROL_STATE_SETUP: + if (cb_data.status != USBH_PACKET_CALLBACK_STATUS_OK) { + dev->control.state = USBH_CONTROL_STATE_NONE; + // Unable to deliver setup control packet - this is a fatal error + usbh_packet_callback_data_t ret_data; + ret_data.status = USBH_PACKET_CALLBACK_STATUS_EFATAL; + ret_data.transferred_length = 0; + dev->control.callback(dev, ret_data); + break; + } + if (dev->control.setup_data.bmRequestType & USB_REQ_TYPE_IN) { + dev->control.state = USBH_CONTROL_STATE_DATA; + device_xfer_control_read(dev->control.data.in, dev->control.data_length, control_state_machine, dev); + } else { + if (dev->control.data_length == 0) { + dev->control.state = USBH_CONTROL_STATE_STATUS; + device_xfer_control_read(0, 0, control_state_machine, dev); + } else { + dev->control.state = USBH_CONTROL_STATE_DATA; + device_xfer_control_write_data(dev->control.data.out, dev->control.data_length, control_state_machine, dev); + } + } + break; + + case USBH_CONTROL_STATE_DATA: + if (dev->control.setup_data.bmRequestType & USB_REQ_TYPE_IN) { + dev->control.state = USBH_CONTROL_STATE_NONE; + dev->control.callback(dev, cb_data); + } else { + if (cb_data.status != USBH_PACKET_CALLBACK_STATUS_OK) { + dev->control.state = USBH_CONTROL_STATE_NONE; + // Unable to deliver data control packet - this is a fatal error + usbh_packet_callback_data_t ret_data; + ret_data.status = USBH_PACKET_CALLBACK_STATUS_EFATAL; + ret_data.transferred_length = 0; + dev->control.callback(dev, ret_data); + break; + } + + if (dev->control.data_length == 0) { + // we should be in status state when the length of data is zero + LOG_PRINTF("Control logic error\n"); + dev->control.state = USBH_CONTROL_STATE_NONE; + dev->control.callback(dev, cb_data); + } else { + dev->control.state = USBH_CONTROL_STATE_STATUS; + device_xfer_control_read(0, 0, control_state_machine, dev); + } + } + break; + + case USBH_CONTROL_STATE_STATUS: + dev->control.state = USBH_CONTROL_STATE_NONE; + dev->control.callback(dev, cb_data); + break; + + default: + break; + } +} + +void device_control(usbh_device_t *dev, usbh_packet_callback_t callback, const struct usb_setup_data *setup_data, void *data) +{ + if (dev->control.state != USBH_CONTROL_STATE_NONE) { + LOG_PRINTF("ERROR: Use of control state machine while not idle\n"); + return; + } + + dev->control.state = USBH_CONTROL_STATE_SETUP; + dev->control.callback = callback; + dev->control.data.out = data; + dev->control.data_length = setup_data->wLength; + dev->control.setup_data = *setup_data; + device_xfer_control_write_setup(&dev->control.setup_data, sizeof(dev->control.setup_data), control_state_machine, dev); +} + bool usbh_enum_available(void) { @@ -675,7 +752,7 @@ void usbh_poll(uint32_t time_curr_us) { uint32_t k = 0; while (usbh_data.lld_drivers[k]) { - usbh_device_t * usbh_device = + usbh_device_t *usbh_device = ((usbh_generic_data_t *)(usbh_data.lld_drivers[k]->driver_data))->usbh_device; usbh_generic_data_t *lld_data = usbh_data.lld_drivers[k]->driver_data; @@ -689,12 +766,14 @@ void usbh_poll(uint32_t time_curr_us) usbh_device[0].lld = usbh_data.lld_drivers[k]; usbh_device[0].speed = usbh_data.lld_drivers[k]->root_speed(lld_data); usbh_device[0].address = 1; + usbh_device[0].control.state = USBH_CONTROL_STATE_NONE; device_enumeration_start(&usbh_device[0]); break; case USBH_POLL_STATUS_DEVICE_DISCONNECTED: { + usbh_device[0].control.state = USBH_CONTROL_STATE_NONE; uint32_t i; for (i = 0; i < USBH_MAX_DEVICES; i++) { device_remove(&usbh_device[i]); -- cgit From d4c74c55c3af5384bae94f27b213ddd0fcbd4c5d Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Mon, 5 Sep 2016 21:22:39 +0200 Subject: core: use new control wrapper to set device's address Signed-off-by: Amir Hammad --- src/usbh_core.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/src/usbh_core.c b/src/usbh_core.c index 4e0f112..216a149 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -400,26 +400,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ uint8_t state_start = dev->state; // Detection of hang // LOG_PRINTF("\nSTATE: %d\n", state); switch (dev->state) { - case USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ: - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - dev->state = USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ_COMPLETE; - LOG_PRINTF("Assigning address: %d\n", usbh_data.address_temporary); - device_xfer_control_read(0, 0, device_enumerate, dev); - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - device_enumeration_terminate(dev); - ERROR(cb_data.status); - break; - } - } - break; - - case USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ_COMPLETE: + case USBH_ENUM_STATE_SET_ADDRESS: switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: if (dev->address == 0) { @@ -740,8 +721,7 @@ void device_enumeration_start(usbh_device_t *dev) setup_data.wIndex = 0; setup_data.wLength = 0; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), - device_enumerate, dev); + device_control(dev, device_enumerate, &setup_data, 0); } /** -- cgit From 7c4ae8d7aa72e2e32cf456007d52ef11545b7f62 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Mon, 5 Sep 2016 21:24:15 +0200 Subject: core: use new control wrapper to read device descriptor Signed-off-by: Amir Hammad --- include/driver/usbh_device_driver.h | 1 - src/usbh_core.c | 30 +++--------------------------- 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/include/driver/usbh_device_driver.h b/include/driver/usbh_device_driver.h index f32457b..f2190ae 100644 --- a/include/driver/usbh_device_driver.h +++ b/include/driver/usbh_device_driver.h @@ -66,7 +66,6 @@ enum USBH_ENUM_STATE { USBH_ENUM_STATE_SET_ADDRESS, USBH_ENUM_STATE_FIRST = USBH_ENUM_STATE_SET_ADDRESS, USBH_ENUM_STATE_DEVICE_DT_READ_SETUP, - USBH_ENUM_STATE_DEVICE_DT_READ, USBH_ENUM_STATE_DEVICE_DT_READ_COMPLETE, USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ_SETUP, USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ, diff --git a/src/usbh_core.c b/src/usbh_core.c index 216a149..c7eca7f 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -423,38 +423,14 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ { struct usb_setup_data setup_data; - setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE; + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_DEVICE; setup_data.bRequest = USB_REQ_GET_DESCRIPTOR; setup_data.wValue = USB_DT_DEVICE << 8; setup_data.wIndex = 0; setup_data.wLength = USB_DT_DEVICE_SIZE; - dev->state = USBH_ENUM_STATE_DEVICE_DT_READ; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), - device_enumerate, dev); - } - break; - - - case USBH_ENUM_STATE_DEVICE_DT_READ: - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - dev->state = USBH_ENUM_STATE_DEVICE_DT_READ_COMPLETE; - device_xfer_control_read(&usbh_buffer[0], USB_DT_DEVICE_SIZE, - device_enumerate, dev); - break; - - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - CONTINUE_WITH(USBH_ENUM_STATE_DEVICE_DT_READ_SETUP); - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - device_enumeration_terminate(dev); - ERROR(cb_data.status); - break; - } + dev->state = USBH_ENUM_STATE_DEVICE_DT_READ_COMPLETE; + device_control(dev, device_enumerate, &setup_data, &usbh_buffer[0]); } break; -- cgit From 2c23090d49a51a59f293ae1afdf763d2cd9fbb49 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Mon, 5 Sep 2016 21:24:51 +0200 Subject: core: use new control wrapper to set configuration to device Signed-off-by: Amir Hammad --- include/driver/usbh_device_driver.h | 1 - src/usbh_core.c | 23 ++--------------------- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/include/driver/usbh_device_driver.h b/include/driver/usbh_device_driver.h index f2190ae..7e013a0 100644 --- a/include/driver/usbh_device_driver.h +++ b/include/driver/usbh_device_driver.h @@ -74,7 +74,6 @@ enum USBH_ENUM_STATE { USBH_ENUM_STATE_CONFIGURATION_DT_READ, USBH_ENUM_STATE_CONFIGURATION_DT_READ_COMPLETE, USBH_ENUM_STATE_SET_CONFIGURATION_SETUP, - USBH_ENUM_STATE_SET_CONFIGURATION_EMPTY_READ, USBH_ENUM_STATE_SET_CONFIGURATION_COMPLETE, USBH_ENUM_STATE_FIND_DRIVER, }; diff --git a/src/usbh_core.c b/src/usbh_core.c index c7eca7f..0570ac3 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -609,27 +609,8 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ setup_data.wIndex = 0; setup_data.wLength = 0; - dev->state = USBH_ENUM_STATE_SET_CONFIGURATION_EMPTY_READ; - - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), device_enumerate, dev); - } - break; - - case USBH_ENUM_STATE_SET_CONFIGURATION_EMPTY_READ: - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - dev->state = USBH_ENUM_STATE_SET_CONFIGURATION_COMPLETE; - device_xfer_control_read(0, 0, device_enumerate, dev); - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - device_enumeration_terminate(dev); - ERROR(cb_data.status); - break; - } + dev->state = USBH_ENUM_STATE_SET_CONFIGURATION_COMPLETE; + device_control(dev, device_enumerate, &setup_data, 0); } break; -- cgit From 66b801b01eecf3750ff8f03e30a658f2e7f7b9e7 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Mon, 5 Sep 2016 21:36:51 +0200 Subject: hid: use control wrapper to simplify hid report writes Signed-off-by: Amir Hammad --- src/usbh_driver_hid.c | 88 +++++---------------------------------------------- 1 file changed, 8 insertions(+), 80 deletions(-) diff --git a/src/usbh_driver_hid.c b/src/usbh_driver_hid.c index b9b95d7..54956b2 100644 --- a/src/usbh_driver_hid.c +++ b/src/usbh_driver_hid.c @@ -38,7 +38,6 @@ enum STATES { STATE_READING_COMPLETE_AND_CHECK_REPORT, STATE_SET_REPORT_EMPTY_READ, STATE_GET_REPORT_DESCRIPTOR_READ_SETUP,// configuration is complete at this point. We write request - STATE_GET_REPORT_DESCRIPTOR_READ, STATE_GET_REPORT_DESCRIPTOR_READ_COMPLETE,// after the read finishes, we parse that descriptor STATE_SET_IDLE, STATE_SET_IDLE_COMPLETE, @@ -47,9 +46,7 @@ enum STATES { enum REPORT_STATE { REPORT_STATE_NULL, REPORT_STATE_READY, - REPORT_STATE_WRITE_PENDING, - REPORT_STATE_WRITE_PENDING_DATA, - REPORT_STATE_EMPTY_READ, + REPORT_STATE_PENDING, }; struct _hid_device { @@ -211,60 +208,10 @@ static bool analyze_descriptor(void *drvdata, void *descriptor) static void report_event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) { - hid_device_t *hid = (hid_device_t *)dev->drvdata; - switch (hid->report_state) { - case REPORT_STATE_WRITE_PENDING: - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - hid->report_state = REPORT_STATE_WRITE_PENDING_DATA; - - device_xfer_control_write_data(hid->report_data, hid->report_data_length, report_event, dev); - break; - - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - ERROR(cb_data.status); - hid->state_next = STATE_INACTIVE; - break; - } - break; - - case REPORT_STATE_WRITE_PENDING_DATA: - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - hid->report_state = REPORT_STATE_EMPTY_READ; - device_xfer_control_read(0, 0, report_event, dev); - LOG_PRINTF("reading empty\n"); - break; - - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - ERROR(cb_data.status); - hid->state_next = STATE_INACTIVE; - break; - } - break; - - - case REPORT_STATE_EMPTY_READ: - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - hid->report_state = REPORT_STATE_READY; - break; + (void)cb_data;// UNUSED - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - ERROR(cb_data.status); - hid->state_next = STATE_INACTIVE; - break; - } - break; - default: - break; - } + hid_device_t *hid = (hid_device_t *)dev->drvdata; + hid->report_state = REPORT_STATE_READY; } static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) @@ -292,25 +239,6 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } break; - case STATE_GET_REPORT_DESCRIPTOR_READ: - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - hid->state_next = STATE_GET_REPORT_DESCRIPTOR_READ_COMPLETE; - device_xfer_control_read(hid->buffer, hid->report0_length, event, dev); - break; - - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - ERROR(cb_data.status); - hid->state_next = STATE_INACTIVE; - break; - } - } - break; - - case STATE_GET_REPORT_DESCRIPTOR_READ_COMPLETE: // read complete, SET_IDLE to 0 { switch (cb_data.status) { @@ -394,8 +322,8 @@ static void poll(void *drvdata, uint32_t time_curr_us) setup_data.wIndex = 0; setup_data.wLength = hid->report0_length; - hid->state_next = STATE_GET_REPORT_DESCRIPTOR_READ; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + hid->state_next = STATE_GET_REPORT_DESCRIPTOR_READ_COMPLETE; + device_control(dev, event, &setup_data, hid->buffer); } break; @@ -440,8 +368,8 @@ bool hid_set_report(uint8_t device_id, uint8_t val) hid->report_data[0] = val; - hid->report_state = REPORT_STATE_WRITE_PENDING; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), report_event, hid->usbh_device); + hid->report_state = REPORT_STATE_PENDING; + device_control(hid->usbh_device, report_event, &setup_data, &hid->report_data); return true; } -- cgit From fe54644237156b7b19ca8a9cfd699c0f4e6a0c9a Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Tue, 6 Sep 2016 09:53:20 +0200 Subject: HUB: make use of control wrappers + use enums Until now, hardcoded numbers were used as states. Signed-off-by: Amir Hammad --- src/usbh_driver_hub.c | 285 +++++++++++------------------------------- src/usbh_driver_hub_private.h | 17 ++- 2 files changed, 84 insertions(+), 218 deletions(-) diff --git a/src/usbh_driver_hub.c b/src/usbh_driver_hub.c index b1b37e5..87f8578 100644 --- a/src/usbh_driver_hub.c +++ b/src/usbh_driver_hub.c @@ -27,7 +27,6 @@ #include - static hub_device_t hub_device[USBH_MAX_HUBS]; static bool initialized = false; @@ -41,7 +40,7 @@ void hub_driver_init(void) for (i = 0; i < USBH_MAX_HUBS; i++) { hub_device[i].device[0] = 0; hub_device[i].ports_num = 0; - hub_device[i].current_port = -1; + hub_device[i].current_port = CURRENT_PORT_NONE; } } @@ -60,15 +59,14 @@ static void *init(void *usbh_dev) break; } } - LOG_PRINTF("%{%d}",i); - LOG_FLUSH(); + LOG_PRINTF("{%d}",i); if (i == USBH_MAX_HUBS) { - LOG_PRINTF("ERRRRRRR"); + LOG_PRINTF("Unable to initialize hub driver"); return 0; } drvdata = &hub_device[i]; - drvdata->state = 0; + drvdata->state = EVENT_STATE_NONE; drvdata->ports_num = 0; drvdata->device[0] = (usbh_device_t *)usbh_dev; drvdata->busy = 0; @@ -119,7 +117,7 @@ static bool analyze_descriptor(void *drvdata, void *descriptor) } if (hub->endpoint_in_address) { - hub->state = 1; + hub->state = EVENT_STATE_INITIAL; LOG_PRINTF("end enum"); return true; } @@ -133,7 +131,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) LOG_PRINTF("\nHUB->STATE = %d\n", hub->state); switch (hub->state) { - case 26: + case EVENT_STATE_POLL: switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: { @@ -149,7 +147,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) // Driver error... port not found if (!psc) { // Continue reading status change endpoint - hub->state = 25; + hub->state = EVENT_STATE_POLL_REQ; break; } @@ -164,7 +162,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) if (hub->current_port >= 1) { if (hub->current_port != port) { LOG_PRINTF("X"); - hub->state = 25; + hub->state = EVENT_STATE_POLL_REQ; break; } } @@ -180,67 +178,30 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) setup_data.wValue = 0; setup_data.wIndex = port; setup_data.wLength = 4; - hub->state = 31; + hub->state = EVENT_STATE_GET_STATUS_COMPLETE; hub->current_port = port; LOG_PRINTF("\n\nPORT FOUND: %d\n", port); - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + device_control(dev, event, &setup_data, &hub->hub_and_port_status[port]); } break; case USBH_PACKET_CALLBACK_STATUS_EFATAL: case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: ERROR(cb_data.status); - hub->state = 0; + hub->state = EVENT_STATE_NONE; break; case USBH_PACKET_CALLBACK_STATUS_EAGAIN: // In case of EAGAIN error, retry read on status endpoint - hub->state = 25; + hub->state = EVENT_STATE_POLL_REQ; LOG_PRINTF("HUB: Retrying...\n"); break; } break; - case EMPTY_PACKET_READ_STATE: - { - LOG_PRINTF("|empty packet read|"); - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - device_xfer_control_read(0, 0, event, dev); - hub->state = hub->state_after_empty_read; - hub->state_after_empty_read = 0; - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - hub->state = hub->state_after_empty_read; - event(dev, cb_data); - break; - } - } - break; - - case 4: // Get HUB Descriptor read - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - hub->state++; - device_xfer_control_read(hub->buffer, hub->desc_len, event, dev); // "error dynamic size" - bad comment, investigate - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - ERROR(cb_data.status); - break; - } - } - break; - - case 5:// Hub descriptor found + case EVENT_STATE_READ_HUB_DESCRIPTOR_COMPLETE:// Hub descriptor found { switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: @@ -259,13 +220,13 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) setup_data.wIndex = 0; setup_data.wLength = hub->desc_len; - hub->state = 4; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + hub->state = EVENT_STATE_READ_HUB_DESCRIPTOR_COMPLETE; + device_control(dev, event, &setup_data, hub->buffer); break; } else if (hub_descriptor->head.bDescLength == hub->desc_len) { hub->ports_num = hub_descriptor->head.bNbrPorts; - hub->state++; + hub->state = EVENT_STATE_ENABLE_PORTS; hub->index = 0; cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK; event(dev, cb_data); @@ -290,7 +251,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) LOG_PRINTF("INCREASE NUMBER OF ENABLED PORTS\n"); hub->ports_num = USBH_HUB_MAX_DEVICES; } - hub->state++; + hub->state = EVENT_STATE_ENABLE_PORTS; hub->index = 0; cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK; @@ -308,7 +269,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } break; - case 6:// enable ports + case EVENT_STATE_ENABLE_PORTS:// enable ports { switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: @@ -323,37 +284,15 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) setup_data.wIndex = hub->index; setup_data.wLength = 0; - hub->state_after_empty_read = hub->state; - hub->state = EMPTY_PACKET_READ_STATE; - - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + device_control(dev, event, &setup_data, 0); } else { - hub->state++; // TODO: // Delay Based on hub descriptor field bPwr2PwrGood // delay_ms_busy_loop(200); LOG_PRINTF("\nHUB CONFIGURED & PORTS POWERED\n"); - cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK; - event(dev, cb_data); - } - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - ERROR(cb_data.status); - break; - } - } - break; - - case 7: - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - { + // get device status struct usb_setup_data setup_data; setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE; @@ -362,8 +301,9 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) setup_data.wIndex = 0; setup_data.wLength = 4; - hub->state++; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + hub->state = EVENT_STATE_GET_PORT_STATUS; + hub->index = 0; + device_control(dev, event, &setup_data, hub->buffer); } break; @@ -373,85 +313,32 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) ERROR(cb_data.status); break; } - - } - break; - case 8: - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - device_xfer_control_read(hub->buffer, 4, event, dev); - hub->index = 0; - hub->state++; - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - ERROR(cb_data.status); - break; - } } break; - case 9: + case EVENT_STATE_GET_PORT_STATUS: { switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: { - struct usb_setup_data setup_data; - - setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT; - setup_data.bRequest = USB_REQ_GET_STATUS; - setup_data.wValue = 0; - setup_data.wIndex = ++hub->index; - setup_data.wLength = 4; + if (hub->index < hub->ports_num) { + //TODO: process data contained in hub->buffer - hub->state++; - - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); - } - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - ERROR(cb_data.status); - break; - } - } - break; + struct usb_setup_data setup_data; - case 10: - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - device_xfer_control_read(hub->buffer, 4, event, dev); - hub->state++; - break; + setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT; + setup_data.bRequest = USB_REQ_GET_STATUS; + setup_data.wValue = 0; + setup_data.wIndex = ++hub->index; + setup_data.wLength = 4; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - ERROR(cb_data.status); - break; - } - } - break; + hub->state = EVENT_STATE_GET_PORT_STATUS; + device_control(dev, event, &setup_data, hub->buffer); + } else { + hub->busy = 0; + hub->state = EVENT_STATE_POLL_REQ; + } - case 11: - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - if (hub->index < hub->ports_num) { - hub->state = 9; - // process data contained in hub->buffer - // TODO: - cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK; - event(dev, cb_data); - } else { - hub->busy = 0; - hub->state = 25; } break; @@ -464,35 +351,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } break; - case 31: // Read port status - { - switch (cb_data.status) { - case USBH_PACKET_CALLBACK_STATUS_OK: - { - int8_t port = hub->current_port; - hub->state++; - - // TODO: rework to endianess aware, - // (maybe whole library is affected by this) - // Detail: - // Isn't universal. Here is endianess ok, - // but on another architecture may be incorrect - device_xfer_control_read(&hub->hub_and_port_status[port], 4, event, dev); - } - break; - - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - ERROR(cb_data.status); - // continue - hub->state = 25; - break; - } - - } - break; - case 32: + case EVENT_STATE_GET_STATUS_COMPLETE: { switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: @@ -512,7 +371,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) if (!hub->device[port]) { if (!usbh_enum_available() || hub->busy) { LOG_PRINTF("\n\t\t\tCannot enumerate %d %d\n", !usbh_enum_available(), hub->busy); - hub->state = 25; + hub->state = EVENT_STATE_POLL_REQ; break; } } @@ -526,10 +385,8 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) setup_data.wIndex = port; setup_data.wLength = 0; - hub->state_after_empty_read = 33; - hub->state = EMPTY_PACKET_READ_STATE; - - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + hub->state = EVENT_STATE_PORT_RESET_REQ; + device_control(dev, event, &setup_data, 0); } else if(stc & (1<state_after_empty_read = 35; - hub->state = EMPTY_PACKET_READ_STATE; + hub->state = EVENT_STATE_PORT_RESET_COMPLETE; LOG_PRINTF("RESET"); - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + device_control(dev, event, &setup_data, 0); } else { LOG_PRINTF("another STC %d\n", stc); } } else { - hub->state = 25; + hub->state = EVENT_STATE_POLL_REQ; LOG_PRINTF("HUB status change\n"); } } @@ -562,12 +418,12 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: ERROR(cb_data.status); // continue - hub->state = 25; + hub->state = EVENT_STATE_POLL_REQ; break; } } break; - case 33: + case EVENT_STATE_PORT_RESET_REQ: { switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: @@ -584,13 +440,12 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) setup_data.wIndex = port; setup_data.wLength = 0; - hub->state_after_empty_read = 11; - hub->state = EMPTY_PACKET_READ_STATE; + hub->state = EVENT_STATE_GET_PORT_STATUS; LOG_PRINTF("CONN"); hub->busy = 1; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + device_control(dev, event, &setup_data, 0); } } else { LOG_PRINTF("\t\t\t\tDISCONNECT EVENT\n"); @@ -603,7 +458,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) hub->device[port]->drvdata = 0; hub->device[port] = 0; hub->current_port = CURRENT_PORT_NONE; - hub->state = 25; + hub->state = EVENT_STATE_POLL_REQ; hub->busy = 0; } } @@ -614,12 +469,12 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: ERROR(cb_data.status); // continue - hub->state = 25; + hub->state = EVENT_STATE_POLL_REQ; break; } } break; - case 35: // RESET COMPLETE, start enumeration + case EVENT_STATE_PORT_RESET_COMPLETE: // RESET COMPLETE, start enumeration { switch (cb_data.status) { case USBH_PACKET_CALLBACK_STATUS_OK: @@ -652,29 +507,29 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) setup_data.wLength = 0; // After write process another devices, poll for events - hub->state_after_empty_read = 11;//Expecting all ports are powered (constant/non-changeable after init) - hub->state = EMPTY_PACKET_READ_STATE; + //Expecting all ports are powered (constant/non-changeable after init) + hub->state = EVENT_STATE_GET_PORT_STATUS; hub->current_port = CURRENT_PORT_NONE; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + device_control(dev, event, &setup_data, 0); #else hub->device[port]->speed = USBH_SPEED_LOW; LOG_PRINTF("Low speed device"); hub->timestamp_us = hub->time_curr_us; - hub->state = 100; // schedule wait for 500ms + hub->state = EVENT_STATE_SLEEP_500_MS; // schedule wait for 500ms #endif } else if (!(sts & (1<<(HUB_FEATURE_PORT_LOWSPEED))) && !(sts & (1<<(HUB_FEATURE_PORT_HIGHSPEED)))) { hub->device[port]->speed = USBH_SPEED_FULL; LOG_PRINTF("Full speed device"); hub->timestamp_us = hub->time_curr_us; - hub->state = 100; // schedule wait for 500ms + hub->state = EVENT_STATE_SLEEP_500_MS; // schedule wait for 500ms } } else { LOG_PRINTF("%s:%d Do not know what to do, when device is disabled after reset\n", __FILE__, __LINE__); - hub->state = 25; + hub->state = EVENT_STATE_POLL_REQ; return; } } @@ -685,7 +540,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: ERROR(cb_data.status); // continue - hub->state = 25; + hub->state = EVENT_STATE_POLL_REQ; break; } } @@ -712,7 +567,7 @@ static void read_ep1(void *drvdata) packet.callback_arg = hub->device[0]; packet.toggle = &hub->endpoint_in_toggle; - hub->state = 26; + hub->state = EVENT_STATE_POLL; usbh_read(hub->device[0], &packet); LOG_PRINTF("@hub %d/EP1 | \n", hub->device[0]->address); @@ -731,7 +586,7 @@ static void poll(void *drvdata, uint32_t time_curr_us) hub->time_curr_us = time_curr_us; switch (hub->state) { - case 25: + case EVENT_STATE_POLL_REQ: { if (usbh_enum_available()) { read_ep1(hub); @@ -741,11 +596,11 @@ static void poll(void *drvdata, uint32_t time_curr_us) } break; - case 1: + case EVENT_STATE_INITIAL: { if (hub->ports_num) { hub->index = 0; - hub->state = 6; + hub->state = EVENT_STATE_ENABLE_PORTS; LOG_PRINTF("No need to get HUB DESC\n"); event(dev, (usbh_packet_callback_data_t){0, 0}); } else { @@ -760,17 +615,17 @@ static void poll(void *drvdata, uint32_t time_curr_us) setup_data.wIndex = 0; setup_data.wLength = hub->desc_len; - hub->state = 4; - device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev); + hub->state = EVENT_STATE_READ_HUB_DESCRIPTOR_COMPLETE; + device_control(dev, event, &setup_data, hub->buffer); LOG_PRINTF("DO Need to get HUB DESC\n"); } } break; - case 100: + case EVENT_STATE_SLEEP_500_MS: if (hub->time_curr_us - hub->timestamp_us > 500000) { int8_t port = hub->current_port; - LOG_PRINTF("PORT: %d", port); - LOG_PRINTF("\nNEW device at address: %d\n", hub->device[port]->address); + LOG_PRINTF("PORT: %d\n", port); + LOG_PRINTF("NEW device at address: %d\n", hub->device[port]->address); hub->device[port]->lld = hub->device[0]->lld; device_enumeration_start(hub->device[port]); @@ -784,7 +639,7 @@ static void poll(void *drvdata, uint32_t time_curr_us) // Only one device on bus can have address==0 hub->busy = 0; - hub->state = 25; + hub->state = EVENT_STATE_POLL_REQ; } break; default: @@ -807,7 +662,7 @@ static void remove(void *drvdata) hub_device_t *hub = (hub_device_t *)drvdata; uint8_t i; - hub->state = 0; + hub->state = EVENT_STATE_NONE; hub->endpoint_in_address = 0; hub->busy = 0; for (i = 0; i < USBH_HUB_MAX_DEVICES + 1; i++) { diff --git a/src/usbh_driver_hub_private.h b/src/usbh_driver_hub_private.h index df38243..8c9bc44 100644 --- a/src/usbh_driver_hub_private.h +++ b/src/usbh_driver_hub_private.h @@ -61,7 +61,19 @@ #define CURRENT_PORT_NONE -1 -#define EMPTY_PACKET_READ_STATE 255 +enum EVENT_STATE { + EVENT_STATE_NONE, + EVENT_STATE_INITIAL, + EVENT_STATE_POLL_REQ, + EVENT_STATE_POLL, + EVENT_STATE_READ_HUB_DESCRIPTOR_COMPLETE, + EVENT_STATE_ENABLE_PORTS, + EVENT_STATE_GET_PORT_STATUS, + EVENT_STATE_PORT_RESET_REQ, + EVENT_STATE_PORT_RESET_COMPLETE, + EVENT_STATE_SLEEP_500_MS, + EVENT_STATE_GET_STATUS_COMPLETE, +}; struct _hub_device { usbh_device_t *device[USBH_HUB_MAX_DEVICES + 1]; @@ -69,8 +81,7 @@ struct _hub_device { uint16_t endpoint_in_maxpacketsize; uint8_t endpoint_in_address; uint8_t endpoint_in_toggle; - uint8_t state; - uint8_t state_after_empty_read; + enum EVENT_STATE state; uint8_t desc_len; uint16_t ports_num; -- cgit From c9869466ddfab7e7f6258397d1b8863c27e37149 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Tue, 6 Sep 2016 08:39:53 +0200 Subject: remove detection of hang Signed-off-by: Amir Hammad --- src/usbh_core.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/usbh_core.c b/src/usbh_core.c index 0570ac3..e673a59 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -397,7 +397,6 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ const usbh_low_level_driver_t *lld = dev->lld; usbh_generic_data_t *lld_data = lld->driver_data; uint8_t *usbh_buffer = lld_data->usbh_buffer; - uint8_t state_start = dev->state; // Detection of hang // LOG_PRINTF("\nSTATE: %d\n", state); switch (dev->state) { case USBH_ENUM_STATE_SET_ADDRESS: @@ -645,10 +644,6 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ LOG_PRINTF("Error: Unknown state "__FILE__"/%d\n", __LINE__); break; } - - if (state_start == dev->state) { - LOG_PRINTF("\n !HANG %d\n", state_start); - } } void device_enumeration_start(usbh_device_t *dev) -- cgit From b895498df9be02eba1c285c5cdc58eb088bb86fc Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Tue, 6 Sep 2016 08:40:32 +0200 Subject: hub: use common code to remove device Signed-off-by: Amir Hammad --- include/driver/usbh_device_driver.h | 1 + src/usbh_core.c | 2 +- src/usbh_driver_hub.c | 7 +------ 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/include/driver/usbh_device_driver.h b/include/driver/usbh_device_driver.h index 7e013a0..03bbd3a 100644 --- a/include/driver/usbh_device_driver.h +++ b/include/driver/usbh_device_driver.h @@ -259,6 +259,7 @@ void usbh_write(usbh_device_t *dev, const usbh_packet_t *packet); /* Helper functions used by device drivers */ void device_control(usbh_device_t *dev, usbh_packet_callback_t callback, const struct usb_setup_data *setup_data, void *data); +void device_remove(usbh_device_t *dev); END_DECLS diff --git a/src/usbh_core.c b/src/usbh_core.c index e673a59..fd1dca5 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -52,7 +52,7 @@ static bool enumeration(void) return usbh_data.enumeration_run; } -static void device_remove(usbh_device_t *dev) +void device_remove(usbh_device_t *dev) { if (dev->drv && dev->drvdata) { dev->drv->remove(dev->drvdata); diff --git a/src/usbh_driver_hub.c b/src/usbh_driver_hub.c index 87f8578..7dc99ea 100644 --- a/src/usbh_driver_hub.c +++ b/src/usbh_driver_hub.c @@ -449,13 +449,8 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } } else { LOG_PRINTF("\t\t\t\tDISCONNECT EVENT\n"); - if (hub->device[port]->drv && hub->device[port]->drvdata) { - hub->device[port]->drv->remove(hub->device[port]->drvdata); - } - hub->device[port]->address = -1; + device_remove(hub->device[port]); - hub->device[port]->drv = 0; - hub->device[port]->drvdata = 0; hub->device[port] = 0; hub->current_port = CURRENT_PORT_NONE; hub->state = EVENT_STATE_POLL_REQ; -- cgit From 63446f99fc03cd21f744f75228175d99c5ef672b Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Wed, 7 Sep 2016 08:56:51 +0200 Subject: lld: don't enable channel on write nack, return EAGAIN instead Signed-off-by: Amir Hammad --- src/usbh_lld_stm32f4.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/usbh_lld_stm32f4.c b/src/usbh_lld_stm32f4.c index 08000a2..aff12c5 100644 --- a/src/usbh_lld_stm32f4.c +++ b/src/usbh_lld_stm32f4.c @@ -504,9 +504,17 @@ static enum USBH_POLL_STATUS poll_run(usbh_lld_stm32f4_driver_data_t *dev) if (hcint & OTG_HCINT_NAK) { REBASE_CH(OTG_HCINT, channel) = OTG_HCINT_NAK; - LOG_PRINTF("NAK"); + LOG_PRINTF("NAK\n"); - REBASE_CH(OTG_HCCHAR, channel) |= OTG_HCCHAR_CHENA; + free_channel(dev, channel); + + usbh_packet_callback_data_t cb_data; + cb_data.status = USBH_PACKET_CALLBACK_STATUS_EAGAIN; + cb_data.transferred_length = channels[channel].data_index; + + channels[channel].packet.callback( + channels[channel].packet.callback_arg, + cb_data); } @@ -540,6 +548,8 @@ static enum USBH_POLL_STATUS poll_run(usbh_lld_stm32f4_driver_data_t *dev) REBASE_CH(OTG_HCINT, channel) = OTG_HCINT_FRMOR; LOG_PRINTF("FRMOR"); + free_channel(dev, channel); + usbh_packet_callback_data_t cb_data; cb_data.status = USBH_PACKET_CALLBACK_STATUS_EFATAL; cb_data.transferred_length = 0; @@ -547,7 +557,6 @@ static enum USBH_POLL_STATUS poll_run(usbh_lld_stm32f4_driver_data_t *dev) channels[channel].packet.callback( channels[channel].packet.callback_arg, cb_data); - free_channel(dev, channel); } if (hcint & OTG_HCINT_TXERR) { -- cgit From bc8dd60b2ebc311427c751937df464ba58b12c42 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Thu, 8 Sep 2016 06:30:37 +0200 Subject: midi: rename prefix of static functions Signed-off-by: Amir Hammad --- src/usbh_driver_ac_midi.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/usbh_driver_ac_midi.c b/src/usbh_driver_ac_midi.c index 87da03b..0a747f7 100644 --- a/src/usbh_driver_ac_midi.c +++ b/src/usbh_driver_ac_midi.c @@ -29,10 +29,10 @@ #include -static void *midi_init(void *usbh_dev); -static bool midi_analyze_descriptor(void *drvdata, void *descriptor); -static void midi_poll(void *drvdata, uint32_t tflp); -static void midi_remove(void *drvdata); +static void *init(void *usbh_dev); +static bool analyze_descriptor(void *drvdata, void *descriptor); +static void poll(void *drvdata, uint32_t tflp); +static void remove(void *drvdata); static midi_device_t midi_device[USBH_AC_MIDI_MAX_DEVICES]; static const midi_config_t *midi_config = 0; @@ -50,10 +50,10 @@ static const usbh_dev_driver_info_t usbh_midi_driver_info = { }; const usbh_dev_driver_t usbh_midi_driver = { - .init = midi_init, - .analyze_descriptor = midi_analyze_descriptor, - .poll = midi_poll, - .remove = midi_remove, + .init = init, + .analyze_descriptor = analyze_descriptor, + .poll = poll, + .remove = remove, .info = &usbh_midi_driver_info }; @@ -70,7 +70,7 @@ void midi_driver_init(const midi_config_t *config) * * */ -static void *midi_init(void *usbh_dev) +static void *init(void *usbh_dev) { if (!midi_config || !initialized) { LOG_PRINTF("\n%s/%d : driver not initialized\n", __FILE__, __LINE__); @@ -101,7 +101,7 @@ static void *midi_init(void *usbh_dev) /** * Returns true if all needed data are parsed */ -static bool midi_analyze_descriptor(void *drvdata, void *descriptor) +static bool analyze_descriptor(void *drvdata, void *descriptor) { midi_device_t *midi = drvdata; uint8_t desc_type = ((uint8_t *)descriptor)[1]; @@ -237,7 +237,7 @@ static void read_midi_in(void *drvdata, const uint8_t nextstate) * * @param t_us global time us */ -static void midi_poll(void *drvdata, uint32_t t_us) +static void poll(void *drvdata, uint32_t t_us) { (void)drvdata; @@ -353,7 +353,7 @@ void usbh_midi_write(uint8_t device_id, const void *data, uint32_t length, midi_ usbh_write(dev, &midi->write_packet); } -static void midi_remove(void *drvdata) +static void remove(void *drvdata) { midi_device_t *midi = drvdata; -- cgit From 1d1b697bc6b13b5db1594c3dafe5452b6b2c1668 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Thu, 8 Sep 2016 06:27:35 +0200 Subject: use NULL instead of 0 for assigning null pointer Signed-off-by: Amir Hammad --- src/demo.c | 4 ++-- src/usbh_core.c | 15 +++++++-------- src/usbh_driver_ac_midi.c | 8 +++++--- src/usbh_driver_hid.c | 3 ++- src/usbh_driver_hub.c | 3 ++- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/demo.c b/src/demo.c index 995e68c..44a94c0 100644 --- a/src/demo.c +++ b/src/demo.c @@ -119,7 +119,7 @@ static const usbh_dev_driver_t *device_drivers[] = { &usbh_hid_driver, &usbh_gp_xbox_driver, &usbh_midi_driver, - 0 + NULL }; static void gp_xbox_update(uint8_t device_id, gp_xbox_packet_t packet) @@ -234,7 +234,7 @@ int main(void) #ifdef USE_STM32F4_USBH_DRIVER_HS usbh_lld_stm32f4_driver_hs, // Make sure USE_STM32F4_USBH_DRIVER_HS is defined in usbh_config.h #endif - 0 + NULL }; usbh_init(lld_drivers, device_drivers); gpio_clear(GPIOD, GPIO13); diff --git a/src/usbh_core.c b/src/usbh_core.c index fd1dca5..5448d6c 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -35,7 +35,7 @@ static struct { const usbh_low_level_driver_t * const *lld_drivers; const usbh_dev_driver_t * const *dev_drivers; int8_t address_temporary; -} usbh_data = {0}; +} usbh_data = {}; static void set_enumeration(void) { @@ -58,8 +58,8 @@ void device_remove(usbh_device_t *dev) dev->drv->remove(dev->drvdata); } dev->address = -1; - dev->drv = 0; - dev->drvdata = 0; + dev->drv = NULL; + dev->drvdata = NULL; } /** @@ -105,11 +105,10 @@ static bool find_driver(usbh_device_t *dev, const usbh_dev_driver_info_t * devic static void device_register(void *descriptors, uint16_t descriptors_len, usbh_device_t *dev) { uint32_t i = 0; - dev->drv = 0; uint8_t *buf = (uint8_t *)descriptors; - dev->drv = 0; - dev->drvdata = 0; + dev->drv = NULL; + dev->drvdata = NULL; uint8_t desc_len = buf[i]; uint8_t desc_type = buf[i + 1]; @@ -285,7 +284,7 @@ static void control_state_machine(usbh_device_t *dev, usbh_packet_callback_data_ } else { if (dev->control.data_length == 0) { dev->control.state = USBH_CONTROL_STATE_STATUS; - device_xfer_control_read(0, 0, control_state_machine, dev); + device_xfer_control_read(NULL, 0, control_state_machine, dev); } else { dev->control.state = USBH_CONTROL_STATE_DATA; device_xfer_control_write_data(dev->control.data.out, dev->control.data_length, control_state_machine, dev); @@ -315,7 +314,7 @@ static void control_state_machine(usbh_device_t *dev, usbh_packet_callback_data_ dev->control.callback(dev, cb_data); } else { dev->control.state = USBH_CONTROL_STATE_STATUS; - device_xfer_control_read(0, 0, control_state_machine, dev); + device_xfer_control_read(NULL, 0, control_state_machine, dev); } } break; diff --git a/src/usbh_driver_ac_midi.c b/src/usbh_driver_ac_midi.c index 0a747f7..9d139d5 100644 --- a/src/usbh_driver_ac_midi.c +++ b/src/usbh_driver_ac_midi.c @@ -24,6 +24,8 @@ #include "usbh_driver_ac_midi_private.h" #include "usart_helpers.h" +#include + #include #include #include @@ -35,7 +37,7 @@ static void poll(void *drvdata, uint32_t tflp); static void remove(void *drvdata); static midi_device_t midi_device[USBH_AC_MIDI_MAX_DEVICES]; -static const midi_config_t *midi_config = 0; +static const midi_config_t *midi_config = NULL; static bool initialized = false; static const usbh_dev_driver_info_t usbh_midi_driver_info = { @@ -77,7 +79,7 @@ static void *init(void *usbh_dev) return 0; } uint32_t i; - midi_device_t *drvdata = 0; + midi_device_t *drvdata = NULL; // find free data space for midi device for (i = 0; i < USBH_AC_MIDI_MAX_DEVICES; i++) { @@ -89,7 +91,7 @@ static void *init(void *usbh_dev) drvdata->endpoint_in_toggle = 0; drvdata->endpoint_out_toggle = 0; drvdata->usbh_device = usbh_dev; - drvdata->write_callback_user = 0; + drvdata->write_callback_user = NULL; drvdata->sending = false; break; } diff --git a/src/usbh_driver_hid.c b/src/usbh_driver_hid.c index 54956b2..0e90ab0 100644 --- a/src/usbh_driver_hid.c +++ b/src/usbh_driver_hid.c @@ -28,6 +28,7 @@ #include #include #include +#include #define USB_HID_SET_REPORT 0x09 #define USB_HID_SET_IDLE 0x0A @@ -100,7 +101,7 @@ static void *init(void *usbh_dev) } uint32_t i; - hid_device_t *drvdata = 0; + hid_device_t *drvdata = NULL; // find free data space for HID device for (i = 0; i < USBH_HID_MAX_DEVICES; i++) { diff --git a/src/usbh_driver_hub.c b/src/usbh_driver_hub.c index 7dc99ea..2127158 100644 --- a/src/usbh_driver_hub.c +++ b/src/usbh_driver_hub.c @@ -25,6 +25,7 @@ #include "usart_helpers.h" #include "usbh_config.h" +#include #include static hub_device_t hub_device[USBH_MAX_HUBS]; @@ -52,7 +53,7 @@ static void *init(void *usbh_dev) } uint32_t i; - hub_device_t *drvdata = 0; + hub_device_t *drvdata = NULL; // find free data space for hub device for (i = 0; i < USBH_MAX_HUBS; i++) { if (hub_device[i].device[0] == 0) { -- cgit From e635674ab0463b8af1db85fa7141b9810f7a4488 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Thu, 8 Sep 2016 08:16:31 +0200 Subject: Doc: set HAVE_DOT property Signed-off-by: Amir Hammad --- Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doxyfile b/Doxyfile index 4efb27b..99f8f1f 100644 --- a/Doxyfile +++ b/Doxyfile @@ -2133,7 +2133,7 @@ HIDE_UNDOC_RELATIONS = YES # set to NO # The default value is: NO. -HAVE_DOT = NO +HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed # to run in parallel. When set to 0 doxygen will base this on the number of -- cgit From decb2d817d806e8ed6e77cf215e4adfef4767a50 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Fri, 9 Sep 2016 18:25:28 +0200 Subject: use forward declaration for usbh_dev_driver_t Signed-off-by: Amir Hammad --- include/driver/usbh_device_driver.h | 64 +++++++++++++++++++++++++++++++++++++ include/usbh_core.h | 58 --------------------------------- include/usbh_driver_gp_xbox.h | 1 + include/usbh_driver_hid.h | 1 + include/usbh_driver_hub.h | 1 + src/usbh_driver_ac_midi.c | 46 ++++++++++++-------------- src/usbh_driver_gp_xbox.c | 4 +-- src/usbh_driver_hid.c | 4 +-- src/usbh_driver_hub.c | 4 +-- 9 files changed, 93 insertions(+), 90 deletions(-) diff --git a/include/driver/usbh_device_driver.h b/include/driver/usbh_device_driver.h index 03bbd3a..20ece5d 100644 --- a/include/driver/usbh_device_driver.h +++ b/include/driver/usbh_device_driver.h @@ -110,6 +110,10 @@ struct _usbh_control { }; typedef struct _usbh_control usbh_control_t; + +//forward declare usbh_dev_driver_t +typedef struct _usbh_dev_driver usbh_dev_driver_t; + /** * @brief The _usbh_device struct * @@ -243,6 +247,66 @@ struct _usbh_generic_data { typedef struct _usbh_generic_data usbh_generic_data_t; +/// set to -1 for unused items ("don't care" functionality) @see find_driver() +struct _usbh_dev_driver_info { + int32_t deviceClass; + int32_t deviceSubClass; + int32_t deviceProtocol; + int32_t idVendor; + int32_t idProduct; + int32_t ifaceClass; + int32_t ifaceSubClass; + int32_t ifaceProtocol; +}; +typedef struct _usbh_dev_driver_info usbh_dev_driver_info_t; + +struct _usbh_dev_driver { + /** + * @brief init is initialization routine of the device driver + * + * This function is called during the initialization of the device driver + */ + void *(*init)(usbh_device_t *usbh_dev); + + /** + * @brief analyze descriptor + * @param[in/out] drvdata is the device driver's private data + * @param[in] descriptor is the pointer to the descriptor that should + * be parsed in order to prepare driver to be loaded + * + * @retval true when the enumeration is complete and the driver is ready to be used + * @retval false when the device driver is not ready to be used + * + * This should be used for getting correct endpoint numbers, getting maximum sizes of endpoints. + * Should return true, when no more data is needed. + * + */ + bool (*analyze_descriptor)(void *drvdata, void *descriptor); + + /** + * @brief poll method is called periodically by the library core + * @param[in/out] drvdata is the device driver's private data + * @param[in] time_curr_us current timestamp in microseconds + * @see usbh_poll() + */ + void (*poll)(void *drvdata, uint32_t time_curr_us); + + /** + * @brief unloads the device driver + * @param[in/out] drvdata is the device driver's private data + * + * This should free any data associated with this device + */ + void (*remove)(void *drvdata); + + /** + * @brief info - compatibility information about the driver. It is used by the core during device enumeration + * @see find_driver() + */ + const usbh_dev_driver_info_t * const info; +}; +typedef struct _usbh_dev_driver usbh_dev_driver_t; + #define ERROR(arg) LOG_PRINTF("UNHANDLED_ERROR %d: file: %s, line: %d",\ arg, __FILE__, __LINE__) diff --git a/include/usbh_core.h b/include/usbh_core.h index 2a36809..308d53b 100644 --- a/include/usbh_core.h +++ b/include/usbh_core.h @@ -40,64 +40,6 @@ BEGIN_DECLS -/// set to -1 for unused items ("don't care" functionality) @see find_driver() -struct _usbh_dev_driver_info { - int32_t deviceClass; - int32_t deviceSubClass; - int32_t deviceProtocol; - int32_t idVendor; - int32_t idProduct; - int32_t ifaceClass; - int32_t ifaceSubClass; - int32_t ifaceProtocol; -}; -typedef struct _usbh_dev_driver_info usbh_dev_driver_info_t; - -struct _usbh_dev_driver { - /** - * @brief init is initialization routine of the device driver - * - * This function is called during the initialization of the device driver - */ - void *(*init)(void *usbh_dev); - - /** - * @brief analyze descriptor - * @param[in/out] drvdata is the device driver's private data - * @param[in] descriptor is the pointer to the descriptor that should - * be parsed in order to prepare driver to be loaded - * - * @retval true when the enumeration is complete and the driver is ready to be used - * @retval false when the device driver is not ready to be used - * - * This should be used for getting correct endpoint numbers, getting maximum sizes of endpoints. - * Should return true, when no more data is needed. - * - */ - bool (*analyze_descriptor)(void *drvdata, void *descriptor); - - /** - * @brief poll method is called periodically by the library core - * @param[in/out] drvdata is the device driver's private data - * @param[in] time_curr_us current timestamp in microseconds - * @see usbh_poll() - */ - void (*poll)(void *drvdata, uint32_t time_curr_us); - - /** - * @brief unloads the device driver - * @param[in/out] drvdata is the device driver's private data - * - * This should free any data associated with this device - */ - void (*remove)(void *drvdata); - - /** - * @brief info - compatibility information about the driver. It is used by the core during device enumeration - * @see find_driver() - */ - const usbh_dev_driver_info_t * const info; -}; typedef struct _usbh_dev_driver usbh_dev_driver_t; /** diff --git a/include/usbh_driver_gp_xbox.h b/include/usbh_driver_gp_xbox.h index d648b90..5d2dc2a 100644 --- a/include/usbh_driver_gp_xbox.h +++ b/include/usbh_driver_gp_xbox.h @@ -71,6 +71,7 @@ typedef struct _gp_xbox_config gp_xbox_config_t; */ void gp_xbox_driver_init(const gp_xbox_config_t *config); +typedef struct _usbh_dev_driver usbh_dev_driver_t; extern const usbh_dev_driver_t usbh_gp_xbox_driver; END_DECLS diff --git a/include/usbh_driver_hid.h b/include/usbh_driver_hid.h index 8155d82..89f950a 100644 --- a/include/usbh_driver_hid.h +++ b/include/usbh_driver_hid.h @@ -78,6 +78,7 @@ enum HID_TYPE hid_get_type(uint8_t device_id); */ bool hid_is_connected(uint8_t device_id); +typedef struct _usbh_dev_driver usbh_dev_driver_t; extern const usbh_dev_driver_t usbh_hid_driver; END_DECLS diff --git a/include/usbh_driver_hub.h b/include/usbh_driver_hub.h index 1066074..dedcc58 100644 --- a/include/usbh_driver_hub.h +++ b/include/usbh_driver_hub.h @@ -32,6 +32,7 @@ BEGIN_DECLS */ void hub_driver_init(void); +typedef struct _usbh_dev_driver usbh_dev_driver_t; extern const usbh_dev_driver_t usbh_hub_driver; END_DECLS diff --git a/src/usbh_driver_ac_midi.c b/src/usbh_driver_ac_midi.c index 9d139d5..50ef963 100644 --- a/src/usbh_driver_ac_midi.c +++ b/src/usbh_driver_ac_midi.c @@ -30,35 +30,10 @@ #include #include - -static void *init(void *usbh_dev); -static bool analyze_descriptor(void *drvdata, void *descriptor); -static void poll(void *drvdata, uint32_t tflp); -static void remove(void *drvdata); - static midi_device_t midi_device[USBH_AC_MIDI_MAX_DEVICES]; static const midi_config_t *midi_config = NULL; static bool initialized = false; -static const usbh_dev_driver_info_t usbh_midi_driver_info = { - .deviceClass = -1, - .deviceSubClass = -1, - .deviceProtocol = -1, - .idVendor = -1, - .idProduct = -1, - .ifaceClass = 0x01, - .ifaceSubClass = 0x03, - .ifaceProtocol = -1, -}; - -const usbh_dev_driver_t usbh_midi_driver = { - .init = init, - .analyze_descriptor = analyze_descriptor, - .poll = poll, - .remove = remove, - .info = &usbh_midi_driver_info -}; - void midi_driver_init(const midi_config_t *config) { uint32_t i; @@ -72,7 +47,7 @@ void midi_driver_init(const midi_config_t *config) * * */ -static void *init(void *usbh_dev) +static void *init(usbh_device_t *usbh_dev) { if (!midi_config || !initialized) { LOG_PRINTF("\n%s/%d : driver not initialized\n", __FILE__, __LINE__); @@ -367,3 +342,22 @@ static void remove(void *drvdata) midi->endpoint_in_address = 0; midi->endpoint_out_address = 0; } + +static const usbh_dev_driver_info_t usbh_midi_driver_info = { + .deviceClass = -1, + .deviceSubClass = -1, + .deviceProtocol = -1, + .idVendor = -1, + .idProduct = -1, + .ifaceClass = 0x01, + .ifaceSubClass = 0x03, + .ifaceProtocol = -1, +}; + +const usbh_dev_driver_t usbh_midi_driver = { + .init = init, + .analyze_descriptor = analyze_descriptor, + .poll = poll, + .remove = remove, + .info = &usbh_midi_driver_info +}; diff --git a/src/usbh_driver_gp_xbox.c b/src/usbh_driver_gp_xbox.c index 92f61b5..6393d1b 100644 --- a/src/usbh_driver_gp_xbox.c +++ b/src/usbh_driver_gp_xbox.c @@ -72,7 +72,7 @@ void gp_xbox_driver_init(const gp_xbox_config_t *config) * * */ -static void *init(void *usbh_dev) +static void *init(usbh_device_t *usbh_dev) { if (!initialized) { LOG_PRINTF("\n%s/%d : driver not initialized\n", __FILE__, __LINE__); @@ -89,7 +89,7 @@ static void *init(void *usbh_dev) drvdata->device_id = i; drvdata->endpoint_in_address = 0; drvdata->endpoint_in_toggle = 0; - drvdata->usbh_device = (usbh_device_t *)usbh_dev; + drvdata->usbh_device = usbh_dev; break; } } diff --git a/src/usbh_driver_hid.c b/src/usbh_driver_hid.c index 0e90ab0..15af80b 100644 --- a/src/usbh_driver_hid.c +++ b/src/usbh_driver_hid.c @@ -93,7 +93,7 @@ void hid_driver_init(const hid_config_t *config) } } -static void *init(void *usbh_dev) +static void *init(usbh_device_t *usbh_dev) { if (!initialized) { LOG_PRINTF("\n%s/%d : driver not initialized\r\n", __FILE__, __LINE__); @@ -111,7 +111,7 @@ static void *init(void *usbh_dev) drvdata->endpoint_in_address = 0; drvdata->endpoint_in_toggle = 0; drvdata->report0_length = 0; - drvdata->usbh_device = (usbh_device_t *)usbh_dev; + drvdata->usbh_device = usbh_dev; drvdata->report_state = REPORT_STATE_NULL; drvdata->hid_type = HID_TYPE_NONE; break; diff --git a/src/usbh_driver_hub.c b/src/usbh_driver_hub.c index 2127158..959a6c2 100644 --- a/src/usbh_driver_hub.c +++ b/src/usbh_driver_hub.c @@ -45,7 +45,7 @@ void hub_driver_init(void) } } -static void *init(void *usbh_dev) +static void *init(usbh_device_t *usbh_dev) { if (!initialized) { LOG_PRINTF("\n%s/%d : driver not initialized\n", __FILE__, __LINE__); @@ -69,7 +69,7 @@ static void *init(void *usbh_dev) drvdata = &hub_device[i]; drvdata->state = EVENT_STATE_NONE; drvdata->ports_num = 0; - drvdata->device[0] = (usbh_device_t *)usbh_dev; + drvdata->device[0] = usbh_dev; drvdata->busy = 0; drvdata->endpoint_in_address = 0; drvdata->endpoint_in_maxpacketsize = 0; -- cgit From 8946cb522b10465d3fe3a9846158dbff4e924240 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Fri, 9 Sep 2016 18:33:26 +0200 Subject: lld: rework low level driver initialization Signed-off-by: Amir Hammad --- include/usbh_core.h | 3 ++- include/usbh_lld_stm32f4.h | 4 ++-- src/demo.c | 22 +++++++++++----------- src/usbh_core.c | 2 +- src/usbh_lld_stm32f4.c | 8 ++++---- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/include/usbh_core.h b/include/usbh_core.h index 308d53b..04dbd29 100644 --- a/include/usbh_core.h +++ b/include/usbh_core.h @@ -41,13 +41,14 @@ BEGIN_DECLS typedef struct _usbh_dev_driver usbh_dev_driver_t; +typedef struct _usbh_low_level_driver usbh_low_level_driver_t; /** * @brief usbh_init * @param low_level_drivers list of the low level drivers to be used by this library * @param device_drivers list of the device drivers that could be used with attached devices */ -void usbh_init(const void *low_level_drivers[], const usbh_dev_driver_t * const device_drivers[]); +void usbh_init(const usbh_low_level_driver_t * const low_level_drivers[], const usbh_dev_driver_t * const device_drivers[]); /** * @brief usbh_poll diff --git a/include/usbh_lld_stm32f4.h b/include/usbh_lld_stm32f4.h index ead40cd..33be145 100644 --- a/include/usbh_lld_stm32f4.h +++ b/include/usbh_lld_stm32f4.h @@ -30,8 +30,8 @@ BEGIN_DECLS // pass this to usbh init -extern const void *usbh_lld_stm32f4_driver_fs; -extern const void *usbh_lld_stm32f4_driver_hs; +extern const usbh_low_level_driver_t usbh_lld_stm32f4_driver_fs; +extern const usbh_low_level_driver_t usbh_lld_stm32f4_driver_hs; #ifdef USART_DEBUG void print_channels(const void *drvdata); diff --git a/src/demo.c b/src/demo.c index 44a94c0..a6b4196 100644 --- a/src/demo.c +++ b/src/demo.c @@ -122,6 +122,17 @@ static const usbh_dev_driver_t *device_drivers[] = { NULL }; +static const usbh_low_level_driver_t * const lld_drivers[] = { +#ifdef USE_STM32F4_USBH_DRIVER_FS + &usbh_lld_stm32f4_driver_fs, // Make sure USE_STM32F4_USBH_DRIVER_FS is defined in usbh_config.h +#endif + +#ifdef USE_STM32F4_USBH_DRIVER_HS + &usbh_lld_stm32f4_driver_hs, // Make sure USE_STM32F4_USBH_DRIVER_HS is defined in usbh_config.h +#endif + NULL + }; + static void gp_xbox_update(uint8_t device_id, gp_xbox_packet_t packet) { (void)device_id; @@ -218,7 +229,6 @@ int main(void) midi_driver_init(&midi_config); gpio_set(GPIOD, GPIO13); - /** * Pass array of supported low level drivers * In case of stm32f407, there are up to two supported OTG hosts on one chip. @@ -226,16 +236,6 @@ int main(void) * * Pass array of supported device drivers */ - const void *lld_drivers[] = { -#ifdef USE_STM32F4_USBH_DRIVER_FS - usbh_lld_stm32f4_driver_fs, // Make sure USE_STM32F4_USBH_DRIVER_FS is defined in usbh_config.h -#endif - -#ifdef USE_STM32F4_USBH_DRIVER_HS - usbh_lld_stm32f4_driver_hs, // Make sure USE_STM32F4_USBH_DRIVER_HS is defined in usbh_config.h -#endif - NULL - }; usbh_init(lld_drivers, device_drivers); gpio_clear(GPIOD, GPIO13); diff --git a/src/usbh_core.c b/src/usbh_core.c index 5448d6c..88fd665 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -176,7 +176,7 @@ static void device_register(void *descriptors, uint16_t descriptors_len, usbh_de LOG_PRINTF("Device NOT Initialized\n"); } -void usbh_init(const void *low_level_drivers[], const usbh_dev_driver_t * const device_drivers[]) +void usbh_init(const usbh_low_level_driver_t * const low_level_drivers[], const usbh_dev_driver_t * const device_drivers[]) { if (!low_level_drivers) { return; diff --git a/src/usbh_lld_stm32f4.c b/src/usbh_lld_stm32f4.c index aff12c5..5ac26e1 100644 --- a/src/usbh_lld_stm32f4.c +++ b/src/usbh_lld_stm32f4.c @@ -1022,7 +1022,7 @@ static usbh_lld_stm32f4_driver_data_t driver_data_fs = { .channels = channels_fs, .num_channels = NUM_CHANNELS_FS }; -static const usbh_low_level_driver_t driver_fs = { +const usbh_low_level_driver_t usbh_lld_stm32f4_driver_fs = { .init = init, .poll = poll, .read = read, @@ -1030,7 +1030,6 @@ static const usbh_low_level_driver_t driver_fs = { .root_speed = root_speed, .driver_data = &driver_data_fs }; -const void *usbh_lld_stm32f4_driver_fs = &driver_fs; #endif // USB High Speed - OTG_HS @@ -1042,7 +1041,8 @@ static usbh_lld_stm32f4_driver_data_t driver_data_hs = { .channels = channels_hs, .num_channels = NUM_CHANNELS_HS }; -static const usbh_low_level_driver_t driver_hs = { + +const usbh_low_level_driver_t usbh_lld_stm32f4_driver_hs = { .init = init, .poll = poll, .read = read, @@ -1050,5 +1050,5 @@ static const usbh_low_level_driver_t driver_hs = { .root_speed = root_speed, .driver_data = &driver_data_hs }; -const void *usbh_lld_stm32f4_driver_hs = &driver_hs; + #endif -- cgit From d7f23c7a8fab589ef35690e4cdaab7ce3ef72b74 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Sun, 11 Sep 2016 09:33:34 +0200 Subject: lld: simplify stm32f4_usbh_port_channel_setup Signed-off-by: Amir Hammad --- src/usbh_lld_stm32f4.c | 59 ++++++++++++++++++++------------------------------ 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/src/usbh_lld_stm32f4.c b/src/usbh_lld_stm32f4.c index 5ac26e1..38b46e7 100644 --- a/src/usbh_lld_stm32f4.c +++ b/src/usbh_lld_stm32f4.c @@ -143,34 +143,31 @@ static void init(void *drvdata) REBASE(OTG_GUSBCFG) |= OTG_GUSBCFG_PHYSEL; } -static void stm32f4_usbh_port_channel_setup( - void *drvdata, uint32_t channel, uint32_t address, - uint32_t eptyp, uint32_t epnum, uint32_t epdir, - uint32_t max_packet_size) +static uint32_t usbh_to_stm32_endpoint_type(enum USBH_ENDPOINT_TYPE usbh_eptyp) { - usbh_lld_stm32f4_driver_data_t *dev = drvdata; - channel_t *channels = dev->channels; - - // TODO: maybe to function - switch (eptyp) { - case USBH_ENDPOINT_TYPE_CONTROL: - eptyp = OTG_HCCHAR_EPTYP_CONTROL; - break; - case USBH_ENDPOINT_TYPE_BULK: - eptyp = OTG_HCCHAR_EPTYP_BULK; - break; - case USBH_ENDPOINT_TYPE_INTERRUPT: - // Use bulk transfer also for interrupt, since no difference is on protocol layer - // Except different behaviour of the core - eptyp = OTG_HCCHAR_EPTYP_BULK; - break; - case USBH_ENDPOINT_TYPE_ISOCHRONOUS: - eptyp = OTG_HCCHAR_EPTYP_ISOCHRONOUS; - break; + switch (usbh_eptyp) { + case USBH_ENDPOINT_TYPE_CONTROL: return OTG_HCCHAR_EPTYP_CONTROL; + case USBH_ENDPOINT_TYPE_BULK: return OTG_HCCHAR_EPTYP_BULK; + + // Use bulk transfer also for interrupt, since no difference is on protocol layer + // Except different behaviour of the core + case USBH_ENDPOINT_TYPE_INTERRUPT: return OTG_HCCHAR_EPTYP_BULK; + case USBH_ENDPOINT_TYPE_ISOCHRONOUS: return OTG_HCCHAR_EPTYP_ISOCHRONOUS; default: LOG_PRINTF("\n\n\n\nWRONG EP TYPE\n\n\n\n\n"); - return; + return OTG_HCCHAR_EPTYP_CONTROL; } +} + +static void stm32f4_usbh_port_channel_setup( + void *drvdata, uint32_t channel, uint32_t epdir) +{ + usbh_lld_stm32f4_driver_data_t *dev = drvdata; + channel_t *channels = dev->channels; + uint32_t max_packet_size = channels[channel].packet.endpoint_size_max; + uint32_t address = channels[channel].packet.address; + uint32_t epnum = channels[channel].packet.endpoint_address; + uint32_t eptyp = usbh_to_stm32_endpoint_type(channels[channel].packet.endpoint_type); uint32_t speed = 0; if (channels[channel].packet.speed == USBH_SPEED_LOW) { @@ -227,12 +224,7 @@ static void read(void *drvdata, usbh_packet_t *packet) REBASE_CH(OTG_HCTSIZ, channel) = dpid | (num_packets << 19) | packet->datalen; - stm32f4_usbh_port_channel_setup(dev, channel, - packet->address, - packet->endpoint_type, - packet->endpoint_address, - OTG_HCCHAR_EPDIR_IN, - packet->endpoint_size_max); + stm32f4_usbh_port_channel_setup(dev, channel, OTG_HCCHAR_EPDIR_IN); } /** @@ -284,12 +276,7 @@ static void write(void *drvdata, const usbh_packet_t *packet) } REBASE_CH(OTG_HCTSIZ, channel) = dpid | (num_packets << 19) | packet->datalen; - stm32f4_usbh_port_channel_setup(dev, channel, - packet->address, - packet->endpoint_type, - packet->endpoint_address, - OTG_HCCHAR_EPDIR_OUT, - packet->endpoint_size_max); + stm32f4_usbh_port_channel_setup(dev, channel, OTG_HCCHAR_EPDIR_OUT); if (packet->endpoint_type == USBH_ENDPOINT_TYPE_CONTROL || packet->endpoint_type == USBH_ENDPOINT_TYPE_BULK) { -- cgit From b055665fb0f978960797cd66fcc93ab7638e3695 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Sun, 11 Sep 2016 09:39:08 +0200 Subject: lld: remove not used error_count field in channel struct Signed-off-by: Amir Hammad --- src/usbh_lld_stm32f4.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/usbh_lld_stm32f4.c b/src/usbh_lld_stm32f4.c index 38b46e7..26ad6bd 100644 --- a/src/usbh_lld_stm32f4.c +++ b/src/usbh_lld_stm32f4.c @@ -47,7 +47,6 @@ struct _channel { enum CHANNEL_STATE state; usbh_packet_t packet; uint32_t data_index; //used in receive function - uint8_t error_count; }; typedef struct _channel channel_t; @@ -918,7 +917,6 @@ static int8_t get_free_channel(void *drvdata) OTG_HCINTMSK_CHHM | OTG_HCINTMSK_STALLM | OTG_HCINTMSK_FRMORM; REBASE(OTG_HAINTMSK) |= (1 << i); - dev->channels[i].error_count = 0; return i; } } -- cgit From 2c81d1a3e65b28c132f64f6d6144f4742d989997 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Sun, 11 Sep 2016 09:44:07 +0200 Subject: drivers: remove redundant forward declaration of usbh_dev_driver_t It is already declared in usbh_core.h Signed-off-by: Amir Hammad --- include/driver/usbh_device_driver.h | 4 ---- include/usbh_driver_gp_xbox.h | 1 - include/usbh_driver_hid.h | 1 - include/usbh_driver_hub.h | 1 - 4 files changed, 7 deletions(-) diff --git a/include/driver/usbh_device_driver.h b/include/driver/usbh_device_driver.h index 20ece5d..e846fd2 100644 --- a/include/driver/usbh_device_driver.h +++ b/include/driver/usbh_device_driver.h @@ -110,10 +110,6 @@ struct _usbh_control { }; typedef struct _usbh_control usbh_control_t; - -//forward declare usbh_dev_driver_t -typedef struct _usbh_dev_driver usbh_dev_driver_t; - /** * @brief The _usbh_device struct * diff --git a/include/usbh_driver_gp_xbox.h b/include/usbh_driver_gp_xbox.h index 5d2dc2a..d648b90 100644 --- a/include/usbh_driver_gp_xbox.h +++ b/include/usbh_driver_gp_xbox.h @@ -71,7 +71,6 @@ typedef struct _gp_xbox_config gp_xbox_config_t; */ void gp_xbox_driver_init(const gp_xbox_config_t *config); -typedef struct _usbh_dev_driver usbh_dev_driver_t; extern const usbh_dev_driver_t usbh_gp_xbox_driver; END_DECLS diff --git a/include/usbh_driver_hid.h b/include/usbh_driver_hid.h index 89f950a..8155d82 100644 --- a/include/usbh_driver_hid.h +++ b/include/usbh_driver_hid.h @@ -78,7 +78,6 @@ enum HID_TYPE hid_get_type(uint8_t device_id); */ bool hid_is_connected(uint8_t device_id); -typedef struct _usbh_dev_driver usbh_dev_driver_t; extern const usbh_dev_driver_t usbh_hid_driver; END_DECLS diff --git a/include/usbh_driver_hub.h b/include/usbh_driver_hub.h index dedcc58..1066074 100644 --- a/include/usbh_driver_hub.h +++ b/include/usbh_driver_hub.h @@ -32,7 +32,6 @@ BEGIN_DECLS */ void hub_driver_init(void); -typedef struct _usbh_dev_driver usbh_dev_driver_t; extern const usbh_dev_driver_t usbh_hub_driver; END_DECLS -- cgit From bacf8ecdbb65774f04fce6ec6cd373a2651ddd67 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Sun, 11 Sep 2016 09:44:58 +0200 Subject: xbox: remove warning about unused variable Signed-off-by: Amir Hammad --- src/usbh_driver_gp_xbox.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/usbh_driver_gp_xbox.c b/src/usbh_driver_gp_xbox.c index 6393d1b..d9e6d79 100644 --- a/src/usbh_driver_gp_xbox.c +++ b/src/usbh_driver_gp_xbox.c @@ -310,7 +310,6 @@ static void poll(void *drvdata, uint32_t time_curr_us) (void)time_curr_us; gp_xbox_device_t *gp_xbox = (gp_xbox_device_t *)drvdata; - usbh_device_t *dev = gp_xbox->usbh_device; switch (gp_xbox->state_next) { case STATE_READING_REQUEST: -- cgit From 4415d960c3d1e52573db02be4aee6e22d22809cf Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Sun, 11 Sep 2016 12:03:20 +0200 Subject: use default case instead of handling other packet statuses explicitely Signed-off-by: Amir Hammad --- src/usbh_core.c | 26 +++++++------------------- src/usbh_driver_ac_midi.c | 5 +++-- src/usbh_driver_gp_xbox.c | 3 +-- src/usbh_driver_hid.c | 7 ++----- src/usbh_driver_hub.c | 26 +++++++------------------- 5 files changed, 20 insertions(+), 47 deletions(-) diff --git a/src/usbh_core.c b/src/usbh_core.c index 88fd665..1a60285 100644 --- a/src/usbh_core.c +++ b/src/usbh_core.c @@ -408,9 +408,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ CONTINUE_WITH(USBH_ENUM_STATE_DEVICE_DT_READ_SETUP); break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + default: device_enumeration_terminate(dev); ERROR(cb_data.status); break; @@ -458,8 +456,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ } break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + default: device_enumeration_terminate(dev); ERROR(cb_data.status); break; @@ -492,9 +489,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ dev->packet_size_max0, device_enumerate, dev); break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + default: device_enumeration_terminate(dev); ERROR(cb_data.status); break; @@ -520,8 +515,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ } break; - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_EFATAL: + default: device_enumeration_terminate(dev); ERROR(cb_data.status); break; @@ -560,9 +554,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ } break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + default: device_enumeration_terminate(dev); ERROR(cb_data.status); break; @@ -583,9 +575,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ } break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + default: device_enumeration_terminate(dev); ERROR(cb_data.status); break; @@ -619,9 +609,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_ CONTINUE_WITH(USBH_ENUM_STATE_FIND_DRIVER); break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + default: device_enumeration_terminate(dev); ERROR(cb_data.status); break; diff --git a/src/usbh_driver_ac_midi.c b/src/usbh_driver_ac_midi.c index 50ef963..96cf383 100644 --- a/src/usbh_driver_ac_midi.c +++ b/src/usbh_driver_ac_midi.c @@ -163,12 +163,13 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t status) midi_in_message(midi, midi->endpoint_in_maxpacketsize); midi->state = 25; break; + case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: midi_in_message(midi, status.transferred_length); midi->state = 25; break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + + default: LOG_PRINTF("FATAL ERROR, MIDI DRIVER DEAD \n"); //~ dev->drv->remove(); midi->state = 0; diff --git a/src/usbh_driver_gp_xbox.c b/src/usbh_driver_gp_xbox.c index d9e6d79..957cb3e 100644 --- a/src/usbh_driver_gp_xbox.c +++ b/src/usbh_driver_gp_xbox.c @@ -257,8 +257,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) gp_xbox->state_next = STATE_READING_REQUEST; break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + default: ERROR(cb_data.status); gp_xbox->state_next = STATE_INACTIVE; break; diff --git a/src/usbh_driver_hid.c b/src/usbh_driver_hid.c index 15af80b..bb842db 100644 --- a/src/usbh_driver_hid.c +++ b/src/usbh_driver_hid.c @@ -231,8 +231,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) hid->state_next = STATE_READING_REQUEST; break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + default: ERROR(cb_data.status); hid->state_next = STATE_INACTIVE; break; @@ -251,9 +250,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) parse_report_descriptor(hid, hid->buffer, cb_data.transferred_length); break; - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + default: ERROR(cb_data.status); hid->state_next = STATE_INACTIVE; break; diff --git a/src/usbh_driver_hub.c b/src/usbh_driver_hub.c index 959a6c2..3f51c68 100644 --- a/src/usbh_driver_hub.c +++ b/src/usbh_driver_hub.c @@ -187,8 +187,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + default: ERROR(cb_data.status); hub->state = EVENT_STATE_NONE; break; @@ -262,8 +261,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: + default: ERROR(cb_data.status); break; } @@ -308,9 +306,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + default: ERROR(cb_data.status); break; } @@ -343,9 +339,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + default: ERROR(cb_data.status); break; } @@ -414,9 +408,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + default: ERROR(cb_data.status); // continue hub->state = EVENT_STATE_POLL_REQ; @@ -460,9 +452,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + default: ERROR(cb_data.status); // continue hub->state = EVENT_STATE_POLL_REQ; @@ -531,9 +521,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data) } break; - case USBH_PACKET_CALLBACK_STATUS_EFATAL: - case USBH_PACKET_CALLBACK_STATUS_EAGAIN: - case USBH_PACKET_CALLBACK_STATUS_ERRSIZ: + default: ERROR(cb_data.status); // continue hub->state = EVENT_STATE_POLL_REQ; -- cgit From b7167bf2aff1a7c9cf223dc2a1d2e401f599d5d8 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Sun, 11 Sep 2016 12:12:41 +0200 Subject: lld: add mask with epdir Signed-off-by: Amir Hammad --- src/usbh_lld_stm32f4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/usbh_lld_stm32f4.c b/src/usbh_lld_stm32f4.c index 26ad6bd..0654d28 100644 --- a/src/usbh_lld_stm32f4.c +++ b/src/usbh_lld_stm32f4.c @@ -178,7 +178,7 @@ static void stm32f4_usbh_port_channel_setup( OTG_HCCHAR_MCNT_1 | (OTG_HCCHAR_EPTYP_MASK & (eptyp)) | (speed) | - (epdir) | + (OTG_HCCHAR_EPDIR_MASK & epdir) | (OTG_HCCHAR_EPNUM_MASK & (epnum << 11)) | (OTG_HCCHAR_MPSIZ_MASK & max_packet_size); -- cgit