Hi, I encountered problems using the USB-CDC-example out of the Atmel software package 1.5 with an AT91SAM9260. Sometimes, when sending data using USBD_Write, the USB driver hangs in the function/define SET_CSR waiting for the AT91C_UDP_TXPKTRDY flag. Other times, USBD_Write returns USBD_STATUS_LOCKED all times, while receiving data works fine.
char USBD_Write(unsigned char eptnum, const void *data, unsigned int size, TransferCallback callback, void *argument) { Endpoint *endpoint = &(endpoints[eptnum]); Transfer *transfer = &(endpoint->transfer); // Check that the endpoint is in Idle state if (endpoint->state != UDP_ENDPOINT_IDLE) { return USBD_STATUS_LOCKED; } trace_LOG(trace_INFO, "Write%d(%u) ", eptnum, size); // Setup the transfer descriptor transfer->data = (char *) data; transfer->remaining = size; transfer->buffered = 0; transfer->transferred = 0; transfer->callback = callback; transfer->argument = argument; // Send the first packet endpoint->state = UDP_ENDPOINT_SENDING; while((AT91C_BASE_UDP->UDP_CSR[eptnum]&AT91C_UDP_TXPKTRDY)==AT91C_UDP_TXPKTRDY); UDP_WritePayload(eptnum); SET_CSR(eptnum, AT91C_UDP_TXPKTRDY); // If double buffering is enabled and there is data remaining, // prepare another packet if ((BOARD_USB_ENDPOINTS_BANKS(eptnum) > 1) && (transfer->remaining > 0)) { UDP_WritePayload(eptnum); } // Enable interrupt on endpoint AT91C_BASE_UDP->UDP_IER = 1 << eptnum; return USBD_STATUS_SUCCESS; }
Does someone else have similar problems?
And another question concerning the USB-CDC-driver: Under WinXP usbser.sys is used as driver for the device and it can be used as a serial port. When connecting to the port (e.g. by HTerm) and then resetting the board, the connection can not be established again, until the device is plugged out and in again. Is this a problem of the USB-CDC-driver on the device or a generic problem of the windows driver?
> Sometimes, when sending data using USBD_Write, the USB driver hangs in the function/define SET_CSR waiting for the AT91C_UDP_TXPKTRDY flag.
Which endpoint does USBD_Write() target, bulk IN or interrupt IN ? Does the hang occurs always on the same endpoint? Do you see IN-NAKs for the endpoint on the bus, with a hardware bus analyzer? (You can't see IN-NAK with any software sniffer)
I have doubt that IN-NAK stops on the bulk IN, because of failure on the PC device driver. It is often caused by noise on the bus. > Under WinXP usbser.sys is used as driver for the device and it can be used as a serial port. When connecting to the port (e.g. by HTerm) and then resetting the board, the connection can not be established again, until the device is plugged out and in again.
Error recovery is troublesome, for any programming target. But usbser.sys is too poor.
As the requirement for CDC device driver, usbser.sys always holds pending requests on these pipes. - bulk IN pipe on the data class interface - interrupt IN pipe on the communication class interface.
When surprised removal is notified to this driver, the bulk IN pipe often causes hang on canceling pending request. It occurs not just for surprised removal, also for transfer error caused by noise on the bus. With pending request, this pipe always puts IN-NAKs to the bus. As noise error attacks even this IN-NAK sequence, noise immunity of usbser.sys is very weak.
> Is this a problem of the USB-CDC-driver on the device or a generic problem of the windows driver?
As Oney wrote in his "Programming the Windows Driver Model", cancel handling on WDM driver is tricky. In this mean, it is a generic problem of WDM. But I believe we can manage the difficulty, following his detailed instruction on the book exactly.
As of the recovery from disconnection/ re-connection over usbser.sys, you may have interest in this topic.
tech.groups.yahoo.com/.../43461
Tsuneo