lpcware

USBCDC sample code of LPC4330 issue.

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by CH Wu on Sun Feb 01 21:45:09 MST 2015
Hello NXP team,

We'd like to ask interruption occurrence condition of USB0 of LPC4330.

We use USBCDC by making reference to a sample code of following Keil
and achieve a virtual serial communication between the PC and LPC4330.
http://www.lpcware.com/content/nxpfile/lpc4350apdlzip

The defect at which data transmission in the LPC4330->PC direction stops at present occurs.
When it's checked, interruption isn't rising from USB0 at the time of data transmission completion.
A rough processing flow is indicated below.
----
[Tx of 330byte data in the LPC4330->PC direction (64 * 5 + 10 byte)]
1) Data is written in Endpoint in BulkIn (EP2) 64 bytes from LPC4330.
2) Data is sent 64 bytes at the timing of BulkIn packet reception from a PC.
3) USB interruption occurs on LPC4330 side by the timing to
    which ACK to BulkIn transmission data has been returned from a PC.
4) Transmission data of the 64byte continued by USB interruption
    processing is written in Endpoint in BulkIn.(EP2) 64 bytes.  ( 2)-4) is repeated 4 times.)
5) Remaining 10 byte is written in Endpoint in BulkIn (EP2).
6) Data is sent 10 bytes at the timing of BulkIn packet reception from a PC.
7) ACK from a PC to BulkIn transmission data is the timing which has returned,
     and interruption of USB0 occurs. Transmission processing is completed by the timing.
----
We expect that interruption of USB0 occurs after transmission of 7),
but there is a case that interrupt of USB0 doesn't occur by a fixed probability.
We want an answer of the following question.

A) We understand as follows.
    Interruption occurs by the timing which received ACK in USB BulkIn
    from a PC after data transmission of BulkIn processing from LPC4330.
    Is this our understanding right?
B)Isn't interruption considered as the factor which doesn't occur?

A question related to above.
We found the cause point of the issue USB0 interruption doesn't generate.

http://www.lpcware.com/content/nxpfile/lpc4350apdlzip
    lpc43xx\Examples\USBDEV\Usb_Cdc\usbhw.c

We are refer to the sample code that available usbhw.c from the above URL.
In the process of them seems to be such a factor
in missed interrupt has occurred following.

* HighSpeed mode USB
* Interrupt source clear ENDPTCOMPLETE is performed
   after the processing for each Endpoint
* In the processing of each Endpoint, take a little time
   to such memory copy to another bank

So we have modified the process as described in "No.8 Details" sheet.
In the modified contents, to perform the processing
of each Endpoint interrupt factors from clear at the beginning.
We applied this modification, the interrupt missed no longer occurred.

We want to hear your opinion about the following.

1) What is the meaning of the interruption factor clearance
   which is ENDPTNAK in the original sample code?
2) Is the handle of "Code modification proposal" proper?
   (Even than missed interrupts can occur in this deal?)
  
--------
The original sample code
http://www.lpcware.com/content/nxpfile/lpc4350apdlzip
lpc43xx\Examples\USBDEV\Usb_Cdc\usbhw.c : L725 - L750
'''
   /* handle completion interrupts */
   val = LPC_USB->ENDPTCOMPLETE;
   if (val)
   {
//                LPC_UART1->THR = 'C';
//                LPC_UART1->THR = '\n';

     LPC_USB->ENDPTNAK = val;<- ???
     for (n = 0; n < EP_NUM_MAX / 2; n++)
     {
       if (val & (1<<n))
       {
         if (g_drv.USB_P_EP[n])
           g_drv.USB_P_EP[n](USB_EVT_OUT);

         LPC_USB->ENDPTCOMPLETE = (1<<n);
       }
       if (val & (1<<(n + 16)))
       {
         ep_TD [(n << 1) + 1 ].total_bytes &= 0xC0;
         if (g_drv.USB_P_EP[n])
           g_drv.USB_P_EP[n](USB_EVT_IN);
         LPC_USB->ENDPTCOMPLETE = (1<<(n + 16));
       }
     }
   }
'''
--------
--------
Code modification proposal
'''
   /* handle completion interrupts */
   val = LPC_USB->ENDPTCOMPLETE;
   if (val)
   {
//                LPC_UART1->THR = 'C';
//                LPC_UART1->THR = '\n';

     LPC_USB->ENDPTNAK = val;
     LPC_USB->ENDPTCOMPLETE = val;  /* XXX clear interruption factor */
     for (n = 0; n < EP_NUM_MAX / 2; n++)
     {
       if (val & (1<<n))
       {
         if (g_drv.USB_P_EP[n])
           g_drv.USB_P_EP[n](USB_EVT_OUT);

//        LPC_USB->ENDPTCOMPLETE = (1<<n);    /* XXX comment out */
       }
       if (val & (1<<(n + 16)))
       {
         ep_TD [(n << 1) + 1 ].total_bytes &= 0xC0;
         if (g_drv.USB_P_EP[n])
           g_drv.USB_P_EP[n](USB_EVT_IN);
//        LPC_USB->ENDPTCOMPLETE = (1<<(n + 16));    /* XXX comment out */
       }
     }
   }
'''
--------

Outcomes