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?