EmbeddedRelated.com
Forums
Memfault Beyond the Launch

LPC2148 and USB CDC-ACM flow control with usbser.sys

Started by Wojciech Kromer November 27, 2008
> This is the standard way. Maybe some trouble occurs on the firmware.
> Call this subroutine from the interrupt handler of the bulk OUT
> endpoint AND SOF (FRAME) interrupt handler. This subroutine is easily
> made modifying the routine which reads out an endpoint.
>
> - Call "Select Endpoint" command and get Full/Empty (FE) bit
> - - if the EP buffer is empty, return
> - Get the packet size on the OUT EP
> - - set RD_EN bit and logical address to USBCtrl register
> - - wait for PKT_RDY bit on USBRxPLen register
> - - mask USBRxPLen and get PKT_LNGTH
> - If the space on the RX buffer is less than packet size,
> - - clear USBCtrl register
> - - return
> - Read out all data to the RX buffer from USBRxData register
> - Clear USBCtrl register
> - Call "Clear Buffer" command
> - Repeat above entire sequence again (for double buffer)
>
> Tsuneo
>
Thank you very much for details.
That's almost i'm doing except reading packet size and clearing USBCtrl
when there is no data.
What about next OUT SOF interrupt with? Will LPC repeat it?

An Engineer's Guide to the LPC2100 Series

If you call the buffer read out routine below just from the ISR
(Interrupt Service Routine) of the bulk OUT endpoint, no more
interrupt for this ISR occurs, when the routine leaves the endpoint
buffer unread because of full RX buffer. The USB engine evokes
endpoint interrupt just when a new OUT transaction is ACKed and the
OUT endpoint buffer is refreshed. It doesn't occur while the endpoint
buffer is occupied.

Then, the firmware should have another supervisor task, which watches
both of the RX buffer and the OUT endpoint periodically, and which
invokes the buffer read out routine. The SOF (FRAME) ISR is one of the
candidates to implement this supervisor task, but any other periodical
(repeated) task will do. Such as a timer ISR, polling on the
superloop, etc. The period is mainly determined by the required speed.
I've shown SOF in above post, just because it's handy. If the firmware
can process the data on the RX buffer faster, a timer interrupt of
shorter than SOF is applied.

IN/OUT endpoint interrupts are the events caused by the host side. On
the device side, however, there are another events caused by the
device processes. For example, RX buffer full/ TX buffer empty, finish
of a process, user's key-in, etc. These device side events occur
independently from the USB events. The supervisor task watches the
events (status) of both sides, and it schedules the transfer between
the endpoint buffer and the firmware buffer.

When this supervisor task cooperates with the endpoint interrupts, the
response latency for the host events (complete of new IN/OUT
transaction) decreases, and the transfer speed increases. However, it
doesn't mean this supervisor task is not required at all. Without this
supervisor task, endpoint interrupt causes data drop (overwrite) on
the firmware buffer for OUT EP, extra packets for IN EP.

No firmware handler for bulk/ interrupt/ control transfer goes without
this supervisor, though it may be in a simplified shape. Not just for
CDC-ACM.

It has been improved recently a little, but still many USB examples
lack the supervisor, examples from KEIL, IAR, STMicro, Atmel, SiLabs,
Microchip, LPCUSB, etc. I discussed on this issue with Bertrik on
LPCUSB once on this forum; He tries to implement this supervisor using
NAK interrupt, and it isn't a good way. Unfortunately, as my
explanation was not so sophisticated in those days, I couldn't get him
to convinced. He sticks to the USB interrupts so much, and drops the
view point of the device side events, and the arbitration of both
side. But I believe he'll come to this insight soon :-)

Tsuneo

--- In l..., Wojciech Kromer
wrote:
> > This is the standard way. Maybe some trouble occurs on the firmware.
> > Call this subroutine from the interrupt handler of the bulk OUT
> > endpoint AND SOF (FRAME) interrupt handler. This subroutine is easily
> > made modifying the routine which reads out an endpoint.
> >
> > - Call "Select Endpoint" command and get Full/Empty (FE) bit
> > - - if the EP buffer is empty, return
> > - Get the packet size on the OUT EP
> > - - set RD_EN bit and logical address to USBCtrl register
> > - - wait for PKT_RDY bit on USBRxPLen register
> > - - mask USBRxPLen and get PKT_LNGTH
> > - If the space on the RX buffer is less than packet size,
> > - - clear USBCtrl register
> > - - return
> > - Read out all data to the RX buffer from USBRxData register
> > - Clear USBCtrl register
> > - Call "Clear Buffer" command
> > - Repeat above entire sequence again (for double buffer)
> >
> > Tsuneo
> >
> Thank you very much for details.
> That's almost i'm doing except reading packet size and clearing USBCtrl
> when there is no data.
> What about next OUT SOF interrupt with? Will LPC repeat it?
>


Memfault Beyond the Launch