Skip to content

Commit 1c4f22a

Browse files
committed
EHCI: fix xfer failed with disconnected device as stalled
- change CFG_TUH_ENDPOINT_MAX to 16 (max endpoint pair per device) if not defined - change QHD_MAX for EHCI, should be user configurable and more optimized in the future
1 parent 206d63e commit 1c4f22a

File tree

5 files changed

+27
-34
lines changed

5 files changed

+27
-34
lines changed

examples/host/cdc_msc_hid/src/hid_app.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t c
263263

264264
if (!rpt_info)
265265
{
266-
printf("Couldn't find the report info for this report !\r\n");
266+
printf("Couldn't find report info !\r\n");
267267
return;
268268
}
269269

hw/bsp/imxrt/family.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,10 @@ void board_init(void)
131131
freq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
132132
}
133133

134-
LPUART_Init(UART_PORT, &uart_config, freq);
134+
if ( kStatus_Success != LPUART_Init(UART_PORT, &uart_config, freq) ) {
135+
// failed to init uart, probably baudrate is not supported
136+
// TU_BREAKPOINT();
137+
}
135138

136139
//------------- USB -------------//
137140
// Note: RT105x RT106x and later have dual USB controllers.

src/class/hid/hid_host.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ tu_static hidh_interface_t _hidh_itf[CFG_TUH_HID];
7272
TU_ATTR_ALWAYS_INLINE static inline
7373
hidh_interface_t* get_hid_itf(uint8_t daddr, uint8_t idx)
7474
{
75-
TU_ASSERT(daddr && idx < CFG_TUH_HID, NULL);
75+
TU_ASSERT(daddr > 0 && idx < CFG_TUH_HID, NULL);
7676
hidh_interface_t* p_hid = &_hidh_itf[idx];
7777
return (p_hid->daddr == daddr) ? p_hid : NULL;
7878
}

src/host/hcd.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@
3939
// Configuration
4040
//--------------------------------------------------------------------+
4141

42+
// Max number of endpoints per device
43+
// TODO optimize memory usage
4244
#ifndef CFG_TUH_ENDPOINT_MAX
43-
#define CFG_TUH_ENDPOINT_MAX (CFG_TUH_HUB + CFG_TUH_HID*2 + CFG_TUH_MSC*2 + CFG_TUH_CDC*3)
45+
#define CFG_TUH_ENDPOINT_MAX 16
4446
// #ifdef TUP_HCD_ENDPOINT_MAX
4547
// #define CFG_TUH_ENDPPOINT_MAX TUP_HCD_ENDPOINT_MAX
4648
// #else

src/portable/ehci/ehci.c

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@
5858

5959
#define FRAMELIST_SIZE (1024 >> FRAMELIST_SIZE_BIT_VALUE)
6060

61-
#define QHD_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX)
61+
// Total queue head pool. TODO should be user configurable and more optimize memory usage in the future
62+
#define QHD_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX + CFG_TUH_HUB)
6263
#define QTD_MAX QHD_MAX
6364

6465
typedef struct
@@ -138,17 +139,6 @@ static inline ehci_qtd_t* qtd_control(uint8_t dev_addr)
138139
static inline ehci_qhd_t* qhd_next (ehci_qhd_t const * p_qhd);
139140
static inline ehci_qhd_t* qhd_find_free (void);
140141
static inline ehci_qhd_t* qhd_get_from_addr (uint8_t dev_addr, uint8_t ep_addr);
141-
142-
// determine if a queue head has bus-related error
143-
static inline bool qhd_has_xact_error (ehci_qhd_t * p_qhd)
144-
{
145-
volatile ehci_qtd_t *qtd_overlay = &p_qhd->qtd_overlay;
146-
147-
// Error count = 0 often occurs when device disconnected
148-
return (qtd_overlay->err_count == 0 || qtd_overlay->buffer_err || qtd_overlay->babble_err || qtd_overlay->xact_err);
149-
//qtd_overlay->non_hs_period_missed_uframe || qtd_overlay->pingstate_err TODO split transaction error
150-
}
151-
152142
static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc);
153143

154144
static inline ehci_qtd_t* qtd_find_free (void);
@@ -392,15 +382,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
392382
TU_ASSERT (ep_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS);
393383

394384
//------------- Prepare Queue Head -------------//
395-
ehci_qhd_t * p_qhd;
396-
397-
if ( ep_desc->bEndpointAddress == 0 )
398-
{
399-
p_qhd = qhd_control(dev_addr);
400-
}else
401-
{
402-
p_qhd = qhd_find_free();
403-
}
385+
ehci_qhd_t *p_qhd = (ep_desc->bEndpointAddress == 0) ? qhd_control(dev_addr) : qhd_find_free();
404386
TU_ASSERT(p_qhd);
405387

406388
qhd_init(p_qhd, dev_addr, ep_desc);
@@ -622,18 +604,23 @@ static void period_list_xfer_complete_isr(uint8_t hostid, uint32_t interval_ms)
622604

623605
static void qhd_xfer_error_isr(ehci_qhd_t * p_qhd)
624606
{
625-
if ( (p_qhd->dev_addr != 0 && p_qhd->qtd_overlay.halted) || // addr0 cannot be protocol STALL
626-
qhd_has_xact_error(p_qhd) )
627-
{
628-
// current qhd has error in transaction
629-
xfer_result_t error_event;
607+
volatile ehci_qtd_t *qtd_overlay = &p_qhd->qtd_overlay;
608+
609+
// TD has error
610+
if (qtd_overlay->halted) {
611+
xfer_result_t xfer_result;
630612

631-
// no error bits are set, endpoint is halted due to STALL
632-
error_event = qhd_has_xact_error(p_qhd) ? XFER_RESULT_FAILED : XFER_RESULT_STALLED;
613+
if (qtd_overlay->err_count == 0 || qtd_overlay->buffer_err || qtd_overlay->babble_err || qtd_overlay->xact_err) {
614+
// Error count = 0 often occurs when device disconnected, or other bus-related error
615+
xfer_result = XFER_RESULT_FAILED;
616+
}else {
617+
// no error bits are set, endpoint is halted due to STALL
618+
xfer_result = XFER_RESULT_STALLED;
619+
}
633620

634621
p_qhd->total_xferred_bytes += p_qhd->p_qtd_list_head->expected_bytes - p_qhd->p_qtd_list_head->total_bytes;
635622

636-
// if ( XFER_RESULT_FAILED == error_event ) {
623+
// if (XFER_RESULT_FAILED == xfer_result ) {
637624
// TU_BREAKPOINT(); // TODO skip unplugged device
638625
// }
639626

@@ -655,7 +642,8 @@ static void qhd_xfer_error_isr(ehci_qhd_t * p_qhd)
655642
}
656643

657644
// call USBH callback
658-
hcd_event_xfer_complete(p_qhd->dev_addr, tu_edpt_addr(p_qhd->ep_number, p_qhd->pid == EHCI_PID_IN ? 1 : 0), p_qhd->total_xferred_bytes, error_event, true);
645+
uint8_t const ep_addr = tu_edpt_addr(p_qhd->ep_number, p_qhd->pid == EHCI_PID_IN ? 1 : 0);
646+
hcd_event_xfer_complete(p_qhd->dev_addr, ep_addr, p_qhd->total_xferred_bytes, xfer_result, true);
659647

660648
p_qhd->total_xferred_bytes = 0;
661649
}

0 commit comments

Comments
 (0)