Reply by Bill Knight May 3, 20072007-05-03
boB
It should not be a problem. A received 0xFF byte is different from
an EOF (0xFFFF). VCOM_getchar() returns an int.

Regards
-Bill Knight
R O SoftWare
bobtransformer wrote:
> Thanks Tsuneo...
>
> I will need to transfer binary data through this scheme so I'm not
> sure exactly what to do about the EOF (-1) character...
> If it is the only byte transferred, or the 63rd byte then
> that's OK.
>
> I also do not need high speed. Something like 19.2K or 38 K baud
> is fine.
>
> I have more looking through the code to do.
>
> Thank you for all of your previous and current help on this.
>
> boB
> --- In l..., "t_chinzei" wrote:
>> Hello boB,
>>
>>> Whenever I plug in the USB connector to the laptop,
>>> everything slows way down.
>> The "the interrupt flood bug" is caused by the NAK interrupt.
>> NAK interrupt is indeterminate. When the USB bus is idle, you'll see
>> 20-30 IN-NAK within 1msec USB frame. But when the bus is populated,
>> very few IN-NAK occur. Maybe Bertrik weren't aware of this NAK
>> indeterminacy when he designed the stack. Usually, just SOF interrupt
>> is applied for this implementation, as I showed on this post.
>> http://tech.groups.yahoo.com/group/lpc2000/message/23334
>>> I also notice that the VCOM_getchar() always gives me 0xFF
>>> if the USB cable is unplugged,
>> It's obvious from this VCOM_getchar() and fifo_get() implementation.
>>
>> main_serial.c
>> #define EOF (-1)
>>
>> int VCOM_getchar(void)
>> {
>> U8 c;
>>
>> return fifo_get(&rxfifo, &c) ? c : EOF;
>> }
>> serial_fifo.c
>> BOOL fifo_get(fifo_t *fifo, U8 *pc)
>> {
>> int next;
>>
>> // check if FIFO has data
>> if (fifo->head == fifo->tail) {
>> return FALSE;
>> }
>>
>> next = (fifo->tail + 1) % VCOM_FIFO_SIZE;
>>
>> *pc = fifo->buf[fifo->tail];
>> fifo->tail = next;
>>
>> return TRUE;
>> }
>> If you don't want to get EOF (0xFF), check the FIFO status before
>> reading out the data by VCOM_getchar(), using this kind of subroutine.
>>
>> BOOL fifo_ready( fifo_t *fifo )
>> {
>> return !(fifo->head == fifo->tail);
>> }
>>
>> Tsuneo
>>
>> --- In l..., "bobtransformer" wrote:
>>>
>>>> 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).
>>>
>>> I think I've got this buggy version... Whenever I plug in the
>>> USB connector to the laptop, everything slows way down.
>>>
>>> Is it correct that main_serial.c is the only file that has to
>>> be changed to get rid of the interrupt flood bug ?????
>>>
>>> I have LPCUSB running on IAR EWARM and have it combined with
>>> RS232 functions for my bootloader software. I noticed that when
>>> I set up a counter in a main while(1) loop and just output
>>> the count value through the RS232 that as soon as I plug in that
>>> cable it slows down about 10 times. I also notice that the
>>> VCOM_getchar() always gives me 0xFF if the USB cable is unplugged,
>>> which I hope I might be able to figure out. I'm still gathering some
>>> good info from the previous threads, but it looks like I have a little
>>> ways to go yet.
>>>
>>> thanks,
>>> boB
>>>
>>>
>>> --- In l..., "darkcobrax" wrote:
>>>> --- 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.
>>>>

An Engineer's Guide to the LPC2100 Series

Reply by bobtransformer May 3, 20072007-05-03
Thanks Tsuneo...

I will need to transfer binary data through this scheme so I'm not
sure exactly what to do about the EOF (-1) character...
If it is the only byte transferred, or the 63rd byte then
that's OK.

I also do not need high speed. Something like 19.2K or 38 K baud
is fine.

I have more looking through the code to do.

Thank you for all of your previous and current help on this.

boB
--- In l..., "t_chinzei" wrote:
>
> Hello boB,
>
> > Whenever I plug in the USB connector to the laptop,
> > everything slows way down.
>
> The "the interrupt flood bug" is caused by the NAK interrupt.
> NAK interrupt is indeterminate. When the USB bus is idle, you'll see
> 20-30 IN-NAK within 1msec USB frame. But when the bus is populated,
> very few IN-NAK occur. Maybe Bertrik weren't aware of this NAK
> indeterminacy when he designed the stack. Usually, just SOF interrupt
> is applied for this implementation, as I showed on this post.
> http://tech.groups.yahoo.com/group/lpc2000/message/23334
> > I also notice that the VCOM_getchar() always gives me 0xFF
> > if the USB cable is unplugged,
>
> It's obvious from this VCOM_getchar() and fifo_get() implementation.
>
> main_serial.c
> #define EOF (-1)
>
> int VCOM_getchar(void)
> {
> U8 c;
>
> return fifo_get(&rxfifo, &c) ? c : EOF;
> }
> serial_fifo.c
> BOOL fifo_get(fifo_t *fifo, U8 *pc)
> {
> int next;
>
> // check if FIFO has data
> if (fifo->head == fifo->tail) {
> return FALSE;
> }
>
> next = (fifo->tail + 1) % VCOM_FIFO_SIZE;
>
> *pc = fifo->buf[fifo->tail];
> fifo->tail = next;
>
> return TRUE;
> }
> If you don't want to get EOF (0xFF), check the FIFO status before
> reading out the data by VCOM_getchar(), using this kind of subroutine.
>
> BOOL fifo_ready( fifo_t *fifo )
> {
> return !(fifo->head == fifo->tail);
> }
>
> Tsuneo
>
> --- In l..., "bobtransformer" wrote:
> >
> >
> > > 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).
> >
> >
> > I think I've got this buggy version... Whenever I plug in the
> > USB connector to the laptop, everything slows way down.
> >
> > Is it correct that main_serial.c is the only file that has to
> > be changed to get rid of the interrupt flood bug ?????
> >
> > I have LPCUSB running on IAR EWARM and have it combined with
> > RS232 functions for my bootloader software. I noticed that when
> > I set up a counter in a main while(1) loop and just output
> > the count value through the RS232 that as soon as I plug in that
> > cable it slows down about 10 times. I also notice that the
> > VCOM_getchar() always gives me 0xFF if the USB cable is unplugged,
> > which I hope I might be able to figure out. I'm still gathering some
> > good info from the previous threads, but it looks like I have a little
> > ways to go yet.
> >
> > thanks,
> > boB
> >
> >
> >
> >
> >
> > --- In l..., "darkcobrax" wrote:
> > >
> > > --- 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.
> > >
>
Reply by t_chinzei May 3, 20072007-05-03
Hello boB,

> Whenever I plug in the USB connector to the laptop,
> everything slows way down.

The "the interrupt flood bug" is caused by the NAK interrupt.
NAK interrupt is indeterminate. When the USB bus is idle, you'll see
20-30 IN-NAK within 1msec USB frame. But when the bus is populated,
very few IN-NAK occur. Maybe Bertrik weren't aware of this NAK
indeterminacy when he designed the stack. Usually, just SOF interrupt
is applied for this implementation, as I showed on this post.
http://tech.groups.yahoo.com/group/lpc2000/message/23334
> I also notice that the VCOM_getchar() always gives me 0xFF
> if the USB cable is unplugged,

It's obvious from this VCOM_getchar() and fifo_get() implementation.

main_serial.c
#define EOF (-1)

int VCOM_getchar(void)
{
U8 c;

return fifo_get(&rxfifo, &c) ? c : EOF;
}
serial_fifo.c
BOOL fifo_get(fifo_t *fifo, U8 *pc)
{
int next;

// check if FIFO has data
if (fifo->head == fifo->tail) {
return FALSE;
}

next = (fifo->tail + 1) % VCOM_FIFO_SIZE;

*pc = fifo->buf[fifo->tail];
fifo->tail = next;

return TRUE;
}
If you don't want to get EOF (0xFF), check the FIFO status before
reading out the data by VCOM_getchar(), using this kind of subroutine.

BOOL fifo_ready( fifo_t *fifo )
{
return !(fifo->head == fifo->tail);
}

Tsuneo

--- In l..., "bobtransformer" wrote:
> > 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).
> I think I've got this buggy version... Whenever I plug in the
> USB connector to the laptop, everything slows way down.
>
> Is it correct that main_serial.c is the only file that has to
> be changed to get rid of the interrupt flood bug ?????
>
> I have LPCUSB running on IAR EWARM and have it combined with
> RS232 functions for my bootloader software. I noticed that when
> I set up a counter in a main while(1) loop and just output
> the count value through the RS232 that as soon as I plug in that
> cable it slows down about 10 times. I also notice that the
> VCOM_getchar() always gives me 0xFF if the USB cable is unplugged,
> which I hope I might be able to figure out. I'm still gathering some
> good info from the previous threads, but it looks like I have a little
> ways to go yet.
>
> thanks,
> boB
>
> --- In l..., "darkcobrax" wrote:
> >
> > --- 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.
>
Reply by bobtransformer May 2, 20072007-05-02
> 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).
I think I've got this buggy version... Whenever I plug in the
USB connector to the laptop, everything slows way down.

Is it correct that main_serial.c is the only file that has to
be changed to get rid of the interrupt flood bug ?????

I have LPCUSB running on IAR EWARM and have it combined with
RS232 functions for my bootloader software. I noticed that when
I set up a counter in a main while(1) loop and just output
the count value through the RS232 that as soon as I plug in that
cable it slows down about 10 times. I also notice that the
VCOM_getchar() always gives me 0xFF if the USB cable is unplugged,
which I hope I might be able to figure out. I'm still gathering some
good info from the previous threads, but it looks like I have a little
ways to go yet.

thanks,
boB

--- In l..., "darkcobrax" wrote:
>
> --- 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.
>
Reply by bobtransformer May 2, 20072007-05-02
> 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).
I think I've got this buggy version... Whenever I plug in the
USB connector to the laptop, everything slows way down.

Is it correct that main_serial.c is the only file that has to
be changed to get rid of the interrupt flood bug ?????

I have LPCUSB running on IAR EWARM and have it combined with
RS232 functions for my bootloader software. I noticed that when
I set up a counter in a main while(1) loop and just output
the count value through the RS232 that as soon as I plug in that
cable it slows down about 10 times. I also notice that the
VCOM_getchar() always gives me numbers, which I hope I might
be able to figure out. I'm still gathering some good info from
the previous threads, but it looks like I have a little ways
to go yet.

thanks,
boB

--- In l..., "darkcobrax" wrote:

> 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.
>
Reply by darkcobrax February 10, 20072007-02-10
--- 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.
Reply by t_chinzei February 10, 20072007-02-10
--- 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
Reply by Bertrik Sikken February 10, 20072007-02-10
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
Reply by t_chinzei February 10, 20072007-02-10
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
Reply by darkcobrax February 9, 20072007-02-09
--- 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.