diff options
| author | Uladzimir Pylinski <barthess@yandex.ru> | 2016-02-17 21:18:15 +0300 | 
|---|---|---|
| committer | Uladzimir Pylinski <barthess@yandex.ru> | 2016-02-17 21:18:15 +0300 | 
| commit | 31066ddfbffd2ee801e63c090e30929bae5b0e43 (patch) | |
| tree | b165f84bc96d0dc961d4e570d1520dde06e5c70b /os/hal/include/usbh.h | |
| parent | d51d9c799f4ed64398f47945329b3138f44c8a37 (diff) | |
| parent | 771feb098db86458340ab2665dfb23bef970ace6 (diff) | |
| download | ChibiOS-Contrib-31066ddfbffd2ee801e63c090e30929bae5b0e43.tar.gz ChibiOS-Contrib-31066ddfbffd2ee801e63c090e30929bae5b0e43.tar.bz2 ChibiOS-Contrib-31066ddfbffd2ee801e63c090e30929bae5b0e43.zip  | |
Merge pull request #40 from fpoussin/usb-host-pull
USB-Host Driver
Merged pull request #40 from fpoussin/usb-host-pull 
Diffstat (limited to 'os/hal/include/usbh.h')
| -rw-r--r-- | os/hal/include/usbh.h | 439 | 
1 files changed, 439 insertions, 0 deletions
diff --git a/os/hal/include/usbh.h b/os/hal/include/usbh.h new file mode 100644 index 0000000..2f8f3dd --- /dev/null +++ b/os/hal/include/usbh.h @@ -0,0 +1,439 @@ +/*
 +    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
 +              Copyright (C) 2015 Diego Ismirlian, TISA, (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.
 +    You may obtain a copy of the License at
 +
 +        http://www.apache.org/licenses/LICENSE-2.0
 +
 +    Unless required by applicable law or agreed to in writing, software
 +    distributed under the License is distributed on an "AS IS" BASIS,
 +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +    See the License for the specific language governing permissions and
 +    limitations under the License.
 +*/
 +
 +#ifndef USBH_H_
 +#define USBH_H_
 +
 +#include "hal.h"
 +
 +#ifndef HAL_USE_USBH
 +#define HAL_USE_USBH FALSE
 +#endif
 +
 +#ifndef HAL_USBH_USE_FTDI
 +#define HAL_USBH_USE_FTDI FALSE
 +#endif
 +
 +#ifndef HAL_USBH_USE_HUB
 +#define HAL_USBH_USE_HUB FALSE
 +#endif
 +
 +#ifndef HAL_USBH_USE_MSD
 +#define HAL_USBH_USE_MSD FALSE
 +#endif
 +
 +#ifndef HAL_USBH_USE_UVC
 +#define HAL_USBH_USE_UVC FALSE
 +#endif
 +
 +#if HAL_USE_USBH
 +
 +#include "osal.h"
 +#include "usbh/list.h"
 +#include "usbh/defs.h"
 +
 +/* TODO:
 + *
 + * - Integrate VBUS power switching functionality to the API.
 + *
 + */
 +
 +
 +/*===========================================================================*/
 +/* Derived constants and error checks.                                       */
 +/*===========================================================================*/
 +
 +#if !HAL_USBH_USE_HUB
 +#define USBH_MAX_ADDRESSES				1
 +#else
 +#define USBH_MAX_ADDRESSES				(HAL_USBHHUB_MAX_PORTS + 1)
 +#endif
 +
 +enum usbh_status {
 +	USBH_STATUS_STOPPED = 0,
 +	USBH_STATUS_STARTED,
 +	USBH_STATUS_SUSPENDED,
 +};
 +
 +enum usbh_devstatus {
 +	USBH_DEVSTATUS_DISCONNECTED = 0,
 +	USBH_DEVSTATUS_ATTACHED,
 +	USBH_DEVSTATUS_CONNECTED,
 +	USBH_DEVSTATUS_DEFAULT,
 +	USBH_DEVSTATUS_ADDRESS,
 +	USBH_DEVSTATUS_CONFIGURED,
 +};
 +
 +enum usbh_devspeed {
 +	USBH_DEVSPEED_LOW = 0,
 +	USBH_DEVSPEED_FULL,
 +	USBH_DEVSPEED_HIGH,
 +};
 +
 +enum usbh_epdir {
 +	USBH_EPDIR_IN		= 0x80,
 +	USBH_EPDIR_OUT		= 0
 +};
 +
 +enum usbh_eptype {
 +	USBH_EPTYPE_CTRL	= 0,
 +	USBH_EPTYPE_ISO		= 1,
 +	USBH_EPTYPE_BULK	= 2,
 +	USBH_EPTYPE_INT		= 3,
 +};
 +
 +enum usbh_epstatus {
 +	USBH_EPSTATUS_UNINITIALIZED = 0,
 +	USBH_EPSTATUS_CLOSED,
 +	USBH_EPSTATUS_OPEN,
 +	USBH_EPSTATUS_HALTED,
 +};
 +
 +enum usbh_urbstatus {
 +	USBH_URBSTATUS_UNINITIALIZED = 0,
 +	USBH_URBSTATUS_INITIALIZED,
 +	USBH_URBSTATUS_PENDING,
 +//	USBH_URBSTATUS_QUEUED,
 +	USBH_URBSTATUS_ERROR,
 +	USBH_URBSTATUS_TIMEOUT,
 +	USBH_URBSTATUS_CANCELLED,
 +	USBH_URBSTATUS_STALL,
 +	USBH_URBSTATUS_DISCONNECTED,
 +//	USBH_URBSTATUS_EPCLOSED,
 +	USBH_URBSTATUS_OK,
 +};
 +
 +/*===========================================================================*/
 +/* Driver data structures and types.                                         */
 +/*===========================================================================*/
 +
 +/* forward declarations */
 +typedef struct USBHDriver USBHDriver;
 +typedef struct usbh_port usbh_port_t;
 +typedef	struct usbh_device usbh_device_t;
 +typedef struct usbh_ep usbh_ep_t;
 +typedef struct usbh_urb usbh_urb_t;
 +typedef struct usbh_baseclassdriver usbh_baseclassdriver_t;
 +typedef struct usbh_classdriverinfo usbh_classdriverinfo_t;
 +#if HAL_USBH_USE_HUB
 +typedef struct USBHHubDriver USBHHubDriver;
 +#endif
 +
 +/* typedefs */
 +typedef enum usbh_status usbh_status_t;
 +typedef enum usbh_devspeed usbh_devspeed_t;
 +typedef enum usbh_devstatus usbh_devstatus_t;
 +typedef enum usbh_epdir usbh_epdir_t;
 +typedef enum usbh_eptype usbh_eptype_t;
 +typedef enum usbh_epstatus usbh_epstatus_t;
 +typedef enum usbh_urbstatus usbh_urbstatus_t;
 +typedef uint16_t usbh_portstatus_t;
 +typedef uint16_t usbh_portcstatus_t;
 +typedef void (*usbh_completion_cb)(usbh_urb_t *);
 +
 +/* include the low level driver; the required definitions are above */
 +#include "usbh_lld.h"
 +
 +#define USBH_DEFINE_BUFFER(type, name)	USBH_LLD_DEFINE_BUFFER(type, name)
 +
 +struct usbh_urb {
 +	usbh_ep_t *ep;
 +
 +	void *userData;
 +	usbh_completion_cb callback;
 +
 +	const void *setup_buff;
 +	void *buff;
 +	uint32_t requestedLength;
 +	uint32_t actualLength;
 +
 +	usbh_urbstatus_t status;
 +
 +	thread_reference_t waitingThread;
 +	thread_reference_t abortingThread;
 +
 +	/* Low level part */
 +	_usbh_urb_ll_data
 +};
 +
 +struct usbh_ep {
 +	usbh_device_t		*device;
 +	usbh_ep_t	 		*next;
 +
 +	usbh_epstatus_t		status;
 +	uint8_t 			address;
 +	bool				in;
 +	usbh_eptype_t		type;
 +	uint16_t			wMaxPacketSize;
 +	uint8_t				bInterval;
 +
 +	/* debug */
 +	const char			*name;
 +
 +	/* Low-level part */
 +	_usbh_ep_ll_data
 +};
 +
 +struct usbh_device {
 +	USBHDriver *host;	/* shortcut to host */
 +
 +	usbh_ep_t ctrl;
 +	usbh_ep_t *endpoints;
 +
 +	usbh_baseclassdriver_t *drivers;
 +
 +	uint16_t langID0;
 +
 +	usbh_devstatus_t status;
 +	usbh_devspeed_t speed;
 +
 +	USBH_DEFINE_BUFFER(usbh_device_descriptor_t, devDesc);
 +	unsigned char align_bytes[2];
 +	USBH_DEFINE_BUFFER(usbh_config_descriptor_t, basicConfigDesc);
 +
 +	uint8_t *fullConfigurationDescriptor;
 +	uint8_t keepFullCfgDesc;
 +
 +	uint8_t address;
 +	uint8_t bConfiguration;
 +
 +	/* Low level part */
 +	_usbh_device_ll_data
 +};
 +
 +
 +struct usbh_port {
 +#if HAL_USBH_USE_HUB
 +	USBHHubDriver *hub;
 +#endif
 +
 +	usbh_portstatus_t status;
 +	usbh_portcstatus_t c_status;
 +
 +	usbh_port_t *next;
 +
 +	uint8_t number;
 +
 +	usbh_device_t device;
 +
 +	/* Low level part */
 +	_usbh_port_ll_data
 +};
 +
 +struct USBHDriver {
 +	usbh_status_t status;
 +	uint8_t address_bitmap[(USBH_MAX_ADDRESSES + 7) / 8];
 +
 +	usbh_port_t rootport;
 +
 +#if HAL_USBH_USE_HUB
 +	struct list_head hubs;
 +#endif
 +
 +	/* Low level part */
 +	_usbhdriver_ll_data
 +
 +#if USBH_DEBUG_ENABLE
 +	/* debug */
 +	uint8_t dbg_buff[USBH_DEBUG_BUFFER];
 +	THD_WORKING_AREA(waDebug, 512);
 +	input_queue_t iq;
 +#endif
 +};
 +
 +
 +
 +/*===========================================================================*/
 +/* External declarations.                                                    */
 +/*===========================================================================*/
 +
 +#if STM32_USBH_USE_OTG1
 +extern USBHDriver USBHD1;
 +#endif
 +
 +#if STM32_USBH_USE_OTG2
 +extern USBHDriver USBHD2;
 +#endif
 +
 +
 +/*===========================================================================*/
 +/* Main driver API.		                                                     */
 +/*===========================================================================*/
 +
 +#ifdef __cplusplus
 +extern "C" {
 +#endif
 +
 +	/* Main functions */
 +	void usbhObjectInit(USBHDriver *usbh);
 +	void usbhInit(void);
 +	void usbhStart(USBHDriver *usbh);
 +	void usbhStop(USBHDriver *usbh);
 +	void usbhSuspend(USBHDriver *usbh);
 +	void usbhResume(USBHDriver *usbh);
 +
 +	/* Device-related */
 +#if	USBH_DEBUG_ENABLE && USBH_DEBUG_ENABLE_INFO
 +	void usbhDevicePrintInfo(usbh_device_t *dev);
 +	void usbhDevicePrintConfiguration(const uint8_t *descriptor, uint16_t rem);
 +#else
 +#	define usbhDevicePrintInfo(dev) do {} while(0)
 +#	define usbhDevicePrintConfiguration(descriptor, rem) do {} while(0)
 +#endif
 +	bool usbhDeviceReadString(usbh_device_t *dev, char *dest, uint8_t size,
 +			uint8_t index, uint16_t langID);
 +	static inline usbh_port_t *usbhDeviceGetPort(usbh_device_t *dev) {
 +		return container_of(dev, usbh_port_t, device);
 +	}
 +
 +	/* Synchronous API */
 +	usbh_urbstatus_t usbhBulkTransfer(usbh_ep_t *ep,
 +			void *data,
 +			uint32_t len,
 +			uint32_t *actual_len,
 +			systime_t timeout);
 +	usbh_urbstatus_t usbhControlRequest(usbh_device_t *dev,
 +			uint8_t bmRequestType,
 +			uint8_t bRequest,
 +			uint16_t wValue,
 +			uint16_t wIndex,
 +			uint16_t wLength,
 +			uint8_t *buff);
 +	usbh_urbstatus_t usbhControlRequestExtended(usbh_device_t *dev,
 +			const usbh_control_request_t *req,
 +			uint8_t *buff,
 +			uint32_t *actual_len,
 +			systime_t timeout);
 +
 +	/* Standard request helpers */
 +	bool usbhStdReqGetDeviceDescriptor(usbh_device_t *dev,
 +			uint16_t wLength,
 +			uint8_t *buf);
 +	bool usbhStdReqGetConfigurationDescriptor(usbh_device_t *dev,
 +			uint8_t index,
 +			uint16_t wLength,
 +			uint8_t *buf);
 +	bool usbhStdReqGetStringDescriptor(usbh_device_t *dev,
 +			uint8_t index,
 +			uint16_t langID,
 +			uint16_t wLength,
 +			uint8_t *buf);
 +	bool usbhStdReqSetInterface(usbh_device_t *dev,
 +			uint8_t bInterfaceNumber,
 +			uint8_t bAlternateSetting);
 +	bool usbhStdReqGetInterface(usbh_device_t *dev,
 +			uint8_t bInterfaceNumber,
 +			uint8_t *bAlternateSetting);
 +
 +	/* Endpoint/pipe management */
 +	void usbhEPObjectInit(usbh_ep_t *ep, usbh_device_t *dev, const usbh_endpoint_descriptor_t *desc);
 +	static inline void usbhEPOpen(usbh_ep_t *ep) {
 +		osalDbgCheck(ep != 0);
 +		osalSysLock();
 +		osalDbgAssert(ep->status == USBH_EPSTATUS_CLOSED, "invalid state");
 +		usbh_lld_ep_open(ep);
 +		ep->next = ep->device->endpoints;
 +		ep->device->endpoints = ep;
 +		osalSysUnlock();
 +	}
 +	static inline void usbhEPCloseS(usbh_ep_t *ep) {
 +		osalDbgCheck(ep != 0);
 +		osalDbgCheckClassS();
 +		osalDbgAssert(ep->status != USBH_EPSTATUS_UNINITIALIZED, "invalid state");
 +		if (ep->status == USBH_EPSTATUS_CLOSED) {
 +			osalOsRescheduleS();
 +			return;
 +		}
 +		usbh_lld_ep_close(ep);
 +	}
 +	static inline void usbhEPClose(usbh_ep_t *ep) {
 +		osalSysLock();
 +		usbhEPCloseS(ep);
 +		osalSysUnlock();
 +	}
 +	static inline void usbhEPResetI(usbh_ep_t *ep) {
 +		osalDbgCheckClassI();
 +		osalDbgCheck(ep != NULL);
 +		usbh_lld_epreset(ep);
 +	}
 +	static inline bool usbhEPIsPeriodic(usbh_ep_t *ep) {
 +		osalDbgCheck(ep != NULL);
 +		return (ep->type & 1) != 0;
 +	}
 +	static inline bool usbhURBIsBusy(usbh_urb_t *urb) {
 +		osalDbgCheck(urb != NULL);
 +		return (urb->status == USBH_URBSTATUS_PENDING);
 +	}
 +	static inline void usbhEPSetName(usbh_ep_t *ep, const char *name) {
 +		ep->name = name;
 +	}
 +
 +	/* URB management */
 +	void usbhURBObjectInit(usbh_urb_t *urb, usbh_ep_t *ep, usbh_completion_cb callback,
 +			void *user, void *buff, uint32_t len);
 +	void usbhURBObjectResetI(usbh_urb_t *urb);
 +	void usbhURBSubmitI(usbh_urb_t *urb);
 +	bool usbhURBCancelI(usbh_urb_t *urb);
 +	msg_t usbhURBSubmitAndWaitS(usbh_urb_t *urb, systime_t timeout);
 +	void usbhURBCancelAndWaitS(usbh_urb_t *urb);
 +	msg_t usbhURBWaitTimeoutS(usbh_urb_t *urb, systime_t timeout);
 +
 +	/* Main loop */
 +	void usbhMainLoop(USBHDriver *usbh);
 +
 +#ifdef __cplusplus
 +}
 +#endif
 +
 +
 +/*===========================================================================*/
 +/* Class driver definitions and API.                                         */
 +/*===========================================================================*/
 +
 +typedef struct usbh_classdriver_vmt usbh_classdriver_vmt_t;
 +struct usbh_classdriver_vmt {
 +	usbh_baseclassdriver_t *(*load)(usbh_device_t *dev,	const uint8_t *descriptor, uint16_t rem);
 +	void (*unload)(usbh_baseclassdriver_t *drv);
 +};
 +
 +struct usbh_classdriverinfo {
 +	int16_t class;
 +	int16_t subclass;
 +	int16_t protocol;
 +	const char *name;
 +	const usbh_classdriver_vmt_t *vmt;
 +};
 +
 +#define _usbh_base_classdriver_data		\
 +	const usbh_classdriverinfo_t *info;	\
 +	usbh_device_t *dev;					\
 +	usbh_baseclassdriver_t *next;
 +
 +struct usbh_baseclassdriver {
 +	_usbh_base_classdriver_data
 +};
 +
 +
 +/*===========================================================================*/
 +/* Helper functions.				                                         */
 +/*===========================================================================*/
 +#include <usbh/desciter.h>	/* descriptor iterators */
 +#include <usbh/debug.h>		/* debug */
 +
 +#endif
 +
 +#endif /* USBH_H_ */
  | 
