AnsweredAssumed Answered

Strange behaviours in USB driver of AN4379 MSC bootloader

Question asked by Kai Liu on Jan 21, 2014

AN4379 MSC bootloader works fine with FRDM-KL25Z, but it doesn't work for FRDM-K20D50M. I am using IAR6.50. The MSC bootloader can enumerate but reports download error.

 

In order to find out why, I enabled debug over OpenSDA VCP. There are LOTS of USB ERRORs ! It is the call stack.

 

        disk.c::    USB_App_Callback()

                    printf("USB_APP_ERROR\r\n");                   

        usb_msc.c::     USB_Class_MSC_Event()

                    g_msc.msc_callback(controller_ID,event,val);                   

        usb_class.c::   USB_Error_Service()

                    g_class_callback(event->controller_ID, USB_APP_ERROR, (uint_8*)(&(event->errors)));                   

        usb_driver.c::  USB_Device_Call_Service()

                    g_usb_CB[type](event);                   

        usb_dci_kinetis.c:: USB_ISR

                    USB_Device_Call_Service(USB_SERVICE_ERROR, &event);

 

        USB_ISR( )

 

            v1 = USB0_ISTAT;

            v2 = USB0_INTEN;

            intr_stat = (v1 & v2)

            ......

            if (ERROR_FLAG(intr_stat))  // ((x)) & 0x02, check ERROR in USB0_ISTAT

            {

                USB0_ISTAT = USB_ISTAT_ERROR_MASK;

                v1 = USB0_ERRSTAT;

                v2 = USB0_ERREN;    // always 0xBF

                event.errors = (uint_8)(v1 & v2)    // I put break point here and watch intr_stat, v1 and v2

                (void)USB_Device_Call_Service(USB_SERVICE_ERROR, &event);

                USB0_ERRSTAT = ERR_STAT_CLEAR_ALL;

                USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;

            }

 

Watch window

        intr_stat,  v1,     USB0_ERRSTAT

        0x02,   0x08,   0x8A

        0x1A,   0x00,   0x00

        0x0E,   0x00,   0x82

        0x0A,   0x00,   0x02

        0x06,   0x00,   0x00

        0x06,   0x00,   0x02

        0x06,   0x00,   0x0A

        0x06,   0x00,   0x8A

        0x06,   0x00,   0x82

        0x06,   0x00,   0x02

        0x06,   0x00,   0x88

        0x06,   0x00,   0x0A

        0x06,   0x00,   0x00

        0x06,   0x00,   0x8A

        0x06,   0x00,   0x8A

        0x06,   0x00,   0x00

        0x06,   0x00,   0x82

        0x06,   0x00,   0x00

        0x06,   0x00,   0x8A

        0x06,   0x00,   0x00

        0x06,   0x00,   0x88

 

        USB0_ERRSTAT (MSB/LSB)

        BTSERR | N/A | DMAERR | BTOERR | DFN8 | CRC16 | CRC5EOF | PIDERR

      

        BTSERR, DFN8, CRC5EOF happens a lot, means a lot of USB communication error.

 

You can easily found variables v1 and register USB0_ERRSTAT are different. So I slightly changes the code as following:

        USB0_ISTAT = USB_ISTAT_ERROR_MASK;

        v1 = USB0_ERRSTAT;

        v2 = USB0_ERREN;

        event.errors = (uint_8)(v1 & v2);

 

        volatile uint_8 v3 = USB0_ERRSTAT;     // volatile prevent optimization by compiler

        volatile uint_8 v4 = v3 & 0xBF;

        volatile uint_8 v5 = USB0_ERRSTAT & 0xBF;

      

        event errors = v3;     // break point here, v3, v4, v5 are watched before recycled

        event.errors = v4;    

        event.errors = v5;

 

And I found v3/v4/v5 are identical, but not always identical to USB0_ERRSTAT. One possible explaination is that when break point reaches, USB0_ERRSTAT have been updated after v3/v4/v5 being operated.

 

I have no idea why this happens. FRDM-KL25Z never drops into error state. And I use to think D+/D- have hardware issues. But Other CDC demo for K20 works, although there is some unexpected behaviour as well.

 

Any ideas? or sugguestions?

Outcomes