aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/include/usbh
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal/include/usbh')
-rw-r--r--os/hal/include/usbh/debug.h6
-rw-r--r--os/hal/include/usbh/defs.h43
-rw-r--r--os/hal/include/usbh/desciter.h4
-rw-r--r--os/hal/include/usbh/dev/aoa.h152
-rw-r--r--os/hal/include/usbh/dev/ftdi.h17
-rw-r--r--os/hal/include/usbh/dev/hid.h144
-rw-r--r--os/hal/include/usbh/dev/hub.h25
-rw-r--r--os/hal/include/usbh/dev/msd.h35
-rw-r--r--os/hal/include/usbh/dev/uvc.h459
-rw-r--r--os/hal/include/usbh/internal.h58
-rw-r--r--os/hal/include/usbh/list.h352
11 files changed, 1007 insertions, 288 deletions
diff --git a/os/hal/include/usbh/debug.h b/os/hal/include/usbh/debug.h
index 5120121..d3bdee7 100644
--- a/os/hal/include/usbh/debug.h
+++ b/os/hal/include/usbh/debug.h
@@ -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.
@@ -23,8 +23,6 @@
#if HAL_USE_USBH
-//TODO: Debug is only for USBHD1, make it generic.
-
#if USBH_DEBUG_ENABLE
void usbDbgPrintf(const char *fmt, ...);
void usbDbgPuts(const char *s);
diff --git a/os/hal/include/usbh/defs.h b/os/hal/include/usbh/defs.h
index c3d8a9a..5e0c466 100644
--- a/os/hal/include/usbh/defs.h
+++ b/os/hal/include/usbh/defs.h
@@ -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.
@@ -25,12 +25,12 @@
#include "osal.h"
#ifdef __IAR_SYSTEMS_ICC__
-#define PACKED_STRUCT typedef PACKED_VAR struct
+#define PACKED_STRUCT PACKED_VAR struct
#else
-#define PACKED_STRUCT typedef struct PACKED_VAR
+#define PACKED_STRUCT struct PACKED_VAR
#endif
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
@@ -49,7 +49,7 @@ PACKED_STRUCT {
#define USBH_DT_DEVICE 0x01
#define USBH_DT_DEVICE_SIZE 18
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
@@ -62,7 +62,7 @@ PACKED_STRUCT {
#define USBH_DT_CONFIG 0x02
#define USBH_DT_CONFIG_SIZE 9
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wData[1];
@@ -70,7 +70,7 @@ PACKED_STRUCT {
#define USBH_DT_STRING 0x03
#define USBH_DT_STRING_SIZE 2
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
@@ -84,7 +84,7 @@ PACKED_STRUCT {
#define USBH_DT_INTERFACE 0x04
#define USBH_DT_INTERFACE_SIZE 9
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
@@ -95,7 +95,7 @@ PACKED_STRUCT {
#define USBH_DT_ENDPOINT 0x05
#define USBH_DT_ENDPOINT_SIZE 7
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bFirstInterface;
@@ -108,7 +108,7 @@ PACKED_STRUCT {
#define USBH_DT_INTERFACE_ASSOCIATION 0x0b
#define USBH_DT_INTERFACE_ASSOCIATION_SIZE 8
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bDescLength;
uint8_t bDescriptorType;
uint8_t bNbrPorts;
@@ -120,7 +120,7 @@ PACKED_STRUCT {
#define USBH_DT_HUB 0x29
#define USBH_DT_HUB_SIZE (7 + 4)
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
@@ -141,18 +141,17 @@ PACKED_STRUCT {
#define USBH_REQ_SET_INTERFACE 0x0B
#define USBH_REQ_SYNCH_FRAME 0x0C
+#define USBH_REQTYPE_DIR_IN 0x80
+#define USBH_REQTYPE_DIR_OUT 0x00
-#define USBH_REQTYPE_IN 0x80
-#define USBH_REQTYPE_OUT 0x00
+#define USBH_REQTYPE_TYPE_STANDARD 0x00
+#define USBH_REQTYPE_TYPE_CLASS 0x20
+#define USBH_REQTYPE_TYPE_VENDOR 0x40
-#define USBH_REQTYPE_STANDARD 0x00
-#define USBH_REQTYPE_CLASS 0x20
-#define USBH_REQTYPE_VENDOR 0x40
-
-#define USBH_REQTYPE_DEVICE 0x00
-#define USBH_REQTYPE_INTERFACE 0x01
-#define USBH_REQTYPE_ENDPOINT 0x02
-#define USBH_REQTYPE_OTHER 0x03
+#define USBH_REQTYPE_RECIP_DEVICE 0x00
+#define USBH_REQTYPE_RECIP_INTERFACE 0x01
+#define USBH_REQTYPE_RECIP_ENDPOINT 0x02
+#define USBH_REQTYPE_RECIP_OTHER 0x03
#endif
diff --git a/os/hal/include/usbh/desciter.h b/os/hal/include/usbh/desciter.h
index 52b0c98..142bd3c 100644
--- a/os/hal/include/usbh/desciter.h
+++ b/os/hal/include/usbh/desciter.h
@@ -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.
diff --git a/os/hal/include/usbh/dev/aoa.h b/os/hal/include/usbh/dev/aoa.h
new file mode 100644
index 0000000..a7f1c1b
--- /dev/null
+++ b/os/hal/include/usbh/dev/aoa.h
@@ -0,0 +1,152 @@
+/*
+ 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.
+ 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_AOA_H_
+#define USBH_AOA_H_
+
+#include "hal_usbh.h"
+
+#if HAL_USE_USBH && HAL_USBH_USE_AOA
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+typedef enum {
+ USBHAOA_CHANNEL_STATE_UNINIT = 0,
+ USBHAOA_CHANNEL_STATE_STOP = 1,
+ USBHAOA_CHANNEL_STATE_ACTIVE = 2,
+ USBHAOA_CHANNEL_STATE_READY = 3
+} usbhaoa_channel_state_t;
+
+typedef enum {
+ USBHAOA_STATE_UNINIT = 0,
+ USBHAOA_STATE_STOP = 1,
+ USBHAOA_STATE_ACTIVE = 2,
+ USBHAOA_STATE_READY = 3
+} usbhaoa_state_t;
+
+typedef enum {
+ USBHAOA_AUDIO_MODE_DISABLED = 0,
+ USBHAOA_AUDIO_MODE_2CH_16BIT_PCM_44100 = 1,
+} usbhaoa_audio_mode_t;
+
+typedef struct {
+ struct _aoa_channel_cfg {
+ const char *manufacturer;
+ const char *model;
+ const char *description;
+ const char *version;
+ const char *uri;
+ const char *serial;
+ } channel;
+
+ struct _aoa_audio_cfg {
+ usbhaoa_audio_mode_t mode;
+ } audio;
+
+} USBHAOAConfig;
+
+#define _aoa_driver_methods \
+ _base_asynchronous_channel_methods
+
+struct AOADriverVMT {
+ _aoa_driver_methods
+};
+
+typedef struct USBHAOAChannel USBHAOAChannel;
+typedef struct USBHAOADriver USBHAOADriver;
+
+struct USBHAOAChannel {
+ /* inherited from abstract asyncrhonous channel driver */
+ const struct AOADriverVMT *vmt;
+ _base_asynchronous_channel_data
+
+ usbh_ep_t epin;
+ usbh_urb_t iq_urb;
+ threads_queue_t iq_waiting;
+ uint32_t iq_counter;
+ USBH_DECLARE_STRUCT_MEMBER(uint8_t iq_buff[64]);
+ uint8_t *iq_ptr;
+
+ usbh_ep_t epout;
+ usbh_urb_t oq_urb;
+ threads_queue_t oq_waiting;
+ uint32_t oq_counter;
+ USBH_DECLARE_STRUCT_MEMBER(uint8_t oq_buff[64]);
+ uint8_t *oq_ptr;
+
+ virtual_timer_t vt;
+
+ usbhaoa_channel_state_t state;
+};
+
+struct USBHAOADriver {
+ /* inherited from abstract class driver */
+ _usbh_base_classdriver_data
+
+ USBHAOAChannel channel;
+
+ usbhaoa_state_t state;
+
+};
+
+#define USBHAOA_ACCESSORY_STRING_MANUFACTURER 0
+#define USBHAOA_ACCESSORY_STRING_MODEL 1
+#define USBHAOA_ACCESSORY_STRING_DESCRIPTION 2
+#define USBHAOA_ACCESSORY_STRING_VERSION 3
+#define USBHAOA_ACCESSORY_STRING_URI 4
+#define USBHAOA_ACCESSORY_STRING_SERIAL 5
+
+typedef bool (*usbhaoa_filter_callback_t)(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem, USBHAOAConfig *config);
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+#define usbhaoaStop(aoap)
+
+#define usbhaoaGetState(aoap) ((aoap)->state)
+
+#define usbhaoaGetChannelState(aoap) ((aoap)->channel.state)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+extern USBHAOADriver USBHAOAD[HAL_USBHAOA_MAX_INSTANCES];
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ /* AOA device driver */
+ void usbhaoaChannelStart(USBHAOADriver *aoap);
+ void usbhaoaChannelStop(USBHAOADriver *aoap);
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
+#endif /* USBH_AOA_H_ */
diff --git a/os/hal/include/usbh/dev/ftdi.h b/os/hal/include/usbh/dev/ftdi.h
index ad6b4cd..eedb056 100644
--- a/os/hal/include/usbh/dev/ftdi.h
+++ b/os/hal/include/usbh/dev/ftdi.h
@@ -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.
@@ -96,7 +96,7 @@ struct USBHFTDIPortDriver {
usbh_urb_t iq_urb;
threads_queue_t iq_waiting;
uint32_t iq_counter;
- USBH_DEFINE_BUFFER(uint8_t, iq_buff[64]);
+ USBH_DECLARE_STRUCT_MEMBER(uint8_t iq_buff[64]);
uint8_t *iq_ptr;
@@ -104,7 +104,7 @@ struct USBHFTDIPortDriver {
usbh_urb_t oq_urb;
threads_queue_t oq_waiting;
uint32_t oq_counter;
- USBH_DEFINE_BUFFER(uint8_t, oq_buff[64]);
+ USBH_DECLARE_STRUCT_MEMBER(uint8_t oq_buff[64]);
uint8_t *oq_ptr;
virtual_timer_t vt;
@@ -113,7 +113,7 @@ struct USBHFTDIPortDriver {
USBHFTDIPortDriver *next;
};
-typedef struct USBHFTDIDriver {
+struct USBHFTDIDriver {
/* inherited from abstract class driver */
_usbh_base_classdriver_data
@@ -121,11 +121,12 @@ typedef struct USBHFTDIDriver {
USBHFTDIPortDriver *ports;
mutex_t mtx;
-} USBHFTDIDriver;
+};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
+#define usbhftdipGetState(ftdipp) ((ftdipp)->state)
/*===========================================================================*/
@@ -137,11 +138,7 @@ extern USBHFTDIPortDriver FTDIPD[HAL_USBHFTDI_MAX_PORTS];
#ifdef __cplusplus
extern "C" {
#endif
- /* FTDI device driver */
- void usbhftdiObjectInit(USBHFTDIDriver *ftdip);
-
/* FTDI port driver */
- void usbhftdipObjectInit(USBHFTDIPortDriver *ftdipp);
void usbhftdipStart(USBHFTDIPortDriver *ftdipp, const USBHFTDIPortConfig *config);
void usbhftdipStop(USBHFTDIPortDriver *ftdipp);
#ifdef __cplusplus
diff --git a/os/hal/include/usbh/dev/hid.h b/os/hal/include/usbh/dev/hid.h
new file mode 100644
index 0000000..c7371ee
--- /dev/null
+++ b/os/hal/include/usbh/dev/hid.h
@@ -0,0 +1,144 @@
+/*
+ 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.
+ 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_HID_H_
+#define USBH_HID_H_
+
+#include "hal_usbh.h"
+
+#if HAL_USE_USBH && HAL_USBH_USE_HID
+
+/* TODO:
+ *
+ */
+
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+#if !defined(HAL_USBHHID_USE_INTERRUPT_OUT)
+#define HAL_USBHHID_USE_INTERRUPT_OUT FALSE
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+typedef enum {
+ USBHHID_STATE_UNINIT = 0,
+ USBHHID_STATE_STOP = 1,
+ USBHHID_STATE_ACTIVE = 2,
+ USBHHID_STATE_READY = 3
+} usbhhid_state_t;
+
+typedef enum {
+ USBHHID_DEVTYPE_GENERIC = 0,
+ USBHHID_DEVTYPE_BOOT_KEYBOARD = 1,
+ USBHHID_DEVTYPE_BOOT_MOUSE = 2,
+} usbhhid_devtype_t;
+
+typedef enum {
+ USBHHID_REPORTTYPE_INPUT = 1,
+ USBHHID_REPORTTYPE_OUTPUT = 2,
+ USBHHID_REPORTTYPE_FEATURE = 3,
+} usbhhid_reporttype_t;
+
+typedef enum {
+ USBHHID_PROTOCOL_BOOT = 0,
+ USBHHID_PROTOCOL_REPORT = 1,
+} usbhhid_protocol_t;
+
+typedef struct USBHHIDDriver USBHHIDDriver;
+typedef struct USBHHIDConfig USBHHIDConfig;
+
+typedef void (*usbhhid_report_callback)(USBHHIDDriver *hidp, uint16_t len);
+
+struct USBHHIDConfig {
+ usbhhid_report_callback cb_report;
+ void *report_buffer;
+ uint16_t report_len;
+ usbhhid_protocol_t protocol;
+};
+
+struct USBHHIDDriver {
+ /* inherited from abstract class driver */
+ _usbh_base_classdriver_data
+
+ usbh_ep_t epin;
+#if HAL_USBHHID_USE_INTERRUPT_OUT
+ usbh_ep_t epout;
+#endif
+ uint8_t ifnum;
+
+ usbhhid_devtype_t type;
+ usbhhid_state_t state;
+
+ usbh_urb_t in_urb;
+
+ const USBHHIDConfig *config;
+
+ semaphore_t sem;
+};
+
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+extern USBHHIDDriver USBHHIDD[HAL_USBHHID_MAX_INSTANCES];
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ /* HID Common API */
+ usbh_urbstatus_t usbhhidGetReport(USBHHIDDriver *hidp,
+ uint8_t report_id, usbhhid_reporttype_t report_type,
+ void *data, uint16_t len);
+ usbh_urbstatus_t usbhhidSetReport(USBHHIDDriver *hidp,
+ uint8_t report_id, usbhhid_reporttype_t report_type,
+ const void *data, uint16_t len);
+ usbh_urbstatus_t usbhhidGetIdle(USBHHIDDriver *hidp, uint8_t report_id, uint8_t *duration);
+ usbh_urbstatus_t usbhhidSetIdle(USBHHIDDriver *hidp, uint8_t report_id, uint8_t duration);
+ usbh_urbstatus_t usbhhidGetProtocol(USBHHIDDriver *hidp, uint8_t *protocol);
+ usbh_urbstatus_t usbhhidSetProtocol(USBHHIDDriver *hidp, uint8_t protocol);
+
+ static inline uint8_t usbhhidGetType(USBHHIDDriver *hidp) {
+ return hidp->type;
+ }
+
+ static inline usbhhid_state_t usbhhidGetState(USBHHIDDriver *hidp) {
+ return hidp->state;
+ }
+
+ void usbhhidStart(USBHHIDDriver *hidp, const USBHHIDConfig *cfg);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif /* USBH_HID_H_ */
diff --git a/os/hal/include/usbh/dev/hub.h b/os/hal/include/usbh/dev/hub.h
index 07e88e6..406fbaf 100644
--- a/os/hal/include/usbh/dev/hub.h
+++ b/os/hal/include/usbh/dev/hub.h
@@ -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.
@@ -23,7 +23,7 @@
#if HAL_USE_USBH
#if HAL_USBH_USE_HUB
-typedef struct USBHHubDriver {
+struct USBHHubDriver {
/* inherited from abstract class driver */
_usbh_base_classdriver_data
@@ -32,19 +32,19 @@ typedef struct USBHHubDriver {
usbh_ep_t epint;
usbh_urb_t urb;
- USBH_DEFINE_BUFFER(uint8_t, scbuff[4]);
+ USBH_DECLARE_STRUCT_MEMBER(uint8_t scbuff[4]);
volatile uint32_t statuschange;
uint16_t status;
uint16_t c_status;
usbh_port_t *ports;
- USBH_DEFINE_BUFFER(usbh_hub_descriptor_t, hubDesc);
+ USBH_DECLARE_STRUCT_MEMBER(usbh_hub_descriptor_t hubDesc);
/* Low level part */
_usbh_hub_ll_data
-} USBHHubDriver;
+};
extern USBHHubDriver USBHHUBD[HAL_USBHHUB_MAX_INSTANCES];
@@ -60,7 +60,7 @@ usbh_urbstatus_t usbhhubControlRequest(USBHDriver *host, USBHHubDriver *hub,
static inline usbh_urbstatus_t usbhhubClearFeaturePort(usbh_port_t *port, uint8_t feature) {
return usbhhubControlRequest(port->device.host, port->hub,
- USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER,
+ USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER,
USBH_REQ_CLEAR_FEATURE,
feature,
port->number,
@@ -70,7 +70,7 @@ static inline usbh_urbstatus_t usbhhubClearFeaturePort(usbh_port_t *port, uint8_
static inline usbh_urbstatus_t usbhhubClearFeatureHub(USBHDriver *host, USBHHubDriver *hub, uint8_t feature) {
return usbhhubControlRequest(host, hub,
- USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE,
+ USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE,
USBH_REQ_CLEAR_FEATURE,
feature,
0,
@@ -80,7 +80,7 @@ static inline usbh_urbstatus_t usbhhubClearFeatureHub(USBHDriver *host, USBHHubD
static inline usbh_urbstatus_t usbhhubSetFeaturePort(usbh_port_t *port, uint8_t feature) {
return usbhhubControlRequest(port->device.host, port->hub,
- 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,
feature,
port->number,
@@ -88,7 +88,6 @@ static inline usbh_urbstatus_t usbhhubSetFeaturePort(usbh_port_t *port, uint8_t
0);
}
-void usbhhubObjectInit(USBHHubDriver *hubdp);
#else
static inline usbh_urbstatus_t usbhhubControlRequest(USBHDriver *host,
@@ -103,7 +102,7 @@ static inline usbh_urbstatus_t usbhhubControlRequest(USBHDriver *host,
static inline usbh_urbstatus_t usbhhubClearFeaturePort(usbh_port_t *port, uint8_t feature) {
return usbhhubControlRequest(port->device.host,
- USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER,
+ USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER,
USBH_REQ_CLEAR_FEATURE,
feature,
port->number,
@@ -113,7 +112,7 @@ static inline usbh_urbstatus_t usbhhubClearFeaturePort(usbh_port_t *port, uint8_
static inline usbh_urbstatus_t usbhhubClearFeatureHub(USBHDriver *host, uint8_t feature) {
return usbhhubControlRequest(host,
- USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE,
+ USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE,
USBH_REQ_CLEAR_FEATURE,
feature,
0,
@@ -123,7 +122,7 @@ static inline usbh_urbstatus_t usbhhubClearFeatureHub(USBHDriver *host, uint8_t
static inline usbh_urbstatus_t usbhhubSetFeaturePort(usbh_port_t *port, uint8_t feature) {
return usbhhubControlRequest(port->device.host,
- 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,
feature,
port->number,
diff --git a/os/hal/include/usbh/dev/msd.h b/os/hal/include/usbh/dev/msd.h
index d164618..eedd474 100644
--- a/os/hal/include/usbh/dev/msd.h
+++ b/os/hal/include/usbh/dev/msd.h
@@ -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.
@@ -25,7 +25,6 @@
/* TODO:
*
* - Implement of conditional compilation of multiple-luns per instance.
- * - Implement error checking and recovery when commands fail.
*
*/
@@ -59,30 +58,15 @@ struct USBHMassStorageLUNDriver {
const struct USBHMassStorageDriverVMT *vmt;
_base_block_device_data
+ /* for serializing access to the LUN driver */
+ semaphore_t sem;
+
BlockDeviceInfo info;
USBHMassStorageDriver *msdp;
USBHMassStorageLUNDriver *next;
};
-typedef struct USBHMassStorageDriver {
- /* inherited from abstract class driver */
- _usbh_base_classdriver_data
-
- /* for LUN request serialization, can be removed
- * if the driver is configured to support only one LUN
- * per USBHMassStorageDriver instance */
- mutex_t mtx;
-
- usbh_ep_t epin;
- usbh_ep_t epout;
- uint8_t ifnum;
- uint8_t max_lun;
- uint32_t tag;
-
- USBHMassStorageLUNDriver *luns;
-} USBHMassStorageDriver;
-
/*===========================================================================*/
/* Driver macros. */
@@ -94,18 +78,13 @@ typedef struct USBHMassStorageDriver {
/*===========================================================================*/
extern USBHMassStorageLUNDriver MSBLKD[HAL_USBHMSD_MAX_LUNS];
-extern USBHMassStorageDriver USBHMSD[HAL_USBHMSD_MAX_INSTANCES];
#ifdef __cplusplus
extern "C" {
#endif
- /* Mass Storage Driver */
- void usbhmsdObjectInit(USBHMassStorageDriver *msdp);
-
/* Mass Storage LUN Driver (block driver) */
- void usbhmsdLUNObjectInit(USBHMassStorageLUNDriver *lunp);
- void usbhmsdLUNStart(USBHMassStorageLUNDriver *lunp);
- void usbhmsdLUNStop(USBHMassStorageLUNDriver *lunp);
+// void usbhmsdLUNStart(USBHMassStorageLUNDriver *lunp);
+// void usbhmsdLUNStop(USBHMassStorageLUNDriver *lunp);
bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp);
bool usbhmsdLUNDisconnect(USBHMassStorageLUNDriver *lunp);
bool usbhmsdLUNRead(USBHMassStorageLUNDriver *lunp, uint32_t startblk,
diff --git a/os/hal/include/usbh/dev/uvc.h b/os/hal/include/usbh/dev/uvc.h
new file mode 100644
index 0000000..0477312
--- /dev/null
+++ b/os/hal/include/usbh/dev/uvc.h
@@ -0,0 +1,459 @@
+/*
+ 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.
+ 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_INCLUDE_USBH_UVC_H_
+#define USBH_INCLUDE_USBH_UVC_H_
+
+#include "hal_usbh.h"
+
+#if HAL_USE_USBH && HAL_USBH_USE_UVC
+
+#include "usbh/desciter.h"
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+#define USBHUVC_MAX_STATUS_PACKET_SZ 16
+
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+
+typedef enum {
+ UVC_CS_INTERFACE = 0x24,
+ UVC_CS_ENDPOINT = 0x25
+} usbh_uvc_cstype_t;
+
+typedef enum {
+ UVC_CC_VIDEO = 0x0e
+} usbh_uvc_cctype_t;
+
+typedef enum {
+ UVC_SC_UNKNOWN = 0x00,
+ UVC_SC_VIDEOCONTROL,
+ UVC_SC_VIDEOSTREAMING,
+ UVC_SC_VIDEO_INTERFACE_COLLECTION
+} usbh_uvc_sctype_t;
+
+typedef enum {
+ UVC_VC_UNDEF = 0x00,
+ UVC_VC_HEADER,
+ UVC_VC_INPUT_TERMINAL,
+ UVC_VC_OUTPUT_TERMINAL,
+ UVC_VC_SELECTOR_UNIT,
+ UVC_VC_PROCESSING_UNIT,
+ UVC_VC_EXTENSION_UNIT
+} usbh_uvc_vctype_t;
+
+typedef enum {
+ UVC_VS_UNDEF = 0x00,
+ UVC_VS_INPUT_HEADER,
+ UVC_VS_OUTPUT_HEADER,
+ UVC_VS_STILL_IMAGE_FRAME,
+ UVC_VS_FORMAT_UNCOMPRESSED,
+ UVC_VS_FRAME_UNCOMPRESSED,
+ UVC_VS_FORMAT_MJPEG,
+ UVC_VS_FRAME_MJPEG,
+ UVC_VS_RESERVED_0,
+ UVC_VS_RESERVED_1,
+ UVC_VS_FORMAT_MPEG2TS,
+ UVC_VS_RESERVED_2,
+ UVC_VS_FORMAT_DV,
+ UVC_VS_COLOR_FORMAT,
+ UVC_VS_RESERVED_3,
+ UVC_VS_RESERVED_4,
+ UVC_VS_FORMAT_FRAME_BASED,
+ UVC_VS_FRAME_FRAME_BASED,
+ UVC_VS_FORMAT_STREAM_BASED
+} usbh_uvc_vstype_t;
+
+typedef enum {
+ UVC_TT_VENDOR_SPECIFIC = 0x0100,
+ UVC_TT_STREAMING = 0x0101,
+ UVC_ITT_VENDOR_SPECIFIC = 0x0200,
+ UVC_ITT_CAMERA = 0x0201,
+ UVC_ITT_MEDIA_TRANSPORT_INPUT = 0x0202,
+ UVC_OTT_VENDOR_SPECIFIC = 0x0300,
+ UVC_OTT_DISPLAY = 0x0301,
+ UVC_OTT_MEDIA_TRANSPORT = 0x0302
+} usbh_uvc_tttype_t;
+
+typedef enum {
+ UVC_SET_CUR = 0x01,
+ UVC_GET_CUR = 0x81,
+ UVC_GET_MIN = 0x82,
+ UVC_GET_MAX = 0x83,
+ UVC_GET_RES = 0x84,
+ UVC_GET_LEN = 0x85,
+ UVC_GET_INFO = 0x86,
+ UVC_GET_DEF = 0x87
+} usbh_uvc_ctrlops_t;
+
+typedef enum {
+ UVC_CTRL_VC_CONTROL_UNDEFINED = 0x00,
+ UVC_CTRL_VC_VIDEO_POWER_MODE_CONTROL = 0x01,
+ UVC_CTRL_VC_REQUEST_ERROR_CODE_CONTROL = 0x02,
+} usbh_uvc_ctrl_vc_interface_controls_t;
+
+typedef enum {
+ UVC_CTRL_SU_CONTROL_UNDEFINED = 0x00,
+ UVC_CTRL_SU_INPUT_SELECT_CONTROL = 0x01,
+} usbh_uvc_ctrl_vc_selectorunit_controls_t;
+
+typedef enum {
+ UVC_CTRL_CT_CONTROL_UNDEFINED = 0x00,
+ UVC_CTRL_CT_SCANNING_MODE_CONTROL = 0x01,
+ UVC_CTRL_CT_AE_MODE_CONTROL = 0x02,
+ UVC_CTRL_CT_AE_PRIORITY_CONTROL = 0x03,
+ UVC_CTRL_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL = 0x04,
+ UVC_CTRL_CT_EXPOSURE_TIME_RELATIVE_CONTROL = 0x05,
+ UVC_CTRL_CT_FOCUS_ABSOLUTE_CONTROL = 0x06,
+ UVC_CTRL_CT_FOCUS_RELATIVE_CONTROL = 0x07,
+ UVC_CTRL_CT_FOCUS_AUTO_CONTROL = 0x08,
+ UVC_CTRL_CT_IRIS_ABSOLUTE_CONTROL = 0x09,
+ UVC_CTRL_CT_IRIS_RELATIVE_CONTROL = 0x0A,
+ UVC_CTRL_CT_ZOOM_ABSOLUTE_CONTROL = 0x0B,
+ UVC_CTRL_CT_ZOOM_RELATIVE_CONTROL = 0x0C,
+ UVC_CTRL_CT_PANTILT_ABSOLUTE_CONTROL = 0x0D,
+ UVC_CTRL_CT_PANTILT_RELATIVE_CONTROL = 0x0E,
+ UVC_CTRL_CT_ROLL_ABSOLUTE_CONTROL = 0x0F,
+ UVC_CTRL_CT_ROLL_RELATIVE_CONTROL = 0x10,
+ UVC_CTRL_CT_PRIVACY_CONTROL = 0x11
+} usbh_uvc_ctrl_vc_cameraterminal_controls_t;
+
+typedef enum {
+ UVC_CTRL_PU_CONTROL_UNDEFINED = 0x00,
+ UVC_CTRL_PU_BACKLIGHT_COMPENSATION_CONTROL = 0x01,
+ UVC_CTRL_PU_BRIGHTNESS_CONTROL = 0x02,
+ UVC_CTRL_PU_CONTRAST_CONTROL = 0x03,
+ UVC_CTRL_PU_GAIN_CONTROL = 0x04,
+ UVC_CTRL_PU_POWER_LINE_FREQUENCY_CONTROL = 0x05,
+ UVC_CTRL_PU_HUE_CONTROL = 0x06,
+ UVC_CTRL_PU_SATURATION_CONTROL = 0x07,
+ UVC_CTRL_PU_SHARPNESS_CONTROL = 0x08,
+ UVC_CTRL_PU_GAMMA_CONTROL = 0x09,
+ UVC_CTRL_PU_WHITE_BALANCE_TEMPERATURE_CONTROL = 0x0A,
+ UVC_CTRL_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL = 0x0B,
+ UVC_CTRL_PU_WHITE_BALANCE_COMPONENT_CONTROL = 0x0C,
+ UVC_CTRL_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL = 0x0D,
+ UVC_CTRL_PU_DIGITAL_MULTIPLIER_CONTROL = 0x0E,
+ UVC_CTRL_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL = 0x0F,
+ UVC_CTRL_PU_HUE_AUTO_CONTROL = 0x10,
+ UVC_CTRL_PU_ANALOG_VIDEO_STANDARD_CONTROL = 0x11,
+ UVC_CTRL_PU_ANALOG_LOCK_STATUS_CONTROL = 0x12,
+} usbh_uvc_ctrl_vc_processingunit_controls_t;
+
+typedef enum {
+ UVC_CTRL_VS_CONTROL_UNDEFINED = 0x00,
+ UVC_CTRL_VS_PROBE_CONTROL = 0x01,
+ UVC_CTRL_VS_COMMIT_CONTROL = 0x02,
+ UVC_CTRL_VS_STILL_PROBE_CONTROL = 0x03,
+ UVC_CTRL_VS_STILL_COMMIT_CONTROL = 0x04,
+ UVC_CTRL_VS_STILL_IMAGE_TRIGGER_CONTROL = 0x05,
+ UVC_CTRL_VS_STREAM_ERROR_CODE_CONTROL = 0x06,
+ UVC_CTRL_VS_GENERATE_KEY_FRAME_CONTROL = 0x07,
+ UVC_CTRL_VS_UPDATE_FRAME_SEGMENT_CONTROL = 0x08,
+ UVC_CTRL_VS_SYNCH_DELAY_CONTROL = 0x09
+} usbh_uvc_ctrl_vs_interface_controls_t;
+
+
+typedef PACKED_STRUCT {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bDescriptorSubType;
+ uint8_t bFormatIndex;
+ uint8_t bNumFrameDescriptors;
+ uint8_t bmFlags;
+ uint8_t bDefaultFrameIndex;
+ uint8_t bAspectRatioX;
+ uint8_t bAspectRatioY;
+ uint8_t bmInterfaceFlags;
+ uint8_t bCopyProtect;
+} usbh_uvc_format_mjpeg_t;
+
+typedef PACKED_STRUCT {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bDescriptorSubType;
+ uint8_t bFrameIndex;
+ uint8_t bmCapabilities;
+ uint16_t wWidth;
+ uint16_t wHeight;
+ uint32_t dwMinBitRate;
+ uint32_t dwMaxBitRate;
+ uint32_t dwMaxVideoFrameBufferSize;
+ uint32_t dwDefaultFrameInterval;
+ uint8_t bFrameIntervalType;
+ uint32_t dwFrameInterval[0];
+} usbh_uvc_frame_mjpeg_t;
+
+
+typedef PACKED_STRUCT {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bDescriptorSubType;
+ uint8_t bFrameIndex;
+ uint8_t bmCapabilities;
+ uint16_t wWidth;
+ uint16_t wHeight;
+ uint32_t dwMinBitRate;
+ uint32_t dwMaxBitRate;
+ uint32_t dwMaxVideoFrameBufferSize;
+ uint32_t dwDefaultFrameInterval;
+ uint8_t bFrameIntervalType;
+ uint32_t dwFrameInterval[0];
+} usbh_uvc_frame_uncompressed_t;
+
+typedef PACKED_STRUCT {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bDescriptorSubType;
+ uint8_t bFormatIndex;
+ uint8_t bNumFrameDescriptors;
+ uint8_t guidFormat[16];
+ uint8_t bBitsPerPixel;
+ uint8_t bDefaultFrameIndex;
+ uint8_t bAspectRatioX;
+ uint8_t bAspectRatioY;
+ uint8_t bmInterfaceFlags;
+ uint8_t bCopyProtect;
+} usbh_uvc_format_uncompressed;
+
+typedef PACKED_STRUCT {
+ uint16_t bmHint;
+ uint8_t bFormatIndex;
+ uint8_t bFrameIndex;
+ uint32_t dwFrameInterval;
+ uint16_t wKeyFrameRate;
+ uint16_t wPFrameRate;
+ uint16_t wCompQuality;
+ uint16_t wCompWindowSize;
+ uint16_t wDelay;
+ uint32_t dwMaxVideoFrameSize;
+ uint32_t dwMaxPayloadTransferSize;
+// uint32_t dwClockFrequency;
+// uint8_t bmFramingInfo;
+// uint8_t bPreferedVersion;
+// uint8_t bMinVersion;
+// uint8_t bMaxVersion;
+} usbh_uvc_ctrl_vs_probecommit_data_t;
+
+
+
+/* D0: Frame ID.
+ * For frame-based formats, this bit toggles between 0 and 1 every time a new video frame begins.
+ * For stream-based formats, this bit toggles between 0 and 1 at the start of each new codec-specific
+ * segment. This behavior is required for frame-based payload formats (e.g., DV) and is optional
+ * for stream-based payload formats (e.g., MPEG-2 TS). For stream-based formats, support for this
+ * bit must be indicated via the bmFramingInfofield of the Video Probe and Commitcontrols
+ * (see section 4.3.1.1, “Video Probe and Commit Controls”).
+ *
+ * D1: End of Frame.
+ * This bit is set if the following payload data marks the end of the current video or still image
+ * frame (for framebased formats), or to indicate the end of a codec-specific segment
+ * (for stream-based formats). This behavior is optional for all payload formats.
+ * For stream-based formats, support for this bit must be indicated via the bmFramingInfofield
+ * of the Video Probe and CommitControls (see section 4.3.1.1, “Video Probe and Commit Controls”).
+ *
+ * D2: Presentation Time.
+ * This bit is set if the dwPresentationTimefield is being sent as part of the header.
+ *
+ * D3: Source Clock Reference
+ * This bit is set if the dwSourceClockfield is being sent as part of the header.
+ *
+ * D4: Reserved
+ *
+ * D5: Still Image
+ * This bit is set ifthe following data is part of a still image frame, and is only used for
+ * methods 2 and 3 of still image capture.
+ *
+ * D6: Error
+ * This bit is set ifthere was an error in the video or still image transmission
+ * for this payload. The StreamError Code control would reflect the cause of the error.
+ *
+ * D7: End of header
+ * This bit is set if this is the last header group in the packet, where the
+ * header group refers to this field and any optional fields identified by the bits in this
+ * field (Defined for future extension)
+*/
+
+#define UVC_HDR_EOH (1 << 7) /* End of header */
+#define UVC_HDR_ERR (1 << 6) /* Error */
+#define UVC_HDR_STILL (1 << 5) /* Still Image */
+#define UVC_HDR_SCR (1 << 3) /* Source Clock Reference */
+#define UVC_HDR_PT (1 << 2) /* Presentation Time */
+#define UVC_HDR_EOF (1 << 1) /* End of Frame */
+#define UVC_HDR_FID (1 << 0) /* Frame ID */
+
+
+
+typedef struct USBHUVCDriver USBHUVCDriver;
+
+#define USBHUVC_MESSAGETYPE_STATUS 1
+#define USBHUVC_MESSAGETYPE_DATA 2
+
+
+#define _usbhuvc_message_base_data \
+ uint16_t type; \
+ uint16_t length; \
+ systime_t timestamp;
+
+typedef struct {
+ _usbhuvc_message_base_data
+} usbhuvc_message_base_t;
+
+typedef struct {
+ _usbhuvc_message_base_data
+ USBH_DECLARE_STRUCT_MEMBER(uint8_t data[0]);
+} usbhuvc_message_data_t;
+
+typedef struct {
+ _usbhuvc_message_base_data
+ USBH_DECLARE_STRUCT_MEMBER(uint8_t data[USBHUVC_MAX_STATUS_PACKET_SZ]);
+} usbhuvc_message_status_t;
+
+
+typedef enum {
+ USBHUVC_STATE_UNINITIALIZED = 0, //must call usbhuvcObjectInit
+ USBHUVC_STATE_STOP = 1, //the device is disconnected
+ USBHUVC_STATE_ACTIVE = 2, //the device is connected
+ USBHUVC_STATE_READY = 3, //the device has negotiated the parameters
+ USBHUVC_STATE_STREAMING = 4, //the device is streaming data
+ USBHUVC_STATE_BUSY = 5 //the driver is busy performing some action
+} usbhuvc_state_t;
+
+
+struct USBHUVCDriver {
+ /* inherited from abstract class driver */
+ _usbh_base_classdriver_data
+
+ usbhuvc_state_t state;
+
+ usbh_ep_t ep_int;
+ usbh_ep_t ep_iso;
+
+ usbh_urb_t urb_iso;
+ usbh_urb_t urb_int;
+
+ if_iterator_t ivc;
+ if_iterator_t ivs;
+
+ USBH_DECLARE_STRUCT_MEMBER(usbh_uvc_ctrl_vs_probecommit_data_t pc);
+ USBH_DECLARE_STRUCT_MEMBER(usbh_uvc_ctrl_vs_probecommit_data_t pc_min);
+ USBH_DECLARE_STRUCT_MEMBER(usbh_uvc_ctrl_vs_probecommit_data_t pc_max);
+
+ mailbox_t mb;
+ msg_t mb_buff[HAL_USBHUVC_MAX_MAILBOX_SZ];
+
+ memory_pool_t mp_data;
+ void *mp_data_buffer;
+
+ memory_pool_t mp_status;
+ usbhuvc_message_status_t mp_status_buffer[HAL_USBHUVC_STATUS_PACKETS_COUNT];
+
+ mutex_t mtx;
+};
+
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+extern USBHUVCDriver USBHUVCD[HAL_USBHUVC_MAX_INSTANCES];
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ static inline usbhuvc_state_t usbhuvcGetState(USBHUVCDriver *uvcd) {
+ return uvcd->state;
+ }
+
+ bool usbhuvcVCRequest(USBHUVCDriver *uvcdp,
+ uint8_t bRequest, uint8_t entity, uint8_t control,
+ uint16_t wLength, uint8_t *data);
+ bool usbhuvcVSRequest(USBHUVCDriver *uvcdp,
+ uint8_t bRequest, uint8_t control,
+ uint16_t wLength, uint8_t *data);
+ bool usbhuvcFindVSDescriptor(USBHUVCDriver *uvcdp,
+ generic_iterator_t *ics,
+ uint8_t bDescriptorSubtype,
+ bool start);
+ uint32_t usbhuvcEstimateRequiredEPSize(USBHUVCDriver *uvcdp, const uint8_t *formatdesc,
+ const uint8_t *framedesc, uint32_t dwFrameInterval);
+
+#if USBH_DEBUG_ENABLE && USBHUVC_DEBUG_ENABLE_INFO
+ void usbhuvcPrintProbeCommit(const usbh_uvc_ctrl_vs_probecommit_data_t *pc);
+#else
+# define usbhuvcPrintProbeCommit(pc) do {} while(0)
+#endif
+ bool usbhuvcProbe(USBHUVCDriver *uvcdp);
+ bool usbhuvcCommit(USBHUVCDriver *uvcdp);
+ void usbhuvcResetPC(USBHUVCDriver *uvcdp);
+ static inline const usbh_uvc_ctrl_vs_probecommit_data_t *usbhuvcGetPCMin(USBHUVCDriver *uvcdp) {
+ return &uvcdp->pc_min;
+ }
+ static inline const usbh_uvc_ctrl_vs_probecommit_data_t *usbhuvcGetPCMax(USBHUVCDriver *uvcdp) {
+ return &uvcdp->pc_min;
+ }
+ static inline usbh_uvc_ctrl_vs_probecommit_data_t *usbhuvcGetPC(USBHUVCDriver *uvcdp) {
+ return &uvcdp->pc;
+ }
+
+ bool usbhuvcStreamStart(USBHUVCDriver *uvcdp, uint16_t min_ep_sz);
+ bool usbhuvcStreamStop(USBHUVCDriver *uvcdp);
+
+ static inline msg_t usbhuvcLockAndFetchS(USBHUVCDriver *uvcdp, msg_t *msg, systime_t timeout) {
+ chMtxLockS(&uvcdp->mtx);
+ msg_t ret = chMBFetchTimeoutS(&uvcdp->mb, msg, timeout);
+ if (ret != MSG_OK)
+ chMtxUnlockS(&uvcdp->mtx);
+ return ret;
+ }
+ static inline msg_t usbhuvcLockAndFetch(USBHUVCDriver *uvcdp, msg_t *msg, systime_t timeout) {
+ osalSysLock();
+ msg_t ret = usbhuvcLockAndFetchS(uvcdp, msg, timeout);
+ osalSysUnlock();
+ return ret;
+ }
+ static inline void usbhuvcUnlock(USBHUVCDriver *uvcdp) {
+ chMtxUnlock(&uvcdp->mtx);
+ }
+ static inline void usbhuvcFreeDataMessage(USBHUVCDriver *uvcdp, usbhuvc_message_data_t *msg) {
+ chPoolFree(&uvcdp->mp_data, msg);
+ }
+ static inline void usbhuvcFreeStatusMessage(USBHUVCDriver *uvcdp, usbhuvc_message_status_t *msg) {
+ chPoolFree(&uvcdp->mp_status, msg);
+ }
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif /* USBH_INCLUDE_USBH_UVC_H_ */
diff --git a/os/hal/include/usbh/internal.h b/os/hal/include/usbh/internal.h
index baa477f..f6f17b7 100644
--- a/os/hal/include/usbh/internal.h
+++ b/os/hal/include/usbh/internal.h
@@ -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.
@@ -29,9 +29,15 @@
#if HAL_USBH_USE_FTDI
extern const usbh_classdriverinfo_t usbhftdiClassDriverInfo;
#endif
+#if HAL_USBH_USE_AOA
+extern const usbh_classdriverinfo_t usbhaoaClassDriverInfo;
+#endif
#if HAL_USBH_USE_MSD
extern const usbh_classdriverinfo_t usbhmsdClassDriverInfo;
#endif
+#if HAL_USBH_USE_HID
+extern const usbh_classdriverinfo_t usbhhidClassDriverInfo;
+#endif
#if HAL_USBH_USE_UVC
extern const usbh_classdriverinfo_t usbhuvcClassDriverInfo;
#endif
@@ -48,30 +54,21 @@ void _usbh_urb_completeI(usbh_urb_t *urb, usbh_urbstatus_t status);
bool _usbh_urb_abortI(usbh_urb_t *urb, usbh_urbstatus_t status);
void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status);
+bool _usbh_match_vid_pid(usbh_device_t *dev, int32_t vid, int32_t pid);
+bool _usbh_match_descriptor(const uint8_t *descriptor, uint16_t rem,
+ int16_t type, int16_t _class, int16_t subclass, int16_t protocol);
-#define USBH_CLASSIN(type, req, value, index) \
- (USBH_REQTYPE_IN | type | USBH_REQTYPE_CLASS), \
- req, \
- value, \
- index
+#define USBH_REQTYPE_CLASSIN(type) \
+ (USBH_REQTYPE_DIR_IN | type | USBH_REQTYPE_TYPE_CLASS)
-#define USBH_CLASSOUT(type, req, value, index) \
- (USBH_REQTYPE_OUT | type | USBH_REQTYPE_CLASS), \
- req, \
- value, \
- index
+#define USBH_REQTYPE_CLASSOUT(type) \
+ (USBH_REQTYPE_DIR_OUT | type | USBH_REQTYPE_TYPE_CLASS)
-#define USBH_STANDARDIN(type, req, value, index) \
- (USBH_REQTYPE_IN | type | USBH_REQTYPE_STANDARD), \
- req, \
- value, \
- index
+#define USBH_REQTYPE_STANDARDIN(type) \
+ (USBH_REQTYPE_DIR_IN | type | USBH_REQTYPE_TYPE_STANDARD)
-#define USBH_STANDARDOUT(type, req, value, index) \
- (USBH_REQTYPE_OUT | type | USBH_REQTYPE_STANDARD), \
- req, \
- value, \
- index
+#define USBH_REQTYPE_STANDARDOUT(type) \
+ (USBH_REQTYPE_DIR_OUT | type | USBH_REQTYPE_TYPE_STANDARD)
#define USBH_PID_DATA0 0
@@ -82,19 +79,19 @@ void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status);
/* GetBusState and SetHubDescriptor are optional, omitted */
-#define ClearHubFeature (((USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE) << 8) \
+#define ClearHubFeature (((USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE) << 8) \
| USBH_REQ_CLEAR_FEATURE)
-#define SetHubFeature (((USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE) << 8) \
+#define SetHubFeature (((USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE) << 8) \
| USBH_REQ_SET_FEATURE)
-#define ClearPortFeature (((USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER) << 8) \
+#define ClearPortFeature (((USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER) << 8) \
| USBH_REQ_CLEAR_FEATURE)
-#define SetPortFeature (((USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER) << 8) \
+#define SetPortFeature (((USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER) << 8) \
| USBH_REQ_SET_FEATURE)
-#define GetHubDescriptor (((USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE) << 8) \
+#define GetHubDescriptor (((USBH_REQTYPE_DIR_IN | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE) << 8) \
| USBH_REQ_GET_DESCRIPTOR)
-#define GetHubStatus (((USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE) << 8) \
+#define GetHubStatus (((USBH_REQTYPE_DIR_IN | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE) << 8) \
| USBH_REQ_GET_STATUS)
-#define GetPortStatus (((USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER) << 8) \
+#define GetPortStatus (((USBH_REQTYPE_DIR_IN | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER) << 8) \
| USBH_REQ_GET_STATUS)
@@ -143,6 +140,9 @@ void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status);
#define sizeof_array(x) (sizeof(x)/sizeof(*(x)))
+#include "usbh/desciter.h" /* descriptor iterators */
+#include "usbh/debug.h"
+
#endif
#endif /* USBH_INTERNAL_H_ */
diff --git a/os/hal/include/usbh/list.h b/os/hal/include/usbh/list.h
index 4eceacd..cdcca04 100644
--- a/os/hal/include/usbh/list.h
+++ b/os/hal/include/usbh/list.h
@@ -7,11 +7,8 @@
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
-#define container_of(ptr, type, member) ((type *)(void *)((char *)(ptr) - offsetof(type, member)))
#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof(((type *)0)->member) * __mptr = (ptr); \
- (type *)((char *)__mptr - offsetof(type, member)); })
+#define container_of(ptr, type, member) ((type *)(void *)((char *)(ptr) - offsetof(type, member)))
#endif
/*
@@ -44,21 +41,15 @@ static inline void INIT_LIST_HEAD(struct list_head *list)
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
-#ifndef CONFIG_DEBUG_LIST
-static inline void __list_add(struct list_head *new,
+static inline void __list_add(struct list_head *_new,
struct list_head *prev,
struct list_head *next)
{
- next->prev = new;
- new->next = next;
- new->prev = prev;
- prev->next = new;
+ next->prev = _new;
+ _new->next = next;
+ _new->prev = prev;
+ prev->next = _new;
}
-#else
-extern void __list_add(struct list_head *new,
- struct list_head *prev,
- struct list_head *next);
-#endif
/**
* list_add - add a new entry
@@ -68,9 +59,9 @@ extern void __list_add(struct list_head *new,
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
-static inline void list_add(struct list_head *new, struct list_head *head)
+static inline void list_add(struct list_head *_new, struct list_head *head)
{
- __list_add(new, head, head->next);
+ __list_add(_new, head, head->next);
}
@@ -82,9 +73,9 @@ static inline void list_add(struct list_head *new, struct list_head *head)
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
-static inline void list_add_tail(struct list_head *new, struct list_head *head)
+static inline void list_add_tail(struct list_head *_new, struct list_head *head)
{
- __list_add(new, head->prev, head);
+ __list_add(_new, head->prev, head);
}
/*
@@ -106,7 +97,7 @@ static inline void __list_del(struct list_head * prev, struct list_head * next)
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
-#ifndef CONFIG_DEBUG_LIST
+
static inline void __list_del_entry(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
@@ -115,35 +106,6 @@ static inline void __list_del_entry(struct list_head *entry)
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
- // entry->next = LIST_POISON1;
- // entry->prev = LIST_POISON2;
-}
-#else
-extern void __list_del_entry(struct list_head *entry);
-extern void list_del(struct list_head *entry);
-#endif
-
-/**
- * list_replace - replace old entry by new one
- * @old : the element to be replaced
- * @new : the new element to insert
- *
- * If @old was empty, it will be overwritten.
- */
-static inline void list_replace(struct list_head *old,
- struct list_head *new)
-{
- new->next = old->next;
- new->next->prev = new;
- new->prev = old->prev;
- new->prev->next = new;
-}
-
-static inline void list_replace_init(struct list_head *old,
- struct list_head *new)
-{
- list_replace(old, new);
- INIT_LIST_HEAD(old);
}
/**
@@ -157,26 +119,159 @@ static inline void list_del_init(struct list_head *entry)
}
/**
- * list_move - delete from one list and add as another's head
+ * list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
- * @head: the head that will precede our entry
+ * @head: the head that will follow our entry
*/
-static inline void list_move(struct list_head *list, struct list_head *head)
+static inline void list_move_tail(struct list_head *list,
+ struct list_head *head)
{
__list_del_entry(list);
- list_add(list, head);
+ list_add_tail(list, head);
}
+
/**
- * list_move_tail - delete from one list and add as another's tail
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+ return head->next == head;
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+/**
+ * list_next_entry - get the next element in list
+ * @pos: the type * to cursor
+ * @member: the name of the list_head within the struct.
+ */
+#define list_next_entry(pos, type, member) \
+ list_entry((pos)->member.next, type, member)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_for_each_entry(pos, type, head, member) \
+ for (pos = list_first_entry(head, type, member); \
+ &pos->member != (head); \
+ pos = list_next_entry(pos, type, member))
+
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_for_each_entry_safe(pos, type, n, head, member) \
+ for (pos = list_first_entry(head, type, member), \
+ n = list_next_entry(pos, type, member); \
+ &pos->member != (head); \
+ pos = n, n = list_next_entry(n, type, member))
+
+#if 0
+
+/**
+ * list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_prev_entry - get the prev element in list
+ * @pos: the type * to cursor
+ * @member: the name of the list_head within the struct.
+ */
+#define list_prev_entry(pos, type, member) \
+ list_entry((pos)->member.prev, type, member)
+
+/**
+ * list_for_each_prev - iterate over a list backwards
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+ for (pos = (head)->prev; pos != (head); pos = pos->prev)
+
+/**
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_prev_safe(pos, n, head) \
+ for (pos = (head)->prev, n = pos->prev; \
+ pos != (head); \
+ pos = n, n = pos->prev)
+
+/**
+ * list_last_entry - get the last element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_last_entry(ptr, type, member) \
+ list_entry((ptr)->prev, type, member)
+
+/**
+ * list_first_entry_or_null - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ *
+ * Note that if the list is empty, it returns NULL.
+ */
+#define list_first_entry_or_null(ptr, type, member) \
+ (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)
+
+
+/**
+ * list_move - delete from one list and add as another's head
* @list: the entry to move
- * @head: the head that will follow our entry
+ * @head: the head that will precede our entry
*/
-static inline void list_move_tail(struct list_head *list,
- struct list_head *head)
+static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del_entry(list);
- list_add_tail(list, head);
+ list_add(list, head);
}
/**
@@ -191,15 +286,6 @@ static inline int list_is_last(const struct list_head *list,
}
/**
- * list_empty - tests whether a list is empty
- * @head: the list to test.
- */
-static inline int list_empty(const struct list_head *head)
-{
- return head->next == head;
-}
-
-/**
* list_empty_careful - tests whether a list is empty and not being modified
* @head: the list to test
*
@@ -353,110 +439,28 @@ static inline void list_splice_tail_init(struct list_head *list,
}
/**
- * list_entry - get the struct for this entry
- * @ptr: the &struct list_head pointer.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_head within the struct.
- */
-#define list_entry(ptr, type, member) \
- container_of(ptr, type, member)
-
-/**
- * list_first_entry - get the first element from a list
- * @ptr: the list head to take the element from.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_head within the struct.
- *
- * Note, that list is expected to be not empty.
- */
-#define list_first_entry(ptr, type, member) \
- list_entry((ptr)->next, type, member)
-
-/**
- * list_last_entry - get the last element from a list
- * @ptr: the list head to take the element from.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_head within the struct.
- *
- * Note, that list is expected to be not empty.
- */
-#define list_last_entry(ptr, type, member) \
- list_entry((ptr)->prev, type, member)
-
-/**
- * list_first_entry_or_null - get the first element from a list
- * @ptr: the list head to take the element from.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_head within the struct.
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
*
- * Note that if the list is empty, it returns NULL.
- */
-#define list_first_entry_or_null(ptr, type, member) \
- (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)
-
-/**
- * list_next_entry - get the next element in list
- * @pos: the type * to cursor
- * @member: the name of the list_head within the struct.
- */
-#define list_next_entry(pos, type, member) \
- list_entry((pos)->member.next, type, member)
-
-/**
- * list_prev_entry - get the prev element in list
- * @pos: the type * to cursor
- * @member: the name of the list_head within the struct.
- */
-#define list_prev_entry(pos, type, member) \
- list_entry((pos)->member.prev, type, member)
-
-/**
- * list_for_each - iterate over a list
- * @pos: the &struct list_head to use as a loop cursor.
- * @head: the head for your list.
- */
-#define list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * list_for_each_prev - iterate over a list backwards
- * @pos: the &struct list_head to use as a loop cursor.
- * @head: the head for your list.
- */
-#define list_for_each_prev(pos, head) \
- for (pos = (head)->prev; pos != (head); pos = pos->prev)
-
-/**
- * list_for_each_safe - iterate over a list safe against removal of list entry
- * @pos: the &struct list_head to use as a loop cursor.
- * @n: another &struct list_head to use as temporary storage
- * @head: the head for your list.
+ * If @old was empty, it will be overwritten.
*/
-#define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
+static inline void list_replace(struct list_head *old,
+ struct list_head *_new)
+{
+ _new->next = old->next;
+ _new->next->prev = _new;
+ _new->prev = old->prev;
+ _new->prev->next = _new;
+}
-/**
- * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
- * @pos: the &struct list_head to use as a loop cursor.
- * @n: another &struct list_head to use as temporary storage
- * @head: the head for your list.
- */
-#define list_for_each_prev_safe(pos, n, head) \
- for (pos = (head)->prev, n = pos->prev; \
- pos != (head); \
- pos = n, n = pos->prev)
+static inline void list_replace_init(struct list_head *old,
+ struct list_head *_new)
+{
+ list_replace(old, _new);
+ INIT_LIST_HEAD(old);
+}
-/**
- * list_for_each_entry - iterate over list of given type
- * @pos: the type * to use as a loop cursor.
- * @head: the head for your list.
- * @member: the name of the list_head within the struct.
- */
-#define list_for_each_entry(pos, type, head, member) \
- for (pos = list_first_entry(head, type, member); \
- &pos->member != (head); \
- pos = list_next_entry(pos, type, member))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
@@ -521,19 +525,6 @@ static inline void list_splice_tail_init(struct list_head *list,
pos = list_next_entry(pos, type, member))
/**
- * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @pos: the type * to use as a loop cursor.
- * @n: another type * to use as temporary storage
- * @head: the head for your list.
- * @member: the name of the list_head within the struct.
- */
-#define list_for_each_entry_safe(pos, type, n, head, member) \
- for (pos = list_first_entry(head, type, member), \
- n = list_next_entry(pos, type, member); \
- &pos->member != (head); \
- pos = n, n = list_next_entry(n, type, member))
-
-/**
* list_for_each_entry_safe_continue - continue list iteration safe against removal
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
@@ -594,5 +585,6 @@ static inline void list_splice_tail_init(struct list_head *list,
*/
#define list_safe_reset_next(pos, type, n, member) \
n = list_next_entry(pos, type, member)
+#endif
#endif /* USBH_LIST_H_ */