diff --git a/tests/test/host/hid/test_hid_host.c b/tests/test/host/hid/test_hid_host.c index 0b40d9c5b..8c53fa083 100644 --- a/tests/test/host/hid/test_hid_host.c +++ b/tests/test/host/hid/test_hid_host.c @@ -40,6 +40,7 @@ #include "tusb_option.h" #include "errors.h" #include "binary.h" +#include "type_helper.h" #include "descriptor_test.h" #include "mock_osal.h" @@ -49,6 +50,9 @@ #include "hid_host.h" uint8_t dev_addr; +pipe_handle_t pipe_hdl; + +extern hidh_keyboard_info_t keyboard_data[TUSB_CFG_HOST_DEVICE_MAX]; tusb_descriptor_interface_t const *p_kbd_interface_desc = &desc_configuration.keyboard_interface; tusb_hid_descriptor_hid_t const *p_kbh_hid_desc = &desc_configuration.keyboard_hid; @@ -57,6 +61,7 @@ tusb_descriptor_endpoint_t const *p_kdb_endpoint_desc = &desc_configuration.ke void setUp(void) { dev_addr = RANDOM(TUSB_CFG_HOST_DEVICE_MAX)+1; + pipe_hdl = (pipe_handle_t) {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_INTERRUPT, .index = 2}; } void tearDown(void) @@ -66,7 +71,7 @@ void tearDown(void) void test_hidh_open_ok(void) { uint16_t length=0; - pipe_handle_t pipe_hdl = {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_INTERRUPT, .index = 2}; + // TODO expect get HID report descriptor hcd_pipe_open_IgnoreAndReturn( pipe_hdl ); @@ -80,9 +85,15 @@ void test_hidh_open_ok(void) void test_hidh_close(void) { - TEST_IGNORE(); + keyboard_data[dev_addr-1].pipe_hdl = pipe_hdl; + keyboard_data[dev_addr-1].report_size = 8; + + hcd_pipe_close_ExpectAndReturn(pipe_hdl, TUSB_ERROR_NONE); + //------------- Code Under TEST -------------// hidh_close(dev_addr); + + TEST_ASSERT_MEM_ZERO(&keyboard_data[dev_addr-1], sizeof(hidh_keyboard_info_t)); } void test_hihd_isr(void) diff --git a/tests/test/host/hid/test_hidh_keyboard.c b/tests/test/host/hid/test_hidh_keyboard.c index b124ade00..fc4531765 100644 --- a/tests/test/host/hid/test_hidh_keyboard.c +++ b/tests/test/host/hid/test_hidh_keyboard.c @@ -109,11 +109,18 @@ void test_keyboard_is_supported_fail_not_opened(void) TEST_ASSERT_FALSE( tusbh_hid_keyboard_is_supported(dev_addr) ); } +void test_keyboard_is_supported_ok(void) +{ + tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED); + TEST_ASSERT_TRUE( tusbh_hid_keyboard_is_supported(dev_addr) ); +} + void test_keyboard_open_ok(void) { uint16_t length=0; pipe_handle_t pipe_hdl = {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_INTERRUPT, .index = 2}; - memclr_(p_hidh_kbd, sizeof(hidh_keyboard_info_t)); + + hidh_init(); hcd_pipe_open_ExpectAndReturn(dev_addr, p_kdb_endpoint_desc, TUSB_CLASS_HID, pipe_hdl); @@ -129,11 +136,6 @@ void test_keyboard_open_ok(void) TEST_ASSERT_TRUE( tusbh_hid_keyboard_is_supported(dev_addr) ); } -void test_keyboard_close(void) -{ - -} - //--------------------------------------------------------------------+ // keyboard_get //--------------------------------------------------------------------+ diff --git a/tinyusb/class/hid_host.c b/tinyusb/class/hid_host.c index 6665d2320..723fd64f1 100644 --- a/tinyusb/class/hid_host.c +++ b/tinyusb/class/hid_host.c @@ -73,6 +73,18 @@ bool tusbh_hid_keyboard_is_supported(uint8_t dev_addr) return tusbh_device_is_configured(dev_addr) && pipehandle_is_valid(keyboard_data[dev_addr-1].pipe_hdl); } +tusb_error_t hidh_keyboard_open(uint8_t dev_addr, tusb_descriptor_endpoint_t const *p_endpoint_desc) +{ + hidh_keyboard_info_t *p_keyboard = get_kbd_data(dev_addr); + + p_keyboard->pipe_hdl = hcd_pipe_open(dev_addr, p_endpoint_desc, TUSB_CLASS_HID); + p_keyboard->report_size = p_endpoint_desc->wMaxPacketSize.size; // TODO get size from report descriptor + + ASSERT (pipehandle_is_valid(p_keyboard->pipe_hdl), TUSB_ERROR_HCD_FAILED); + + return TUSB_ERROR_NONE; +} + tusb_error_t tusbh_hid_keyboard_get_report(uint8_t dev_addr, uint8_t instance_num, tusb_keyboard_report_t * const report) { //------------- parameters validation -------------// @@ -89,6 +101,16 @@ tusb_error_t tusbh_hid_keyboard_get_report(uint8_t dev_addr, uint8_t instance_nu return TUSB_ERROR_NONE; } +void hidh_keyboard_close(uint8_t dev_addr) +{ + pipe_handle_t pipe_hdl = keyboard_data[dev_addr-1].pipe_hdl; + if ( pipehandle_is_valid(pipe_hdl) ) + { + memclr_(&keyboard_data[dev_addr-1], sizeof(hidh_keyboard_info_t)); + ASSERT_INT( TUSB_ERROR_NONE, hcd_pipe_close(pipe_hdl), (void) 0 ); + } +} + #endif //--------------------------------------------------------------------+ @@ -109,18 +131,6 @@ void hidh_init(void) #endif } -tusb_error_t hidh_keyboard_open(uint8_t dev_addr, tusb_descriptor_endpoint_t const *p_endpoint_desc) -{ - hidh_keyboard_info_t *p_keyboard = get_kbd_data(dev_addr); - - p_keyboard->pipe_hdl = hcd_pipe_open(dev_addr, p_endpoint_desc, TUSB_CLASS_HID); - p_keyboard->report_size = p_endpoint_desc->wMaxPacketSize.size; // TODO get size from report descriptor - - ASSERT (pipehandle_is_valid(p_keyboard->pipe_hdl), TUSB_ERROR_HCD_FAILED); - - return TUSB_ERROR_NONE; -} - tusb_error_t hidh_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t const *p_interface_desc, uint16_t *p_length) { uint8_t const *p_desc = (uint8_t const *) p_interface_desc; @@ -174,7 +184,7 @@ void hidh_isr(pipe_handle_t pipe_hdl, tusb_bus_event_t event) void hidh_close(uint8_t dev_addr) { #if TUSB_CFG_HOST_HID_KEYBOARD -// hidh_keyboard_close(dev_addr); + hidh_keyboard_close(dev_addr); #endif #if TUSB_CFG_HOST_HID_MOUSE diff --git a/tinyusb/host/usbh.c b/tinyusb/host/usbh.c index 6717b2c70..67ad72ac0 100644 --- a/tinyusb/host/usbh.c +++ b/tinyusb/host/usbh.c @@ -386,32 +386,39 @@ OSAL_TASK_DECLARE(usbh_enumeration_task) // parse each interfaces while( p_desc < enum_data_buffer + ((tusb_descriptor_configuration_t*)enum_data_buffer)->wTotalLength ) { - TASK_ASSERT( TUSB_DESC_INTERFACE == p_desc[DESCRIPTOR_OFFSET_TYPE] ); // TODO should we skip this descriptor and advance - - uint8_t class_code = ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass; - if (class_code == 0) + // skip until we see interface descriptor + if ( TUSB_DESC_INTERFACE != p_desc[DESCRIPTOR_OFFSET_TYPE] ) { - TASK_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) + p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip the descriptor, increase by the descriptor's length + }else { - 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) ); - - // TODO check class_open_subtask status - usbh_devices[new_addr].flag_supported_class |= BIT_(((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass); - - p_desc += length; - } else // unsupported class (not enable or yet implemented) - { - do + uint8_t class_code = ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass; + if (class_code == 0) { - p_desc += (*p_desc); // skip the descriptor, increase by the descriptor's length - } while ( (p_desc < enum_data_buffer + ((tusb_descriptor_configuration_t*)enum_data_buffer)->wTotalLength) - && TUSB_DESC_INTERFACE != p_desc[1] ); + TASK_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) + { + 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) ); + + // TODO check class_open_subtask status + if (length == 0) // Interface open failed, for example a subclass is not supported + { + p_desc += p_desc[DESCRIPTOR_OFFSET_TYPE]; // skip this interface, the rest will be skipped by the above loop + // TODO can optimize the length --> open_subtask return a OPEN FAILED status + }else + { + usbh_devices[new_addr].flag_supported_class |= BIT_(((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass); + p_desc += length; + } + } else // unsupported class (not enable or yet implemented) + { + p_desc += p_desc[DESCRIPTOR_OFFSET_TYPE]; // skip this interface, the rest will be skipped by the above loop + } } }