summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/device/keyboard/main.c2
-rw-r--r--tinyusb/class/custom_class.h79
-rw-r--r--tinyusb/class/custom_class_host.c115
-rw-r--r--tinyusb/class/hid_device.c2
-rw-r--r--tinyusb/class/hid_host.c53
-rw-r--r--tinyusb/common/errors.h1
-rw-r--r--tinyusb/core/tusb_types.h10
-rw-r--r--tinyusb/device/dcd.h2
-rw-r--r--tinyusb/device/dcd_lpc175x_6x.c2
-rw-r--r--tinyusb/device/usbd.c19
-rw-r--r--tinyusb/device/usbd.h1
-rw-r--r--tinyusb/host/ehci/ehci.c18
-rw-r--r--tinyusb/host/usbh.c57
-rw-r--r--tinyusb/tusb.h8
14 files changed, 303 insertions, 66 deletions
diff --git a/demos/device/keyboard/main.c b/demos/device/keyboard/main.c
index 388f0cb8f..eb943221e 100644
--- a/demos/device/keyboard/main.c
+++ b/demos/device/keyboard/main.c
@@ -94,7 +94,7 @@ void led_blinking_task(void * p_para)
void keyboard_device_app_task(void * p_para)
{
#if 0
- if (tusb_device_is_configured())
+ if (tusbd_is_configured())
{
static uint32_t count =0;
if (count < 4)
diff --git a/tinyusb/class/custom_class.h b/tinyusb/class/custom_class.h
new file mode 100644
index 000000000..9a6588a26
--- /dev/null
+++ b/tinyusb/class/custom_class.h
@@ -0,0 +1,79 @@
+/**************************************************************************/
+/*!
+ @file custom_class.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup TBD
+ * \defgroup TBD
+ * \brief TBD
+ *
+ * @{
+ */
+
+#ifndef _TUSB_CUSTOM_CLASS_H_
+#define _TUSB_CUSTOM_CLASS_H_
+
+#include "common/common.h"
+#include "host/usbh.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+typedef struct {
+ pipe_handle_t pipe_in;
+ pipe_handle_t pipe_out;
+}custom_interface_info_t;
+
+//--------------------------------------------------------------------+
+// USBH-CLASS DRIVER API
+//--------------------------------------------------------------------+
+#ifdef _TINY_USB_SOURCE_FILE_
+
+void cush_init(void);
+tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t const *p_interface_desc, uint16_t *p_length) ATTR_WARN_UNUSED_RESULT;
+void cush_isr(pipe_handle_t pipe_hdl, tusb_event_t event);
+void cush_close(uint8_t dev_addr);
+
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_CUSTOM_CLASS_H_ */
+
+/** @} */
diff --git a/tinyusb/class/custom_class_host.c b/tinyusb/class/custom_class_host.c
new file mode 100644
index 000000000..723cb06ff
--- /dev/null
+++ b/tinyusb/class/custom_class_host.c
@@ -0,0 +1,115 @@
+/**************************************************************************/
+/*!
+ @file custom_class_host.c
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#include "tusb_option.h"
+
+#if (MODE_HOST_SUPPORTED && TUSB_CFG_HOST_CUSTOM_CLASS)
+
+#define _TINY_USB_SOURCE_FILE_
+
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include "common/common.h"
+#include "custom_class.h"
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
+
+//--------------------------------------------------------------------+
+// INTERNAL OBJECT & FUNCTION DECLARATION
+//--------------------------------------------------------------------+
+custom_interface_info_t custom_interface[TUSB_CFG_HOST_DEVICE_MAX];
+//--------------------------------------------------------------------+
+// IMPLEMENTATION
+//--------------------------------------------------------------------+
+void cush_init(void)
+{
+ memclr_(&custom_interface, sizeof(custom_interface_info_t) * TUSB_CFG_HOST_DEVICE_MAX);
+}
+
+tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t const *p_interface_desc, uint16_t *p_length)
+{
+ // FIXME quick hack to test lpc1k custom class with 2 bulk endpoints
+ uint8_t const *p_desc = (uint8_t const *) p_interface_desc;
+
+ //------------- 1st Bulk Endpiont Descriptor -------------//
+ for(uint32_t i=0; i<2; i++)
+ {
+ p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH];
+ tusb_descriptor_endpoint_t const *p_endpoint = (tusb_descriptor_endpoint_t const *) p_desc;
+ ASSERT_INT(TUSB_DESC_TYPE_ENDPOINT, p_endpoint->bDescriptorType, TUSB_ERROR_INVALID_PARA);
+
+ pipe_handle_t * pipe_hdl = ( p_endpoint->bEndpointAddress & TUSB_DIR_DEV_TO_HOST_MASK ) ?
+ &custom_interface[dev_addr-1].pipe_in : &custom_interface[dev_addr-1].pipe_out;
+ *pipe_hdl = hcd_pipe_open(dev_addr, p_endpoint, TUSB_CLASS_VENDOR_SPECIFIC);
+ ASSERT ( pipehandle_is_valid(*pipe_hdl), TUSB_ERROR_HCD_OPEN_PIPE_FAILED );
+ }
+
+ (*p_length) = sizeof(tusb_descriptor_interface_t) + 2*sizeof(tusb_descriptor_endpoint_t);
+ return TUSB_ERROR_NONE;
+}
+
+void cush_isr(pipe_handle_t pipe_hdl, tusb_event_t event)
+{
+
+}
+
+void cush_close(uint8_t dev_addr)
+{
+ tusb_error_t err1, err2;
+ custom_interface_info_t * p_interface = &custom_interface[dev_addr-1];
+
+ // TODO re-consider to check pipe valid before calling pipe_close
+ if( pipehandle_is_valid( p_interface->pipe_in ) )
+ {
+ err1 = hcd_pipe_close( p_interface->pipe_in );
+ }
+
+ if ( pipehandle_is_valid( p_interface->pipe_out ) )
+ {
+ err2 = hcd_pipe_close( p_interface->pipe_out );
+ }
+
+ memclr_(p_interface, sizeof(custom_interface_info_t));
+
+ ASSERT(err1 == TUSB_ERROR_NONE && err2 == TUSB_ERROR_NONE, (void) 0 );
+}
+
+#endif
diff --git a/tinyusb/class/hid_device.c b/tinyusb/class/hid_device.c
index 2aba541bb..adb252c11 100644
--- a/tinyusb/class/hid_device.c
+++ b/tinyusb/class/hid_device.c
@@ -136,7 +136,7 @@ tusb_error_t hidd_init(uint8_t coreid, tusb_descriptor_interface_t const * p_int
{
#if TUSB_CFG_DEVICE_HID_KEYBOARD
case HID_PROTOCOL_KEYBOARD:
- ASSERT_STATUS( dcd_endpoint_configure(coreid, p_desc_endpoint) );
+ ASSERT_STATUS( dcd_pipe_open(coreid, p_desc_endpoint) );
break;
#endif
diff --git a/tinyusb/class/hid_host.c b/tinyusb/class/hid_host.c
index b109430af..3546a512a 100644
--- a/tinyusb/class/hid_host.c
+++ b/tinyusb/class/hid_host.c
@@ -38,7 +38,7 @@
#include "tusb_option.h"
-#if (MODE_HOST_SUPPORTED && defined HOST_CLASS_HID)
+#if (MODE_HOST_SUPPORTED && HOST_CLASS_HID)
#define _TINY_USB_SOURCE_FILE_
//--------------------------------------------------------------------+
@@ -214,40 +214,33 @@ tusb_error_t hidh_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con
p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH];
ASSERT_INT(TUSB_DESC_TYPE_ENDPOINT, p_desc[DESCRIPTOR_OFFSET_TYPE], TUSB_ERROR_INVALID_PARA);
- if (p_interface_desc->bInterfaceSubClass == HID_SUBCLASS_BOOT)
+ switch(p_interface_desc->bInterfaceProtocol)
{
- switch(p_interface_desc->bInterfaceProtocol)
- {
- #if TUSB_CFG_HOST_HID_KEYBOARD
- case HID_PROTOCOL_KEYBOARD:
- ASSERT_STATUS ( hidh_interface_open(dev_addr, (tusb_descriptor_endpoint_t const *) p_desc, &keyboard_data[dev_addr-1]) );
- if ( tusbh_hid_keyboard_isr )
- {
- tusbh_hid_keyboard_isr(dev_addr, 0, TUSB_EVENT_INTERFACE_OPEN);
- }
- break;
- #endif
+ #if TUSB_CFG_HOST_HID_KEYBOARD
+ case HID_PROTOCOL_KEYBOARD:
+ ASSERT_STATUS ( hidh_interface_open(dev_addr, (tusb_descriptor_endpoint_t const *) p_desc, &keyboard_data[dev_addr-1]) );
+ if ( tusbh_hid_keyboard_isr )
+ {
+ tusbh_hid_keyboard_isr(dev_addr, 0, TUSB_EVENT_INTERFACE_OPEN);
+ }
+ break;
+ #endif
- #if TUSB_CFG_HOST_HID_MOUSE
- case HID_PROTOCOL_MOUSE:
- ASSERT_STATUS ( hidh_interface_open(dev_addr, (tusb_descriptor_endpoint_t const *) p_desc, &mouse_data[dev_addr-1]) );
- if (tusbh_hid_mouse_isr)
- {
- tusbh_hid_mouse_isr(dev_addr, 0, TUSB_EVENT_INTERFACE_OPEN);
- }
- break;
- #endif
+ #if TUSB_CFG_HOST_HID_MOUSE
+ case HID_PROTOCOL_MOUSE:
+ ASSERT_STATUS ( hidh_interface_open(dev_addr, (tusb_descriptor_endpoint_t const *) p_desc, &mouse_data[dev_addr-1]) );
+ if (tusbh_hid_mouse_isr)
+ {
+ tusbh_hid_mouse_isr(dev_addr, 0, TUSB_EVENT_INTERFACE_OPEN);
+ }
+ break;
+ #endif
- default: // TODO unknown, unsupported protocol --> skip this interface
- return TUSB_ERROR_NONE;
- }
- *p_length = sizeof(tusb_descriptor_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_descriptor_endpoint_t);
- }else
- {
- // open generic
- *p_length = 0;
+ default: // TODO unknown, unsupported protocol --> skip this interface
+ return TUSB_ERROR_NONE;
}
+ *p_length = sizeof(tusb_descriptor_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_descriptor_endpoint_t);
return TUSB_ERROR_NONE;
}
diff --git a/tinyusb/common/errors.h b/tinyusb/common/errors.h
index 02cdae1e6..e444a04f8 100644
--- a/tinyusb/common/errors.h
+++ b/tinyusb/common/errors.h
@@ -64,6 +64,7 @@
ENTRY(TUSB_ERROR_DEVICE_NOT_READY )\
ENTRY(TUSB_ERROR_INTERFACE_IS_BUSY )\
ENTRY(TUSB_ERROR_HCD_FAILED )\
+ ENTRY(TUSB_ERROR_HCD_OPEN_PIPE_FAILED )\
ENTRY(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND )\
ENTRY(TUSB_ERROR_USBH_MOUNT_CONFIG_DESC_TOO_LONG )\
ENTRY(TUSB_ERROR_OSAL_TIMEOUT )\
diff --git a/tinyusb/core/tusb_types.h b/tinyusb/core/tusb_types.h
index 35cb07cd8..ceabb6484 100644
--- a/tinyusb/core/tusb_types.h
+++ b/tinyusb/core/tusb_types.h
@@ -70,10 +70,13 @@ typedef enum {
}tusb_transfer_type_t;
typedef enum {
- TUSB_DIR_HOST_TO_DEV = 0,
- TUSB_DIR_DEV_TO_HOST = 1
+ TUSB_DIR_HOST_TO_DEV = 0,
+ TUSB_DIR_DEV_TO_HOST = 1,
+
+ TUSB_DIR_DEV_TO_HOST_MASK = 0x80
}tusb_direction_t;
+
/// USB Descriptor Types (section 9.4 table 9-5)
typedef enum {
TUSB_DESC_TYPE_DEVICE =1 , ///< 1
@@ -137,7 +140,8 @@ typedef enum {
TUSB_CLASS_PERSONAL_HEALTHCARE = 15 , ///< 15
TUSB_CLASS_AUDIO_VIDEO = 16 , ///< 16
- TUSB_CLASS_MAX_CONSEC_NUMBER = 17 , // TODO compact & minimize this number
+ TUSB_CLASS_MAPPED_INDEX_START = 17 , // TODO compact & minimize this number
+ TUSB_CLASS_MAPPED_INDEX_END = TUSB_CLASS_MAPPED_INDEX_START + 5,
TUSB_CLASS_DIAGNOSTIC = 0xDC ,
TUSB_CLASS_WIRELESS_CONTROLLER = 0xE0 ,
diff --git a/tinyusb/device/dcd.h b/tinyusb/device/dcd.h
index 0ae804d08..b6415a1b5 100644
--- a/tinyusb/device/dcd.h
+++ b/tinyusb/device/dcd.h
@@ -66,7 +66,7 @@ tusb_error_t dcd_pipe_control_write(uint8_t coreid, void const * buffer, uint16_
tusb_error_t dcd_pipe_control_read(uint8_t coreid, void * buffer, uint16_t length);
void dcd_pipe_control_write_zero_length(uint8_t coreid);
-tusb_error_t dcd_endpoint_configure(uint8_t coreid, tusb_descriptor_endpoint_t const * p_endpoint_desc) ATTR_WARN_UNUSED_RESULT;
+tusb_error_t dcd_pipe_open(uint8_t coreid, tusb_descriptor_endpoint_t const * p_endpoint_desc) ATTR_WARN_UNUSED_RESULT;
void dcd_device_set_address(uint8_t coreid, uint8_t dev_addr);
void dcd_device_set_configuration(uint8_t coreid, uint8_t config_num);
diff --git a/tinyusb/device/dcd_lpc175x_6x.c b/tinyusb/device/dcd_lpc175x_6x.c
index bbae9d314..c6ab3990c 100644
--- a/tinyusb/device/dcd_lpc175x_6x.c
+++ b/tinyusb/device/dcd_lpc175x_6x.c
@@ -297,7 +297,7 @@ static inline uint8_t endpoint_address_to_physical_index(uint8_t ep_address)
return (ep_address << 1) + (ep_address & 0x80 ? 1 : 0 );
}
-tusb_error_t dcd_endpoint_configure(uint8_t coreid, tusb_descriptor_endpoint_t const * p_endpoint_desc)
+tusb_error_t dcd_pipe_open(uint8_t coreid, tusb_descriptor_endpoint_t const * p_endpoint_desc)
{
uint8_t phy_ep = endpoint_address_to_physical_index( p_endpoint_desc->bEndpointAddress );
diff --git a/tinyusb/device/usbd.c b/tinyusb/device/usbd.c
index 02a8b5f28..3fb8fa542 100644
--- a/tinyusb/device/usbd.c
+++ b/tinyusb/device/usbd.c
@@ -55,7 +55,7 @@
usbd_device_info_t usbd_devices[CONTROLLER_DEVICE_NUMBER];
// TODO fix/compress number of class driver
-static device_class_driver_t const usbd_class_drivers[TUSB_CLASS_MAX_CONSEC_NUMBER] =
+static device_class_driver_t const usbd_class_drivers[TUSB_CLASS_MAPPED_INDEX_START] =
{
#if DEVICE_CLASS_HID
[TUSB_CLASS_HID] = {
@@ -78,6 +78,9 @@ bool tusbd_is_configured(uint8_t coreid)
return usbd_devices[coreid].state == TUSB_DEVICE_STATE_CONFIGURED;
}
+//--------------------------------------------------------------------+
+// IMPLEMENTATION
+//--------------------------------------------------------------------+
void usbd_bus_reset(uint32_t coreid)
{
memclr_(usbd_devices, sizeof(usbd_device_info_t)*CONTROLLER_DEVICE_NUMBER);
@@ -166,9 +169,6 @@ void usbd_setup_received(uint8_t coreid)
}
}
-//--------------------------------------------------------------------+
-// IMPLEMENTATION
-//--------------------------------------------------------------------+
tusb_error_t usbd_init (void)
{
ASSERT_STATUS ( usbd_string_descriptor_init() );
@@ -197,10 +197,17 @@ tusb_error_t usbd_init (void)
return TUSB_ERROR_NONE;
}
-#endif
//--------------------------------------------------------------------+
+// USBD-CLASS API
+//--------------------------------------------------------------------+
+tusb_error_t usbd_pipe_open(uint8_t coreid, tusb_descriptor_interface_t const * p_interfacae, tusb_descriptor_endpoint_t const * p_endpoint_desc)
+{
+ return TUSB_ERROR_NONE;
+}
+
+//--------------------------------------------------------------------+
// callback from DCD ISR
//--------------------------------------------------------------------+
void usbd_isr(uint8_t coreid, tusb_event_t event)
@@ -252,3 +259,5 @@ static tusb_error_t usbd_string_descriptor_init(void)
return TUSB_ERROR_NONE;
}
+
+#endif
diff --git a/tinyusb/device/usbd.h b/tinyusb/device/usbd.h
index 929900ffc..2f362f6fd 100644
--- a/tinyusb/device/usbd.h
+++ b/tinyusb/device/usbd.h
@@ -86,6 +86,7 @@ bool tusbd_is_configured(uint8_t coreid) ATTR_WARN_UNUSED_RESULT;
#ifdef _TINY_USB_SOURCE_FILE_
tusb_error_t usbd_init(void);
+tusb_error_t usbd_pipe_open(uint8_t coreid, tusb_descriptor_interface_t const * p_interfacae, tusb_descriptor_endpoint_t const * p_endpoint_desc);
#endif
diff --git a/tinyusb/host/ehci/ehci.c b/tinyusb/host/ehci/ehci.c
index 21c457c17..4a030cbbe 100644
--- a/tinyusb/host/ehci/ehci.c
+++ b/tinyusb/host/ehci/ehci.c
@@ -373,10 +373,13 @@ pipe_handle_t hcd_pipe_open(uint8_t dev_addr, tusb_descriptor_endpoint_t const *
if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_BULK)
{
list_head = (ehci_link_t*) get_async_head(usbh_devices[dev_addr].core_id);
- }else if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_INTERRUPT)
+ }
+ #if EHCI_PERIODIC_LIST // TODO refractor/group this together
+ else if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_INTERRUPT)
{
list_head = get_period_head(usbh_devices[dev_addr].core_id, p_qhd->interval_ms);
}
+ #endif
//------------- insert to async/period list TODO might need to disable async/period list -------------//
list_insert( list_head,
@@ -428,12 +431,15 @@ tusb_error_t hcd_pipe_close(pipe_handle_t pipe_hdl)
ASSERT_STATUS( list_remove_qhd(
(ehci_link_t*) get_async_head( usbh_devices[pipe_hdl.dev_addr].core_id ),
(ehci_link_t*) p_qhd) );
- }else
+ }
+ #if EHCI_PERIODIC_LIST // TODO refractor/group this together
+ else
{
ASSERT_STATUS( list_remove_qhd(
get_period_head( usbh_devices[pipe_hdl.dev_addr].core_id, p_qhd->interval_ms ),
(ehci_link_t*) p_qhd) );
}
+ #endif
return TUSB_ERROR_NONE;
}
@@ -530,6 +536,7 @@ void async_list_process_isr(ehci_qhd_t * const async_head)
// TODO abstract max loop guard for async
}
+#if EHCI_PERIODIC_LIST // TODO refractor/group this together
void period_list_process_isr(uint8_t hostid, uint8_t interval_ms)
{
uint8_t max_loop = 0;
@@ -585,6 +592,7 @@ void period_list_process_isr(uint8_t hostid, uint8_t interval_ms)
max_loop++;
}
}
+#endif
void xfer_error_isr(uint8_t hostid)
{
@@ -653,6 +661,7 @@ void hcd_isr(uint8_t hostid)
async_list_process_isr( get_async_head(hostid) );
}
+#if EHCI_PERIODIC_LIST // TODO refractor/group this together
if (int_status & EHCI_INT_MASK_NXP_PERIODIC)
{
for (uint8_t i=1; i <= EHCI_FRAMELIST_SIZE; i *= 2)
@@ -660,6 +669,7 @@ void hcd_isr(uint8_t hostid)
period_list_process_isr( hostid, i );
}
}
+#endif
//------------- There is some removed async previously -------------//
if (int_status & EHCI_INT_MASK_ASYNC_ADVANCE) // need to place after EHCI_INT_MASK_NXP_ASYNC
@@ -676,6 +686,7 @@ STATIC_ INLINE_ ehci_registers_t* get_operational_register(uint8_t hostid)
return (ehci_registers_t*) (hostid ? (&LPC_USB1->USBCMD_H) : (&LPC_USB0->USBCMD_H) );
}
+#if EHCI_PERIODIC_LIST // TODO refractor/group this together
STATIC_ INLINE_ ehci_link_t* get_period_frame_list(uint8_t hostid)
{
switch(hostid)
@@ -693,6 +704,7 @@ STATIC_ INLINE_ ehci_link_t* get_period_frame_list(uint8_t hostid)
return NULL;
}
+#endif
STATIC_ INLINE_ uint8_t hostid_to_data_idx(uint8_t hostid)
{
@@ -710,11 +722,13 @@ STATIC_ INLINE_ ehci_qhd_t* get_async_head(uint8_t hostid)
return &ehci_data.async_head[ hostid_to_data_idx(hostid) ];
}
+#if EHCI_PERIODIC_LIST // TODO refractor/group this together
STATIC_ INLINE_ ehci_link_t* get_period_head(uint8_t hostid, uint8_t interval_ms)
{
return (ehci_link_t*) (&ehci_data.period_head_arr[ hostid_to_data_idx(hostid) ]
[ log2_of( min8_of(EHCI_FRAMELIST_SIZE, interval_ms) ) ] );
}
+#endif
STATIC_ INLINE_ ehci_qhd_t* get_control_qhd(uint8_t dev_addr)
{
diff --git a/tinyusb/host/usbh.c b/tinyusb/host/usbh.c
index 3dc28e2b3..33e68b5ed 100644
--- a/tinyusb/host/usbh.c
+++ b/tinyusb/host/usbh.c
@@ -54,7 +54,7 @@
#define ENUM_QUEUE_DEPTH 5
// TODO fix/compress number of class driver
-static host_class_driver_t const usbh_class_drivers[TUSB_CLASS_MAX_CONSEC_NUMBER] =
+static host_class_driver_t const usbh_class_drivers[TUSB_CLASS_MAPPED_INDEX_END] =
{
#if HOST_CLASS_HID
[TUSB_CLASS_HID] = {
@@ -83,6 +83,14 @@ static host_class_driver_t const usbh_class_drivers[TUSB_CLASS_MAX_CONSEC_NUMBER
}
#endif
+#if TUSB_CFG_HOST_CUSTOM_CLASS
+ [TUSB_CLASS_MAPPED_INDEX_END-1] = {
+ .init = cush_init,
+ .open_subtask = cush_open_subtask,
+ .isr = cush_isr,
+ .close = cush_close
+ }
+#endif
};
//--------------------------------------------------------------------+
@@ -102,6 +110,17 @@ STATIC_ uint8_t enum_data_buffer[TUSB_CFG_HOST_ENUM_BUFFER_SIZE] TUSB_CFG_ATTR_U
static inline uint8_t get_new_address(void) ATTR_ALWAYS_INLINE;
static inline uint8_t get_configure_number_for_device(tusb_descriptor_device_t* dev_desc) ATTR_ALWAYS_INLINE;
+static inline uint8_t std_class_code_to_index(uint8_t std_class_code) ATTR_CONST ATTR_ALWAYS_INLINE;
+static inline uint8_t std_class_code_to_index(uint8_t std_class_code)
+{
+ return (std_class_code <= TUSB_CLASS_AUDIO_VIDEO ) ? std_class_code :
+ (std_class_code == TUSB_CLASS_DIAGNOSTIC ) ? TUSB_CLASS_MAPPED_INDEX_START :
+ (std_class_code == TUSB_CLASS_WIRELESS_CONTROLLER ) ? TUSB_CLASS_MAPPED_INDEX_START + 1 :
+ (std_class_code == TUSB_CLASS_MISC ) ? TUSB_CLASS_MAPPED_INDEX_START + 2 :
+ (std_class_code == TUSB_CLASS_APPLICATION_SPECIFIC ) ? TUSB_CLASS_MAPPED_INDEX_START + 3 :
+ (std_class_code == TUSB_CLASS_VENDOR_SPECIFIC ) ? TUSB_CLASS_MAPPED_INDEX_START + 4 : 0;
+}
+
//--------------------------------------------------------------------+
// PUBLIC API (Parameter Verification is required)
//--------------------------------------------------------------------+
@@ -133,7 +152,7 @@ tusb_error_t usbh_init(void)
ASSERT_PTR(enum_queue_hdl, TUSB_ERROR_OSAL_QUEUE_FAILED);
//------------- class init -------------//
- for (uint8_t class_code = 1; class_code < TUSB_CLASS_MAX_CONSEC_NUMBER; class_code++)
+ for (uint8_t class_code = 1; class_code < TUSB_CLASS_MAPPED_INDEX_END; class_code++)
{
if (usbh_class_drivers[class_code].init)
usbh_class_drivers[class_code].init();
@@ -229,12 +248,12 @@ void usbh_device_unplugged_isr(uint8_t hostid)
if (dev_addr > 0) // device can still be unplugged when not set new address
{
// if device unplugged is not a hub TODO handle hub unplugged
- for (uint8_t class_code = 1; class_code < TUSB_CLASS_MAX_CONSEC_NUMBER; class_code++)
+ for (uint8_t class_index = 1; class_index < TUSB_CLASS_MAPPED_INDEX_END; class_index++)
{
- if ((usbh_devices[dev_addr].flag_supported_class & BIT_(class_code)) &&
- usbh_class_drivers[class_code].close)
+ if ((usbh_devices[dev_addr].flag_supported_class & BIT_(class_index)) &&
+ usbh_class_drivers[class_index].close)
{
- usbh_class_drivers[class_code].close(dev_addr);
+ usbh_class_drivers[class_index].close(dev_addr);
}
}
}
@@ -434,29 +453,27 @@ tusb_error_t enumeration_body_subtask(void)
p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip the descriptor, increase by the descriptor's length
}else
{
- uint8_t class_code = ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass;
- if (class_code == 0)
- {
- SUBTASK_ASSERT( false ); // corrupted data, abort enumeration
- }
- // supported class TODO custom class
- else if ( class_code < TUSB_CLASS_MAX_CONSEC_NUMBER && usbh_class_drivers[class_code].open_subtask)
+ static uint8_t class_index; // has to be static as it is used to call class's open_subtask
+
+ class_index = std_class_code_to_index( ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass );
+ SUBTASK_ASSERT( class_index != 0); // class_code == 0 means corrupted data, abort enumeration
+
+ if (usbh_class_drivers[class_index].open_subtask) // supported class
{
uint16_t length=0;
OSAL_SUBTASK_INVOKED_AND_WAIT ( // parameters in task/sub_task must be static storage (static or global)
- usbh_class_drivers[ ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass ].open_subtask(
- new_addr, (tusb_descriptor_interface_t*) p_desc, &length),
+ usbh_class_drivers[class_index].open_subtask( new_addr, (tusb_descriptor_interface_t*) p_desc, &length ),
error
);
- if (error != TUSB_ERROR_NONE || length == 0) // Interface open failed, for example a subclass is not supported
+ if (error == TUSB_ERROR_NONE) // Interface open failed, for example a subclass is not supported
{
- p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip this interface, the rest will be skipped by the above loop
- // TODO can optimize the length --> open_subtask return a OPEN FAILED status
+ SUBTASK_ASSERT( length >= sizeof(tusb_descriptor_interface_t) );
+ usbh_devices[new_addr].flag_supported_class |= BIT_(class_index);
+ p_desc += length;
}else
{
- usbh_devices[new_addr].flag_supported_class |= BIT_(((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass);
- p_desc += length;
+ p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip this interface, the rest will be skipped by the above loop
}
} else // unsupported class (not enable or yet implemented)
{
diff --git a/tinyusb/tusb.h b/tinyusb/tusb.h
index f7c14d9f6..0e5ddc8ca 100644
--- a/tinyusb/tusb.h
+++ b/tinyusb/tusb.h
@@ -59,15 +59,19 @@
#if MODE_HOST_SUPPORTED
#include "host/usbh.h"
- #ifdef HOST_CLASS_HID
+ #if HOST_CLASS_HID
#include "class/hid_host.h"
#endif
- #define HOST_CLASS_MSC
+// #define HOST_CLASS_MSC // FIXME hack to test massstorage class
#ifdef HOST_CLASS_MSC
#include "class/msc_host.h"
#endif
+ #if TUSB_CFG_HOST_CUSTOM_CLASS
+ #include "class/custom_class.h"
+ #endif
+
#endif
//------------- DEVICE -------------//