diff options
| author | hathach <[email protected]> | 2013-06-21 13:11:16 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2013-06-21 13:11:45 +0700 |
| commit | 3924764dff9d90ccff09e1d657c6f40ed8def8d9 (patch) | |
| tree | c3b124a2f9a76be89cbb34d36a38678d0fb3e8b2 /tinyusb/host | |
| parent | 743e5a7a930b7e22d85ed1ae9714d42e75ef43c6 (diff) | |
[host lpc43xx] adding support for host custom class
refractor usbh class driver indexing
opt out periodic list code in EHCI (need to refractor/group later)
[device lpc176x] rename dcd_endpoint_configure to dcd_pipe_open
add usbd_pipe_open to manage pipe
Diffstat (limited to 'tinyusb/host')
| -rw-r--r-- | tinyusb/host/ehci/ehci.c | 18 | ||||
| -rw-r--r-- | tinyusb/host/usbh.c | 57 |
2 files changed, 53 insertions, 22 deletions
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) { |
