Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USB_CompositeDevice_MSC_CDC example on MAX32666FTHR will not enumerate after USB disconnect/reconnect #722

Open
khpeterson opened this issue Aug 29, 2023 · 5 comments
Labels
bug Something isn't working

Comments

@khpeterson
Copy link
Contributor

khpeterson commented Aug 29, 2023

I know this app was written for the EvKit and not the FTHR but I am trying to integrate this functionality into a FTHR based application. Running the app on the EvKit works fine - it will enumerate each time USB on CN2 is connected to a host:

2023-08-28T11:31:37.600562: ***** MAX32665 USB Composite Device (CDCACM and Mass Storage) Example *****
2023-08-28T11:31:37.600775: Waiting for VBUS...
2023-08-28T11:34:58.818959: VBUS Connect
2023-08-28T11:34:58.819201: Suspended
2023-08-28T11:34:58.914743: Bus Reset
2023-08-28T11:34:58.915511: Bus Reset Done: High speed
2023-08-28T11:34:58.996455: Enumeration complete...
2023-08-28T11:35:07.898868: Suspended
2023-08-28T11:35:13.462384: Bus Reset
2023-08-28T11:35:13.463063: Bus Reset Done: High speed
2023-08-28T11:35:13.526044: Enumeration complete...

However, because VBUS on CN1 is providing power to the EvKit, the VBUS Disconnect event is never generated.

On a MAX32666FTHR powered with a LiPo battery, disconnecting produces VBUS Disconnect as expected but the Suspend, Bus Reset (and Done) events do not follow VBUS Connect as they do after power on:

2023-08-28T15:37:12.144284: ***** MAX32665 USB Composite Device (CDCACM and Mass Storage) Example *****
2023-08-28T15:37:12.146163: Waiting for VBUS...
2023-08-28T15:37:12.151887: VBUS Connect
2023-08-28T15:37:12.152778: Suspended
2023-08-28T15:37:12.252169: Bus Reset
2023-08-28T15:37:12.254097: Bus Reset Done: High speed
2023-08-28T15:37:12.327265: Enumeration complete...
2023-08-28T15:37:21.600820: VBUS Disconnect
2023-08-28T15:37:34.201727: VBUS Connect

I instrumented the usb.c driver to save the first 8 sets of interrupt flags handled by MXC_USB_IrqHandler():

static struct {
	uint32_t MXC_USBHS_intrusb;
	uint32_t MXC_USBHS_intrusben;
	uint32_t MXC_USB_mxm_flags;
} mxc_usb_irqhist[8];
static int mxc_usb_irqhist_idx;

...

    /* Note: Hardware clears these after read, so we must process them all or they are lost */
    MXC_USBHS_intrusb = MXC_USBHS->intrusb;
    MXC_USBHS_intrusben = MXC_USBHS->intrusben;
    MXC_USB_flags = MXC_USBHS_intrusb & MXC_USBHS_intrusben;
    in_flags = MXC_USBHS->intrin & MXC_USBHS->intrinen;
    out_flags = MXC_USBHS->introut & MXC_USBHS->introuten;

    /* These USB interrupt flags are W1C. */
    MXC_USB_mxm_flags = MXC_USBHS->mxm_int & MXC_USBHS->mxm_int_en;
    MXC_USBHS->mxm_int = MXC_USB_mxm_flags;

    if (mxc_usb_irqhist_idx < 8) {
	mxc_usb_irqhist[mxc_usb_irqhist_idx].MXC_USBHS_intrusb = MXC_USBHS_intrusb;
	mxc_usb_irqhist[mxc_usb_irqhist_idx].MXC_USBHS_intrusben = MXC_USBHS_intrusben;
	mxc_usb_irqhist[mxc_usb_irqhist_idx].MXC_USB_mxm_flags = MXC_USB_mxm_flags;	
	mxc_usb_irqhist_idx += 1;
    }

After the normal startup sequence that history looks like:

(gdb) p mxc_usb_irqhist[0]@mxc_usb_irqhist_idx
$9 = {{
    MXC_USBHS_intrusb = 0, 
    MXC_USBHS_intrusben = 0, 
    MXC_USB_mxm_flags = 1
  }, {
    MXC_USBHS_intrusb = 9, 
    MXC_USBHS_intrusben = 5, 
    MXC_USB_mxm_flags = 0
  }, {
    MXC_USBHS_intrusb = 4, 
    MXC_USBHS_intrusben = 5, 
    MXC_USB_mxm_flags = 0
  }, {
    MXC_USBHS_intrusb = 8, 
    MXC_USBHS_intrusben = 5, 
    MXC_USB_mxm_flags = 0
  }, {
    MXC_USBHS_intrusb = 8, 
    MXC_USBHS_intrusben = 5, 
    MXC_USB_mxm_flags = 0
  }, {
    MXC_USBHS_intrusb = 8, 
    MXC_USBHS_intrusben = 5, 
    MXC_USB_mxm_flags = 0
  }, {
    MXC_USBHS_intrusb = 8, 
    MXC_USBHS_intrusben = 5, 
    MXC_USB_mxm_flags = 0
  }, {
    MXC_USBHS_intrusb = 8, 
    MXC_USBHS_intrusben = 5, 
    MXC_USB_mxm_flags = 0
  }}

Resetting the history idx after the VBUS Disconnect and tracing the re-connection shows:

(gdb) p mxc_usb_irqhist[0]@mxc_usb_irqhist_idx
$11 = {{
    MXC_USBHS_intrusb = 8, 
    MXC_USBHS_intrusben = 0, 
    MXC_USB_mxm_flags = 1
  }}

I have tried forcing a shutdown/softreset/re-init when handling the VBUS Disconnect event:

		MXC_USB_Shutdown();
		MXC_USBHS->softreset = 3;
		if (MXC_USB_Init(&usb_opts) != 0) {
			printf("usb_init() failed\n");
		}

to mimic POR conditions but no go - the RESET interrupt never triggers after the second VBUS Connect. I have not confirmed that the host is initiating the second RESET but FWIW, I do see the same behavior on macOS 12.6.8 and win10.

I will keep digging but any suggestions from a MAXUSB expert would be greatly appreciated. It would be helpful if this example app showed the necessary steps to disconnect and reconnect USB when powered by something other than USB.

@Jake-Carter
Copy link
Contributor

Hi @khpeterson, our MAXUSB expert recently transitioned to a different team. I've reached out to see if they are still available for some guidance.

In the meantime... I have limited experience with USB but conceptually I think you've illustrated the issue very well. So apologies if my follow-up questions are off-base...

Starting with the basics... I wonder if differential pair is being grounded after the first disconnect? I think the idea that the host is never seeing the re-connect is worth investigating. AFAIK the host detects the presence and speed class of the device based on a pull-up on DM or DP, but I don't see a pull-up on either the FTHR or EVKIT. So perhaps the POR state manages the signal levels correctly, but something about the disconnect logic is grounding them and preventing the reconnect from being detected. Can you probe the DM/DP pins after the second reconnect?

image

This is a really hacky potential workaround, but you could try issuing a system reset on the VBUS disconnect event. The micro's state should be almost identical to a POR. It's definitely ugly, but might make an interesting data point at least...

image

image

@khpeterson
Copy link
Contributor Author

Thank you @Jake-Carter, I don't have a way to probe DM/DP until next week (and will do then) but FYI, your workaround suggestion to issue a full system reset on VBUS disconnect does do the right thing and enumeration completes successfully.

@sanjayjaroli
Copy link
Contributor

Hi @khpeterson,
Is it possible for you to monitor VDDB when USB is disconnected?

@khpeterson
Copy link
Contributor Author

khpeterson commented Sep 25, 2023

@Jake-Carter - I probed DP and DM (on U2 pins 4 and 3) on the first and second VBUS connects... I see the pull-up action on DP (DM stays low) on the first VBUS connect but nothing triggers on the second VBUS connect. Here's what I see on DP the first connect:

IMG_6825

@sanjayjaroli - I probed VDDB on one side of C27 and here's what that looks like when VBUS is disconnected - I hope the timescale is long enough to be useful to you.

IMG_6826

@Jake-Carter
Copy link
Contributor

Thanks @khpeterson, we're looking at the VDDB behavior on the FTHR a little deeper. It's a little suspicious that it doesn't drop to 0 on disconnect.

@Jake-Carter Jake-Carter added the bug Something isn't working label Sep 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants