Other Parts Discussed in Thread: SYSCONFIG, C2000WARE, TMS320F28069
Tool/software:
I am attempting to get a USB MSC host application working on prototype hardware.
I successfully ran the "usb_msc_host_ex7" example on our hardware, with minor modifications (clock settings, pin assignment, etc). I can attach a flash drive, and the program enumerates it and mounts the FAT filesystem.
The problems start when I try to interact with USB from CPU2, rather than CPU1. The USB peripheral appears to spontaneously leave host mode and enter device mode, and then stay there forever.
I tried to make minimal changes to the example code. The USB peripheral+library is set up for CPU2 in sysconfig.
Pseudocode for CPU1:
- Run device_init(), board_init(), etc. to set up clocks and other hardware.
- Run "SysCtl_selectCPUForPeripheralInstance(SYSCTL_CPUSEL_USBA, SYSCTL_CPUSEL_CPU2);", to transfer USB peripheral control to CPU2.
- Boot CPU 2 and ask it to start initialization (via IPC flag).
- Wait for CPU 2 to finish initialization (via IPC flag).
- Enable interrupts and start main loop.
Pseudocode for CPU2:
- Wait for CPU 1 to tell us to start initialization.
- Run device_init(), board_init(), etc.
- Run C2000ware_libraries_init(). Notably, this also calls "USBStackModeSet(0, eUSBModeForceHost, ModeCallback);", since sysctl is aware that we want to run in host mode.
- Tell CPU1 that we are done with initialization (via IPC flag).
- Enable interrupts and start main loop. The main loop calls USBHCDMain() (from usbhost.h) and monitors status.
Here is what happens:
1. The system starts up successfully. At this point, the USBDEVCTL register contains DEV=0, HOST=0, and FSDEV=0.
2. As soon as interrupts are enabled, a USB_INTCTRL_MODE_DETECT interrupt goes off. Nothing changes, except that USBIDVISC=1. The main loop starts running.
3. I plug in a flash drive. A USB_INTCTRL_CONNECT interrupt goes off. At this point, the USBDEVCTL register contains DEV=0, HOST=1, FSDEV=1.
4. The main loop calls USBHCDMain(), which sees that a device has connected. USBHCDMAIN() calls USBHCDReset() to reset the device.
5. A USB_INTCTRL_RESET interrupt goes off. At this point, the USBDEVCTL register contains DEV=1, HOST=0, FSDEV. The USB controller has decided that it is no longer a host, and is now a device.
-- Note that the USBDEVCTL change has already occurred at the start of the ISR, so the ISR cannot be causing the problem.
-- Note that this happens before the main context has even returned from USBHCDReset().
6. Meanwhile, USBHCDMain() continues to run through its state machine. It starts a control transfer to retrieve the device descriptor, but the control transfer hangs forever because the USB controller thinks it's in device mode. Disconnecting and connecting the flash drive no longer triggers interrupts.
Reading through the documentation, I am struggling to understand how the USB controller decides which mode to be in. It seems to be a dynamic process, which depends on the state of the D+ and D- pins, and the (nonexistent) ID and Vbus-detect pins. Does anyone know why the peripheral might be setting itself to device mode after a bus reset? Another poster seems to have had the same issue in the past, with a TMS320F28069.
Thank you!