diff --git a/tests/test/host/ehci/test_pipe_bulk_xfer.c b/tests/test/host/ehci/test_pipe_bulk_xfer.c index ac9be3727..47115cd90 100644 --- a/tests/test/host/ehci/test_pipe_bulk_xfer.c +++ b/tests/test/host/ehci/test_pipe_bulk_xfer.c @@ -137,9 +137,31 @@ void verify_qtd(ehci_qtd_t *p_qtd, uint8_t p_data[], uint16_t length) } } +void test_bulk_xfer_hs_ping_out(void) +{ + tusb_descriptor_endpoint_t const desc_ept_bulk_out = + { + .bLength = sizeof(tusb_descriptor_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + .bEndpointAddress = 0x01, + .bmAttributes = { .xfer = TUSB_XFER_BULK }, + .wMaxPacketSize = 512, + .bInterval = 0 + }; + usbh_device_info_pool[dev_addr].speed = TUSB_SPEED_HIGH; + + pipe_handle_t pipe_hdl = hcd_pipe_open(dev_addr, &desc_ept_bulk_out, TUSB_CLASS_MSC); + ehci_qhd_t *p_qhd = get_qhd_from_pipe_handle(pipe_hdl); + + //------------- Code Under Test -------------// + hcd_pipe_xfer(pipe_hdl, xfer_data, sizeof(xfer_data), true); + + ehci_qtd_t* p_qtd = p_qhd->p_qtd_list_head; + TEST_ASSERT(p_qtd->pingstate_err); +} + void test_bulk_xfer(void) { - //------------- Code Under Test -------------// hcd_pipe_xfer(pipe_hdl_bulk, xfer_data, sizeof(xfer_data), true); diff --git a/tests/test/support/ehci_controller.h b/tests/test/support/ehci_controller.h index ee3acfa56..843d13bf2 100644 --- a/tests/test/support/ehci_controller.h +++ b/tests/test/support/ehci_controller.h @@ -67,6 +67,7 @@ ehci_qhd_t* get_async_head(uint8_t hostid); ehci_qhd_t* get_period_head(uint8_t hostid); ehci_qhd_t* get_control_qhd(uint8_t dev_addr); ehci_qtd_t* get_control_qtds(uint8_t dev_addr); +ehci_qhd_t* get_qhd_from_pipe_handle(pipe_handle_t pipe_hdl); #ifdef __cplusplus } diff --git a/tinyusb/host/ehci/ehci.c b/tinyusb/host/ehci/ehci.c index 1b4ff3b2e..734251d7f 100644 --- a/tinyusb/host/ehci/ehci.c +++ b/tinyusb/host/ehci/ehci.c @@ -616,8 +616,8 @@ pipe_handle_t hcd_pipe_open(uint8_t dev_addr, tusb_descriptor_endpoint_t const * return (pipe_handle_t) { .dev_addr = dev_addr, .xfer_type = p_endpoint_desc->bmAttributes.xfer, .index = get_qhd_index(p_qhd) }; } -static inline ehci_qhd_t* get_qhd_from_pipe_handle(pipe_handle_t pipe_hdl) ATTR_PURE ATTR_ALWAYS_INLINE; -static inline ehci_qhd_t* get_qhd_from_pipe_handle(pipe_handle_t pipe_hdl) +STATIC_ INLINE_ ehci_qhd_t* get_qhd_from_pipe_handle(pipe_handle_t pipe_hdl) ATTR_PURE ATTR_ALWAYS_INLINE; +STATIC_ INLINE_ ehci_qhd_t* get_qhd_from_pipe_handle(pipe_handle_t pipe_hdl) { return &ehci_data.device[ pipe_hdl.dev_addr-1 ].qhd[ pipe_hdl.index ]; } @@ -647,6 +647,11 @@ tusb_error_t hcd_pipe_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[], uint16_t t init_qtd(p_qtd, (uint32_t) buffer, total_bytes); p_qtd->pid = p_qhd->pid_non_control; p_qtd->int_on_complete = int_on_complete ? 1 : 0; + // do PING for Highspeed Bulk OUT, EHCI section 4.11 + if (pipe_hdl.xfer_type == TUSB_XFER_BULK && p_qhd->endpoint_speed == TUSB_SPEED_HIGH && p_qtd->pid == EHCI_PID_OUT) + { + p_qtd->pingstate_err = 1; + } //------------- insert TD to TD list -------------// insert_qtd_to_qhd(p_qhd, p_qtd);