From 940d7fb7f6086afc5483f277077c6c05a8d8b539 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 13 Apr 2014 15:39:57 +0700 Subject: [PATCH] merge EHCI_MAX_QHD/QTD and OHCI_MAX_QHD/QTD to HCD_MAX_ENDPOINT/XFER and scale with number of enabled classes. default config to support up to 5 device (hub + 4 others) --- demos/host/src/tusb_config.h | 2 +- doxygen/getting_started.md | 3 ++- tinyusb/host/ehci/ehci.c | 24 ++++++++++++------------ tinyusb/host/ehci/ehci.h | 20 +++++++++----------- tinyusb/host/hcd.h | 12 ++++++++++-- tinyusb/host/ohci/ohci.c | 8 ++++---- tinyusb/host/ohci/ohci.h | 10 +++++----- 7 files changed, 43 insertions(+), 36 deletions(-) diff --git a/demos/host/src/tusb_config.h b/demos/host/src/tusb_config.h index b1a4f151..a39762a5 100644 --- a/demos/host/src/tusb_config.h +++ b/demos/host/src/tusb_config.h @@ -52,7 +52,7 @@ //--------------------------------------------------------------------+ // HOST CONFIGURATION //--------------------------------------------------------------------+ -#define TUSB_CFG_HOST_DEVICE_MAX 3 // TODO be a part of HUB config +#define TUSB_CFG_HOST_DEVICE_MAX 5 // TODO be a part of HUB config //------------- CLASS -------------// #define TUSB_CFG_HOST_HUB 1 diff --git a/doxygen/getting_started.md b/doxygen/getting_started.md index a5b2d374..13e65b95 100644 --- a/doxygen/getting_started.md +++ b/doxygen/getting_started.md @@ -38,4 +38,5 @@ In order to build and run application demo, you would need - A supported toolchain: LPCXpresso, Keil, IAR. \subpage md_boards_readme -\subpage md_doxygen_started_build \ No newline at end of file +\subpage md_doxygen_started_build_demo +\subpage md_doxygen_started_run_demo \ No newline at end of file diff --git a/tinyusb/host/ehci/ehci.c b/tinyusb/host/ehci/ehci.c index 213876f3..62915b6b 100644 --- a/tinyusb/host/ehci/ehci.c +++ b/tinyusb/host/ehci/ehci.c @@ -523,12 +523,12 @@ static void async_advance_isr(ehci_qhd_t * const async_head) // Host Controller has cleaned up its cached data for this device, set state to unplug usbh_devices[relative_dev_addr+1].state = TUSB_DEVICE_STATE_UNPLUG; - for (uint8_t i=0; ip_qtd_list_head != NULL && !p_qhd->p_qtd_list_head->active - && max_loop < EHCI_MAX_QTD) + && max_loop < HCD_MAX_XFER) { // TD need to be freed and removed from qhd, before invoking callback bool is_ioc = (p_qhd->p_qtd_list_head->int_on_complete != 0); @@ -593,7 +593,7 @@ static void async_list_xfer_complete_isr(ehci_qhd_t * const async_head) } p_qhd = qhd_next(p_qhd); max_loop++; - }while(p_qhd != async_head && max_loop < EHCI_MAX_QHD); // async list traversal, stop if loop around + }while(p_qhd != async_head && max_loop < HCD_MAX_ENDPOINT); // async list traversal, stop if loop around // TODO abstract max loop guard for async } @@ -607,7 +607,7 @@ static void period_list_xfer_complete_isr(uint8_t hostid, uint8_t interval_ms) // TODO abstract max loop guard for period while( !next_item.terminate && !(interval_ms > 1 && period_1ms_addr == align32(next_item.address)) && - max_loop < (EHCI_MAX_QHD + EHCI_MAX_ITD + EHCI_MAX_SITD)) + max_loop < (HCD_MAX_ENDPOINT + EHCI_MAX_ITD + EHCI_MAX_SITD)) { switch ( next_item.type ) { @@ -692,7 +692,7 @@ static void xfer_error_isr(uint8_t hostid) qhd_xfer_error_isr( p_qhd ); p_qhd = qhd_next(p_qhd); max_loop++; - }while(p_qhd != async_head && max_loop < EHCI_MAX_QHD); // async list traversal, stop if loop around + }while(p_qhd != async_head && max_loop < HCD_MAX_ENDPOINT); // async list traversal, stop if loop around #if EHCI_PERIODIC_LIST //------------- TODO refractor period list -------------// @@ -705,7 +705,7 @@ static void xfer_error_isr(uint8_t hostid) // TODO abstract max loop guard for period while( !next_item.terminate && !(interval_ms > 1 && period_1ms_addr == align32(next_item.address)) && - period_max_loop < (EHCI_MAX_QHD + EHCI_MAX_ITD + EHCI_MAX_SITD)) + period_max_loop < (HCD_MAX_ENDPOINT + EHCI_MAX_ITD + EHCI_MAX_SITD)) { switch ( next_item.type ) { @@ -852,11 +852,11 @@ static inline ehci_qhd_t* qhd_find_free (uint8_t dev_addr) { uint8_t relative_address = dev_addr-1; uint8_t index=0; - while( indexaddress) != (uint32_t) p_head) && // not loop around (align32(p_prev->address) != (uint32_t) p_current) && // not found yet !p_prev->terminate && // not advanceable - max_loop < EHCI_MAX_QHD) + max_loop < HCD_MAX_ENDPOINT) { p_prev = list_next(p_prev); max_loop++; diff --git a/tinyusb/host/ehci/ehci.h b/tinyusb/host/ehci/ehci.h index 7b3ddfaa..2feb1e70 100644 --- a/tinyusb/host/ehci/ehci.h +++ b/tinyusb/host/ehci/ehci.h @@ -71,19 +71,17 @@ #define HOST_HCD_XFER_INTERRUPT // TODO interrupt is used widely, should always be enalbed #define EHCI_PERIODIC_LIST (defined HOST_HCD_XFER_INTERRUPT || defined HOST_HCD_XFER_ISOCHRONOUS) -// TODO merge OHCI with EHCI -#define EHCI_MAX_QHD 8 -#define EHCI_MAX_QTD 20 -#define EHCI_MAX_ITD 4 -#define EHCI_MAX_SITD 16 - #define EHCI_CFG_FRAMELIST_SIZE_BITS 7 /// Framelist Size (NXP specific) (0:1024) - (1:512) - (2:256) - (3:128) - (4:64) - (5:32) - (6:16) - (7:8) #define EHCI_FRAMELIST_SIZE (1024 >> EHCI_CFG_FRAMELIST_SIZE_BITS) +// TODO merge OHCI with EHCI +enum { + EHCI_MAX_ITD = 4, + EHCI_MAX_SITD = 16 +}; + //------------- Validation -------------// -#if EHCI_CFG_FRAMELIST_SIZE_BITS > 7 - #error EHCI_CFG_FRAMELIST_SIZE_BITS must be from 0-7 -#endif +STATIC_ASSERT(EHCI_CFG_FRAMELIST_SIZE_BITS <= 7, "incorrect value"); //--------------------------------------------------------------------+ // EHCI Data Structure @@ -469,8 +467,8 @@ typedef struct { ehci_qtd_t qtd[3]; }control; - ehci_qhd_t qhd[EHCI_MAX_QHD] ; ///< Queue Head Pool - ehci_qtd_t qtd[EHCI_MAX_QTD] ATTR_ALIGNED(32) ; ///< Queue Element Transfer Pool + ehci_qhd_t qhd[HCD_MAX_ENDPOINT] ; ///< Queue Head Pool + ehci_qtd_t qtd[HCD_MAX_XFER] ATTR_ALIGNED(32) ; ///< Queue Element Transfer Pool // ehci_itd_t itd[EHCI_MAX_ITD] ; ///< Iso Transfer Pool // ehci_sitd_t sitd[EHCI_MAX_SITD] ; ///< Split (FS) Isochronous Transfer Pool }device[TUSB_CFG_HOST_DEVICE_MAX]; diff --git a/tinyusb/host/hcd.h b/tinyusb/host/hcd.h index 0515f7a9..a7b5210e 100644 --- a/tinyusb/host/hcd.h +++ b/tinyusb/host/hcd.h @@ -43,12 +43,20 @@ #ifndef _TUSB_HCD_H_ #define _TUSB_HCD_H_ -#include "common/common.h" - #ifdef __cplusplus extern "C" { #endif +#include "common/common.h" + +// Max number of endpoints per device +enum { + HCD_MAX_ENDPOINT = TUSB_CFG_HOST_HUB + TUSB_CFG_HOST_HID_KEYBOARD + TUSB_CFG_HOST_HID_MOUSE + TUSB_CFG_HOST_HID_GENERIC + + TUSB_CFG_HOST_MSC*2 + TUSB_CFG_HOST_CDC*3, + + HCD_MAX_XFER = HCD_MAX_ENDPOINT*2, +}; + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ diff --git a/tinyusb/host/ohci/ohci.c b/tinyusb/host/ohci/ohci.c index c1cdc3ea..12876077 100644 --- a/tinyusb/host/ohci/ohci.c +++ b/tinyusb/host/ohci/ohci.c @@ -371,7 +371,7 @@ static inline ohci_ed_t * ed_from_pipe_handle(pipe_handle_t pipe_hdl) static inline ohci_ed_t * ed_find_free(uint8_t dev_addr) ATTR_PURE ATTR_ALWAYS_INLINE; static inline ohci_ed_t * ed_find_free(uint8_t dev_addr) { - for(uint8_t i = 0; i < OHCI_MAX_QHD; i++) + for(uint8_t i = 0; i < HCD_MAX_ENDPOINT; i++) { if ( !ohci_data.device[dev_addr-1].ed[i].used ) { @@ -384,7 +384,7 @@ static inline ohci_ed_t * ed_find_free(uint8_t dev_addr) static ohci_ed_t * ed_list_find_previous(ohci_ed_t const * p_head, ohci_ed_t const * p_ed) { - uint32_t max_loop = OHCI_MAX_QHD; + uint32_t max_loop = HCD_MAX_ENDPOINT; ohci_ed_t const * p_prev = p_head; @@ -444,7 +444,7 @@ pipe_handle_t hcd_pipe_open(uint8_t dev_addr, tusb_descriptor_endpoint_t const * static ohci_gtd_t * gtd_find_free(uint8_t dev_addr) { - for(uint8_t i=0; i < OHCI_MAX_QTD; i++) + for(uint8_t i=0; i < HCD_MAX_XFER; i++) { if (!ohci_data.device[dev_addr-1].gtd[i].used) { @@ -608,7 +608,7 @@ static inline uint32_t gtd_xfer_byte_left(uint32_t buffer_end, uint32_t current_ static void done_queue_isr(uint8_t hostid) { - uint8_t max_loop = (TUSB_CFG_HOST_DEVICE_MAX+1)*(OHCI_MAX_QTD+OHCI_MAX_ITD); + uint8_t max_loop = (TUSB_CFG_HOST_DEVICE_MAX+1)*(HCD_MAX_XFER+OHCI_MAX_ITD); // done head is written in reversed order of completion --> need to reverse the done queue first ohci_td_item_t* td_head = list_reverse ( (ohci_td_item_t*) align16(ohci_data.hcca.done_head) ); diff --git a/tinyusb/host/ohci/ohci.h b/tinyusb/host/ohci/ohci.h index eed6909a..3d3607c2 100644 --- a/tinyusb/host/ohci/ohci.h +++ b/tinyusb/host/ohci/ohci.h @@ -58,9 +58,9 @@ #define OHCI_PERIODIC_LIST (defined HOST_HCD_XFER_INTERRUPT || defined HOST_HCD_XFER_ISOCHRONOUS) // TODO merge OHCI with EHCI -#define OHCI_MAX_QHD 8 -#define OHCI_MAX_QTD 20 -#define OHCI_MAX_ITD 4 +enum { + OHCI_MAX_ITD = 4 +}; enum { OHCI_PID_SETUP = 0, @@ -195,8 +195,8 @@ typedef struct ATTR_ALIGNED(256) { struct { // ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32 - ohci_ed_t ed[OHCI_MAX_QHD]; - ohci_gtd_t gtd[OHCI_MAX_QTD]; + ohci_ed_t ed[HCD_MAX_ENDPOINT]; + ohci_gtd_t gtd[HCD_MAX_XFER]; }device[TUSB_CFG_HOST_DEVICE_MAX]; } ohci_data_t;