From de0c3e70c689cb8861497c245904ab10001e0721 Mon Sep 17 00:00:00 2001 From: Nicolas Reinecke Date: Mon, 14 Nov 2016 01:32:28 +0100 Subject: usbh: cleanup --- os/hal/src/hal_usbh.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index 1caa183..befe17f 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -69,7 +69,7 @@ static bool _classdriver_load(usbh_device_t *dev, uint8_t class, /*===========================================================================*/ -/* Checks. */ +/* Checks. */ /*===========================================================================*/ static inline void _check_dev(usbh_device_t *dev) { @@ -92,7 +92,7 @@ static inline void _check_urb(usbh_urb_t *urb) { } /*===========================================================================*/ -/* Main driver API. */ +/* Main driver API. */ /*===========================================================================*/ void usbhObjectInit(USBHDriver *usbh) { @@ -143,7 +143,7 @@ void usbhResume(USBHDriver *usbh) { } /*===========================================================================*/ -/* Endpoint API. */ +/* Endpoint API. */ /*===========================================================================*/ void usbhEPObjectInit(usbh_ep_t *ep, usbh_device_t *dev, const usbh_endpoint_descriptor_t *desc) { @@ -183,7 +183,7 @@ static void _ep0_object_init(usbh_device_t *dev, uint16_t wMaxPacketSize) { /*===========================================================================*/ -/* URB API. */ +/* URB API. */ /*===========================================================================*/ void usbhURBObjectInit(usbh_urb_t *urb, usbh_ep_t *ep, usbh_completion_cb callback, @@ -350,7 +350,7 @@ void _usbh_urb_completeI(usbh_urb_t *urb, usbh_urbstatus_t status) { } /*===========================================================================*/ -/* Synchronous API. */ +/* Synchronous API. */ /*===========================================================================*/ usbh_urbstatus_t usbhBulkTransfer(usbh_ep_t *ep, @@ -419,7 +419,7 @@ usbh_urbstatus_t usbhControlRequest(usbh_device_t *dev, } /*===========================================================================*/ -/* Standard request helpers. */ +/* Standard request helpers. */ /*===========================================================================*/ #define USBH_GET_DESCRIPTOR(type, value, index) \ @@ -523,7 +523,7 @@ bool usbhStdReqGetInterface(usbh_device_t *dev, /*===========================================================================*/ -/* Device-related functions. */ +/* Device-related functions. */ /*===========================================================================*/ static uint8_t _find_address(USBHDriver *host) { @@ -846,7 +846,7 @@ bool usbhDeviceReadString(usbh_device_t *dev, char *dest, uint8_t size, /*===========================================================================*/ -/* Port processing functions. */ +/* Port processing functions. */ /*===========================================================================*/ static void _port_connected(usbh_port_t *port); @@ -1078,7 +1078,7 @@ void _usbh_port_disconnected(usbh_port_t *port) { /*===========================================================================*/ -/* Hub processing functions. */ +/* Hub processing functions. */ /*===========================================================================*/ #if HAL_USBH_USE_HUB @@ -1176,7 +1176,7 @@ static void _hub_process(USBHDriver *host) { #endif /*===========================================================================*/ -/* Main processing loop (enumeration, loading/unloading drivers, etc). */ +/* Main processing loop (enumeration, loading/unloading drivers, etc). */ /*===========================================================================*/ void usbhMainLoop(USBHDriver *usbh) { @@ -1200,7 +1200,7 @@ void usbhMainLoop(USBHDriver *usbh) { /*===========================================================================*/ -/* IAD class driver. */ +/* IAD class driver. */ /*===========================================================================*/ #if HAL_USBH_USE_IAD static usbh_baseclassdriver_t *iad_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); @@ -1258,7 +1258,7 @@ static void iad_unload(usbh_baseclassdriver_t *drv) { /*===========================================================================*/ -/* Class driver loader. */ +/* Class driver loader. */ /*===========================================================================*/ static const usbh_classdriverinfo_t *usbh_classdrivers_lookup[] = { -- cgit v1.2.3 From 5ecaf7722b5f1f9d0c41213fc5c129b451302f99 Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Mon, 5 Jun 2017 10:18:45 -0300 Subject: USB Host fixes - Cleaned up alignment macros for GCC & IAR - Corrected EP halt and Clear halt behaviours - Initialization of class drivers by USB Host main driver - Minor cosmetic fixes - Updated USB_HOST testhal app --- os/hal/src/hal_usbh.c | 66 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 18 deletions(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index befe17f..0d0bf06 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -19,10 +19,14 @@ #if HAL_USE_USBH -#include "usbh/dev/hub.h" #include "usbh/internal.h" #include +//devices +#include "usbh/dev/hub.h" +#include "usbh/dev/ftdi.h" +#include "usbh/dev/msd.h" + #if USBH_DEBUG_ENABLE_TRACE #define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) #define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__) @@ -107,11 +111,14 @@ void usbhObjectInit(USBHDriver *usbh) { } void usbhInit(void) { +#if HAL_USBH_USE_FTDI + usbhftdiInit(); +#endif +#if HAL_USBH_USE_MSD + usbhmsdInit(); +#endif #if HAL_USBH_USE_HUB - uint8_t i; - for (i = 0; i < HAL_USBHHUB_MAX_INSTANCES; i++) { - usbhhubObjectInit(&USBHHUBD[i]); - } + usbhhubInit(); #endif usbh_lld_init(); } @@ -128,7 +135,6 @@ void usbhStart(USBHDriver *usbh) { osalSysUnlock(); } - void usbhStop(USBHDriver *usbh) { //TODO: implement (void)usbh; @@ -181,6 +187,22 @@ static void _ep0_object_init(usbh_device_t *dev, uint16_t wMaxPacketSize) { usbhEPSetName(&dev->ctrl, "DEV[CTRL]"); } +bool usbhEPResetS(usbh_ep_t *ep) { + osalDbgCheckClassS(); + osalDbgCheck(ep != NULL); + osalDbgAssert((ep->status == USBH_EPSTATUS_OPEN) || (ep->status == USBH_EPSTATUS_HALTED), "invalid state"); + osalDbgAssert(ep->type != USBH_EPTYPE_CTRL, "don't need to reset control endpoint"); + + usbh_urbstatus_t ret = usbhControlRequest(ep->device, + USBH_STANDARDOUT(USBH_REQTYPE_ENDPOINT, USBH_REQ_CLEAR_FEATURE, 0, ep->address | (ep->in ? 0x80 : 0x00)), + 0, 0); + + /* TODO: GET_STATUS to see if endpoint is still halted */ + if ((ret == USBH_URBSTATUS_OK) && usbh_lld_ep_reset(ep)) { + return HAL_SUCCESS; + } + return HAL_FAILED; +} /*===========================================================================*/ /* URB API. */ @@ -258,7 +280,6 @@ bool _usbh_urb_abortI(usbh_urb_t *urb, usbh_urbstatus_t status) { _usbh_urb_completeI(urb, status); return TRUE; -// case USBH_URBSTATUS_QUEUED: case USBH_URBSTATUS_PENDING: return usbh_lld_urb_abort(urb, status); } @@ -271,11 +292,18 @@ void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status) { if (_usbh_urb_abortI(urb, status) == FALSE) { uwarn("URB wasn't aborted immediately, suspend"); osalThreadSuspendS(&urb->abortingThread); - urb->abortingThread = 0; - } else { + osalDbgAssert(urb->abortingThread == 0, "maybe we should uncomment the line below"); + //urb->abortingThread = 0; + } +#if !(USBH_DEBUG_ENABLE && USBH_DEBUG_ENABLE_WARNINGS) + else { osalOsRescheduleS(); } +#else uwarn("URB aborted"); + osalOsRescheduleS(); /* debug printing functions call I-class functions inside + which may cause a priority violation without this call */ +#endif } bool usbhURBCancelI(usbh_urb_t *urb) { @@ -295,9 +323,9 @@ msg_t usbhURBWaitTimeoutS(usbh_urb_t *urb, systime_t timeout) { switch (urb->status) { case USBH_URBSTATUS_INITIALIZED: case USBH_URBSTATUS_PENDING: -// case USBH_URBSTATUS_QUEUED: ret = osalThreadSuspendTimeoutS(&urb->waitingThread, timeout); - urb->waitingThread = 0; + osalDbgAssert(urb->waitingThread == 0, "maybe we should uncomment the line below"); + //urb->waitingThread = 0; break; case USBH_URBSTATUS_OK: @@ -408,7 +436,7 @@ usbh_urbstatus_t usbhControlRequest(usbh_device_t *dev, uint16_t wLength, uint8_t *buff) { - const USBH_DEFINE_BUFFER(usbh_control_request_t, req) = { + USBH_DEFINE_BUFFER(const usbh_control_request_t req) = { bmRequestType, bRequest, wValue, @@ -511,7 +539,7 @@ bool usbhStdReqGetInterface(usbh_device_t *dev, uint8_t bInterfaceNumber, uint8_t *bAlternateSetting) { - USBH_DEFINE_BUFFER(uint8_t, alt); + USBH_DEFINE_BUFFER(uint8_t alt); usbh_urbstatus_t ret = usbhControlRequest(dev, USBH_GET_INTERFACE(bInterfaceNumber), 1, &alt); if (ret != USBH_URBSTATUS_OK) @@ -720,7 +748,7 @@ static bool _device_enumerate(usbh_device_t *dev) { #if USBH_DEBUG_ENABLE && USBH_DEBUG_ENABLE_INFO void usbhDevicePrintInfo(usbh_device_t *dev) { - USBH_DEFINE_BUFFER(char, str[64]); + USBH_DEFINE_BUFFER(char str[64]); usbh_device_descriptor_t *const desc = &dev->devDesc; uinfo("----- Device info -----"); @@ -934,7 +962,7 @@ static void _port_connected(usbh_port_t *port) { uint8_t i; uint8_t retries; usbh_devspeed_t speed; - USBH_DEFINE_BUFFER(usbh_string_descriptor_t, strdesc); + USBH_DEFINE_BUFFER(usbh_string_descriptor_t strdesc); uinfof("Port %d connected, wait debounce...", port->number); @@ -1313,9 +1341,11 @@ static bool _classdriver_load(usbh_device_t *dev, uint8_t class, success: /* Link this driver to the device */ - drv->next = dev->drivers; - dev->drivers = drv; - drv->dev = dev; + if (!drv->dev) { + drv->next = dev->drivers; + dev->drivers = drv; + drv->dev = dev; + } return HAL_SUCCESS; } -- cgit v1.2.3 From 835bb887c0557f0f26716c7f3570f6049925b1ec Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Mon, 5 Jun 2017 10:38:05 -0300 Subject: Add AOA (Android Accessory) class driver --- os/hal/src/hal_usbh.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index 0d0bf06..350d1a7 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -24,6 +24,7 @@ //devices #include "usbh/dev/hub.h" +#include "usbh/dev/aoa.h" #include "usbh/dev/ftdi.h" #include "usbh/dev/msd.h" @@ -114,6 +115,9 @@ void usbhInit(void) { #if HAL_USBH_USE_FTDI usbhftdiInit(); #endif +#if HAL_USBH_USE_AOA + usbhaoaInit(); +#endif #if HAL_USBH_USE_MSD usbhmsdInit(); #endif @@ -1303,7 +1307,10 @@ static const usbh_classdriverinfo_t *usbh_classdrivers_lookup[] = { &usbhmsdClassDriverInfo, #endif #if HAL_USBH_USE_HUB - &usbhhubClassDriverInfo + &usbhhubClassDriverInfo, +#endif +#if HAL_USBH_USE_AOA + &usbhaoaClassDriverInfo, /* Leave always last */ #endif }; -- cgit v1.2.3 From 5bc62c93e02b0f1ac9a92ed110a1cf2aa42f7cf2 Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Mon, 5 Jun 2017 10:53:59 -0300 Subject: Add HID class driver --- os/hal/src/hal_usbh.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index 350d1a7..39f48e1 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -27,6 +27,7 @@ #include "usbh/dev/aoa.h" #include "usbh/dev/ftdi.h" #include "usbh/dev/msd.h" +#include "usbh/dev/hid.h" #if USBH_DEBUG_ENABLE_TRACE #define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) @@ -121,6 +122,9 @@ void usbhInit(void) { #if HAL_USBH_USE_MSD usbhmsdInit(); #endif +#if HAL_USBH_USE_HID + usbhhidInit(); +#endif #if HAL_USBH_USE_HUB usbhhubInit(); #endif @@ -1306,6 +1310,9 @@ static const usbh_classdriverinfo_t *usbh_classdrivers_lookup[] = { #if HAL_USBH_USE_MSD &usbhmsdClassDriverInfo, #endif +#if HAL_USBH_USE_HID + &usbhhidClassDriverInfo, +#endif #if HAL_USBH_USE_HUB &usbhhubClassDriverInfo, #endif -- cgit v1.2.3 From 61c3a28398c7cb0da4a2cdca2a8fc0ebf6f66271 Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Mon, 5 Jun 2017 11:04:30 -0300 Subject: Mass license dates update --- os/hal/src/hal_usbh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index 39f48e1..80180d6 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -1,6 +1,6 @@ /* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail) + ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio + Copyright (C) 2015..2017 Diego Ismirlian, (dismirlian (at) google's mail) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. -- cgit v1.2.3 From 108ae2534cf5e487b569ea34bdae4e86b9c2d024 Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Tue, 6 Jun 2017 09:23:07 -0300 Subject: Fixed endpoint halt reset implementation --- os/hal/src/hal_usbh.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index 80180d6..11add0d 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -195,8 +195,7 @@ static void _ep0_object_init(usbh_device_t *dev, uint16_t wMaxPacketSize) { usbhEPSetName(&dev->ctrl, "DEV[CTRL]"); } -bool usbhEPResetS(usbh_ep_t *ep) { - osalDbgCheckClassS(); +bool usbhEPReset(usbh_ep_t *ep) { osalDbgCheck(ep != NULL); osalDbgAssert((ep->status == USBH_EPSTATUS_OPEN) || (ep->status == USBH_EPSTATUS_HALTED), "invalid state"); osalDbgAssert(ep->type != USBH_EPTYPE_CTRL, "don't need to reset control endpoint"); @@ -206,9 +205,12 @@ bool usbhEPResetS(usbh_ep_t *ep) { 0, 0); /* TODO: GET_STATUS to see if endpoint is still halted */ + osalSysLock(); if ((ret == USBH_URBSTATUS_OK) && usbh_lld_ep_reset(ep)) { + osalSysUnlock(); return HAL_SUCCESS; } + osalSysUnlock(); return HAL_FAILED; } -- cgit v1.2.3 From 9349f7400432ae5a999c524b89da8a835da59b08 Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Tue, 6 Jun 2017 10:21:00 -0300 Subject: Clean up request type helpers --- os/hal/src/hal_usbh.c | 101 ++++++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 53 deletions(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index 11add0d..538f36e 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -201,8 +201,9 @@ bool usbhEPReset(usbh_ep_t *ep) { osalDbgAssert(ep->type != USBH_EPTYPE_CTRL, "don't need to reset control endpoint"); usbh_urbstatus_t ret = usbhControlRequest(ep->device, - USBH_STANDARDOUT(USBH_REQTYPE_ENDPOINT, USBH_REQ_CLEAR_FEATURE, 0, ep->address | (ep->in ? 0x80 : 0x00)), - 0, 0); + USBH_REQTYPE_STANDARDOUT(USBH_REQTYPE_RECIP_ENDPOINT), + USBH_REQ_CLEAR_FEATURE, + 0, ep->address | (ep->in ? 0x80 : 0x00), 0, 0); /* TODO: GET_STATUS to see if endpoint is still halted */ osalSysLock(); @@ -460,27 +461,19 @@ usbh_urbstatus_t usbhControlRequest(usbh_device_t *dev, /* Standard request helpers. */ /*===========================================================================*/ -#define USBH_GET_DESCRIPTOR(type, value, index) \ - USBH_STANDARDIN(type, \ - USBH_REQ_GET_DESCRIPTOR, \ - value, \ - index) \ - -#define USBH_GETDEVICEDESCRIPTOR \ - USBH_GET_DESCRIPTOR(USBH_REQTYPE_DEVICE, (USBH_DT_DEVICE << 8) | 0, 0) - -#define USBH_GETCONFIGURATIONDESCRIPTOR(index) \ - USBH_GET_DESCRIPTOR(USBH_REQTYPE_DEVICE, (USBH_DT_CONFIG << 8) | index, 0) - -#define USBH_GETSTRINGDESCRIPTOR(index, langID) \ - USBH_GET_DESCRIPTOR(USBH_REQTYPE_DEVICE, (USBH_DT_STRING << 8) | index, langID) - bool usbhStdReqGetDeviceDescriptor(usbh_device_t *dev, uint16_t wLength, uint8_t *buf) { usbh_device_descriptor_t *desc; - usbh_urbstatus_t ret = usbhControlRequest(dev, USBH_GETDEVICEDESCRIPTOR, wLength, buf); + + usbh_urbstatus_t ret = usbhControlRequest(dev, + USBH_REQTYPE_STANDARDIN(USBH_REQTYPE_RECIP_DEVICE), + USBH_REQ_GET_DESCRIPTOR, + (USBH_DT_DEVICE << 8) | 0, 0, + wLength, buf); + desc = (usbh_device_descriptor_t *)buf; + if ((ret != USBH_URBSTATUS_OK) || (desc->bLength != USBH_DT_DEVICE_SIZE) || (desc->bDescriptorType != USBH_DT_DEVICE)) { @@ -493,8 +486,15 @@ bool usbhStdReqGetConfigurationDescriptor(usbh_device_t *dev, uint8_t index, uint16_t wLength, uint8_t *buf) { - usbh_urbstatus_t ret = usbhControlRequest(dev, USBH_GETCONFIGURATIONDESCRIPTOR(index), wLength, buf); + + usbh_urbstatus_t ret = usbhControlRequest(dev, + USBH_REQTYPE_STANDARDIN(USBH_REQTYPE_RECIP_DEVICE), + USBH_REQ_GET_DESCRIPTOR, + (USBH_DT_CONFIG << 8) | index, 0, + wLength, buf); + usbh_config_descriptor_t *const desc = (usbh_config_descriptor_t *)buf; + if ((ret != USBH_URBSTATUS_OK) || (desc->bLength < USBH_DT_CONFIG_SIZE) || (desc->bDescriptorType != USBH_DT_CONFIG)) { @@ -511,7 +511,13 @@ bool usbhStdReqGetStringDescriptor(usbh_device_t *dev, osalDbgAssert(wLength >= USBH_DT_STRING_SIZE, "wrong size"); usbh_string_descriptor_t *desc = (usbh_string_descriptor_t *)buf; - usbh_urbstatus_t ret = usbhControlRequest(dev, USBH_GETSTRINGDESCRIPTOR(index, langID), wLength, buf); + + usbh_urbstatus_t ret = usbhControlRequest(dev, + USBH_REQTYPE_STANDARDIN(USBH_REQTYPE_RECIP_DEVICE), + USBH_REQ_GET_DESCRIPTOR, + (USBH_DT_STRING << 8) | index, langID, + wLength, buf); + if ((ret != USBH_URBSTATUS_OK) || (desc->bLength < USBH_DT_STRING_SIZE) || (desc->bDescriptorType != USBH_DT_STRING)) { @@ -520,25 +526,17 @@ bool usbhStdReqGetStringDescriptor(usbh_device_t *dev, return HAL_SUCCESS; } - - -#define USBH_SET_INTERFACE(interface, alt) \ - USBH_STANDARDOUT(USBH_REQTYPE_INTERFACE, \ - USBH_REQ_SET_INTERFACE, \ - alt, \ - interface) \ - -#define USBH_GET_INTERFACE(interface) \ - USBH_STANDARDIN(USBH_REQTYPE_INTERFACE, \ - USBH_REQ_GET_INTERFACE, \ - 0, \ - interface) \ - bool usbhStdReqSetInterface(usbh_device_t *dev, uint8_t bInterfaceNumber, uint8_t bAlternateSetting) { - usbh_urbstatus_t ret = usbhControlRequest(dev, USBH_SET_INTERFACE(bInterfaceNumber, bAlternateSetting), 0, NULL); + usbh_urbstatus_t ret = usbhControlRequest(dev, + USBH_REQTYPE_STANDARDOUT(USBH_REQTYPE_RECIP_INTERFACE), + USBH_REQ_SET_INTERFACE, + bAlternateSetting, + bInterfaceNumber, + 0, NULL); + if (ret != USBH_URBSTATUS_OK) return HAL_FAILED; @@ -551,7 +549,13 @@ bool usbhStdReqGetInterface(usbh_device_t *dev, USBH_DEFINE_BUFFER(uint8_t alt); - usbh_urbstatus_t ret = usbhControlRequest(dev, USBH_GET_INTERFACE(bInterfaceNumber), 1, &alt); + usbh_urbstatus_t ret = usbhControlRequest(dev, + USBH_REQTYPE_STANDARDIN(USBH_REQTYPE_RECIP_INTERFACE), + USBH_REQ_GET_INTERFACE, + 0, + bInterfaceNumber, + 1, &alt); + if (ret != USBH_URBSTATUS_OK) return HAL_FAILED; @@ -596,7 +600,8 @@ static void _device_initialize(usbh_device_t *dev, usbh_devspeed_t speed) { static bool _device_setaddress(usbh_device_t *dev, uint8_t address) { usbh_urbstatus_t ret = usbhControlRequest(dev, - USBH_STANDARDOUT(USBH_REQTYPE_DEVICE, USBH_REQ_SET_ADDRESS, address, 0), + USBH_REQTYPE_STANDARDOUT(USBH_REQTYPE_RECIP_DEVICE), + USBH_REQ_SET_ADDRESS, address, 0, 0, 0); if (ret != USBH_URBSTATUS_OK) @@ -649,22 +654,12 @@ static void _device_free_full_cfgdesc(usbh_device_t *dev) { } } - -#define USBH_SET_CONFIGURATION(type, value, index) \ - USBH_STANDARDOUT(type, \ - USBH_REQ_SET_CONFIGURATION, \ - value, \ - index) \ - -#define USBH_SETDEVICECONFIGURATION(index) \ - USBH_SET_CONFIGURATION(USBH_REQTYPE_DEVICE, index, 0) - - static bool _device_set_configuration(usbh_device_t *dev, uint8_t configuration) { usbh_urbstatus_t ret = usbhControlRequest(dev, - USBH_SETDEVICECONFIGURATION(configuration), - 0, - 0); + USBH_REQTYPE_STANDARDOUT(USBH_REQTYPE_RECIP_DEVICE), + USBH_REQ_SET_CONFIGURATION, + configuration, + 0, 0, 0); if (ret != USBH_URBSTATUS_OK) return HAL_FAILED; return HAL_SUCCESS; @@ -894,7 +889,7 @@ static void _port_reset(usbh_port_t *port) { #if HAL_USBH_USE_HUB port->hub, #endif - USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER, + USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER, USBH_REQ_SET_FEATURE, USBH_PORT_FEAT_RESET, port->number, @@ -908,7 +903,7 @@ static void _port_update_status(usbh_port_t *port) { #if HAL_USBH_USE_HUB port->hub, #endif - USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER, + USBH_REQTYPE_DIR_IN | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER, USBH_REQ_GET_STATUS, 0, port->number, -- cgit v1.2.3 From e2f7c9277c18b497935ac13d37e6ffab83da675b Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Tue, 6 Jun 2017 10:24:39 -0300 Subject: mend --- os/hal/src/hal_usbh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index 538f36e..457abba 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -1119,7 +1119,7 @@ static void _hub_update_status(USBHDriver *host, USBHHubDriver *hub) { uint32_t stat; if (usbhhubControlRequest(host, hub, - USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE, + USBH_REQTYPE_DIR_IN | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE, USBH_REQ_GET_STATUS, 0, 0, -- cgit v1.2.3 From 50dda7cff22574816f415d5c5003240badcf3d32 Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Tue, 6 Jun 2017 15:21:37 -0300 Subject: Add UVC driver and test/example --- os/hal/src/hal_usbh.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index 457abba..d242086 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -28,6 +28,7 @@ #include "usbh/dev/ftdi.h" #include "usbh/dev/msd.h" #include "usbh/dev/hid.h" +#include "usbh/dev/uvc.h" #if USBH_DEBUG_ENABLE_TRACE #define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) @@ -125,6 +126,9 @@ void usbhInit(void) { #if HAL_USBH_USE_HID usbhhidInit(); #endif +#if HAL_USBH_USE_UVC + usbhuvcInit(); +#endif #if HAL_USBH_USE_HUB usbhhubInit(); #endif @@ -421,7 +425,8 @@ usbh_urbstatus_t usbhControlRequestExtended(usbh_device_t *dev, uint32_t *actual_len, systime_t timeout) { - _check_dev(dev); + if (!dev) return USBH_URBSTATUS_DISCONNECTED; + osalDbgCheck(req != NULL); usbh_urb_t urb; @@ -1310,6 +1315,9 @@ static const usbh_classdriverinfo_t *usbh_classdrivers_lookup[] = { #if HAL_USBH_USE_HID &usbhhidClassDriverInfo, #endif +#if HAL_USBH_USE_UVC + &usbhuvcClassDriverInfo, +#endif #if HAL_USBH_USE_HUB &usbhhubClassDriverInfo, #endif @@ -1341,7 +1349,7 @@ static bool _classdriver_load(usbh_device_t *dev, uint8_t class, #if HAL_USBH_USE_IAD /* special case: */ if (info == &usbhiadClassDriverInfo) - return HAL_SUCCESS; + goto success; //return HAL_SUCCESS; #endif if (drv != NULL) -- cgit v1.2.3 From c9388668449f9d686b1e4df14f9143263cc0fafc Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Sun, 9 Jul 2017 18:29:44 -0300 Subject: USBH: moved definition of driver to LLD --- os/hal/src/hal_usbh.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index d242086..9e6c8eb 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -62,14 +62,6 @@ #define uerr(f, ...) do {} while(0) #endif -#if STM32_USBH_USE_OTG1 -USBHDriver USBHD1; -#endif -#if STM32_USBH_USE_OTG2 -USBHDriver USBHD2; -#endif - - static void _classdriver_process_device(usbh_device_t *dev); static bool _classdriver_load(usbh_device_t *dev, uint8_t class, uint8_t subclass, uint8_t protocol, uint8_t *descbuff, uint16_t rem); -- cgit v1.2.3 From 025ca5345a8ffbb7de3b1c64fb0a5ddbbdacd3b0 Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Sun, 9 Jul 2017 18:30:46 -0300 Subject: USBH: Added mechanism for out-of-tree class driver enumeration --- os/hal/src/hal_usbh.c | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index 9e6c8eb..d0d3cb7 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -66,6 +66,12 @@ static void _classdriver_process_device(usbh_device_t *dev); static bool _classdriver_load(usbh_device_t *dev, uint8_t class, uint8_t subclass, uint8_t protocol, uint8_t *descbuff, uint16_t rem); +#if HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS +#include "usbh_additional_class_drivers.h" +#ifndef HAL_USBH_ADDITIONAL_CLASS_DRIVERS +#error "Must define HAL_USBH_ADDITIONAL_CLASS_DRIVERS" +#endif +#endif /*===========================================================================*/ /* Checks. */ @@ -105,28 +111,6 @@ void usbhObjectInit(USBHDriver *usbh) { #endif } -void usbhInit(void) { -#if HAL_USBH_USE_FTDI - usbhftdiInit(); -#endif -#if HAL_USBH_USE_AOA - usbhaoaInit(); -#endif -#if HAL_USBH_USE_MSD - usbhmsdInit(); -#endif -#if HAL_USBH_USE_HID - usbhhidInit(); -#endif -#if HAL_USBH_USE_UVC - usbhuvcInit(); -#endif -#if HAL_USBH_USE_HUB - usbhhubInit(); -#endif - usbh_lld_init(); -} - void usbhStart(USBHDriver *usbh) { usbDbgInit(usbh); @@ -1236,6 +1220,7 @@ void usbhMainLoop(USBHDriver *usbh) { static usbh_baseclassdriver_t *iad_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); static void iad_unload(usbh_baseclassdriver_t *drv); static const usbh_classdriver_vmt_t usbhiadClassDriverVMT = { + NULL, iad_load, iad_unload }; @@ -1290,8 +1275,11 @@ static void iad_unload(usbh_baseclassdriver_t *drv) { /*===========================================================================*/ /* Class driver loader. */ /*===========================================================================*/ - static const usbh_classdriverinfo_t *usbh_classdrivers_lookup[] = { +#if HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS + /* user-defined out of tree class drivers */ + HAL_USBH_ADDITIONAL_CLASS_DRIVERS +#endif #if HAL_USBH_USE_FTDI &usbhftdiClassDriverInfo, #endif @@ -1431,6 +1419,14 @@ exit: } } +void usbhInit(void) { + uint8_t i; + for (i = 0; i < sizeof_array(usbh_classdrivers_lookup); i++) { + if (usbh_classdrivers_lookup[i]->vmt->init) { + usbh_classdrivers_lookup[i]->vmt->init(); + } + } +} #endif -- cgit v1.2.3 From c9cc2abf3e6854f68a87f72e73cd4eec92262317 Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Thu, 13 Jul 2017 12:57:06 -0300 Subject: USBH: cleanup --- os/hal/src/hal_usbh.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index d0d3cb7..007ef1b 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -20,15 +20,8 @@ #if HAL_USE_USBH #include "usbh/internal.h" -#include - -//devices #include "usbh/dev/hub.h" -#include "usbh/dev/aoa.h" -#include "usbh/dev/ftdi.h" -#include "usbh/dev/msd.h" -#include "usbh/dev/hid.h" -#include "usbh/dev/uvc.h" +#include #if USBH_DEBUG_ENABLE_TRACE #define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -- cgit v1.2.3 From c044306ad058689783b1a6941a2a44d5baf738a2 Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Thu, 13 Jul 2017 16:45:31 -0300 Subject: USBH: Add flexibility to the enumeration process --- os/hal/src/hal_usbh.c | 203 ++++++++++++++++++++++++++------------------------ 1 file changed, 105 insertions(+), 98 deletions(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index 007ef1b..dad022f 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -56,8 +56,7 @@ #endif static void _classdriver_process_device(usbh_device_t *dev); -static bool _classdriver_load(usbh_device_t *dev, uint8_t class, - uint8_t subclass, uint8_t protocol, uint8_t *descbuff, uint16_t rem); +static bool _classdriver_load(usbh_device_t *dev, uint8_t *descbuff, uint16_t rem); #if HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS #include "usbh_additional_class_drivers.h" @@ -1205,69 +1204,68 @@ void usbhMainLoop(USBHDriver *usbh) { #endif } - /*===========================================================================*/ -/* IAD class driver. */ +/* Class driver loader. */ /*===========================================================================*/ -#if HAL_USBH_USE_IAD -static usbh_baseclassdriver_t *iad_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); -static void iad_unload(usbh_baseclassdriver_t *drv); -static const usbh_classdriver_vmt_t usbhiadClassDriverVMT = { - NULL, - iad_load, - iad_unload -}; -static const usbh_classdriverinfo_t usbhiadClassDriverInfo = { - 0xef, 0x02, 0x01, "IAD", &usbhiadClassDriverVMT -}; -static usbh_baseclassdriver_t *iad_load(usbh_device_t *dev, - const uint8_t *descriptor, uint16_t rem) { - (void)rem; +bool _usbh_match_vid_pid(usbh_device_t *dev, int32_t vid, int32_t pid) { + if (((vid < 0) || (dev->devDesc.idVendor == vid)) + && ((pid < 0) || (dev->devDesc.idProduct == pid))) + return HAL_SUCCESS; - if (descriptor[1] != USBH_DT_DEVICE) - return 0; + return HAL_FAILED; +} - uinfo("Load a driver for each IF collection."); +bool _usbh_match_descriptor(const uint8_t *descriptor, uint16_t rem, + int16_t type, int16_t _class, int16_t subclass, int16_t protocol) { - generic_iterator_t icfg; - if_iterator_t iif; - const usbh_ia_descriptor_t *last_iad = 0; + int16_t dclass, dsubclass, dprotocol; - cfg_iter_init(&icfg, dev->fullConfigurationDescriptor, - dev->basicConfigDesc.wTotalLength); - if (!icfg.valid) { - uerr("Invalid configuration descriptor."); - return 0; - } + if ((rem < descriptor[0]) || (rem < 2)) + return HAL_FAILED; - for (if_iter_init(&iif, &icfg); iif.valid; if_iter_next(&iif)) { - if (iif.iad && (iif.iad != last_iad)) { - last_iad = iif.iad; - if (_classdriver_load(dev, iif.iad->bFunctionClass, - iif.iad->bFunctionSubClass, - iif.iad->bFunctionProtocol, - (uint8_t *)iif.iad, - (uint8_t *)iif.curr - (uint8_t *)iif.iad + iif.rem) != HAL_SUCCESS) { - uwarnf("No drivers found for IF collection #%d:%d", - iif.iad->bFirstInterface, - iif.iad->bFirstInterface + iif.iad->bInterfaceCount - 1); - } - } + uint8_t dtype = descriptor[1]; + + if ((type >= 0) && (type != dtype)) + return HAL_FAILED; + + switch (dtype) { + case USBH_DT_DEVICE: { + if (rem < USBH_DT_DEVICE_SIZE) + return HAL_FAILED; + const usbh_device_descriptor_t *const desc = (const usbh_device_descriptor_t *)descriptor; + dclass = desc->bDeviceClass; + dsubclass = desc->bDeviceSubClass; + dprotocol = desc->bDeviceProtocol; + } break; + case USBH_DT_INTERFACE: { + if (rem < USBH_DT_INTERFACE_SIZE) + return HAL_FAILED; + const usbh_interface_descriptor_t *const desc = (const usbh_interface_descriptor_t *)descriptor; + dclass = desc->bInterfaceClass; + dsubclass = desc->bInterfaceSubClass; + dprotocol = desc->bInterfaceProtocol; + } break; + case USBH_DT_INTERFACE_ASSOCIATION: { + if (rem < USBH_DT_INTERFACE_ASSOCIATION_SIZE) + return HAL_FAILED; + const usbh_ia_descriptor_t *const desc = (const usbh_ia_descriptor_t *)descriptor; + dclass = desc->bFunctionClass; + dsubclass = desc->bFunctionSubClass; + dprotocol = desc->bFunctionProtocol; + } break; + default: + return HAL_FAILED; } - return 0; -} + if (((_class < 0) || (_class == dclass)) + && ((subclass < 0) || (subclass == dsubclass)) + && ((protocol < 0) || (protocol == dprotocol))) + return HAL_SUCCESS; -static void iad_unload(usbh_baseclassdriver_t *drv) { - (void)drv; + return HAL_FAILED; } -#endif - -/*===========================================================================*/ -/* Class driver loader. */ -/*===========================================================================*/ static const usbh_classdriverinfo_t *usbh_classdrivers_lookup[] = { #if HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS /* user-defined out of tree class drivers */ @@ -1276,8 +1274,8 @@ static const usbh_classdriverinfo_t *usbh_classdrivers_lookup[] = { #if HAL_USBH_USE_FTDI &usbhftdiClassDriverInfo, #endif -#if HAL_USBH_USE_IAD - &usbhiadClassDriverInfo, +#if HAL_USBH_USE_HUB + &usbhhubClassDriverInfo, #endif #if HAL_USBH_USE_UVC &usbhuvcClassDriverInfo, @@ -1291,44 +1289,24 @@ static const usbh_classdriverinfo_t *usbh_classdrivers_lookup[] = { #if HAL_USBH_USE_UVC &usbhuvcClassDriverInfo, #endif -#if HAL_USBH_USE_HUB - &usbhhubClassDriverInfo, -#endif #if HAL_USBH_USE_AOA &usbhaoaClassDriverInfo, /* Leave always last */ #endif }; -static bool _classdriver_load(usbh_device_t *dev, uint8_t class, - uint8_t subclass, uint8_t protocol, uint8_t *descbuff, uint16_t rem) { +static bool _classdriver_load(usbh_device_t *dev, uint8_t *descbuff, uint16_t rem) { uint8_t i; usbh_baseclassdriver_t *drv = NULL; for (i = 0; i < sizeof_array(usbh_classdrivers_lookup); i++) { const usbh_classdriverinfo_t *const info = usbh_classdrivers_lookup[i]; - if (class == 0xff) { - /* vendor specific */ - if (info->class == 0xff) { - uinfof("Try load vendor-specific driver %s", info->name); - drv = info->vmt->load(dev, descbuff, rem); - if (drv != NULL) - goto success; - } - } else if ((info->class < 0) || ((info->class == class) - && ((info->subclass < 0) || ((info->subclass == subclass) - && ((info->protocol < 0) || (info->protocol == protocol)))))) { - uinfof("Try load driver %s", info->name); - drv = info->vmt->load(dev, descbuff, rem); -#if HAL_USBH_USE_IAD - /* special case: */ - if (info == &usbhiadClassDriverInfo) - goto success; //return HAL_SUCCESS; -#endif + uinfof("Try load driver %s", info->name); + drv = info->vmt->load(dev, descbuff, rem); - if (drv != NULL) - goto success; - } + if (drv != NULL) + goto success; } + return HAL_FAILED; success: @@ -1369,13 +1347,16 @@ static void _classdriver_process_device(usbh_device_t *dev) { usbhDevicePrintConfiguration(dev->fullConfigurationDescriptor, dev->basicConfigDesc.wTotalLength); - if (devdesc->bDeviceClass == 0) { - /* each interface defines its own device class/subclass/protocol */ - uinfo("Load a driver for each IF."); +#if HAL_USBH_USE_IAD + if (dev->devDesc.bDeviceClass == 0xef + && dev->devDesc.bDeviceSubClass == 0x02 + && dev->devDesc.bDeviceProtocol == 0x01) { + + uinfo("Load a driver for each IF collection."); generic_iterator_t icfg; if_iterator_t iif; - uint8_t last_if = 0xff; + const usbh_ia_descriptor_t *last_iad = 0; cfg_iter_init(&icfg, dev->fullConfigurationDescriptor, dev->basicConfigDesc.wTotalLength); @@ -1385,24 +1366,49 @@ static void _classdriver_process_device(usbh_device_t *dev) { } for (if_iter_init(&iif, &icfg); iif.valid; if_iter_next(&iif)) { - const usbh_interface_descriptor_t *const ifdesc = if_get(&iif); - if (ifdesc->bInterfaceNumber != last_if) { - last_if = ifdesc->bInterfaceNumber; - if (_classdriver_load(dev, ifdesc->bInterfaceClass, - ifdesc->bInterfaceSubClass, - ifdesc->bInterfaceProtocol, - (uint8_t *)ifdesc, iif.rem) != HAL_SUCCESS) { - uwarnf("No drivers found for IF #%d", ifdesc->bInterfaceNumber); + if (iif.iad && (iif.iad != last_iad)) { + last_iad = iif.iad; + if (_classdriver_load(dev, + (uint8_t *)iif.iad, + (uint8_t *)iif.curr - (uint8_t *)iif.iad + iif.rem) != HAL_SUCCESS) { + uwarnf("No drivers found for IF collection #%d:%d", + iif.iad->bFirstInterface, + iif.iad->bFirstInterface + iif.iad->bInterfaceCount - 1); } } } - } else { - if (_classdriver_load(dev, devdesc->bDeviceClass, - devdesc->bDeviceSubClass, - devdesc->bDeviceProtocol, - (uint8_t *)devdesc, USBH_DT_DEVICE_SIZE) != HAL_SUCCESS) { - uwarn("No drivers found."); + } else +#endif + if (_classdriver_load(dev, (uint8_t *)devdesc, USBH_DT_DEVICE_SIZE) != HAL_SUCCESS) { + uinfo("No drivers found for device."); + + if (devdesc->bDeviceClass == 0) { + /* each interface defines its own device class/subclass/protocol */ + uinfo("Try load a driver for each IF."); + + generic_iterator_t icfg; + if_iterator_t iif; + uint8_t last_if = 0xff; + + cfg_iter_init(&icfg, dev->fullConfigurationDescriptor, + dev->basicConfigDesc.wTotalLength); + if (!icfg.valid) { + uerr("Invalid configuration descriptor."); + goto exit; + } + + for (if_iter_init(&iif, &icfg); iif.valid; if_iter_next(&iif)) { + const usbh_interface_descriptor_t *const ifdesc = if_get(&iif); + if (ifdesc->bInterfaceNumber != last_if) { + last_if = ifdesc->bInterfaceNumber; + if (_classdriver_load(dev, (uint8_t *)ifdesc, iif.rem) != HAL_SUCCESS) { + uwarnf("No drivers found for IF #%d", ifdesc->bInterfaceNumber); + } + } + } + } else { + uwarn("Unable to load driver."); } } @@ -1419,6 +1425,7 @@ void usbhInit(void) { usbh_classdrivers_lookup[i]->vmt->init(); } } + usbh_lld_init(); } #endif -- cgit v1.2.3 From ce8f18291fb45048685be52bcff5088b14a6823c Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Sun, 16 Jul 2017 18:40:09 -0300 Subject: USBH: Use infinite timeout for control request, when timeouts are not specified --- os/hal/src/hal_usbh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index dad022f..d72ab8c 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -427,7 +427,7 @@ usbh_urbstatus_t usbhControlRequest(usbh_device_t *dev, wIndex, wLength }; - return usbhControlRequestExtended(dev, &req, buff, NULL, MS2ST(1000)); + return usbhControlRequestExtended(dev, &req, buff, NULL, TIME_INFINITE); } /*===========================================================================*/ -- cgit v1.2.3 From dee22cee18dd98502b19e41e45503f8c20f447d6 Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Sun, 16 Jul 2017 20:01:50 -0300 Subject: USBH: remove unnecessary reschedules and add necessary ones --- os/hal/src/hal_usbh.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index d72ab8c..1aa35d0 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -111,7 +111,6 @@ void usbhStart(USBHDriver *usbh) { "invalid state"); usbh_lld_start(usbh); usbh->status = USBH_STATUS_STARTED; - osalOsRescheduleS(); osalSysUnlock(); } @@ -224,6 +223,7 @@ void usbhURBObjectResetI(usbh_urb_t *urb) { usbh_lld_urb_object_reset(urb); } +/* usbhURBSubmitI may require a reschedule if called from a S-locked state */ void usbhURBSubmitI(usbh_urb_t *urb) { osalDbgCheckClassI(); _check_urb(urb); @@ -245,6 +245,7 @@ void usbhURBSubmitI(usbh_urb_t *urb) { usbh_lld_urb_submit(urb); } +/* _usbh_urb_abortI may require a reschedule if called from a S-locked state */ bool _usbh_urb_abortI(usbh_urb_t *urb, usbh_urbstatus_t status) { osalDbgCheckClassI(); _check_urb(urb); @@ -280,15 +281,18 @@ void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status) { } #if !(USBH_DEBUG_ENABLE && USBH_DEBUG_ENABLE_WARNINGS) else { + /* This call is necessary because _usbh_urb_abortI may require a reschedule */ osalOsRescheduleS(); } #else uwarn("URB aborted"); osalOsRescheduleS(); /* debug printing functions call I-class functions inside - which may cause a priority violation without this call */ + which may cause a priority violation without this call + Also, _usbh_urb_abortI may require a reschedule */ #endif } +/* usbhURBCancelI may require a reschedule if called from a S-locked state */ bool usbhURBCancelI(usbh_urb_t *urb) { return _usbh_urb_abortI(urb, USBH_URBSTATUS_CANCELLED); } @@ -313,7 +317,6 @@ msg_t usbhURBWaitTimeoutS(usbh_urb_t *urb, systime_t timeout) { case USBH_URBSTATUS_OK: ret = MSG_OK; - osalOsRescheduleS(); break; /* case USBH_URBSTATUS_UNINITIALIZED: @@ -324,7 +327,6 @@ msg_t usbhURBWaitTimeoutS(usbh_urb_t *urb, systime_t timeout) { * case USBH_URBSTATUS_DISCONNECTED: */ default: ret = MSG_RESET; - osalOsRescheduleS(); break; } return ret; @@ -350,6 +352,7 @@ static inline msg_t _wakeup_message(usbh_urbstatus_t status) { return MSG_RESET; } +/* _usbh_urb_completeI may require a reschedule if called from a S-locked state */ void _usbh_urb_completeI(usbh_urb_t *urb, usbh_urbstatus_t status) { osalDbgCheckClassI(); _check_urb(urb); @@ -1128,7 +1131,6 @@ static uint32_t _hub_get_status_change_bitmap(USBHDriver *host, USBHHubDriver *h osalSysLock(); uint32_t ret = hub->statuschange; hub->statuschange = 0; - osalOsRescheduleS(); osalSysUnlock(); return ret; } -- cgit v1.2.3 From 2fb4cf92737dae0fbcea90939e4af5b534eb35d6 Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Mon, 31 Jul 2017 18:38:46 -0300 Subject: USBH: improved main driver - improved connection/disconnection handling - corrected bug on aborting non-pending URB - corrected bug on disconnecting multiple hubs - improved debug messages --- os/hal/src/hal_usbh.c | 105 ++++++++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 47 deletions(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index 1aa35d0..a7ba236 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -249,24 +249,17 @@ void usbhURBSubmitI(usbh_urb_t *urb) { bool _usbh_urb_abortI(usbh_urb_t *urb, usbh_urbstatus_t status) { osalDbgCheckClassI(); _check_urb(urb); + osalDbgCheck(urb->status != USBH_URBSTATUS_UNINITIALIZED); - switch (urb->status) { -/* case USBH_URBSTATUS_UNINITIALIZED: - * case USBH_URBSTATUS_INITIALIZED: - * case USBH_URBSTATUS_ERROR: - * case USBH_URBSTATUS_TIMEOUT: - * case USBH_URBSTATUS_CANCELLED: - * case USBH_URBSTATUS_STALL: - * case USBH_URBSTATUS_DISCONNECTED: - * case USBH_URBSTATUS_OK: */ - default: - /* already finished */ - _usbh_urb_completeI(urb, status); - return TRUE; - - case USBH_URBSTATUS_PENDING: + if (urb->status == USBH_URBSTATUS_PENDING) { return usbh_lld_urb_abort(urb, status); } + + /* already finished or never submitted: + * USBH_URBSTATUS_INITIALIZED, USBH_URBSTATUS_ERROR, USBH_URBSTATUS_TIMEOUT, + * USBH_URBSTATUS_CANCELLED, USBH_URBSTATUS_STALL, USBH_URBSTATUS_DISCONNECTED + * USBH_URBSTATUS_OK */ + return TRUE; } void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status) { @@ -430,7 +423,7 @@ usbh_urbstatus_t usbhControlRequest(usbh_device_t *dev, wIndex, wLength }; - return usbhControlRequestExtended(dev, &req, buff, NULL, TIME_INFINITE); + return usbhControlRequestExtended(dev, &req, buff, NULL, HAL_USBH_CONTROL_REQUEST_DEFAULT_TIMEOUT); } /*===========================================================================*/ @@ -896,46 +889,48 @@ static void _port_process_status_change(usbh_port_t *port) { _port_update_status(port); if (port->c_status & USBH_PORTSTATUS_C_CONNECTION) { - /* port connected status changed */ port->c_status &= ~USBH_PORTSTATUS_C_CONNECTION; usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_CONNECTION); - if ((port->status & (USBH_PORTSTATUS_CONNECTION | USBH_PORTSTATUS_ENABLE)) - == USBH_PORTSTATUS_CONNECTION) { - if (port->device.status != USBH_DEVSTATUS_DISCONNECTED) { + + if (port->device.status != USBH_DEVSTATUS_DISCONNECTED) { + if (!(port->status & USBH_PORTSTATUS_CONNECTION)) { _usbh_port_disconnected(port); } + } + } - /* connected, disabled */ + if (port->device.status == USBH_DEVSTATUS_DISCONNECTED) { + if (port->status & USBH_PORTSTATUS_CONNECTION) { _port_connected(port); - } else { - /* disconnected */ - _usbh_port_disconnected(port); } } if (port->c_status & USBH_PORTSTATUS_C_RESET) { port->c_status &= ~USBH_PORTSTATUS_C_RESET; usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_RESET); + uinfof("Port %d: reset=%d", port->number, port->status & USBH_PORTSTATUS_RESET ? 1 : 0); } if (port->c_status & USBH_PORTSTATUS_C_ENABLE) { port->c_status &= ~USBH_PORTSTATUS_C_ENABLE; usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_ENABLE); + uinfof("Port %d: enable=%d", port->number, port->status & USBH_PORTSTATUS_ENABLE ? 1 : 0); } if (port->c_status & USBH_PORTSTATUS_C_OVERCURRENT) { port->c_status &= ~USBH_PORTSTATUS_C_OVERCURRENT; usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_OVERCURRENT); + uwarnf("Port %d: overcurrent=%d", port->number, port->status & USBH_PORTSTATUS_OVERCURRENT ? 1 : 0); } if (port->c_status & USBH_PORTSTATUS_C_SUSPEND) { port->c_status &= ~USBH_PORTSTATUS_C_SUSPEND; usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_SUSPEND); + uinfof("Port %d: suspend=%d", port->number, port->status & USBH_PORTSTATUS_SUSPEND ? 1 : 0); } } - static void _port_connected(usbh_port_t *port) { /* connected */ @@ -945,9 +940,8 @@ static void _port_connected(usbh_port_t *port) { usbh_devspeed_t speed; USBH_DEFINE_BUFFER(usbh_string_descriptor_t strdesc); - uinfof("Port %d connected, wait debounce...", port->number); - port->device.status = USBH_DEVSTATUS_ATTACHED; + uinfof("Port %d: attached, wait debounce...", port->number); /* wait for attach de-bounce */ osalThreadSleepMilliseconds(HAL_USBH_PORT_DEBOUNCE_TIME); @@ -955,16 +949,26 @@ static void _port_connected(usbh_port_t *port) { /* check disconnection */ _port_update_status(port); if (port->c_status & USBH_PORTSTATUS_C_CONNECTION) { - /* connection state changed; abort */ + port->c_status &= ~USBH_PORTSTATUS_C_CONNECTION; + usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_CONNECTION); + uwarnf("Port %d: connection state changed; abort #1", port->number); + goto abort; + } + + /* make sure that the device is still connected */ + if ((port->status & USBH_PORTSTATUS_CONNECTION) == 0) { + uwarnf("Port %d: device is disconnected", port->number); goto abort; } + uinfof("Port %d: connected", port->number); port->device.status = USBH_DEVSTATUS_CONNECTED; retries = 3; reset: for (i = 0; i < 3; i++) { - uinfo("Try reset..."); + uinfof("Port %d: Try reset...", port->number); + /* TODO: check that port is actually disabled */ port->c_status &= ~(USBH_PORTSTATUS_C_RESET | USBH_PORTSTATUS_C_ENABLE); _port_reset(port); osalThreadSleepMilliseconds(20); /* give it some time to reset (min. 10ms) */ @@ -973,8 +977,12 @@ reset: _port_update_status(port); /* check for disconnection */ - if (port->c_status & USBH_PORTSTATUS_C_CONNECTION) + if (port->c_status & USBH_PORTSTATUS_C_CONNECTION) { + port->c_status &= ~USBH_PORTSTATUS_C_CONNECTION; + usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_CONNECTION); + uwarnf("Port %d: connection state changed; abort #2", port->number); goto abort; + } /* check for reset completion */ if (port->c_status & USBH_PORTSTATUS_C_RESET) { @@ -988,7 +996,10 @@ reset: } /* check for timeout */ - if (osalOsGetSystemTimeX() - start > HAL_USBH_PORT_RESET_TIMEOUT) break; + if (osalOsGetSystemTimeX() - start > HAL_USBH_PORT_RESET_TIMEOUT) { + uwarnf("Port %d: reset timeout", port->number); + break; + } } } @@ -996,8 +1007,7 @@ reset: goto abort; reset_success: - - uinfo("Reset OK, recovery..."); + uinfof("Port %d: Reset OK, recovery...", port->number); /* reset recovery */ osalThreadSleepMilliseconds(100); @@ -1014,19 +1024,22 @@ reset_success: usbhEPOpen(&port->device.ctrl); /* device with default address (0), try enumeration */ - if (_device_enumerate(&port->device)) { + if (_device_enumerate(&port->device) != HAL_SUCCESS) { /* enumeration failed */ usbhEPClose(&port->device.ctrl); - if (!--retries) + if (!--retries) { + uwarnf("Port %d: enumeration failed; abort", port->number); goto abort; + } /* retry reset & enumeration */ + uwarnf("Port %d: enumeration failed; retry reset & enumeration", port->number); goto reset; } /* load the default language ID */ - uinfo("Loading langID0..."); + uinfof("Port %d: Loading langID0...", port->number); if (!usbhStdReqGetStringDescriptor(&port->device, 0, 0, USBH_DT_STRING_SIZE, (uint8_t *)&strdesc) && (strdesc.bLength >= 4) @@ -1034,12 +1047,12 @@ reset_success: 4, (uint8_t *)&strdesc)) { port->device.langID0 = strdesc.wData[0]; - uinfof("langID0=%04x", port->device.langID0); + uinfof("Port %d: langID0=%04x", port->number, port->device.langID0); } /* check if the device has only one configuration */ if (port->device.devDesc.bNumConfigurations == 1) { - uinfo("Device has only one configuration"); + uinfof("Port %d: device has only one configuration", port->number); _device_configure(&port->device, 0); } @@ -1047,7 +1060,7 @@ reset_success: return; abort: - uerr("Abort"); + uerrf("Port %d: abort", port->number); port->device.status = USBH_DEVSTATUS_DISCONNECTED; } @@ -1055,14 +1068,14 @@ void _usbh_port_disconnected(usbh_port_t *port) { if (port->device.status == USBH_DEVSTATUS_DISCONNECTED) return; - uinfo("Port disconnected"); + uinfof("Port %d: disconnected", port->number); /* unload drivers */ while (port->device.drivers) { usbh_baseclassdriver_t *drv = port->device.drivers; /* unload */ - uinfof("Unload driver %s", drv->info->name); + uinfof("Port %d: unload driver %s", port->number, drv->info->name); drv->info->vmt->unload(drv); /* unlink */ @@ -1071,9 +1084,7 @@ void _usbh_port_disconnected(usbh_port_t *port) { } /* close control endpoint */ - osalSysLock(); - usbhEPCloseS(&port->device.ctrl); - osalSysUnlock(); + usbhEPClose(&port->device.ctrl); /* free address */ if (port->device.address) @@ -1113,7 +1124,7 @@ static void _hub_process_status_change(USBHDriver *host, USBHHubDriver *hub) { uinfo("Hub status change. GET_STATUS."); _hub_update_status(host, hub); - if (hub->c_status & USBH_HUBSTATUS_C_HUB_LOCAL_POWER) { + if (hub->c_status & USBH_HUBSTATUS_C_HUB_LOCAL_POWER) { hub->c_status &= ~USBH_HUBSTATUS_C_HUB_LOCAL_POWER; uinfo("Clear USBH_HUB_FEAT_C_HUB_LOCAL_POWER"); usbhhubClearFeatureHub(host, hub, USBH_HUB_FEAT_C_HUB_LOCAL_POWER); @@ -1196,8 +1207,8 @@ void usbhMainLoop(USBHDriver *usbh) { _hub_process(usbh, NULL); /* process connected hubs */ - USBHHubDriver *hub; - list_for_each_entry(hub, USBHHubDriver, &usbh->hubs, node) { + USBHHubDriver *hub, *temp; + list_for_each_entry_safe(hub, USBHHubDriver, temp, &usbh->hubs, node) { _hub_process(usbh, hub); } #else -- cgit v1.2.3 From 21f95b50f40e9b558709006c73e14367851c3b67 Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Mon, 7 Aug 2017 17:51:34 -0300 Subject: USBH: simplify/cleanup main driver --- os/hal/src/hal_usbh.c | 54 ++++++++++----------------------------------------- 1 file changed, 10 insertions(+), 44 deletions(-) (limited to 'os/hal/src/hal_usbh.c') diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index a7ba236..7dff98a 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -233,11 +233,8 @@ void usbhURBSubmitI(usbh_urb_t *urb) { _usbh_urb_completeI(urb, USBH_URBSTATUS_STALL); return; } - if (ep->status != USBH_EPSTATUS_OPEN) { - _usbh_urb_completeI(urb, USBH_URBSTATUS_DISCONNECTED); - return; - } - if (!(usbhDeviceGetPort(ep->device)->status & USBH_PORTSTATUS_ENABLE)) { + if ((ep->status != USBH_EPSTATUS_OPEN) + || !(usbhDeviceGetPort(ep->device)->status & USBH_PORTSTATUS_ENABLE)) { _usbh_urb_completeI(urb, USBH_URBSTATUS_DISCONNECTED); return; } @@ -271,18 +268,11 @@ void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status) { osalThreadSuspendS(&urb->abortingThread); osalDbgAssert(urb->abortingThread == 0, "maybe we should uncomment the line below"); //urb->abortingThread = 0; - } -#if !(USBH_DEBUG_ENABLE && USBH_DEBUG_ENABLE_WARNINGS) - else { + } else { /* This call is necessary because _usbh_urb_abortI may require a reschedule */ osalOsRescheduleS(); } -#else uwarn("URB aborted"); - osalOsRescheduleS(); /* debug printing functions call I-class functions inside - which may cause a priority violation without this call - Also, _usbh_urb_abortI may require a reschedule */ -#endif } /* usbhURBCancelI may require a reschedule if called from a S-locked state */ @@ -295,34 +285,14 @@ void usbhURBCancelAndWaitS(usbh_urb_t *urb) { } msg_t usbhURBWaitTimeoutS(usbh_urb_t *urb, systime_t timeout) { - msg_t ret; - osalDbgCheckClassS(); _check_urb(urb); - - switch (urb->status) { - case USBH_URBSTATUS_INITIALIZED: - case USBH_URBSTATUS_PENDING: - ret = osalThreadSuspendTimeoutS(&urb->waitingThread, timeout); - osalDbgAssert(urb->waitingThread == 0, "maybe we should uncomment the line below"); - //urb->waitingThread = 0; - break; - - case USBH_URBSTATUS_OK: - ret = MSG_OK; - break; - -/* case USBH_URBSTATUS_UNINITIALIZED: - * case USBH_URBSTATUS_ERROR: - * case USBH_URBSTATUS_TIMEOUT: - * case USBH_URBSTATUS_CANCELLED: - * case USBH_URBSTATUS_STALL: - * case USBH_URBSTATUS_DISCONNECTED: */ - default: - ret = MSG_RESET; - break; + if (urb->status == USBH_URBSTATUS_OK) { + return MSG_OK; + } else if (urb->status != USBH_URBSTATUS_PENDING) { + return MSG_RESET; } - return ret; + return osalThreadSuspendTimeoutS(&urb->waitingThread, timeout); } msg_t usbhURBSubmitAndWaitS(usbh_urb_t *urb, systime_t timeout) { @@ -844,9 +814,6 @@ bool usbhDeviceReadString(usbh_device_t *dev, char *dest, uint8_t size, return HAL_SUCCESS; } - - - /*===========================================================================*/ /* Port processing functions. */ /*===========================================================================*/ @@ -908,13 +875,13 @@ static void _port_process_status_change(usbh_port_t *port) { if (port->c_status & USBH_PORTSTATUS_C_RESET) { port->c_status &= ~USBH_PORTSTATUS_C_RESET; usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_RESET); - uinfof("Port %d: reset=%d", port->number, port->status & USBH_PORTSTATUS_RESET ? 1 : 0); + udbgf("Port %d: reset=%d", port->number, port->status & USBH_PORTSTATUS_RESET ? 1 : 0); } if (port->c_status & USBH_PORTSTATUS_C_ENABLE) { port->c_status &= ~USBH_PORTSTATUS_C_ENABLE; usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_ENABLE); - uinfof("Port %d: enable=%d", port->number, port->status & USBH_PORTSTATUS_ENABLE ? 1 : 0); + udbgf("Port %d: enable=%d", port->number, port->status & USBH_PORTSTATUS_ENABLE ? 1 : 0); } if (port->c_status & USBH_PORTSTATUS_C_OVERCURRENT) { @@ -1096,7 +1063,6 @@ void _usbh_port_disconnected(usbh_port_t *port) { } - /*===========================================================================*/ /* Hub processing functions. */ /*===========================================================================*/ -- cgit v1.2.3