Skip to content

Commit f674561

Browse files
authored
Merge pull request #3246 from HiFiPhile/nxp_host
ehci: fix device removal and endpoint open on next plug
2 parents c484aae + 99bee6a commit f674561

File tree

7 files changed

+476
-418
lines changed

7 files changed

+476
-418
lines changed

hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h

Lines changed: 389 additions & 0 deletions
Large diffs are not rendered by default.

hw/bsp/imxrt/family.c

Lines changed: 5 additions & 387 deletions
Large diffs are not rendered by default.

hw/bsp/imxrt/family.cmake

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ function(add_board_target BOARD_TARGET)
6868

6969
if (NOT M4 STREQUAL "1")
7070
target_compile_definitions(${BOARD_TARGET} PUBLIC
71-
__ARMVFP__=0
72-
__ARMFPV5__=0
7371
XIP_EXTERNAL_FLASH=1
7472
XIP_BOOT_HEADER_ENABLE=1
7573
)

hw/bsp/imxrt/family.mk

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ CFLAGS += \
1414

1515
ifneq ($(M4), 1)
1616
CFLAGS += \
17-
-D__ARMVFP__=0 \
18-
-D__ARMFPV5__=0 \
1917
-DXIP_EXTERNAL_FLASH=1 \
2018
-DXIP_BOOT_HEADER_ENABLE=1
2119
endif

src/class/hid/hid_host.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,8 @@ bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_
519519

520520
// Assume bNumDescriptors = 1
521521
p_hid->report_desc_type = desc_hid->bReportType;
522-
p_hid->report_desc_len = tu_unaligned_read16(&desc_hid->wReportLength);
522+
// Use offsetof to avoid pointer to the odd/misaligned address
523+
p_hid->report_desc_len = tu_unaligned_read16((uint8_t const*)desc_hid + offsetof(tusb_hid_descriptor_hid_t, wReportLength));
523524

524525
// Per HID Specs: default is Report protocol, though we will force Boot protocol when set_config
525526
p_hid->protocol_mode = _hidh_default_protocol;

src/host/usbh.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ bool tuh_descriptor_get_device_local(uint8_t daddr, tusb_desc_device_t* desc_dev
400400
tusb_speed_t tuh_speed_get(uint8_t daddr) {
401401
tuh_bus_info_t bus_info;
402402
tuh_bus_info_get(daddr, &bus_info);
403-
return bus_info.speed;
403+
return (tusb_speed_t)bus_info.speed;
404404
}
405405

406406
bool tuh_rhport_is_active(uint8_t rhport) {
@@ -651,7 +651,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
651651
tuh_xfer_t xfer = {
652652
.daddr = event.dev_addr,
653653
.ep_addr = ep_addr,
654-
.result = event.xfer_complete.result,
654+
.result = (xfer_result_t)event.xfer_complete.result,
655655
.actual_len = event.xfer_complete.len,
656656
.buflen = 0, // not available
657657
.buffer = NULL, // not available
@@ -832,18 +832,19 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t
832832
}
833833
TU_ATTR_FALLTHROUGH;
834834

835-
case CONTROL_STAGE_DATA:
836-
if (request->wLength) {
837-
TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, daddr);
838-
TU_LOG_MEM_USBH(ctrl_info->buffer, xferred_bytes, 2);
839-
}
840-
ctrl_info->actual_len = (uint16_t) xferred_bytes;
835+
case CONTROL_STAGE_DATA: {
836+
if (request->wLength) {
837+
TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, daddr);
838+
TU_LOG_MEM_USBH(ctrl_info->buffer, xferred_bytes, 2);
839+
}
840+
ctrl_info->actual_len = (uint16_t) xferred_bytes;
841841

842-
// ACK stage: toggle is always 1
843-
_control_set_xfer_stage(CONTROL_STAGE_ACK);
844-
const uint8_t ep_status = tu_edpt_addr(0, 1 - request->bmRequestType_bit.direction);
845-
TU_ASSERT(hcd_edpt_xfer(rhport, daddr, ep_status, NULL, 0));
846-
break;
842+
// ACK stage: toggle is always 1
843+
_control_set_xfer_stage(CONTROL_STAGE_ACK);
844+
const uint8_t ep_status = tu_edpt_addr(0, 1 - request->bmRequestType_bit.direction);
845+
TU_ASSERT(hcd_edpt_xfer(rhport, daddr, ep_status, NULL, 0));
846+
break;
847+
}
847848

848849
case CONTROL_STAGE_ACK: {
849850
// Abort all pending transfers if SET_CONFIGURATION request

src/portable/ehci/ehci.c

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,15 @@
3535

3636
#include "host/hcd.h"
3737
#include "host/usbh.h"
38+
#include "host/usbh_pvt.h"
3839
#include "ehci_api.h"
3940
#include "ehci.h"
4041

42+
// NXP specific fixes
43+
#if TU_CHECK_MCU(OPT_MCU_MIMXRT1XXX, OPT_MCU_LPC55, OPT_MCU_MCXN9)
44+
#include "fsl_device_registers.h"
45+
#endif
46+
4147
//--------------------------------------------------------------------+
4248
// MACRO CONSTANT TYPEDEF
4349
//--------------------------------------------------------------------+
@@ -179,12 +185,43 @@ static void ehci_enable_schedule(ehci_registers_t* regs, bool is_period) {
179185
}
180186
}
181187

188+
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
189+
static void nxp_usbphy_disconn_detector_set(uint8_t port, bool enable) {
190+
// unify naming convention
191+
#if !defined(USBPHY1) && defined(USBPHY)
192+
#define USBPHY1 USBPHY
193+
#endif
194+
195+
if (port == 0) {
196+
if (enable) {
197+
USBPHY1->CTRL_SET = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
198+
} else {
199+
USBPHY1->CTRL_CLR = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
200+
}
201+
}
202+
#if FSL_FEATURE_SOC_USBPHY_COUNT > 1U
203+
else if (port == 1) {
204+
if (enable) {
205+
USBPHY2->CTRL_SET = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
206+
} else {
207+
USBPHY2->CTRL_CLR = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
208+
}
209+
}
210+
#endif
211+
212+
#if !defined(USBPHY1) && defined(USBPHY)
213+
#undef USBPHY1
214+
#endif
215+
}
216+
#endif
217+
182218
//--------------------------------------------------------------------+
183219
// HCD API
184220
//--------------------------------------------------------------------+
185221
uint32_t hcd_frame_number(uint8_t rhport) {
186222
(void) rhport;
187-
return (ehci_data.uframe_number + ehci_data.regs->frame_index) >> 3;
223+
uint32_t uframe = ehci_data.regs->frame_index;
224+
return (ehci_data.uframe_number + uframe) >> 3;
188225
}
189226

190227
void hcd_port_reset(uint8_t rhport) {
@@ -212,16 +249,21 @@ void hcd_port_reset_end(uint8_t rhport) {
212249
(void) rhport;
213250
ehci_registers_t* regs = ehci_data.regs;
214251

215-
// skip if reset is already complete
216-
if (!regs->portsc_bm.port_reset) {
217-
return;
218-
}
252+
// stop reset only if is not complete yet
253+
if (regs->portsc_bm.port_reset) {
254+
// mask out all change bits since they are Write 1 to clear
255+
uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_W1C;
256+
portsc &= ~EHCI_PORTSC_MASK_PORT_RESET;
219257

220-
// mask out all change bits since they are Write 1 to clear
221-
uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_W1C;
222-
portsc &= ~EHCI_PORTSC_MASK_PORT_RESET;
258+
regs->portsc = portsc;
259+
}
223260

224-
regs->portsc = portsc;
261+
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
262+
// Enable disconnect detector for highspeed device only
263+
if (hcd_port_speed_get(rhport) == TUSB_SPEED_HIGH) {
264+
nxp_usbphy_disconn_detector_set(rhport, true);
265+
}
266+
#endif
225267
}
226268

227269
bool hcd_port_connect_status(uint8_t rhport) {
@@ -578,6 +620,10 @@ void port_connect_status_change_isr(uint8_t rhport) {
578620
hcd_event_device_attach(rhport, true);
579621
} else // device unplugged
580622
{
623+
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
624+
// Disable disconnect detector
625+
nxp_usbphy_disconn_detector_set(rhport, false);
626+
#endif
581627
hcd_event_device_remove(rhport, true);
582628
}
583629
}
@@ -821,14 +867,21 @@ static ehci_qhd_t *qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr) {
821867
}
822868

823869
ehci_qhd_t *qhd_pool = ehci_data.qhd_pool;
870+
871+
// protect qhd_pool since 'used' and 'removing' can be changed in isr
872+
ehci_qhd_t *result = NULL;
873+
usbh_spin_lock(false);
824874
for (uint32_t i = 0; i < QHD_MAX; i++) {
825875
if ((qhd_pool[i].dev_addr == dev_addr) &&
826-
ep_addr == qhd_ep_addr(&qhd_pool[i])) {
827-
return &qhd_pool[i];
876+
ep_addr == qhd_ep_addr(&qhd_pool[i]) &&
877+
qhd_pool[i].used && !qhd_pool[i].removing) {
878+
result = &qhd_pool[i];
879+
break;
828880
}
829881
}
882+
usbh_spin_unlock(false);
830883

831-
return NULL;
884+
return result;
832885
}
833886

834887
// Init queue head with endpoint descriptor
@@ -896,7 +949,7 @@ static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t c
896949
p_qhd->used = 1;
897950
p_qhd->removing = 0;
898951
p_qhd->attached_qtd = NULL;
899-
p_qhd->pid = tu_edpt_dir(ep_desc->bEndpointAddress) ? EHCI_PID_IN : EHCI_PID_OUT; // PID for TD under this endpoint
952+
p_qhd->pid = tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ? EHCI_PID_IN : EHCI_PID_OUT; // PID for TD under this endpoint
900953

901954
//------------- active, but no TD list -------------//
902955
p_qhd->qtd_overlay.halted = 0;

0 commit comments

Comments
 (0)