EmbeddedRelated.com
Forums

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

Started by Wojciech Kromer November 27, 2008
Hello.

I'm trying to use my own LPC2148 USB stack, and getting sick with
usbser.sys.
What is correct way to stop transmission from HOST to DEVICE?

a) sending USB_CDC_NOTIFY_SERIAL_STATE with DSR off is not working with
usbser.sys
b) not reading data from EP causes NAK (it's OK) but it seems some data
are lost wit this way
c) stall-in EP, causes ERROR on USB

Any suggestions?
Some tricks with .inf file?
Another CDC-ACM driver for windows?

Regards.

An Engineer's Guide to the LPC2100 Series

On Thu, Nov 27, 2008 at 10:42 PM, Wojciech Kromer
wrote:
> Hello.
>
> I'm trying to use my own LPC2148 USB stack, and getting sick with
> usbser.sys.
> What is correct way to stop transmission from HOST to DEVICE?

Just close the handle?

> a) sending USB_CDC_NOTIFY_SERIAL_STATE with DSR off is not working with
> usbser.sys
> b) not reading data from EP causes NAK (it's OK) but it seems some data
> are lost wit this way
> c) stall-in EP, causes ERROR on USB
>
> Any suggestions?
This might help.
http://www.cygnal.org/ubb/Forum9/HTML/000945.html

> Some tricks with .inf file?
What is your inf file?

> Another CDC-ACM driver for windows?
Why do you want to use CDC-ACM? Why not HID?

Xiaofan

>> I'm trying to use my own LPC2148 USB stack, and getting sick with
>> usbser.sys.
>> What is correct way to stop transmission from HOST to DEVICE?
>>
>
> Just close the handle?
>
>
I mean how to stop HOST sending data being a DEVICE.
I'm trying to run on a device typical flow control, and send from DEVICE
to HOST something
like 'hey do not send me data now', and of course 'send it now'.
>> a) sending USB_CDC_NOTIFY_SERIAL_STATE with DSR off is not working with
>> usbser.sys
>> b) not reading data from EP causes NAK (it's OK) but it seems some data
>> are lost wit this way
>> c) stall-in EP, causes ERROR on USB
>>
>> Any suggestions?
>>
> This might help.
> http://www.cygnal.org/ubb/Forum9/HTML/000945.html
>
>

>> Some tricks with .inf file?
>>
> What is your inf file?
>
Here it is:

[Version]
Signature="$Windows NT$"
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}

Provider=%DGT%
LayoutFile=layout.inf
DriverVer/04/2004,5.1.2600.2180

[Manufacturer]
%DGT%=DGT

[DGT]
%XXX%= XXX,USB\VID_1BB7&PID_0002
[DestinationDirs]
FakeModemCopyFileSection
DefaultDestDir = 12

[XXX.NT]
include=mdmcpq.inf
CopyFileseModemCopyFileSection
AddReg=XXX.NT.AddReg

[XXX.NT.Services]
AddService = usbser, 0x00000002, Service_Inst

[Service_Inst]
DisplayName = %Serial.SvcDesc%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\usbser.sys
LoadOrderGroup = Base

[XXX.NT.AddReg]
HKR,,NTMPDriver,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
HKR,,PortSubClass,1,01

[Strings]
DGT = "DGT"
XXX = "XXX"
Serial.SvcDesc = "XXX USB Driver"

>
>> Another CDC-ACM driver for windows?
>>
> Why do you want to use CDC-ACM? Why not HID?
>
>
I'm implementing a kind of modem.

Regards.

Are you sure this is a usbser.sys problem? The program that uses the
connection (HyperTerm, for example), has to honor hardware flow control,
just like when using a real UART.

--jc

> Are you sure this is a usbser.sys problem? The program that uses the
> connection (HyperTerm, for example), has to honor hardware flow control,
> just like when using a real UART.
>
>
I'm using FreeSerialPortMonitor to see all control "leds".
The seems not to change on clearing DSR bit after sending
USB_CDC_NOTIFY_SERIAL_STATE

Hyperterminal is not a good tool for testing. Problem appears with ppp
dialup.
I'm testing it on XP-SP3.

What I need to say, that with linux cdc_acm driver it works fine.

Regards.
--- In l..., Wojciech Kromer
wrote:
> I mean how to stop HOST sending data being a DEVICE.
> I'm trying to run on a device typical flow control, and send from DEVICE
> to HOST something
> like 'hey do not send me data now', and of course 'send it now'.

I have made very little progress with my USB projects, but I believe
there are two levels of flow control that you might deal with. The
first is USB host-device flow control, and the second is flow control
that higher-level code on the host and device agree to perform. For
USB-level flow control, I think what happens is that when the host
wants to send data, it first sends an "OUT" transaction setup
sequence, then the device acknowledges it, and then the host sends the
data. If the device isn't ready to accept data, it NAKs (or maybe
STALLs?) and the host waits to send. I think this is the most
reliable way for a USB device to do flow control.

The other way, with a CDC-ACM device, is for the device to send
(Interrupt?) packets to notify the host that one of the control lines
has changed state. Normally, the USB device would also have a UART,
and the USB part would report UART state to the host, but if you're
doing a pseudo-serial device, you could fake the UART modem control
signals however you want. If the host software is configured to honor
hardware flow control indications, then the device could report "CTS
off" when it wanted the host to stop sending. However, if the host
software doesn't respect the flow control indications, then the USB
layer will happily send the data.

So, depending on which parts of the system you're working on (and have
access to the code for), you may decide to use USB or modem-control
flow control.
This is the old "windows CDC" issues again.

The windows implementation of CDC (usbser.sys) does not handle
handshaking signals reliably. I believe the Linux one does, as do most
of the 3rd party drivers to go with prolific or FTTI chipsets.

That said, I'm not sure if any actually implement flow control using
CTS/RTS. The other controls signals such as DTR/DST/DCD/RI etc should be
handled correctly and passed through as notify control, but flow control
would be better handled by the NAK process.

Since you are using CDC, and you probably want to handle connecting to a
Windows box, there really is only 1 choice left anyway.

Cheers,
Bruce
-----Original Message-----
From: l... [mailto:l...] On Behalf
Of thirdshoedrops
Sent: Friday, 28 November 2008 8:49 AM
To: l...
Subject: [lpc2000] Re: LPC2148 and USB CDC-ACM flow control with
usbser.sys

--- In l..., Wojciech Kromer
wrote:
> I mean how to stop HOST sending data being a DEVICE.
> I'm trying to run on a device typical flow control, and send from
DEVICE
> to HOST something
> like 'hey do not send me data now', and of course 'send it now'.

I have made very little progress with my USB projects, but I believe
there are two levels of flow control that you might deal with. The
first is USB host-device flow control, and the second is flow control
that higher-level code on the host and device agree to perform. For
USB-level flow control, I think what happens is that when the host
wants to send data, it first sends an "OUT" transaction setup
sequence, then the device acknowledges it, and then the host sends the
data. If the device isn't ready to accept data, it NAKs (or maybe
STALLs?) and the host waits to send. I think this is the most
reliable way for a USB device to do flow control.

The other way, with a CDC-ACM device, is for the device to send
(Interrupt?) packets to notify the host that one of the control lines
has changed state. Normally, the USB device would also have a UART,
and the USB part would report UART state to the host, but if you're
doing a pseudo-serial device, you could fake the UART modem control
signals however you want. If the host software is configured to honor
hardware flow control indications, then the device could report "CTS
off" when it wanted the host to stop sending. However, if the host
software doesn't respect the flow control indications, then the USB
layer will happily send the data.

So, depending on which parts of the system you're working on (and have
access to the code for), you may decide to use USB or modem-control
flow control.
Bruce Paterson pisze:
> This is the old "windows CDC" issues again.
>
> The windows implementation of CDC (usbser.sys) does not handle
> handshaking signals reliably. I believe the Linux one does, as do most
> of the 3rd party drivers to go with prolific or FTTI chipsets.
>
> That said, I'm not sure if any actually implement flow control using
> CTS/RTS. The other controls signals such as DTR/DST/DCD/RI etc should be
> handled correctly and passed through as notify control, but flow control
> would be better handled by the NAK process.
>
> Since you are using CDC, and you probably want to handle connecting to a
> Windows box, there really is only 1 choice left anyway.
>
Is there any other way to force NAK, except not reading EP data after
OUT interrupt?

>What is correct way to stop transmission from HOST to DEVICE?
> b) not reading data from EP causes NAK (it's OK) but it seems some
data are lost wit this way

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

--- In l..., Wojciech Kromer
wrote:
>
> Hello.
>
> I'm trying to use my own LPC2148 USB stack, and getting sick with
> usbser.sys.
> What is correct way to stop transmission from HOST to DEVICE?
>
> a) sending USB_CDC_NOTIFY_SERIAL_STATE with DSR off is not working with
> usbser.sys
> b) not reading data from EP causes NAK (it's OK) but it seems some data
> are lost wit this way
> c) stall-in EP, causes ERROR on USB
>
> Any suggestions?
> Some tricks with .inf file?
> Another CDC-ACM driver for windows?
>
> Regards.
>

> I believe there are two levels of flow control that you might deal with.

Splendid!!
You got a good view point which closes to the USB class essence.
Most of USB classes are designed to carry other protocols [*1]. For
CDC-ACM, USB carries RS232 signaling. CDC-ACM supposes that a MODEM
(UART) is attached to the other end. Therefore, the flow control of
RS232 (DTR-DSR, Xon-Xoff etc) doesn't concern to the USB side
directly. The MODEM does the flow control with an external device
connected to the MODEM. USB just carries the handshake signaling [*2].
Of course, we can connect any other peripheral to CDC-ACM instead of
MODEM. Or, we can connect some virtual device which is made up just on
the firmware. In these cases also, CDC-ACM supposes a virtual MODEM there.

Other than this protocol-level flow control, there is a USB
hardware-level flow control - NAKing. NAKing is an intrinsic flow
control of USB. NAKing is applied to Bulk, Interrupt and data stage of
Control transfer, to match the transfer speed between USB host and device.

The Wojciech problem is solved by NAKing.
Wojciech > What is correct way to stop transmission from HOST to DEVICE?

While the RX buffer on the firmware is full, don't read out data from
the bulk OUT endpoint. Just when there is enough space on the RX
buffer, read it out. While the OUT endpoint buffer is occupied, the
device USB engine returns NAK on OUT transaction. Host controller
repeats OUT transactions of the last contents until the engine ACKs,
unless the device driver stops it on timeout (SetCommTimeouts). In
this way, the data stream pauses without any data loss.

[*1] Protocols carried by USB class
Audio class: PCM, MPEG, AC-3, MIDI, etc
CCID class: Smart Card
Mass storage - BOT class: SCSI
Printer class: IEEE P1284
Still Image class: PTP (PIMA 15740)
USBTMC: VISA
Video: MPEG, H.264, DV, etc.

[*2] RS232 handshake carried by CDC-ACM
SetControlLineState request - RTS, DTR
SerialState notification - RI, DSR, DCD
-- note: CTS is not counted in CDC-ACM

Tsuneo

--- In l..., "thirdshoedrops" wrote:
>
> --- In l..., Wojciech Kromer
> wrote:
> > I mean how to stop HOST sending data being a DEVICE.
> > I'm trying to run on a device typical flow control, and send from
DEVICE
> > to HOST something
> > like 'hey do not send me data now', and of course 'send it now'.
>
> I have made very little progress with my USB projects, but I believe
> there are two levels of flow control that you might deal with. The
> first is USB host-device flow control, and the second is flow control
> that higher-level code on the host and device agree to perform. For
> USB-level flow control, I think what happens is that when the host
> wants to send data, it first sends an "OUT" transaction setup
> sequence, then the device acknowledges it, and then the host sends the
> data. If the device isn't ready to accept data, it NAKs (or maybe
> STALLs?) and the host waits to send. I think this is the most
> reliable way for a USB device to do flow control.
>
> The other way, with a CDC-ACM device, is for the device to send
> (Interrupt?) packets to notify the host that one of the control lines
> has changed state. Normally, the USB device would also have a UART,
> and the USB part would report UART state to the host, but if you're
> doing a pseudo-serial device, you could fake the UART modem control
> signals however you want. If the host software is configured to honor
> hardware flow control indications, then the device could report "CTS
> off" when it wanted the host to stop sending. However, if the host
> software doesn't respect the flow control indications, then the USB
> layer will happily send the data.
>
> So, depending on which parts of the system you're working on (and have
> access to the code for), you may decide to use USB or modem-control
> flow control.
>