[OHCI] Allow more than 16 devices
This commit is contained in:
@@ -157,6 +157,7 @@ static ohci_ed_t * const p_ed_head[] =
|
||||
|
||||
static void ed_list_insert(ohci_ed_t * p_pre, ohci_ed_t * p_ed);
|
||||
static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr);
|
||||
static gtd_extra_data_t *gtd_get_extra_data(ohci_gtd_t const * const gtd);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USBH-HCD API
|
||||
@@ -345,7 +346,7 @@ static void gtd_init(ohci_gtd_t *p_td, uint8_t *data_ptr, uint16_t total_bytes)
|
||||
tu_memclr(p_td, sizeof(ohci_gtd_t));
|
||||
|
||||
p_td->used = 1;
|
||||
p_td->expected_bytes = total_bytes;
|
||||
gtd_get_extra_data(p_td)->expected_bytes = total_bytes;
|
||||
|
||||
p_td->buffer_rounding = 1; // less than queued length is not a error
|
||||
p_td->delay_interrupt = OHCI_INT_ON_COMPLETE_NO;
|
||||
@@ -610,6 +611,16 @@ static inline ohci_ed_t* gtd_get_ed(ohci_gtd_t const * const p_qtd)
|
||||
}
|
||||
}
|
||||
|
||||
static gtd_extra_data_t *gtd_get_extra_data(ohci_gtd_t const * const gtd) {
|
||||
if ( gtd_is_control(gtd) )
|
||||
{
|
||||
return &ohci_data.control[((intptr_t)gtd - (intptr_t)&ohci_data.control->gtd) / sizeof(ohci_data.control[0])].gtd_data;
|
||||
}else
|
||||
{
|
||||
return &ohci_data.gtd_data[gtd - ohci_data.gtd_pool];
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t gtd_xfer_byte_left(uint32_t buffer_end, uint32_t current_buffer)
|
||||
{
|
||||
// 5.2.9 OHCI sample code
|
||||
@@ -641,8 +652,7 @@ static void done_queue_isr(uint8_t hostid)
|
||||
if ( (qtd->delay_interrupt == OHCI_INT_ON_COMPLETE_YES) || (event != XFER_RESULT_SUCCESS) )
|
||||
{
|
||||
ohci_ed_t * const ed = gtd_get_ed(qtd);
|
||||
|
||||
uint32_t const xferred_bytes = qtd->expected_bytes - gtd_xfer_byte_left((uint32_t) qtd->buffer_end, (uint32_t) qtd->current_buffer_pointer);
|
||||
uint32_t const xferred_bytes = gtd_get_extra_data(qtd)->expected_bytes - gtd_xfer_byte_left((uint32_t) qtd->buffer_end, (uint32_t) qtd->current_buffer_pointer);
|
||||
|
||||
// NOTE Assuming the current list is BULK and there is no other EDs in the list has queued TDs.
|
||||
// When there is a error resulting this ED is halted, and this EP still has other queued TD
|
||||
|
@@ -45,6 +45,9 @@ enum {
|
||||
#define ED_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX)
|
||||
#define GTD_MAX ED_MAX
|
||||
|
||||
// tinyUSB's OHCI implementation caps number of EDs to 8 bits
|
||||
TU_VERIFY_STATIC (ED_MAX <= 256, "Reduce CFG_TUH_DEVICE_MAX or CFG_TUH_ENDPOINT_MAX");
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// OHCI Data Structure
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -70,9 +73,8 @@ typedef struct TU_ATTR_ALIGNED(16)
|
||||
{
|
||||
// Word 0
|
||||
uint32_t used : 1;
|
||||
uint32_t index : 4; // endpoint index the td belongs to, or device address in case of control xfer
|
||||
uint32_t expected_bytes : 13; // TODO available for hcd
|
||||
|
||||
uint32_t index : 8; // endpoint index the gtd belongs to, or device address in case of control xfer
|
||||
uint32_t : 9; // can be used
|
||||
uint32_t buffer_rounding : 1;
|
||||
uint32_t pid : 2;
|
||||
uint32_t delay_interrupt : 3;
|
||||
@@ -152,6 +154,12 @@ typedef struct TU_ATTR_ALIGNED(32)
|
||||
|
||||
TU_VERIFY_STATIC( sizeof(ochi_itd_t) == 32, "size is not correct" );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t expected_bytes : 13; // can be up to 8192 bytes long so use 13 bits
|
||||
uint16_t : 3; // can be used
|
||||
} gtd_extra_data_t;
|
||||
|
||||
// structure with member alignment required from large to small
|
||||
typedef struct TU_ATTR_ALIGNED(256)
|
||||
{
|
||||
@@ -164,11 +172,13 @@ typedef struct TU_ATTR_ALIGNED(256)
|
||||
struct {
|
||||
ohci_ed_t ed;
|
||||
ohci_gtd_t gtd;
|
||||
gtd_extra_data_t gtd_data;
|
||||
}control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1];
|
||||
|
||||
// ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32
|
||||
ohci_ed_t ed_pool[ED_MAX];
|
||||
ohci_gtd_t gtd_pool[GTD_MAX];
|
||||
gtd_extra_data_t gtd_data[GTD_MAX]; // extra data needed by TDs that can't fit in the TD struct
|
||||
|
||||
volatile uint16_t frame_number_hi;
|
||||
|
||||
|
Reference in New Issue
Block a user