diff --git a/examples/host/cdc_msc_hid/Makefile b/examples/host/cdc_msc_hid/Makefile
index 20cd7ba69..373dbbf9e 100644
--- a/examples/host/cdc_msc_hid/Makefile
+++ b/examples/host/cdc_msc_hid/Makefile
@@ -15,8 +15,9 @@ SRC_C += \
src/host/usbh.c \
src/host/hub.c \
src/host/ehci/ehci.c \
- src/class/cdc/cdc_host.c \
src/host/ehci/ehci.c \
+ src/class/cdc/cdc_host.c \
+ src/class/msc/msc_host.c \
src/portable/nxp/lpc18_43/hcd_lpc18_43.c
include ../../rules.mk
diff --git a/examples/host/cdc_msc_hid/ses/lpc18xx/lpc18xx.emProject b/examples/host/cdc_msc_hid/ses/lpc18xx/lpc18xx.emProject
index 2b68bfa23..e0a2f6f97 100644
--- a/examples/host/cdc_msc_hid/ses/lpc18xx/lpc18xx.emProject
+++ b/examples/host/cdc_msc_hid/ses/lpc18xx/lpc18xx.emProject
@@ -124,6 +124,10 @@
+
USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5);
-
-// LPC_USB0->PORTSC1_D |= (1<<24); // FIXME force full speed for debugging
+ LPC_USB0->PORTSC1_H |= (1<<24); // FIXME force full speed for debugging
#else // TODO OTG
LPC_USB0->USBMODE_D = USBMODE_DEVICE;
LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/;
diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c
index 6b36ea94d..e62f47b72 100644
--- a/src/class/cdc/cdc_host.c
+++ b/src/class/cdc/cdc_host.c
@@ -158,7 +158,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
// notification endpoint
tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) p_desc;
- TU_ASSERT( hcd_edpt_open(rhport, dev_addr, ep_desc) );
+ TU_ASSERT( usbh_edpt_open(rhport, dev_addr, ep_desc) );
p_cdc->ep_notif = ep_desc->bEndpointAddress;
(*p_length) += p_desc[DESC_OFFSET_LEN];
@@ -179,7 +179,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType);
TU_ASSERT(TUSB_XFER_BULK == ep_desc->bmAttributes.xfer);
- TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
+ TU_ASSERT(usbh_edpt_open(rhport, dev_addr, ep_desc));
if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN )
{
diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c
index 69c49b012..8abb3cd22 100644
--- a/src/class/hid/hid_host.c
+++ b/src/class/hid/hid_host.c
@@ -40,7 +40,7 @@
//--------------------------------------------------------------------+
static inline bool hidh_interface_open(uint8_t dev_addr, uint8_t interface_number, tusb_desc_endpoint_t const *p_endpoint_desc, hidh_interface_info_t *p_hid)
{
- p_hid->pipe_hdl = hcd_edpt_open(dev_addr, p_endpoint_desc, TUSB_CLASS_HID);
+ p_hid->pipe_hdl = usbh_edpt_open(dev_addr, p_endpoint_desc, TUSB_CLASS_HID);
p_hid->report_size = p_endpoint_desc->wMaxPacketSize.size; // TODO get size from report descriptor
p_hid->interface_number = interface_number;
diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c
index e20969f57..98c71eb70 100644
--- a/src/class/msc/msc_host.c
+++ b/src/class/msc/msc_host.c
@@ -293,7 +293,7 @@ bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType);
TU_ASSERT(TUSB_XFER_BULK == ep_desc->bmAttributes.xfer);
- TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
+ TU_ASSERT(usbh_edpt_open(rhport, dev_addr, ep_desc));
if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN )
{
diff --git a/src/class/vendor/vendor_host.c b/src/class/vendor/vendor_host.c
index 3e8dac0f6..0524cb981 100644
--- a/src/class/vendor/vendor_host.c
+++ b/src/class/vendor/vendor_host.c
@@ -107,7 +107,7 @@ tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_
pipe_handle_t * p_pipe_hdl = ( p_endpoint->bEndpointAddress & TUSB_DIR_IN_MASK ) ?
&custom_interface[dev_addr-1].pipe_in : &custom_interface[dev_addr-1].pipe_out;
- *p_pipe_hdl = hcd_edpt_open(dev_addr, p_endpoint, TUSB_CLASS_VENDOR_SPECIFIC);
+ *p_pipe_hdl = usbh_edpt_open(dev_addr, p_endpoint, TUSB_CLASS_VENDOR_SPECIFIC);
TU_ASSERT ( pipehandle_is_valid(*p_pipe_hdl), TUSB_ERROR_HCD_OPEN_PIPE_FAILED );
p_desc = tu_desc_next(p_desc);
diff --git a/src/host/ehci/ehci.c b/src/host/ehci/ehci.c
index 048affb1e..e2ead7b08 100644
--- a/src/host/ehci/ehci.c
+++ b/src/host/ehci/ehci.c
@@ -120,10 +120,27 @@ void hcd_port_reset(uint8_t rhport)
ehci_registers_t* regs = ehci_data.regs;
- regs->portsc_bm.port_enabled = 0; // disable port before reset
- regs->portsc_bm.port_reset = 1;
+// regs->portsc_bm.port_enabled = 0; // disable port before reset
+// regs->portsc_bm.port_reset = 1;
+
+ uint32_t portsc = regs->portsc;
+
+ portsc &= ~(EHCI_PORTSC_MASK_PORT_EANBLED);
+ portsc |= EHCI_PORTSC_MASK_PORT_RESET;
+
+ regs->portsc = portsc;
}
+#if 0
+void hcd_port_reset_end(uint8_t rhport)
+{
+ (void) rhport;
+
+ ehci_registers_t* regs = ehci_data.regs;
+ regs->portsc_bm.port_reset = 0;
+}
+#endif
+
bool hcd_port_connect_status(uint8_t rhport)
{
(void) rhport;
diff --git a/src/host/ehci/ehci.h b/src/host/ehci/ehci.h
index f11c4536a..a6342b2d2 100644
--- a/src/host/ehci/ehci.h
+++ b/src/host/ehci/ehci.h
@@ -311,10 +311,14 @@ enum ehci_usbcmd_pos_ {
};
enum ehci_portsc_change_mask_{
+ EHCI_PORTSC_MASK_CURRENT_CONNECT_STATUS = TU_BIT(0),
EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE = TU_BIT(1),
+ EHCI_PORTSC_MASK_PORT_EANBLED = TU_BIT(2),
EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE = TU_BIT(3),
EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE = TU_BIT(5),
+ EHCI_PORTSC_MASK_PORT_RESET = TU_BIT(8),
+
EHCI_PORTSC_MASK_ALL =
EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE |
EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE |
diff --git a/src/host/hcd.h b/src/host/hcd.h
index d9307ca09..f2ca0a1d6 100644
--- a/src/host/hcd.h
+++ b/src/host/hcd.h
@@ -104,6 +104,7 @@ static inline uint32_t hcd_frame_number(uint8_t rhport)
/// return the current connect status of roothub port
bool hcd_port_connect_status(uint8_t hostid);
void hcd_port_reset(uint8_t hostid);
+void hcd_port_reset_end(uint8_t rhport);
tusb_speed_t hcd_port_speed_get(uint8_t hostid);
// HCD closes all opened endpoints belong to this device
diff --git a/src/host/hub.c b/src/host/hub.c
index 00450b704..eb85dfa42 100644
--- a/src/host/hub.c
+++ b/src/host/hub.c
@@ -154,7 +154,7 @@ bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf
TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType);
TU_ASSERT(TUSB_XFER_INTERRUPT == ep_desc->bmAttributes.xfer);
- TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
+ TU_ASSERT(usbh_edpt_open(rhport, dev_addr, ep_desc));
hub_data[dev_addr-1].itf_num = itf_desc->bInterfaceNumber;
hub_data[dev_addr-1].ep_status = ep_desc->bEndpointAddress;
diff --git a/src/host/usbh.c b/src/host/usbh.c
index 7171f6bab..8536cec0a 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -116,7 +116,6 @@ CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t _usbh_ctrl_buf[CFG_TUSB_H
//------------- Helper Function Prototypes -------------//
static inline uint8_t get_new_address(void);
static inline uint8_t get_configure_number_for_device(tusb_desc_device_t* dev_desc);
-static void mark_interface_endpoint(uint8_t ep2drv[8][2], uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id);
//--------------------------------------------------------------------+
// PUBLIC API (Parameter Verification is required)
@@ -225,6 +224,30 @@ tusb_error_t usbh_pipe_control_open(uint8_t dev_addr, uint8_t max_packet_size)
return TUSB_ERROR_NONE;
}
+bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc)
+{
+ bool ret = hcd_edpt_open(rhport, dev_addr, ep_desc);
+
+ if (ret)
+ {
+ usbh_device_t* dev = &_usbh_devices[dev_addr];
+
+ // new endpoints belongs to latest interface (last valid value)
+ uint8_t drvid = 0xff;
+ for(uint8_t i=0; i < sizeof(dev->itf2drv); i++)
+ {
+ if ( dev->itf2drv[i] == 0xff ) break;
+ drvid = dev->itf2drv[i];
+ }
+ TU_ASSERT(drvid < USBH_CLASS_DRIVER_COUNT);
+
+ uint8_t const ep_addr = ep_desc->bEndpointAddress;
+ dev->ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)] = drvid;
+ }
+
+ return ret;
+}
+
//--------------------------------------------------------------------+
// USBH-HCD ISR/Callback API
//--------------------------------------------------------------------+
@@ -358,6 +381,8 @@ bool enum_task(hcd_event_t* event)
{
if( hcd_port_connect_status(dev0->rhport) )
{
+ TU_LOG2("Connect \r\n");
+
// connection event
osal_task_delay(POWER_STABLE_DELAY); // wait until device is stable. Increase this if the first 8 bytes is failed to get
@@ -371,6 +396,8 @@ bool enum_task(hcd_event_t* event)
}
else
{
+ TU_LOG2("Disconnect \r\n");
+
// disconnection event
usbh_device_unplugged(dev0->rhport, 0, 0);
return true; // restart task
@@ -424,6 +451,7 @@ bool enum_task(hcd_event_t* event)
TU_ASSERT_ERR( usbh_pipe_control_open(0, 8) );
//------------- Get first 8 bytes of device descriptor to get Control Endpoint Size -------------//
+ TU_LOG2("Get 8 byte of Device Descriptor \r\n");
request = (tusb_control_request_t ) {
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_IN },
.bRequest = TUSB_REQ_GET_DESCRIPTOR,
@@ -434,12 +462,16 @@ bool enum_task(hcd_event_t* event)
bool is_ok = usbh_control_xfer(0, &request, _usbh_ctrl_buf);
//------------- Reset device again before Set Address -------------//
+ TU_LOG2("Port reset \r\n");
+
if (dev0->hub_addr == 0)
{
// connected directly to roothub
TU_ASSERT(is_ok); // TODO some slow device is observed to fail the very fist controller xfer, can try more times
hcd_port_reset( dev0->rhport ); // reset port after 8 byte descriptor
osal_task_delay(RESET_DELAY);
+// hcd_port_reset_end(dev0->rhport);
+// osal_task_delay(RESET_DELAY);
}
#if CFG_TUH_HUB
else
@@ -458,6 +490,7 @@ bool enum_task(hcd_event_t* event)
#endif
//------------- Set new address -------------//
+ TU_LOG2("Set Address \r\n");
uint8_t const new_addr = get_new_address();
TU_ASSERT(new_addr <= CFG_TUSB_HOST_DEVICE_MAX); // TODO notify application we reach max devices
@@ -484,6 +517,7 @@ bool enum_task(hcd_event_t* event)
TU_ASSERT_ERR ( usbh_pipe_control_open(new_addr, ((tusb_desc_device_t*) _usbh_ctrl_buf)->bMaxPacketSize0 ) );
//------------- Get full device descriptor -------------//
+ TU_LOG2("Get Device Descriptor \r\n");
request = (tusb_control_request_t ) {
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_IN },
.bRequest = TUSB_REQ_GET_DESCRIPTOR,
@@ -502,6 +536,7 @@ bool enum_task(hcd_event_t* event)
TU_ASSERT(configure_selected <= new_dev->configure_count); // TODO notify application when invalid configuration
//------------- Get 9 bytes of configuration descriptor -------------//
+ TU_LOG2("Get 9 bytes of Configuration Descriptor \r\n");
request = (tusb_control_request_t ) {
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_IN },
.bRequest = TUSB_REQ_GET_DESCRIPTOR,
@@ -515,6 +550,7 @@ bool enum_task(hcd_event_t* event)
TU_ASSERT( CFG_TUSB_HOST_ENUM_BUFFER_SIZE >= ((tusb_desc_configuration_t*)_usbh_ctrl_buf)->wTotalLength );
//------------- Get full configuration descriptor -------------//
+ TU_LOG2("Get full Configuration Descriptor \r\n");
request.wLength = ((tusb_desc_configuration_t*)_usbh_ctrl_buf)->wTotalLength; // full length
TU_ASSERT( usbh_control_xfer( new_addr, &request, _usbh_ctrl_buf ) );
@@ -522,6 +558,7 @@ bool enum_task(hcd_event_t* event)
new_dev->interface_count = ((tusb_desc_configuration_t*) _usbh_ctrl_buf)->bNumInterfaces;
//------------- Set Configure -------------//
+ TU_LOG2("Set Configuration Descriptor \r\n");
request = (tusb_control_request_t ) {
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_OUT },
.bRequest = TUSB_REQ_SET_CONFIGURATION,
@@ -577,11 +614,7 @@ bool enum_task(hcd_event_t* event)
{
uint16_t itf_len = 0;
- if ( usbh_class_drivers[drv_id].open(new_dev->rhport, new_addr, desc_itf, &itf_len) )
- {
- mark_interface_endpoint(new_dev->ep2drv, p_desc, itf_len, drv_id);
- }
-
+ TU_ASSERT( usbh_class_drivers[drv_id].open(new_dev->rhport, new_addr, desc_itf, &itf_len) );
TU_ASSERT( itf_len >= sizeof(tusb_desc_interface_t) );
p_desc += itf_len;
}
@@ -597,7 +630,7 @@ bool enum_task(hcd_event_t* event)
/* USB Host Driver task
* This top level thread manages all host controller event and delegates events to class-specific drivers.
* This should be called periodically within the mainloop or rtos thread.
- *
+ *_usbh_devices[dev_addr].
@code
int main(void)
{
@@ -661,25 +694,4 @@ static inline uint8_t get_configure_number_for_device(tusb_desc_device_t* dev_de
return config_num;
}
-// Helper marking endpoint of interface belongs to class driver
-// TODO merge with usbd
-static void mark_interface_endpoint(uint8_t ep2drv[8][2], uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id)
-{
- uint16_t len = 0;
-
- while( len < desc_len )
- {
- if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) )
- {
- uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress;
-
- ep2drv[ tu_edpt_number(ep_addr) ][ tu_edpt_dir(ep_addr) ] = driver_id;
- }
-
- len += tu_desc_len(p_desc);
- p_desc = tu_desc_next(p_desc);
- }
-}
-
-
#endif
diff --git a/src/host/usbh.h b/src/host/usbh.h
index 42a2bd095..bc0abcccc 100644
--- a/src/host/usbh.h
+++ b/src/host/usbh.h
@@ -94,6 +94,8 @@ TU_ATTR_WEAK void tuh_umount_cb(uint8_t dev_addr);
bool usbh_init(void);
bool usbh_control_xfer (uint8_t dev_addr, tusb_control_request_t* request, uint8_t* data);
+bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc);
+
#ifdef __cplusplus
}
#endif