diff options
Diffstat (limited to 'os/hal/src/hal_usbh.c')
| -rw-r--r-- | os/hal/src/hal_usbh.c | 199 | 
1 files changed, 124 insertions, 75 deletions
| diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index befe17f..d242086 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. @@ -19,10 +19,17 @@  #if HAL_USE_USBH -#include "usbh/dev/hub.h"  #include "usbh/internal.h"  #include <string.h> +//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" +  #if USBH_DEBUG_ENABLE_TRACE  #define udbgf(f, ...)  usbDbgPrintf(f, ##__VA_ARGS__)  #define udbg(f, ...)  usbDbgPuts(f, ##__VA_ARGS__) @@ -107,11 +114,23 @@ void usbhObjectInit(USBHDriver *usbh) {  }  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 -	uint8_t i; -	for (i = 0; i < HAL_USBHHUB_MAX_INSTANCES; i++) { -		usbhhubObjectInit(&USBHHUBD[i]); -	} +	usbhhubInit();  #endif  	usbh_lld_init();  } @@ -128,7 +147,6 @@ void usbhStart(USBHDriver *usbh) {  	osalSysUnlock();  } -  void usbhStop(USBHDriver *usbh) {  	//TODO: implement  	(void)usbh; @@ -181,6 +199,25 @@ static void _ep0_object_init(usbh_device_t *dev, uint16_t wMaxPacketSize) {  	usbhEPSetName(&dev->ctrl, "DEV[CTRL]");  } +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"); + +	usbh_urbstatus_t ret = usbhControlRequest(ep->device, +			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(); +	if ((ret == USBH_URBSTATUS_OK) && usbh_lld_ep_reset(ep)) { +		osalSysUnlock(); +		return HAL_SUCCESS; +	} +	osalSysUnlock(); +	return HAL_FAILED; +}  /*===========================================================================*/  /* URB API.                                                                  */ @@ -258,7 +295,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 +307,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 +338,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: @@ -382,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; @@ -408,7 +452,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, @@ -422,27 +466,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)) { @@ -455,8 +491,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)) { @@ -473,7 +516,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)) { @@ -482,25 +531,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; @@ -511,9 +552,15 @@ 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_REQTYPE_STANDARDIN(USBH_REQTYPE_RECIP_INTERFACE), +			USBH_REQ_GET_INTERFACE, +			0, +			bInterfaceNumber, +			1, &alt); -	usbh_urbstatus_t ret = usbhControlRequest(dev, USBH_GET_INTERFACE(bInterfaceNumber), 1, &alt);  	if (ret != USBH_URBSTATUS_OK)  		return HAL_FAILED; @@ -558,7 +605,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) @@ -611,22 +659,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; @@ -720,7 +758,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 -----"); @@ -856,7 +894,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, @@ -870,7 +908,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, @@ -934,7 +972,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); @@ -1086,7 +1124,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, @@ -1274,8 +1312,17 @@ 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_UVC +	&usbhuvcClassDriverInfo, +#endif  #if HAL_USBH_USE_HUB -	&usbhhubClassDriverInfo +	&usbhhubClassDriverInfo, +#endif +#if HAL_USBH_USE_AOA +	&usbhaoaClassDriverInfo,	/* Leave always last */  #endif  }; @@ -1302,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) @@ -1313,9 +1360,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;  } | 
