EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Re: LPCusb with crossworks

Started by pete...@esysr.com November 22, 2008
Hello everyone,
>
>I am attempting to use the lpcusb library available on sourceforge
>with an Olimex LPC-P2148 board and crossworks. I have been able to
>set up a project that builds the virtual com example just fine and
>shows the appropriate startup text on the console upon startup:
>
>Initialising USB stack
>Registered handler for device status
>Registered handler for EP 0x0
>Registered handler for EP 0x80
>Registered handler for EP 0x81
>Registered handler for EP 0x82
>Registered handler for EP 0x5
>Starting USB communication
>
>When I connect the board via USB, windows will say its found an
>unknown USB device, never asking for a driver. During this time the
>LPC2148 usually ends up at an abort handler.
>
>There seems to be very little documentation for the library so at this
>point I'm kinda guessing at what has to be done. If anyone has used
>this with Crossworks I would very much like to hear how you set up the
>project.

Did anyone ever get LPCUSB to work with Crossworks interrupts? I am using the latest SVN trunk version of LPCUSB (Revision 172) with the VCON example ported to run as a task using CTL. Since the example just polls for characters I added a ctl_timeout_wait at the end of the loop. My program dumps into ctl_handle_error when I let it run. The error passed to ctl_handle_error is CTL_UNSUPPORTED_CAL_FROM_ISR, but this not in an ISR at this point.

LPCUSB seems to be initilaizing just fine, here is what gets reported at start up:

Initialising USB stack
Registered handler for device status
Registered handler for EP 0x0
Registered handler for EP 0x80
Registered handler for EP 0x81
Registered handler for EP 0x82
Registered handler for EP 0x5
Registered handler for frame
Registered handler for device status
Starting USB communication
I have increased my stack sizes to 256 bytes and it look like I still have 50 bytes left at the deepest point.

I am just starting with Crossworks, but other ISRs I have implemented worked fine. Any example code for LPCUSB with Crossworks would be most
appreciated.

Pete

An Engineer's Guide to the LPC2100 Series

p...@esysr.com wrote:
> Did anyone ever get LPCUSB to work with Crossworks interrupts? I am using the latest SVN trunk version of LPCUSB (Revision 172) with the VCON example ported to run as a task using CTL. Since the example just polls for characters I added a ctl_timeout_wait at the end of the loop. My program dumps into ctl_handle_error when I let it run. The error passed to ctl_handle_error is CTL_UNSUPPORTED_CAL_FROM_ISR, but this not in an ISR at this point.
>
Hi Pete

I'm just about to tackle this today. I got the HID and MSD examples
running with crossworks, however I found it's unreliable when the call
to USBHwISR is put in a task. In the demos this is called in the main
loop, however I wanted to take advantage of CTL, but it's proving
difficult to use. I tried putting the call in a task, and having it call
ctl_timeout_wait so that other loweer priority task get a chance, but
any calls to ctl_timeout_wait in the same task as the call to USBHwISR
results in usb not enumerating at all. I looked at the FreeRTOS example
which does use interrupts and was hoping to try that method. I'll post
my results here later.

--
Regards

Vincent Parrett

VSoft Technologies Pty Ltd
http://www.finalbuilder.com
Blog: http://www.finalbuilder.com/blogs.aspx
Automate your Software builds with FinalBuilder.
p...@esysr.com wrote:
> I have increased my stack sizes to 256 bytes and it look like I still have 50 bytes left at the deepest point.
>
> I am just starting with Crossworks, but other ISRs I have implemented worked fine. Any example code for LPCUSB with Crossworks would be most
> appreciated.
>

Hi Pete

I spent a frustrating day working on this... most of which was wasted
trying to figure out why my port 1 gpio's suddenly stopped working
(still trying to figure that out!). Anyway, I did get the usb isr
working. I currenty have 2 ctl tasks, one just flashes an led and the
other reads a bunch of gpio pins (buttons and alps rotary encoders).

This is my usb init routine (for a composite HID + MSD device, adjust
accordingly) :

void G1000_USBInit(void)
{
ctl_global_interrupts_disable();

// ConsoleInit(60000000 / (16 * BAUD_RATE));

DBG("Initialising Block Dev\n");
// initialise the SD card
BlockDevInit();

DBG("Initialising USB stack\n");
// initialise stack
USBInit();

// enable bulk-in interrupts on NAKs
// these are required to get the BOT protocol going again after a STALL
USBHwNakIntEnable(INACK_BI);

// register device descriptors
USBRegisterDescriptors(abDescriptors);

// register HID standard request handler
USBRegisterCustomReqHandler(HIDHandleStdReq);

// register class request handler
USBRegisterRequestHandler(REQTYPE_TYPE_CLASS, HandleClassRequest,
abClassReqData);

// register endpoint
USBHwRegisterEPIntHandler(INTR_IN_EP, NULL);

// register endpoint handlers
USBHwRegisterEPIntHandler(MSC_BULK_IN_EP, MSCBotBulkIn);
USBHwRegisterEPIntHandler(MSC_BULK_OUT_EP, MSCBotBulkOut);
// register frame handler
USBHwRegisterFrameHandler(HandleFrame);

//usbSetupInterruptHandler ();
DBG("Starting USB communication\n");

ctl_set_isr(22, 22, CTL_ISR_TRIGGER_FIXED, usb_isr, 0);
ctl_unmask_isr(22);
ctl_global_interrupts_enable();
USBHwConnect(TRUE);
}

And my isr :

static void usb_isr(void)
{
ctl_global_interrupts_re_enable_from_isr();
USBHwISR();
ctl_global_interrupts_un_re_enable_from_isr();
}

It all seems to be working well at the moment. I don't have any other
isr's in my code, but I'm about to add an spi port expander into the mix
with interupt on change (23S17) so that should be fun :)

HTH
--
Regards

Vincent Parrett

VSoft Technologies Pty Ltd
http://www.finalbuilder.com
Blog: http://www.finalbuilder.com/blogs.aspx
Automate your Software builds with FinalBuilder.
--- In l..., Vincent Parrett wrote:
>
> pete.klemm@... wrote:
> > Did anyone ever get LPCUSB to work with Crossworks interrupts? I
am using the latest SVN trunk version of LPCUSB (Revision 172) with
the VCON example ported to run as a task using CTL. Since the example
just polls for characters I added a ctl_timeout_wait at the end of the
loop. My program dumps into ctl_handle_error when I let it run. The
error passed to ctl_handle_error is CTL_UNSUPPORTED_CAL_FROM_ISR, but
this not in an ISR at this point.
> >
> Hi Pete
>
> I'm just about to tackle this today. I got the HID and MSD examples
> running with crossworks, however I found it's unreliable when the call
> to USBHwISR is put in a task. In the demos this is called in the main
> loop, however I wanted to take advantage of CTL, but it's proving
> difficult to use. I tried putting the call in a task, and having it
call
> ctl_timeout_wait so that other loweer priority task get a chance, but
> any calls to ctl_timeout_wait in the same task as the call to USBHwISR
> results in usb not enumerating at all. I looked at the FreeRTOS example
> which does use interrupts and was hoping to try that method. I'll post
> my results here later.
>

You might as well forget about such trials. You cannot handle a
high-speed peripheral under an RTOS by continually polling from a
thread with waits. It is hugely inefficient and, well, just won't
work. That said, the OP's CTL_UNSUPPORTED_CALL_FROM_ISR is not
something I would have expected - I would have thought that really bad
throughput accompanied by continual 'overrun/timeout' type errors from
the stack would be more likely.

If you do not have interrupt-driven I/O, there is no point in using an
RTOS at all - fast and efficient response to interrupt signals is the
best trick that a preemptive RTOS has - you must take advantage of it.

I have not found Rowley ctl to be particularly difficult to use. It
provides all the basic RTOS services I would expect. I have had no
problems with it except my own bugs.

Best approach I've found so far for these little uC with tiny RAM is
to use one high-priority thread for I/O that waits on a semaphore with
a timeout. Any ISR or other thread that needs I/O action posts a unit
to the semaphore. The I/O thread then polls a thread-safe input
queue, (to see if other threads have posted an output request -
another semaphore needed to protect the queue), all ISR output queues
to see if any rx data buffers have been posted for forwarding or any
tx data buffers need to be repooled/freed, and a buffer-supply queue
for the receive ISRs to ensure it's topped-up. The timed/periodic
actions that are probably needed can be handled by another queue/list
containing timed-actions that the thread iterates on every run to see
if anything has timed-out,
(currentTickCount-timedAction->timeoutTickCount), executes it if it
has, calculates the shortest timeout-time if all the remaining
timeout-actions to use for the next semaphore wait. I prefer a
straight list because, with the typical number of timed actions on a
uC, iterating the list on every run doesn't take that long and it
eliminates the insertion sort needed by a delta-queue.

It would be nice if the thread could wake up and 'know' what action is
expected of it without polling the various signal sources, (like
Windows WaitForMultipleObjects API), but this is a bit of an ask for a
uC RTOS.

Rgds,
Martin

Hi,

> It would be nice if the thread could wake up and 'know' what action is
> expected of it without polling the various signal sources, (like
> Windows WaitForMultipleObjects API), but this is a bit of an ask for a
> uC RTOS.

...that's what CTL events are for...

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors

--- In l..., "Paul Curtis" wrote:
>
> Hi,
>
> > It would be nice if the thread could wake up and 'know' what action is
> > expected of it without polling the various signal sources, (like
> > Windows WaitForMultipleObjects API), but this is a bit of an ask for a
> > uC RTOS.
>
> ...that's what CTL events are for...
>

I had forgotten about events:(

I have not used them in my project because the events have no count.
Without a count, there can be conditions where an event is signaled
twice before the handling thread runs and so one signal gets lost.

Rgds,
Martin

mjames_doveridge schrieb:

> I had forgotten about events:(
>
> I have not used them in my project because the events have no count.
> Without a count, there can be conditions where an event is signaled
> twice before the handling thread runs and so one signal gets lost.

Use (direct) message passing :-) instead of events.
http://www.google.de/search?q=direct+message+passing
--
42Bastian

Note: SPAM-only account, direct mail to bs42@...

Hi Martin,

> > > It would be nice if the thread could wake up and 'know' what action is
> > > expected of it without polling the various signal sources, (like
> > > Windows WaitForMultipleObjects API), but this is a bit of an ask for a
> > > uC RTOS.
> >
> > ...that's what CTL events are for...
> > I had forgotten about events:(
>
> I have not used them in my project because the events have no count.
> Without a count, there can be conditions where an event is signaled
> twice before the handling thread runs and so one signal gets lost.

Whilst they have no count they can be used to wait for multiple sources to
be "ready". In the next version of CTL (after V2), you'll see more
functionality (hate that word).

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors

Hi,

> mjames_doveridge schrieb:
>
> > I had forgotten about events:(
> >
> > I have not used them in my project because the events have no count.
> > Without a count, there can be conditions where an event is signaled
> > twice before the handling thread runs and so one signal gets lost.
>
> Use (direct) message passing :-) instead of events.
> http://www.google.de/search?q=direct+message+passing

...wow, a (buffered) channel... ;-) There's nothing new under the sun.
:-)

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors

Paul Curtis schrieb:

>> Use (direct) message passing :-) instead of events.
>> http://www.google.de/search?q=direct+message+passing
>
> ...wow, a (buffered) channel... ;-) There's nothing new under the sun.
> :-)

Sometimes names change.

But it sounded like buffering/queueing was what the OP needed.

BTW: The event-tutorial code on you site has a bug/flaw:

void task1(void *p)
{
for (;;
{
unsigned e;
e = ctl_events_wait(CTL_EVENT_WAIT_ANY_EVENTS_AUTO_CLEAR,
&e1,
1 | 2,
0, 0);
if (e & 1)
{
// ISRfn1 completed
}
else if (e & 2)
{
// ISRfn2 completed
}
else
{
// error
}
}
}

If the two events happen _before_ task1 is swapped in, ctl_events_wait()
needs to be called twice.
I would not do the "else if".

--
42Bastian

Note: SPAM-only account, direct mail to bs42@...


Memfault Beyond the Launch