From 600fac1845abec7630adda4dc7487f7711a58300 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 11 Dec 2018 16:18:56 +0700 Subject: [PATCH] fix build error with ohci --- src/class/cdc/cdc_host.c | 1 + src/common/tusb_types.h | 4 +- src/host/ohci/ohci.c | 249 ++++++++++++++------------------------- src/host/ohci/ohci.h | 28 ++--- src/host/usbh.c | 2 +- 5 files changed, 103 insertions(+), 181 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index df07e0683..53f62d684 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -226,6 +226,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it void cdch_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) { + (void) ep_addr; tuh_cdc_xfer_isr( dev_addr, event, 0, xferred_bytes ); } diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 6ba713084..8be1e87f6 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -392,9 +392,9 @@ static inline uint8_t edpt_number(uint8_t addr) return addr & (~TUSB_DIR_IN_MASK); } -static inline uint8_t edpt_addr(uint8_t num, tusb_dir_t dir) +static inline uint8_t edpt_addr(uint8_t num, uint8_t dir) { - return num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0); + return num | (dir ? TUSB_DIR_IN_MASK : 0); } //--------------------------------------------------------------------+ diff --git a/src/host/ohci/ohci.c b/src/host/ohci/ohci.c index 4c54c5eaa..5593cd55d 100644 --- a/src/host/ohci/ohci.c +++ b/src/host/ohci/ohci.c @@ -136,7 +136,7 @@ enum { //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -CFG_TUSB_MEM_SECTION ATTR_ALIGNED(256) STATIC_VAR ohci_data_t ohci_data; +CFG_TUSB_MEM_SECTION ATTR_ALIGNED(256) static ohci_data_t ohci_data; static ohci_ed_t * const p_ed_head[] = { @@ -216,11 +216,11 @@ tusb_speed_t hcd_port_speed_get(uint8_t hostid) return OHCI_REG->rhport_status_bit[0].low_speed_device_attached ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; } -// TODO refractor abtract later -void hcd_port_unplug(uint8_t hostid) +void hcd_device_remove(uint8_t rhport, uint8_t dev_addr) { // TODO OHCI - (void) hostid; + (void) rhport; + (void) dev_addr; } //--------------------------------------------------------------------+ @@ -273,67 +273,6 @@ static void gtd_init(ohci_gtd_t* p_td, void* data_ptr, uint16_t total_bytes) p_td->buffer_end = total_bytes ? (((uint8_t*) data_ptr) + total_bytes-1) : NULL; } - -bool hcd_pipe_control_open(uint8_t dev_addr, uint8_t max_packet_size) -{ - ohci_ed_t* p_ed = &ohci_data.control[dev_addr].ed; - - ed_init(p_ed, dev_addr, max_packet_size, 0, TUSB_XFER_CONTROL, 0); // TODO binterval of control is ignored - - if ( dev_addr != 0 ) - { // insert to control head - ed_list_insert( p_ed_head[TUSB_XFER_CONTROL], p_ed); - }else - { - p_ed->skip = 0; // addr0 is used as static control head --> only need to clear skip bit - } - - return true; -} - -//bool hcd_pipe_control_xfer(uint8_t dev_addr, tusb_control_request_t const * p_request, uint8_t data[]) -//{ -// ohci_ed_t* const p_ed = &ohci_data.control[dev_addr].ed; -// -// ohci_gtd_t *p_setup = &ohci_data.control[dev_addr].gtd[0]; -// ohci_gtd_t *p_data = p_setup + 1; -// ohci_gtd_t *p_status = p_setup + 2; -// -// //------------- SETUP Phase -------------// -// gtd_init(p_setup, (void*) p_request, 8); -// p_setup->index = dev_addr; -// p_setup->pid = OHCI_PID_SETUP; -// p_setup->data_toggle = BIN8(10); // DATA0 -// p_setup->next_td = (uint32_t) p_data; -// -// //------------- DATA Phase -------------// -// if (p_request->wLength > 0) -// { -// gtd_init(p_data, data, p_request->wLength); -// p_data->index = dev_addr; -// p_data->pid = p_request->bmRequestType_bit.direction ? OHCI_PID_IN : OHCI_PID_OUT; -// p_data->data_toggle = BIN8(11); // DATA1 -// }else -// { -// p_data = p_setup; -// } -// p_data->next_td = (uint32_t) p_status; -// -// //------------- STATUS Phase -------------// -// gtd_init(p_status, NULL, 0); // zero-length data -// p_status->index = dev_addr; -// p_status->pid = p_request->bmRequestType_bit.direction ? OHCI_PID_OUT : OHCI_PID_IN; // reverse direction of data phase -// p_status->data_toggle = BIN8(11); // DATA1 -// p_status->delay_interrupt = OHCI_INT_ON_COMPLETE_YES; -// -// //------------- Attach TDs list to Control Endpoint -------------// -// p_ed->td_head.address = (uint32_t) p_setup; -// -// OHCI_REG->command_status_bit.control_list_filled = 1; -// -// return true; -//} - bool hcd_pipe_control_close(uint8_t dev_addr) { ohci_ed_t* const p_ed = &ohci_data.control[dev_addr].ed; @@ -352,13 +291,6 @@ bool hcd_pipe_control_close(uint8_t dev_addr) return true; } -bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const* ep_desc) -{ - // FIXME control only for now - (void) rhport; - return hcd_pipe_control_open(dev_addr, ep_desc->wMaxPacketSize.size); -} - bool hcd_edpt_close(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { // FIXME control only for now @@ -373,7 +305,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet (void) rhport; ohci_ed_t* p_ed = &ohci_data.control[dev_addr].ed; - ohci_gtd_t *p_setup = &ohci_data.control[dev_addr].gtd[0]; + ohci_gtd_t *p_setup = &ohci_data.control[dev_addr].gtd; gtd_init(p_setup, (void*) setup_packet, 8); p_setup->index = dev_addr; @@ -400,7 +332,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * if ( epnum == 0 ) { ohci_ed_t* const p_ed = &ohci_data.control[dev_addr].ed; - ohci_gtd_t *p_data = &ohci_data.control[dev_addr].gtd[0]; + ohci_gtd_t *p_data = &ohci_data.control[dev_addr].gtd; gtd_init(p_data, buffer, buflen); @@ -420,27 +352,31 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * //--------------------------------------------------------------------+ // BULK/INT/ISO PIPE API //--------------------------------------------------------------------+ -static inline uint8_t ed_get_index(ohci_ed_t const * const p_ed) ATTR_PURE ATTR_ALWAYS_INLINE; -static inline uint8_t ed_get_index(ohci_ed_t const * const p_ed) +static inline ohci_ed_t * ed_from_addr(uint8_t dev_addr, uint8_t ep_addr) { - return p_ed - ohci_data.device[p_ed->device_address-1].ed; + if ( edpt_number(ep_addr) == 0 ) return &ohci_data.control[dev_addr].ed; + + ohci_ed_t* ed_pool = ohci_data.ed_pool; + + for(uint32_t i=0; iused = 0; // free ED } -pipe_handle_t hcd_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * p_endpoint_desc, uint8_t class_code) +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) { - pipe_handle_t const null_handle = { .dev_addr = 0, .xfer_type = 0, .index = 0 }; + (void) rhport; // TODO iso support - TU_ASSERT(p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS, null_handle ); + TU_ASSERT(ep_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); //------------- Prepare Queue Head -------------// - ohci_ed_t * const p_ed = ed_find_free(dev_addr); - TU_ASSERT(p_ed, null_handle); + ohci_ed_t * p_ed; - ed_init( p_ed, dev_addr, p_endpoint_desc->wMaxPacketSize.size, p_endpoint_desc->bEndpointAddress, - p_endpoint_desc->bmAttributes.xfer, p_endpoint_desc->bInterval ); - p_ed->td_tail.class_code = class_code; - - ed_list_insert( p_ed_head[p_endpoint_desc->bmAttributes.xfer], p_ed ); - - return (pipe_handle_t) + if ( ep_desc->bEndpointAddress == 0 ) { - .dev_addr = dev_addr, - .xfer_type = p_endpoint_desc->bmAttributes.xfer, - .index = ed_get_index(p_ed) - }; + p_ed = &ohci_data.control[dev_addr].ed; + }else + { + p_ed = ed_find_free(); + } + TU_ASSERT(p_ed); + + ed_init( p_ed, dev_addr, ep_desc->wMaxPacketSize.size, ep_desc->bEndpointAddress, + ep_desc->bmAttributes.xfer, ep_desc->bInterval ); + + // control of dev0 is used as static async head + if ( dev_addr == 0 ) + { + p_ed->skip = 0; // only need to clear skip bit + return true; + } + + ed_list_insert( p_ed_head[ep_desc->bmAttributes.xfer], p_ed ); + + return true; } -static ohci_gtd_t * gtd_find_free(uint8_t dev_addr) +static ohci_gtd_t * gtd_find_free(void) { for(uint8_t i=0; i < HCD_MAX_XFER; i++) { - if (!ohci_data.device[dev_addr-1].gtd[i].used) - { - return &ohci_data.device[dev_addr-1].gtd[i]; - } + if ( !ohci_data.gtd_pool[i].used ) return &ohci_data.gtd_pool[i]; } return NULL; @@ -532,72 +474,71 @@ static void td_insert_to_ed(ohci_ed_t* p_ed, ohci_gtd_t * p_gtd) } } -static tusb_error_t pipe_queue_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[], uint16_t total_bytes, bool int_on_complete) +static bool pipe_queue_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t buffer[], uint16_t total_bytes, bool int_on_complete) { - ohci_ed_t* const p_ed = ed_from_pipe_handle(pipe_hdl); + ohci_ed_t* const p_ed = ed_from_addr(dev_addr, ep_addr); - if ( !p_ed->is_iso ) - { - ohci_gtd_t * const p_gtd = gtd_find_free(pipe_hdl.dev_addr); - TU_ASSERT(p_gtd, TUSB_ERROR_EHCI_NOT_ENOUGH_QTD); // TODO refractor error code + // not support ISO yet + TU_VERIFY ( !p_ed->is_iso ); - gtd_init(p_gtd, buffer, total_bytes); - p_gtd->index = pipe_hdl.index; - if ( int_on_complete ) p_gtd->delay_interrupt = OHCI_INT_ON_COMPLETE_YES; + ohci_gtd_t * const p_gtd = gtd_find_free(); + TU_ASSERT(p_gtd); // not enough gtd - td_insert_to_ed(p_ed, p_gtd); - }else - { - TU_ASSERT_ERR(TUSB_ERROR_NOT_SUPPORTED_YET); - } + gtd_init(p_gtd, buffer, total_bytes); + p_gtd->index = p_ed-ohci_data.ed_pool; - return TUSB_ERROR_NONE; + if ( int_on_complete ) p_gtd->delay_interrupt = OHCI_INT_ON_COMPLETE_YES; + + td_insert_to_ed(p_ed, p_gtd); + + return true; } -tusb_error_t hcd_pipe_queue_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[], uint16_t total_bytes) +bool hcd_pipe_queue_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t buffer[], uint16_t total_bytes) { - return pipe_queue_xfer(pipe_hdl, buffer, total_bytes, false); + return pipe_queue_xfer(dev_addr, ep_addr, buffer, total_bytes, false); } -tusb_error_t hcd_pipe_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[], uint16_t total_bytes, bool int_on_complete) +bool hcd_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t buffer[], uint16_t total_bytes, bool int_on_complete) { (void) int_on_complete; - TU_ASSERT_ERR( pipe_queue_xfer(pipe_hdl, buffer, total_bytes, true) ); + TU_ASSERT( pipe_queue_xfer(dev_addr, ep_addr, buffer, total_bytes, true) ); - tusb_xfer_type_t xfer_type = ed_get_xfer_type( ed_from_pipe_handle(pipe_hdl) ); + tusb_xfer_type_t xfer_type = ed_get_xfer_type( ed_from_addr(dev_addr, ep_addr) ); if (TUSB_XFER_BULK == xfer_type) OHCI_REG->command_status_bit.bulk_list_filled = 1; - return TUSB_ERROR_NONE; + return true; } /// pipe_close should only be called as a part of unmount/safe-remove process // endpoints are tied to an address, which only reclaim after a long delay when enumerating // thus there is no need to make sure ED is not in HC's cahed as it will not for sure -tusb_error_t hcd_pipe_close(pipe_handle_t pipe_hdl) +bool hcd_pipe_close(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { - ohci_ed_t * const p_ed = ed_from_pipe_handle(pipe_hdl); + (void) rhport; + ohci_ed_t * const p_ed = ed_from_addr(dev_addr, ep_addr); ed_list_remove( p_ed_head[ ed_get_xfer_type(p_ed)], p_ed ); - return TUSB_ERROR_FAILED; + return true; } -bool hcd_edpt_busy(pipe_handle_t pipe_hdl) +bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) { - ohci_ed_t const * const p_ed = ed_from_pipe_handle(pipe_hdl); + ohci_ed_t const * const p_ed = ed_from_addr(dev_addr, ep_addr); return tu_align16(p_ed->td_head.address) != tu_align16(p_ed->td_tail.address); } -bool hcd_edpt_stalled(pipe_handle_t pipe_hdl) +bool hcd_edpt_stalled(uint8_t dev_addr, uint8_t ep_addr) { - ohci_ed_t const * const p_ed = ed_from_pipe_handle(pipe_hdl); + ohci_ed_t const * const p_ed = ed_from_addr(dev_addr, ep_addr); return p_ed->td_head.halted && p_ed->is_stalled; } -tusb_error_t hcd_edpt_clear_stall(pipe_handle_t pipe_hdl) +bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) { - ohci_ed_t * const p_ed = ed_from_pipe_handle(pipe_hdl); + ohci_ed_t * const p_ed = ed_from_addr(dev_addr, ep_addr); p_ed->is_stalled = 0; p_ed->td_tail.address &= 0x0Ful; // set tail pointer back to NULL @@ -607,7 +548,7 @@ tusb_error_t hcd_edpt_clear_stall(pipe_handle_t pipe_hdl) if ( TUSB_XFER_BULK == ed_get_xfer_type(p_ed) ) OHCI_REG->command_status_bit.bulk_list_filled = 1; - return TUSB_ERROR_NONE; + return true; } @@ -632,13 +573,11 @@ static ohci_td_item_t* list_reverse(ohci_td_item_t* td_head) return td_reverse_head; } -static inline bool gtd_is_control(ohci_gtd_t const * const p_qtd) ATTR_CONST ATTR_ALWAYS_INLINE; static inline bool gtd_is_control(ohci_gtd_t const * const p_qtd) { - return ((uint32_t) p_qtd) < ((uint32_t) ohci_data.device); // check ohci_data_t for memory layout + return ((uint32_t) p_qtd) < ((uint32_t) ohci_data.gtd_pool); // check ohci_data_t for memory layout } -static inline ohci_ed_t* gtd_get_ed(ohci_gtd_t const * const p_qtd) ATTR_PURE ATTR_ALWAYS_INLINE; static inline ohci_ed_t* gtd_get_ed(ohci_gtd_t const * const p_qtd) { if ( gtd_is_control(p_qtd) ) @@ -646,13 +585,10 @@ static inline ohci_ed_t* gtd_get_ed(ohci_gtd_t const * const p_qtd) return &ohci_data.control[p_qtd->index].ed; }else { - uint8_t dev_addr_idx = (((uint32_t)p_qtd) - ((uint32_t)ohci_data.device)) / sizeof(ohci_data.device[0]); - - return &ohci_data.device[dev_addr_idx].ed[p_qtd->index]; + return &ohci_data.ed_pool[p_qtd->index]; } } -static inline uint32_t gtd_xfer_byte_left(uint32_t buffer_end, uint32_t current_buffer) ATTR_CONST ATTR_ALWAYS_INLINE; static inline uint32_t gtd_xfer_byte_left(uint32_t buffer_end, uint32_t current_buffer) { // 5.2.9 OHCI sample code return (tu_align4k(buffer_end ^ current_buffer) ? 0x1000 : 0) + @@ -663,18 +599,16 @@ static void done_queue_isr(uint8_t hostid) { (void) hostid; - uint8_t max_loop = (CFG_TUSB_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*) tu_align16(ohci_data.hcca.done_head) ); - while( td_head != NULL && max_loop > 0) + while( td_head != NULL ) { // TODO check if td_head is iso td //------------- Non ISO transfer -------------// ohci_gtd_t * const p_qtd = (ohci_gtd_t *) td_head; xfer_result_t const event = (p_qtd->condition_code == OHCI_CCODE_NO_ERROR) ? XFER_RESULT_SUCCESS : - (p_qtd->condition_code == OHCI_CCODE_STALL) ? XFER_RESULT_STALLED : XFER_RESULT_FAILED; + (p_qtd->condition_code == OHCI_CCODE_STALL) ? XFER_RESULT_STALLED : XFER_RESULT_FAILED; p_qtd->used = 0; // free TD if ( (p_qtd->delay_interrupt == OHCI_INT_ON_COMPLETE_YES) || (event != XFER_RESULT_SUCCESS) ) @@ -697,19 +631,12 @@ static void done_queue_isr(uint8_t hostid) if ( event == XFER_RESULT_STALLED ) p_ed->is_stalled = 1; } - pipe_handle_t pipe_hdl = - { - .dev_addr = p_ed->device_address, - .xfer_type = ed_get_xfer_type(p_ed), - }; - - if ( pipe_hdl.xfer_type != TUSB_XFER_CONTROL) pipe_hdl.index = ed_get_index(p_ed); - - hcd_event_xfer_complete(pipe_hdl, p_ed->td_tail.class_code, event, xferred_bytes); + hcd_event_xfer_complete(p_ed->device_address, + edpt_addr(p_ed->endpoint_number, p_ed->direction == OHCI_PID_IN), + event, xferred_bytes); } td_head = (ohci_td_item_t*) td_head->next_td; - max_loop--; } } diff --git a/src/host/ohci/ohci.h b/src/host/ohci/ohci.h index c407b8ac1..f68500703 100644 --- a/src/host/ohci/ohci.h +++ b/src/host/ohci/ohci.h @@ -88,8 +88,9 @@ typedef struct { }ohci_td_item_t; -typedef struct ATTR_ALIGNED(16) { - //------------- Word 0 -------------// +typedef struct 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 @@ -100,15 +101,14 @@ typedef struct ATTR_ALIGNED(16) { volatile uint32_t data_toggle : 2; volatile uint32_t error_count : 2; volatile uint32_t condition_code : 4; - /*---------- End Word 1 ----------*/ - //------------- Word 1 -------------// + // Word 1 volatile uint8_t* current_buffer_pointer; - //------------- Word 2 -------------// + // Word 2 volatile uint32_t next_td; - //------------- Word 3 -------------// + // Word 3 uint8_t* buffer_end; } ohci_gtd_t; @@ -132,11 +132,7 @@ typedef struct ATTR_ALIGNED(16) { //------------- Word 1 -------------// union { - uint32_t address; // 4 lsb bits are free to use - struct { - uint32_t class_code : 4; // FIXME refractor to use interface number instead - uint32_t : 28; - }; + uint32_t address; }td_tail; //------------- Word 2 -------------// @@ -190,14 +186,12 @@ typedef struct ATTR_ALIGNED(256) { // control endpoints has reserved resources struct { ohci_ed_t ed; - ohci_gtd_t gtd[3]; // setup, data, status + ohci_gtd_t gtd; }control[CFG_TUSB_HOST_DEVICE_MAX+1]; - struct { - // ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32 - ohci_ed_t ed[HCD_MAX_ENDPOINT]; - ohci_gtd_t gtd[HCD_MAX_XFER]; - }device[CFG_TUSB_HOST_DEVICE_MAX]; + // ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32 + ohci_ed_t ed_pool[HCD_MAX_ENDPOINT]; + ohci_gtd_t gtd_pool[HCD_MAX_XFER]; } ohci_data_t; diff --git a/src/host/usbh.c b/src/host/usbh.c index ff4343fd2..456eff531 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -515,7 +515,7 @@ bool enum_task(hcd_event_t* event) new_dev->speed = dev0->speed; new_dev->state = TUSB_DEVICE_STATE_ADDRESSED; - usbh_pipe_control_close(0); + usbh_pipe_control_close(0); // hcd_device_remove(rhport, 0); // close device 0 dev0->state = TUSB_DEVICE_STATE_UNPLUG; // open control pipe for new address