diff --git a/src/host/usbh.c b/src/host/usbh.c index e99d9e977..a725b7c8b 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1405,12 +1405,13 @@ static void remove_device_tree(uint8_t rhport, uint8_t hub_addr, uint8_t hub_por // NOTE: due to the shared control buffer, we must complete enumerating // one device before enumerating another one. //--------------------------------------------------------------------+ -enum { // USB 2.0 specs 7.1.7 for timing - ENUM_DEBOUNCING_DELAY_MS = 150, // T(ATTDB) minimum 100 ms for stable connection - ENUM_RESET_ROOT_DELAY_MS = 50, // T(DRSTr) minimum 50 ms for reset from root port - ENUM_RESET_HUB_DELAY_MS = 20, // T(DRST) 10-20 ms for hub reset - ENUM_RESET_RECOVERY_DELAY_MS = 10, // T(RSTRCY) minimum 10 ms for reset recovery - ENUM_SET_ADDRESS_RECOVERY_DELAY_MS = 2, // USB 2.0 Spec 9.2.6.3 min is 2 ms +enum { // USB 2.0 specs 7.1.7 for timing + ENUM_DEBOUNCING_DELAY_MS = 150, // T(ATTDB) minimum 100 ms for stable connection + ENUM_RESET_ROOT_DELAY_MS = 50, // T(DRSTr) minimum 50 ms for reset from root port + ENUM_RESET_ROOT_POST_DELAY_MS = 2, // 2 ms delay after root port reset before getting speed/status + ENUM_RESET_HUB_DELAY_MS = 20, // T(DRST) 10-20 ms for hub reset + ENUM_RESET_RECOVERY_DELAY_MS = 10, // T(RSTRCY) minimum 10 ms for reset recovery + ENUM_SET_ADDRESS_RECOVERY_DELAY_MS = 2, // USB 2.0 Spec 9.2.6.3 min is 2 ms }; enum { @@ -1469,6 +1470,7 @@ static bool enum_new_device(hcd_event_t* event) { hcd_port_reset(dev0_bus->rhport); tusb_time_delay_ms_api(ENUM_RESET_ROOT_DELAY_MS); hcd_port_reset_end(dev0_bus->rhport); + tusb_time_delay_ms_api(ENUM_RESET_ROOT_POST_DELAY_MS); if (!hcd_port_connect_status(dev0_bus->rhport)) { // device unplugged while delaying diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c index 6f6d27d0e..d70599f5b 100644 --- a/src/portable/renesas/rusb2/hcd_rusb2.c +++ b/src/portable/renesas/rusb2/hcd_rusb2.c @@ -76,12 +76,10 @@ typedef struct TU_ATTR_PACKED { TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) TU_ATTR_BIT_FIELD_ORDER_END -typedef struct -{ - bool need_reset; /* The device has not been reset after connection. */ +typedef struct { pipe_state_t pipe[PIPE_COUNT]; - uint8_t ep[4][2][15]; /* a lookup table for a pipe index from an endpoint address */ - uint8_t ctl_mps[5]; /* EP0 max packet size for each device */ + uint8_t ep[4][2][15]; /* a lookup table for a pipe index from an endpoint address */ + uint8_t ctl_mps[5]; /* EP0 max packet size for each device */ } hcd_data_t; //--------------------------------------------------------------------+ @@ -535,13 +533,8 @@ void hcd_int_disable(uint8_t rhport) { rusb2_int_disable(rhport); } -uint32_t hcd_frame_number(uint8_t rhport) -{ - rusb2_reg_t* rusb = RUSB2_REG(rhport); - - /* The device must be reset at least once after connection - * in order to start the frame counter. */ - if (_hcd.need_reset) hcd_port_reset(rhport); +uint32_t hcd_frame_number(uint8_t rhport) { + rusb2_reg_t *rusb = RUSB2_REG(rhport); return rusb->FRMNUM_b.FRNM; } @@ -550,32 +543,18 @@ uint32_t hcd_frame_number(uint8_t rhport) *--------------------------------------------------------------------+*/ bool hcd_port_connect_status(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); - return rusb->INTSTS1_b.ATTCH ? true : false; + const uint16_t line_state = rusb->SYSSTS0 & RUSB2_SYSSTS0_LNST_Msk; + return line_state == RUSB2_SYSSTS0_LNST_FS_J || line_state == RUSB2_SYSSTS0_LNST_FS_K; } void hcd_port_reset(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); - rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; - while (rusb->DCPCTR_b.PBUSY) {} - - hcd_int_disable(rhport); - rusb->DVSTCTR0_b.UACT = 0; - if (rusb->DCPCTR_b.SUREQ) { - rusb->DCPCTR_b.SUREQCLR = 1; - } - hcd_int_enable(rhport); - - /* Reset should be asserted 10-20ms. */ rusb->DVSTCTR0_b.USBRST = 1; - for (volatile int i = 0; i < 2400000; ++i) {} - rusb->DVSTCTR0_b.USBRST = 0; - - rusb->DVSTCTR0_b.UACT = 1; - _hcd.need_reset = false; } void hcd_port_reset_end(uint8_t rhport) { - (void) rhport; + rusb2_reg_t *rusb = RUSB2_REG(rhport); + rusb->DVSTCTR0_b.USBRST = 0; } tusb_speed_t hcd_port_speed_get(uint8_t rhport) { @@ -584,7 +563,8 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport) { case RUSB2_DVSTCTR0_RHST_HS: return TUSB_SPEED_HIGH; case RUSB2_DVSTCTR0_RHST_FS: return TUSB_SPEED_FULL; case RUSB2_DVSTCTR0_RHST_LS: return TUSB_SPEED_LOW; - default: return TUSB_SPEED_INVALID; + default: + return TUSB_SPEED_INVALID; } } @@ -802,7 +782,6 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { if (is1 & RUSB2_INTSTS1_ATTCH_Msk) { rusb->DVSTCTR0_b.UACT = 1; - _hcd.need_reset = true; rusb->INTENB1 = (rusb->INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk; hcd_event_device_attach(rhport, true); } diff --git a/src/portable/renesas/rusb2/rusb2_type.h b/src/portable/renesas/rusb2/rusb2_type.h index 71837d03c..cf685ea3c 100644 --- a/src/portable/renesas/rusb2/rusb2_type.h +++ b/src/portable/renesas/rusb2/rusb2_type.h @@ -1669,15 +1669,20 @@ TU_ATTR_BIT_FIELD_ORDER_END /*--------------------------------------------------------------------*/ /* Register Bit Utils */ /*--------------------------------------------------------------------*/ -#define RUSB2_PIPE_CTR_PID_NAK (0U << RUSB2_PIPE_CTR_PID_Pos) /* NAK response */ -#define RUSB2_PIPE_CTR_PID_BUF (1U << RUSB2_PIPE_CTR_PID_Pos) /* BUF response (depends buffer state) */ -#define RUSB2_PIPE_CTR_PID_STALL (2U << RUSB2_PIPE_CTR_PID_Pos) /* STALL response */ -#define RUSB2_PIPE_CTR_PID_STALL2 (3U << RUSB2_PIPE_CTR_PID_Pos) /* Also STALL response */ +#define RUSB2_SYSSTS0_LNST_SE0 (0) +#define RUSB2_SYSSTS0_LNST_FS_J (1u << RUSB2_SYSSTS0_LNST_Pos) /* Full-speed J state */ +#define RUSB2_SYSSTS0_LNST_FS_K (2u << RUSB2_SYSSTS0_LNST_Pos) /* Full-speed K state */ +#define RUSB2_SYSSTS0_LNST_LS_SE1 (3u << RUSB2_SYSSTS0_LNST_Pos) /* Low-speed SE1 state */ #define RUSB2_DVSTCTR0_RHST_LS (1U << RUSB2_DVSTCTR0_RHST_Pos) /* Low-speed connection */ #define RUSB2_DVSTCTR0_RHST_FS (2U << RUSB2_DVSTCTR0_RHST_Pos) /* Full-speed connection */ #define RUSB2_DVSTCTR0_RHST_HS (3U << RUSB2_DVSTCTR0_RHST_Pos) /* Full-speed connection */ +#define RUSB2_PIPE_CTR_PID_NAK (0U << RUSB2_PIPE_CTR_PID_Pos) /* NAK response */ +#define RUSB2_PIPE_CTR_PID_BUF (1U << RUSB2_PIPE_CTR_PID_Pos) /* BUF response (depends buffer state) */ +#define RUSB2_PIPE_CTR_PID_STALL (2U << RUSB2_PIPE_CTR_PID_Pos) /* STALL response */ +#define RUSB2_PIPE_CTR_PID_STALL2 (3U << RUSB2_PIPE_CTR_PID_Pos) /* Also STALL response */ + #define RUSB2_DEVADD_USBSPD_LS (1U << RUSB2_DEVADD_USBSPD_Pos) /* Target Device Low-speed */ #define RUSB2_DEVADD_USBSPD_FS (2U << RUSB2_DEVADD_USBSPD_Pos) /* Target Device Full-speed */