Handling USB errors

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Handling USB errors

824 Views
kevinledinh
Contributor II

Hi NXP team,

I'm using a K21 with FSL_USB_Stack from MCUOnEclipse as a CDC device. The K21 is used in a Smart Card reader design.

Recently I've run into an interesting EMI-related problem. Whenever the RF field is energised, the USB comms just drops. There is no further comms from the CDC device (it usually sends a heart beat every 30 seconds). I know that the K21 still runs as normal (the field times out) and not stuck.

While looking around for answers, I come across this threadHow to recover from USB errors, or how to reinitialize USB0 without a full reset? . I've since commented out 

} else if (event_type == USB_APP_ERROR) { /* detach? */

//start_app = FALSE;

//start_transactions = FALSE;

}

and every thing works normally. 

I've also done some analysis and noticed that the error happens roughly twice every second. After the USB_ISR is called and an error is read out of USB0_ERRSTAT (e.g. DFN8)USB_ISR is called again after 5us but USB0_ERRSTAT is zero this time. Why is this happening?

Re. the above thread, it is recommended to disable the pull up on the data line and let enumeration happens if there is any error. Is it a standard practice to do so? Or are some errors tolerable, thus can be ignored? 

Best wishes,

0 Kudos
1 Reply

481 Views
mjbcswitzerland
Specialist V

Phuc

I use the uTasker USB device stack in industrial environments with lots of noise, also with USB-CDC.

Since bulk endpoints have error checking and re-transmission, errors (if not continuous and lasting many seconds or minutes) shouldn't have any big impact.

I just count the errors for statistics:

            if ((ucUSB_Int_status & USB_ERROR) != 0) {  // error detected
    #if defined USE_BUS_TIMEOUT
                if ((ERR_STAT & BTO_ERR) != 0) {        // bus turnaround timeout error
                    USB_errors.ulUSB_timeouts++;
                }
    #endif
                if ((ERR_STAT & CRC16) != 0) {          // CRC-16 error
                    USB_errors.ulUSB_errors_CRC16++;    // count errors
                }
                if ((ERR_STAT & CRC5_EOF) != 0) {       // CRC-5 error
                    USB_errors.ulUSB_errors_CRC5++;     // count errors
                }
                ERR_STAT = (CRC16 | CRC5_EOF | BTO_ERR);// clear error sources
                INT_STAT = USB_ERROR;                   // reset flag
            }

Notice that the error interrupt is optional and the errors that usually occur are CRC errors.

In serious situations where the link really fails (eg. USB host stops the device), turning off the D+ pull-up and turning back on will initiate a new enumeration.

Regards

Mark

Kinetis for professionals: http://www.utasker.com/

0 Kudos