summaryrefslogtreecommitdiff
path: root/src/portable
diff options
context:
space:
mode:
authorhathach <[email protected]>2023-08-07 18:22:28 +0700
committerhathach <[email protected]>2023-08-07 20:48:07 +0700
commit1f95a417f271e627ec981be3d211eed8c37cb052 (patch)
treeadb765472225597271293028d4676867d0afe3f4 /src/portable
parent1b92108bc33bb87a2d7ca11dde739837c9571d4e (diff)
Add tuh_rhport_is_active() and tuh_rhport_reset_bus()
- also improve ehci bus reset - seperate bus reset delay and contact debouncing delay in enumeration
Diffstat (limited to 'src/portable')
-rw-r--r--src/portable/chipidea/ci_hs/hcd_ci_hs.c43
-rw-r--r--src/portable/ehci/ehci.c24
2 files changed, 40 insertions, 27 deletions
diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c
index 6ee91e18e..462cbd301 100644
--- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c
+++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c
@@ -39,24 +39,27 @@
#include "ci_hs_type.h"
#if CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX
- #include "ci_hs_imxrt.h"
- bool hcd_dcache_clean(void const* addr, uint32_t data_size) {
- return imxrt_dcache_clean(addr, data_size);
- }
+#include "ci_hs_imxrt.h"
- bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) {
- return imxrt_dcache_invalidate(addr, data_size);
- }
+bool hcd_dcache_clean(void const* addr, uint32_t data_size) {
+ return imxrt_dcache_clean(addr, data_size);
+}
+
+bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) {
+ return imxrt_dcache_invalidate(addr, data_size);
+}
- bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
- return imxrt_dcache_clean_invalidate(addr, data_size);
- }
+bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
+ return imxrt_dcache_clean_invalidate(addr, data_size);
+}
#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX)
- #include "ci_hs_lpc18_43.h"
+
+#include "ci_hs_lpc18_43.h"
+
#else
- #error "Unsupported MCUs"
+#error "Unsupported MCUs"
#endif
//--------------------------------------------------------------------+
@@ -67,25 +70,25 @@
// Controller API
//--------------------------------------------------------------------+
-bool hcd_init(uint8_t rhport)
-{
- ci_hs_regs_t* hcd_reg = CI_HS_REG(rhport);
+bool hcd_init(uint8_t rhport) {
+ ci_hs_regs_t *hcd_reg = CI_HS_REG(rhport);
// Reset controller
hcd_reg->USBCMD |= USBCMD_RESET;
- while( hcd_reg->USBCMD & USBCMD_RESET ) {}
+ while ( hcd_reg->USBCMD & USBCMD_RESET ) {}
// Set mode to device, must be set immediately after reset
#if CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX
// LPC18XX/43XX need to set VBUS Power Select to HIGH
// RHPORT1 is fullspeed only (need external PHY for Highspeed)
hcd_reg->USBMODE = USBMODE_CM_HOST | USBMODE_VBUS_POWER_SELECT;
- if (rhport == 1) hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED;
+ if ( rhport == 1 ) hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED;
#else
hcd_reg->USBMODE = USBMODE_CM_HOST;
#endif
// FIXME force full speed, still have issue with Highspeed enumeration
+ // probably due to physical connection bouncing when plug/unplug
// 1. Have issue when plug/unplug devices, maybe the port is not reset properly
// 2. Also does not seems to detect disconnection
hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED;
@@ -93,13 +96,11 @@ bool hcd_init(uint8_t rhport)
return ehci_init(rhport, (uint32_t) &hcd_reg->CAPLENGTH, (uint32_t) &hcd_reg->USBCMD);
}
-void hcd_int_enable(uint8_t rhport)
-{
+void hcd_int_enable(uint8_t rhport) {
CI_HCD_INT_ENABLE(rhport);
}
-void hcd_int_disable(uint8_t rhport)
-{
+void hcd_int_disable(uint8_t rhport) {
CI_HCD_INT_DISABLE(rhport);
}
diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c
index 9be24c888..79811985c 100644
--- a/src/portable/ehci/ehci.c
+++ b/src/portable/ehci/ehci.c
@@ -188,6 +188,11 @@ void hcd_port_reset(uint8_t rhport)
ehci_registers_t* regs = ehci_data.regs;
+ // skip if already in reset
+ if (regs->portsc_bm.port_reset) {
+ return;
+ }
+
// mask out Write-1-to-Clear bits
uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_W1C;
@@ -202,16 +207,18 @@ void hcd_port_reset(uint8_t rhport)
void hcd_port_reset_end(uint8_t rhport)
{
(void) rhport;
-
-#if 0 // TODO check if this is necessary
ehci_registers_t* regs = ehci_data.regs;
+ // skip if reset is already complete
+ if (!regs->portsc_bm.port_reset) {
+ return;
+ }
+
// mask out all change bits since they are Write 1 to clear
- uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_CHANGE_ALL;
- portsc &= ~(EHCI_PORTSC_MASK_PORT_RESET);
+ uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_W1C;
+ portsc &= ~EHCI_PORTSC_MASK_PORT_RESET;
regs->portsc = portsc;
-#endif
}
bool hcd_port_connect_status(uint8_t rhport)
@@ -426,6 +433,11 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
hcd_dcache_clean(setup_packet, 8);
+ // Control endpoint never be stalled. Skip reset Data Toggle since it is fixed per stage
+ if (qhd->qtd_overlay.halted) {
+ qhd->qtd_overlay.halted = false;
+ }
+
// attach TD to QHD -> start transferring
qhd_attach_qtd(qhd, td);
@@ -662,7 +674,7 @@ void hcd_int_handler(uint8_t rhport)
if (int_status & EHCI_INT_MASK_PORT_CHANGE) {
// Including: Force port resume, over-current change, enable/disable change and connect status change.
uint32_t const port_status = regs->portsc & EHCI_PORTSC_MASK_W1C;
- print_portsc(regs);
+ // print_portsc(regs);
if (regs->portsc_bm.connect_status_change) {
port_connect_status_change_isr(rhport);