rp2040 enable suspend and resume interrupt

This commit is contained in:
hathach 2021-08-11 20:06:57 +07:00
parent a5b464c5ca
commit f3a6e564ee
No known key found for this signature in database
GPG Key ID: 2FA891220FBFD581
3 changed files with 52 additions and 35 deletions

View File

@ -37,6 +37,14 @@
#include "device/dcd.h"
// Current implementation force vbus detection as always present, causing device think it is always plugged into host.
// Therefore it cannot detect disconnect event, mistaken it as suspend.
// Note: won't work if change to 0 (for now)
//
// Note: Line state when disconnected is very sensitive, in actual testing,
// it can toggles between J-state (idle) and SE1 if cable still connected to rp2040 (not connected to host)
#define FORCE_VBUS_DETECT 1
/*------------------------------------------------------------------*/
/* Low level controller
*------------------------------------------------------------------*/
@ -290,7 +298,9 @@ static void dcd_rp2040_irq(void)
hw_handle_buff_status();
}
// SE0 for 2 us or more, usually together with Bus Reset
#if FORCE_VBUS_DETECT == 0
// Since we force VBUS detect On, device will always think it is connected and
// couldn't distinguish between disconnect and suspend
if (status & USB_INTS_DEV_CONN_DIS_BITS)
{
handled |= USB_INTS_DEV_CONN_DIS_BITS;
@ -306,6 +316,7 @@ static void dcd_rp2040_irq(void)
usb_hw_clear->sie_status = USB_SIE_STATUS_CONNECTED_BITS;
}
#endif
// SE0 for 2.5 us or more
if (status & USB_INTS_BUS_RESET_BITS)
@ -322,7 +333,7 @@ static void dcd_rp2040_irq(void)
#endif
}
#if 0
#if 1
// TODO Enable SUSPEND & RESUME interrupt and test later on with/without VBUS detection
/* Note from pico datasheet 4.1.2.6.4 (v1.2)
@ -364,6 +375,7 @@ static void dcd_rp2040_irq(void)
/*------------------------------------------------------------------*/
/* Controller API
*------------------------------------------------------------------*/
void dcd_init (uint8_t rhport)
{
pico_trace("dcd_init %d\n", rhport);
@ -372,6 +384,11 @@ void dcd_init (uint8_t rhport)
// Reset hardware to default state
rp2040_usb_init();
#if FORCE_VBUS_DETECT
// Force VBUS detect so the device thinks it is plugged into a host
usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS;
#endif
irq_set_exclusive_handler(USBCTRL_IRQ, dcd_rp2040_irq);
memset(hw_endpoints, 0, sizeof(hw_endpoints));
next_buffer_ptr = &usb_dpram->epx_data[0];
@ -388,10 +405,11 @@ void dcd_init (uint8_t rhport)
// Enable individual controller IRQS here. Processor interrupt enable will be used
// for the global interrupt enable...
// TODO Enable SUSPEND & RESUME interrupt
// Note: Force VBUS detect cause disconnection not detectable
usb_hw->sie_ctrl = USB_SIE_CTRL_EP0_INT_1BUF_BITS;
usb_hw->inte = USB_INTS_BUFF_STATUS_BITS | USB_INTS_BUS_RESET_BITS | USB_INTS_SETUP_REQ_BITS |
USB_INTS_DEV_CONN_DIS_BITS /* | USB_INTS_DEV_SUSPEND_BITS | USB_INTS_DEV_RESUME_FROM_HOST_BITS */ ;
USB_INTS_DEV_SUSPEND_BITS | USB_INTS_DEV_RESUME_FROM_HOST_BITS |
(FORCE_VBUS_DETECT ? 0 : USB_INTS_DEV_CONN_DIS_BITS);
dcd_connect(rhport);
}

View File

@ -360,6 +360,9 @@ bool hcd_init(uint8_t rhport)
// Reset any previous state
rp2040_usb_init();
// Force VBUS detect to always present, for now we assume vbus is always provided (without using VBUS En)
usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS;
irq_set_exclusive_handler(USBCTRL_IRQ, hcd_rp2040_irq);
// clear epx and interrupt eps

View File

@ -63,10 +63,6 @@ void rp2040_usb_init(void)
// Mux the controller to the onboard usb phy
usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS;
// Force VBUS detect so the device thinks it is plugged into a host
// TODO support VBUs detect
usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS;
}
void hw_endpoint_reset_transfer(struct hw_endpoint *ep)