EmbeddedRelated.com
Forums

A real virtual COM

Started by varuzhandanielyan February 1, 2007
The Philips example of virtual COM on USB is
virtual only looking from the PC side. Is there
any solution available, which looks like UART from
inside the microcontroller too? Functions like putchar,
getchar and other stdio functions.

Thanks in advance,
Varuzhan

An Engineer's Guide to the LPC2100 Series

--- In l..., "varuzhandanielyan" wrote:
>
> The Philips example of virtual COM on USB is
> virtual only looking from the PC side. Is there
> any solution available, which looks like UART from
> inside the microcontroller too? Functions like putchar,
> getchar and other stdio functions.
>
> Thanks in advance,
> Varuzhan
>
May be I did not understand your question. Why would you look for a
virtual COM port if you have between 2 and 4 real, physical COM ports
on the microcontroller itself. putchar and getchar work with the real
UARTs.

Did I miss something?

Bob
--- In l..., "lpc2100_fan" wrote:
>
> --- In l..., "varuzhandanielyan" wrote:
> >
> > The Philips example of virtual COM on USB is
> > virtual only looking from the PC side. Is there
> > any solution available, which looks like UART from
> > inside the microcontroller too? Functions like putchar,
> > getchar and other stdio functions.
> >
> > Thanks in advance,
> > Varuzhan
> >
> May be I did not understand your question. Why would you look for a
> virtual COM port if you have between 2 and 4 real, physical COM ports
> on the microcontroller itself. putchar and getchar work with the real
> UARTs.
>
> Did I miss something?
>
> Bob
>

For example I have software working with communication
between LPC UART and PC COM port. Now I want with minimal
changes adapt it to work with laptop, which does not have
COM port. I put a virtual COM driver on PC and need to change
getchar and putchar functions to work with USB. I want
the changes to be minimal and do not want to dig into the
USB stack.
One solution is to use ftdichip USB/UART converter chip,
but as the LPC214x and LPC23xx have an internal USB, I am
looking for simple software solution.
Thank you,
Varuzhan
--- In l..., "varuzhandanielyan" wrote:
> For example I have software working with communication
> between LPC UART and PC COM port. Now I want with minimal
> changes adapt it to work with laptop, which does not have
> COM port. I put a virtual COM driver on PC and need to change
> getchar and putchar functions to work with USB. I want
> the changes to be minimal and do not want to dig into the
> USB stack.
> One solution is to use ftdichip USB/UART converter chip,
> but as the LPC214x and LPC23xx have an internal USB, I am
> looking for simple software solution.
> Thank you,
> Varuzhan

I think I understand what you want.

LPCUSB is available for the the LPC214x, which has an excellent
virtual COM example. Homepage is here:

http://wiki.sikken.nl/index.php?title=Main_Page

I suggest you get build 142 from the SVN archive, not the older
version on Sourceforge which has a known bug (excessive interrupts
and thus load on processor, but otherwise harmless).

LPCUSB's VCOM example allows you to communicate over USB with the
VCOM driver on the PC, via simple character put and get functions,
and it also provides adjustable FIFO buffers. I don't think it's
directly stdio compatible, but it should be trivial to modify or
write a wrapper to achieve this, without any understanding of the USB
stack and with minimal changes to existing code.

My situation is similar to yours - I needed fast, simple serial
communications over USB, and I didn't want to dig into the USB
stack. One of the main reasons I selected the LPC2148 for my project
is because I knew of the existence of LPCUSB. I also considered
using a FTDI converter chip as a backup plan in case I couldn't get
LPCUSB to work, but LPCUSB has worked out very nicely indeed.
Thank you very much,

I downloaded your link and will try to run it.
But the wrapper you mentioned can be not so trivial
as you write. So I will highly appreciate if you
share your code. Be sure, that it is used in
scientific instrumentation, not commercial.

Best regards,
Varuzhan
--- In l..., "darkcobrax" wrote:
>
> --- In l..., "varuzhandanielyan" wrote:
> > For example I have software working with communication
> > between LPC UART and PC COM port. Now I want with minimal
> > changes adapt it to work with laptop, which does not have
> > COM port. I put a virtual COM driver on PC and need to change
> > getchar and putchar functions to work with USB. I want
> > the changes to be minimal and do not want to dig into the
> > USB stack.
> > One solution is to use ftdichip USB/UART converter chip,
> > but as the LPC214x and LPC23xx have an internal USB, I am
> > looking for simple software solution.
> > Thank you,
> > Varuzhan
>
> I think I understand what you want.
>
> LPCUSB is available for the the LPC214x, which has an excellent
> virtual COM example. Homepage is here:
>
> http://wiki.sikken.nl/index.php?title=Main_Page
>
> I suggest you get build 142 from the SVN archive, not the older
> version on Sourceforge which has a known bug (excessive interrupts
> and thus load on processor, but otherwise harmless).
>
> LPCUSB's VCOM example allows you to communicate over USB with the
> VCOM driver on the PC, via simple character put and get functions,
> and it also provides adjustable FIFO buffers. I don't think it's
> directly stdio compatible, but it should be trivial to modify or
> write a wrapper to achieve this, without any understanding of the USB
> stack and with minimal changes to existing code.
>
> My situation is similar to yours - I needed fast, simple serial
> communications over USB, and I didn't want to dig into the USB
> stack. One of the main reasons I selected the LPC2148 for my project
> is because I knew of the existence of LPCUSB. I also considered
> using a FTDI converter chip as a backup plan in case I couldn't get
> LPCUSB to work, but LPCUSB has worked out very nicely indeed.
>
--- In l..., "varuzhandanielyan" wrote:
>
> Thank you very much,
>
> I downloaded your link and will try to run it.
> But the wrapper you mentioned can be not so trivial
> as you write. So I will highly appreciate if you
> share your code. Be sure, that it is used in
> scientific instrumentation, not commercial.
>
> Best regards,
> Varuzhan

I could be wrong, but it sounds simple since from what you describe,
there already exists a stdio-compatible "wrapper" in your application
that directs everything to the UART. All i/o essentially breaks down
to just putting or getting individual characters.

In LPCUSB VCOM, functions VCOM_putchar and VCOM_getchar in
main_serial.c perform these functions. Start by redirecting the
existing UART putchar/getchar functions to these.

Also look into implementing/modifying __putchar to direct to
VCOM_putchar, which I think will give you printf support.

At this point, I'm working on building up some custom hardware. My
software hasn't gotten beyond getting LPCUSB VCOM to work, and stress-
testing it to ensure it will perform reliably in my planned use (it
will), so I don't have any useful code to share at this time.
Sorry for my intrusion.

--- In l..., "darkcobrax" wrote:
> My situation is similar to yours - I needed fast, simple serial
> communications over USB, and I didn't want to dig into the USB
> stack. One of the main reasons I selected the LPC2148 for my project
> is because I knew of the existence of LPCUSB. I also considered
> using a FTDI converter chip as a backup plan in case I couldn't get
> LPCUSB to work, but LPCUSB has worked out very nicely indeed.

Surely, the VCOM example hides the complicated USB enumeration thingy,
but if you need fast communication, you should know the USB
characteristic under the VCOM implementation.

I've observed 600-800 KBtyes/sec of max transfer speed on full-speed
USB devices like LPC2148, on WinXP SP2 VCOM using its built-in
usbser.sys device driver. But this top speed is not always achieved.
Just when the transfer size is appropriately selected, you'll see the
top speed.

On the PC side, a single WriteFile() call to the VCOM port corresponds
to single transfer.
On the serial side, interval between data bytes delimits transfer.

When you send data one byte by one, ie. transfer size is one byte, you
don't see more than 1 Kbytes/sec transfer speed. While the transfer
size increases, the transfer speed also increases proportionally to
the transfer size. And when the transfer size reaches to 600-800
bytes, you'll see the top speed. The top speed (and the optimum
transfer size) depends on the PC.

When the transfer size increases more, the transfer speed suddenly
decreases to about half. And then transfer speed increases slowly
along with transfer size. You'll see the second peak of the speed at
the twice of the first optimum transfer size.

This phenomena is explained by the fact that every USB transfer occurs
on a new 1 msec USB frame.
When the transfer size is one byte, USB can carry just one byte on
every frame; 1 Kbytes/sec. Transfer speed increases until the transfer
size fills an USB frame. When the size exceeds single USB frame even
by one byte, the transfer occupies two USB frames. So, the speed
decreases to half.

Here, I explained it without USB terms as possible. It may not be
exact in the strict sense, but I hope you get the outline.

Tsueno
t_chinzei wrote:
> Sorry for my intrusion.
>
> --- In l..., "darkcobrax" wrote:
>> My situation is similar to yours - I needed fast, simple serial
>> communications over USB, and I didn't want to dig into the USB
>> stack. One of the main reasons I selected the LPC2148 for my project
>> is because I knew of the existence of LPCUSB. I also considered
>> using a FTDI converter chip as a backup plan in case I couldn't get
>> LPCUSB to work, but LPCUSB has worked out very nicely indeed.
>
> Surely, the VCOM example hides the complicated USB enumeration thingy,
> but if you need fast communication, you should know the USB
> characteristic under the VCOM implementation.
>
> I've observed 600-800 KBtyes/sec of max transfer speed on full-speed
> USB devices like LPC2148, on WinXP SP2 VCOM using its built-in
> usbser.sys device driver. But this top speed is not always achieved.
> Just when the transfer size is appropriately selected, you'll see the
> top speed.
>
> On the PC side, a single WriteFile() call to the VCOM port corresponds
> to single transfer.
> On the serial side, interval between data bytes delimits transfer.
>
> When you send data one byte by one, ie. transfer size is one byte, you
> don't see more than 1 Kbytes/sec transfer speed. While the transfer
> size increases, the transfer speed also increases proportionally to
> the transfer size. And when the transfer size reaches to 600-800
> bytes, you'll see the top speed. The top speed (and the optimum
> transfer size) depends on the PC.
>
> When the transfer size increases more, the transfer speed suddenly
> decreases to about half. And then transfer speed increases slowly
> along with transfer size. You'll see the second peak of the speed at
> the twice of the first optimum transfer size.
>
> This phenomena is explained by the fact that every USB transfer occurs
> on a new 1 msec USB frame.
> When the transfer size is one byte, USB can carry just one byte on
> every frame; 1 Kbytes/sec. Transfer speed increases until the transfer
> size fills an USB frame. When the size exceeds single USB frame even
> by one byte, the transfer occupies two USB frames. So, the speed
> decreases to half.
>
> Here, I explained it without USB terms as possible. It may not be
> exact in the strict sense, but I hope you get the outline.

Some time ago I did some benchmarks with the lpcusb stack and
I just put my results online here:
http://wiki.sikken.nl/index.php?title=LPCUSB#Benchmarks

I agree with you mostly, but I haven't seen the phenomenon that
you describe (speed dropping to half). The curves do show a point
where increasing the block size from 512 to 1024 bytes apparently
doesn't increase the throughput (it stays about the same). See the
'nec ohci' curve.

Very funny things happen if you connect the LPC2148 (a full-speed
device) through a high-speed hub to a high-speed host controller.
In that case the throughput is much higher for small blocksizes.

Kind regards,
Bertrik
--- In l..., Bertrik Sikken wrote:
> Some time ago I did some benchmarks with the lpcusb stack and
> I just put my results online here:
> http://wiki.sikken.nl/index.php?title=LPCUSB#Benchmarks
>
> I agree with you mostly, but I haven't seen the phenomenon that
> you describe (speed dropping to half). The curves do show a point
> where increasing the block size from 512 to 1024 bytes apparently
> doesn't increase the throughput (it stays about the same). See the
> 'nec ohci' curve.
When you take more sample points between the block size of 512 and
1024, you'll see the first dip. For example, when the first peak
appears at the block size of 640 bytes (10 full packets + ZLP), the
second peak will show up on 1280 bytes. And the peaks repeat in every
640 bytes. As a whole, the curve shows saw-tooth, gradually flatten on
greater block size.

The reasons you cannot see this saw-tooth curve is that the block size
increases in power of 2, non linear. The series of power of 2, such as
1024-2048-4096 is too rough to catch the cycle.

If you have a hardware USB bus analyzer, you'll easily confirm that a
transfer always starts in a new USB frame.

> Very funny things happen if you connect the LPC2148 (a full-speed
> device) through a high-speed hub to a high-speed host controller.
> In that case the throughput is much higher for small blocksizes.
I described on full-speed bus behavior so far.
When a full-speed (FS) device is connected to EHCI over high-speed
(HS) hub, a transaction translator (TT) on the hub works. TT can issue
multiple transfers gathered from up-stream HS side to the FS device in
a single USB frame. That is why you see the 'funny' behavior.

Tsuneo
--- In l..., "t_chinzei" wrote:
>
> Sorry for my intrusion.
>
> Surely, the VCOM example hides the complicated USB enumeration
thingy,
> but if you need fast communication, you should know the USB
> characteristic under the VCOM implementation.

It was a welcome intrusion. That's a great description, and I've
saved it to my notes for future reference. It also matches and
explains the results of my own stress testing.

I used "fast" as a relative term, meaning "faster than UART".
Implementing my project over UART is possible, but would require
limiting some functions and/or using some tricky data packing. With
USB I won't have to worry about such things, since I'll never come
close to the max.