From 7557a807a97bcb9edc2d36a9944d6715ee6f3525 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 6 Mar 2013 16:24:32 +0700 Subject: [PATCH] basically finish code for control transfer & test code --- tests/test/host/ehci/test_ehci_pipe_xfer.c | 111 +++++++++++++-------- tinyusb/host/ehci/ehci.c | 47 +++++---- 2 files changed, 99 insertions(+), 59 deletions(-) diff --git a/tests/test/host/ehci/test_ehci_pipe_xfer.c b/tests/test/host/ehci/test_ehci_pipe_xfer.c index e7e703bda..7abf8b3f0 100644 --- a/tests/test/host/ehci/test_ehci_pipe_xfer.c +++ b/tests/test/host/ehci/test_ehci_pipe_xfer.c @@ -121,43 +121,8 @@ tusb_std_request_t request_get_dev_desc = .wLength = 18 }; -void test_control_addr0_xfer_get_check_qhd_qtd_mapping(void) +void verify_qtd(ehci_qtd_t *p_qtd, uint8_t p_data[], uint16_t length) { - dev_addr = 0; - ehci_qhd_t * const p_qhd = async_head; - hcd_pipe_control_open(dev_addr, control_max_packet_size); - - //------------- Code Under TEST -------------// - hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data); - - p_setup = &ehci_data.addr0.qtd[0]; - p_data = &ehci_data.addr0.qtd[1]; - p_status = &ehci_data.addr0.qtd[2]; - - TEST_ASSERT_EQUAL_HEX( p_setup, p_qhd->qtd_overlay.next.address ); - - TEST_ASSERT_EQUAL_HEX( p_setup , p_qhd->p_qtd_list); - TEST_ASSERT_EQUAL_HEX( p_data , p_setup->next.address); - TEST_ASSERT_EQUAL_HEX( p_status , p_data->next.address ); - TEST_ASSERT_TRUE( p_status->next.terminate ); -} - -void test_control_xfer_get(void) -{ - ehci_qhd_t * const p_qhd = &ehci_data.device[dev_addr].control.qhd; - hcd_pipe_control_open(dev_addr, control_max_packet_size); - - //------------- Code Under TEST -------------// - hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data); - - TEST_ASSERT_EQUAL_HEX( p_setup, p_qhd->qtd_overlay.next.address ); - - TEST_ASSERT_EQUAL_HEX( p_setup , p_qhd->p_qtd_list); - TEST_ASSERT_EQUAL_HEX( p_data , p_setup->next.address); - TEST_ASSERT_EQUAL_HEX( p_status , p_data->next.address ); - TEST_ASSERT_TRUE( p_status->next.terminate ); - - ehci_qtd_t *p_qtd = p_setup; TEST_ASSERT_TRUE(p_qtd->alternate.terminate); // not used, always invalid TEST_ASSERT_FALSE(p_qtd->pingstate_err); @@ -171,15 +136,70 @@ void test_control_xfer_get(void) TEST_ASSERT_EQUAL(3, p_qtd->cerr); TEST_ASSERT_EQUAL(0, p_qtd->current_page); - TEST_ASSERT_FALSE(p_qtd->int_on_complete); - TEST_ASSERT_EQUAL(8, p_qtd->total_bytes); - TEST_ASSERT_FALSE(p_qtd->data_toggle); + TEST_ASSERT_EQUAL(length, p_qtd->total_bytes); - uint8_t *p_data = (uint8_t *) &ehci_data.device[dev_addr].control.request; TEST_ASSERT_EQUAL_HEX(p_data, p_qtd->buffer[0]); - TEST_ASSERT_EQUAL_MEMORY(&request_get_dev_desc, p_data, sizeof(tusb_std_request_t)); +} - TEST_ASSERT_EQUAL(EHCI_PID_SETUP, p_qtd->pid); +void test_control_addr0_xfer_get_check_qhd_qtd_mapping(void) +{ + dev_addr = 0; + ehci_qhd_t * const p_qhd = async_head; + + hcd_pipe_control_open(dev_addr, control_max_packet_size); + + //------------- Code Under TEST -------------// + hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data); + + p_setup = &ehci_data.addr0.qtd[0]; + p_data = &ehci_data.addr0.qtd[1]; + p_status = &ehci_data.addr0.qtd[2]; + + TEST_ASSERT_EQUAL_HEX( p_setup, p_qhd->qtd_overlay.next.address ); + TEST_ASSERT_EQUAL_HEX( p_setup , p_qhd->p_qtd_list); + TEST_ASSERT_EQUAL_HEX( p_data , p_setup->next.address); + TEST_ASSERT_EQUAL_HEX( p_status , p_data->next.address ); + TEST_ASSERT_TRUE( p_status->next.terminate ); + + verify_qtd(p_setup, &ehci_data.addr0.request, 8); +} + + +void test_control_xfer_get(void) +{ + ehci_qhd_t * const p_qhd = &ehci_data.device[dev_addr].control.qhd; + hcd_pipe_control_open(dev_addr, control_max_packet_size); + + //------------- Code Under TEST -------------// + hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data); + + TEST_ASSERT_EQUAL_HEX( p_setup, p_qhd->qtd_overlay.next.address ); + TEST_ASSERT_EQUAL_HEX( p_setup , p_qhd->p_qtd_list); + TEST_ASSERT_EQUAL_HEX( p_data , p_setup->next.address); + TEST_ASSERT_EQUAL_HEX( p_status , p_data->next.address ); + TEST_ASSERT_TRUE( p_status->next.terminate ); + + //------------- SETUP -------------// + uint8_t* p_request = (uint8_t *) &ehci_data.device[dev_addr].control.request; + verify_qtd(p_setup, p_request, 8); + + TEST_ASSERT_EQUAL_MEMORY(&request_get_dev_desc, p_request, sizeof(tusb_std_request_t)); + + TEST_ASSERT_FALSE(p_setup->int_on_complete); + TEST_ASSERT_FALSE(p_setup->data_toggle); + TEST_ASSERT_EQUAL(EHCI_PID_SETUP, p_setup->pid); + + //------------- DATA -------------// + verify_qtd(p_data, xfer_data, request_get_dev_desc.wLength); + TEST_ASSERT_FALSE(p_data->int_on_complete); + TEST_ASSERT_TRUE(p_data->data_toggle); + TEST_ASSERT_EQUAL(EHCI_PID_IN, p_data->pid); + + //------------- STATUS -------------// + verify_qtd(p_status, NULL, 0); + TEST_ASSERT_TRUE(p_status->int_on_complete); + TEST_ASSERT_TRUE(p_status->data_toggle); + TEST_ASSERT_EQUAL(EHCI_PID_OUT, p_status->pid); } void test_control_xfer_set(void) @@ -197,9 +217,16 @@ void test_control_xfer_set(void) //------------- Code Under TEST -------------// hcd_pipe_control_xfer(dev_addr, &request_set_dev_addr, xfer_data); + TEST_ASSERT_EQUAL_HEX( p_setup, p_qhd->qtd_overlay.next.address ); TEST_ASSERT_EQUAL_HEX( p_setup , p_qhd->p_qtd_list); TEST_ASSERT_EQUAL_HEX( p_status , p_setup->next.address ); TEST_ASSERT_TRUE( p_status->next.terminate ); + + //------------- STATUS -------------// + verify_qtd(p_status, NULL, 0); + TEST_ASSERT_TRUE(p_status->int_on_complete); + TEST_ASSERT_TRUE(p_status->data_toggle); + TEST_ASSERT_EQUAL(EHCI_PID_IN, p_status->pid); } diff --git a/tinyusb/host/ehci/ehci.c b/tinyusb/host/ehci/ehci.c index 913c43a77..86cb40dcb 100644 --- a/tinyusb/host/ehci/ehci.c +++ b/tinyusb/host/ehci/ehci.c @@ -246,6 +246,7 @@ tusb_error_t hcd_controller_reset(uint8_t hostid) // PIPE API //--------------------------------------------------------------------+ static void queue_head_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, uint16_t max_packet_size, uint8_t endpoint_addr, uint8_t xfer_type); + static inline ehci_qhd_t* const get_control_qhd(uint8_t dev_addr) ATTR_ALWAYS_INLINE ATTR_PURE ATTR_WARN_UNUSED_RESULT; static inline ehci_qtd_t* get_control_qtds(uint8_t dev_addr) ATTR_ALWAYS_INLINE ATTR_PURE ATTR_WARN_UNUSED_RESULT; static inline tusb_std_request_t* const get_control_request_ptr(uint8_t dev_addr) ATTR_ALWAYS_INLINE ATTR_PURE ATTR_WARN_UNUSED_RESULT; @@ -301,6 +302,20 @@ pipe_handle_t hcd_pipe_open(uint8_t dev_addr, tusb_descriptor_endpoint_t const * return null_handle; } +static void queue_td_init(ehci_qtd_t* p_qtd, uint32_t data_ptr, uint16_t total_bytes) +{ + memclr_(p_qtd, sizeof(ehci_qtd_t)); + + p_qtd->alternate.terminate = 1; // not used, always set to terminated + p_qtd->active = 1; + p_qtd->cerr = 3; // TODO 3 consecutive errors tolerance + p_qtd->data_toggle = 0; + p_qtd->total_bytes = total_bytes; + + p_qtd->buffer[0] = data_ptr; + +} + tusb_error_t hcd_pipe_control_xfer(uint8_t dev_addr, tusb_std_request_t const * p_request, uint8_t data[]) { ehci_qhd_t * const p_qhd = get_control_qhd(dev_addr); @@ -309,21 +324,19 @@ tusb_error_t hcd_pipe_control_xfer(uint8_t dev_addr, tusb_std_request_t const * ehci_qtd_t *p_data = p_setup + 1; ehci_qtd_t *p_status = p_setup + 2; - memclr_(p_setup, sizeof(ehci_qtd_t)); - p_setup->next.address = (uint32_t) p_data; - p_setup->active = 1; - p_setup->cerr = 3; // TODO 3 consecutive errors tolerance - p_setup->data_toggle = 0; - p_setup->total_bytes = 8; // sizeof (tusb_std_request_t) - - p_setup->buffer[0] = (uint32_t) get_control_request_ptr(dev_addr); - *(get_control_request_ptr(dev_addr)) = *p_request; + //------------- SETUP Phase -------------// + *(get_control_request_ptr(dev_addr)) = *p_request; // copy request + queue_td_init(p_setup, (uint32_t) get_control_request_ptr(dev_addr), 8); p_setup->pid = EHCI_PID_SETUP; + p_setup->next.address = (uint32_t) p_data; + //------------- DATA Phase -------------// if (p_request->wLength > 0) { - + queue_td_init(p_data, (uint32_t) data, p_request->wLength); + p_data->data_toggle = 1; + p_data->pid = p_request->bmRequestType.direction ? EHCI_PID_IN : EHCI_PID_OUT; }else { p_data = p_setup; @@ -331,15 +344,15 @@ tusb_error_t hcd_pipe_control_xfer(uint8_t dev_addr, tusb_std_request_t const * p_data->next.address = (uint32_t) p_status; - p_status->next.terminate = 1; - - //------------- alternate link is not used -------------// - p_data->alternate.terminate = 1; - p_setup->alternate.terminate = 1; - p_data->alternate.terminate = 1; + //------------- STATUS Phase -------------// + queue_td_init(p_status, 0, 0); // zero-length data + p_status->int_on_complete = 1; + p_status->data_toggle = 1; + p_status->pid = p_request->bmRequestType.direction ? EHCI_PID_OUT : EHCI_PID_IN; // reverse direction of data phase + p_status->next.terminate = 1; //------------- hook TD List to Queue Head -------------// - p_qhd->p_qtd_list = p_setup; + p_qhd->p_qtd_list = p_setup; p_qhd->qtd_overlay.next.address = (uint32_t) p_setup; return TUSB_ERROR_NONE;