Closed ejolson9 closed 4 years ago
Here is an example of libusb host code which shows problem. You'll have to link to libusb and build using compiler with with newer cpp support (I'm using VS2017). You'll have to put in your vid/pid as well.
As described above, the application hangs on second iteration of control transfer:
Please remove the USB_DEVICE_ControlStatus() call at line number 213 in your app.c.txt file.
case USB_DEVICE_EVENT_CONTROL_TRANSFER_DATA_SENT: {
// Control transfer data has been sent!
USB_DEVICE_ControlStatus(appData.usbDevHandle, USB_DEVICE_CONTROL_STATUS_OK);
// will this help ?
// USB_DEVICE_IRPCancelAll ();
break;
The above code snippet is taken from your app.c. The USB_DEVICE_ControlStatus() call is not required when the application receives the event USB_DEVICE_EVENT_CONTROL_TRANSFER_DATA_SENT. This event indicates that the Status stage of the Control transfer has been completed and the application can now schedule a new a Control transfer.
Please refer library documentation for more details (https://microchip-mplab-harmony.github.io/usb/00289.html).
Thank you for the comment and doc reference, that fixed my example program.
I was mainly looking at the header files, and the 'usb_device.h' file contains the following code snippet in that documentation for USB_DEVICE_ControlSend() :
Example:
<code>
// The following code example shows an example of how the
// USB_DEVICE_ControlSend() function is called in response to the
// USB_DEVICE_EVENT_CONTROL_TRANSFER_SETUP_REQUEST event to enable a control
// read transfer.
void APP_USBDeviceEventHandler
(
USB_DEVICE_EVENT event,
void * pData,
uintptr_t context
)
{
USB_SETUP_PACKET * setupPkt;
switch(event)
{
case USB_DEVICE_EVENT_CONTROL_TRANSFER_SETUP_REQUEST:
setupPkt = (USB_SETUP_PACKET *)pData;
// Submit a buffer to send 32 bytes in the control read transfer.
USB_DEVICE_ControlSend(usbDeviceHandle, data, 32);
break;
case USB_DEVICE_EVENT_CONTROL_TRANSFER_DATA_RECEIVED:
// This means that data in the data stage of the control
// write transfer has been received. The application can either
// accept the received data by calling the
// USB_DEVICE_ControlStatus function with
// USB_DEVICE_CONTROL_STATUS_OK flag (as shown in this example)
// or it can reject it by calling the USB_DEVICE_ControlStatus
// function with USB_DEVICE_CONTROL_STATUS_ERROR flag.
USB_DEVICE_ControlStatus(usbDeviceHandle, USB_DEVICE_CONTROL_STATUS_OK);
break;
case USB_DEVICE_EVENT_CONTROL_TRANSFER_DATA_SENT:
// This means that data in the data stage of the control
// read transfer has been sent. The application would typically
// end the control transfer by calling the
// USB_DEVICE_ControlStatus function with
// USB_DEVICE_CONTROL_STATUS_OK flag (as shown in this example).
USB_DEVICE_ControlStatus(usbDeviceHandle, USB_DEVICE_CONTROL_STATUS_OK);
break;
This is where my confusion came from.
Thanks!
Note that the online docs (possibly coming from same source doc, idk) has the same example on the ControlSend() page: https://microchip-mplab-harmony.github.io/usb/00758.html
In my testing I have not been able to get control transfers to send data from the MCU (SAM V71, on ultra xplained eval board) back to host PC. I am using libusb on the host side. On the MCU side, I am starting with the provided 'vendor' example, and just adding the bare minimum code to service a specific control transfer (mainly to APP_USBDeviceEventHandler()) - see app.c.txt attached. app.c.txt
Expected behaviour: Host PC application will be able to use libusb_control_transfer() to receive data from MCU without issue.
Observed behaviour: The first libusb_control_transfer() appears to work correctly, then hangs on the next transaction. When I add the 'CONSOLE' and 'DEBUG' components via Harmony, I can see the following error message via EDBG COM port (the last message occurs on the second control transfer):
The MCU seems to fail other control endpoint requests after the first control transfer as well. For example if I only do one control transfer, then try to query the device descriptors, these requests also timeout/hang; it appears that the MCU is in some bad state.
Hopefully there is something wrong with my example. Other things I've tried: