EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

those crazy interrupts (2138)

Started by WadeA & RebeccaM Smith March 10, 2009
On Wed, 11 Mar 2009, J.C. Wren wrote:

> Excuse my distrust, but after creating the lpc214x.h file for the LPC2148
> demo code, and having people find a couple errors in it, I'm naturally
> suspicious.

I'll bet you mean things like how I2CXSCLL/H should be (unsigned long *)
instead of the incorrect (unsigned short *) that ate up a good 2 hrs of
head-scratching. :-\

-Kenny

--
Kenneth R. Crudup Sr. SW Engineer, Scott County Consulting, Los Angeles
O: 3630 S. Sepulveda Blvd. #138, L.A., CA 90034-6809 (888) 454-8181

An Engineer's Guide to the LPC2100 Series

As a matter of fact, I do have VECTORED_IRQ_INTERRUPTS set in Properties (common) Preprocessor Options -> Preprocessor definitions.

However, for UART0 it does not matter how I set that. ???
I tried it both ways and no problem with UART0. UART1 dies if it exists. Oh, well, I didn't need my sanity anyway.

--- In l..., "Paul Curtis" wrote:
>
> Wade,
>
> > "Common misconception is that using ctl_set_isr is somehow related to
> using
> > the CTL library". Actually, that is EXACTLY what I thought. And since I
> > wasn't using the CTaskingLibrary, I went and modified the Rowley uart
> > example code and "manually" set up the VIC.
> >
> > OK. The results are in. No change. As long as I do not call
> > "ctl_unmask_isr(VIC_CTRL_UART1);" everything works as normal. If I call
> > that and unmask UART1 ISR, la la land, i.e., abort, as soon as I enable
> > IRQs.
> >
> > Ideas? What should I change in the Rowley uart example to make uart1
> > happy? Is it THAT much different than uart0?
> > Timer:
> > ------------ start of code ------------
> > void timer0_isr(void) __attribute__ ((interrupt ("IRQ")));
> > void tmr1_ISR(void) __attribute__ ((interrupt ("IRQ")));
> > void RTC_ISR(void) __attribute__ ((interrupt ("IRQ")));
>
> By default the function you pass into ctl_set_isr must not have the IRQ
> attribute on them, in general.
>
> Exception: if you have set VECTORED_IRQ_INTERRUPTS in the LPC2k startup code
> then they *must* have those attributes as the IRQs are processed using the
> VIC.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>

Yup. After I sent the function I got to thinking that maybe when you said "prologue", that may be what I call the "prototype". Communication gap between you and the uneducated. :-)

--- In l..., Kenneth Crudup wrote:
> On Wed, 11 Mar 2009, WadeA & RebeccaM Smith wrote:
>
> > void timer0_isr(void) __attribute__ ((interrupt ("IRQ")));
> > void tmr1_ISR(void) __attribute__ ((interrupt ("IRQ")));
> > void RTC_ISR(void) __attribute__ ((interrupt ("IRQ")));
>
> > void uart0ISR(void) __attribute__ ((interrupt ("IRQ")));
> > void uart1ISR(void) __attribute__ ((interrupt ("IRQ")));
>
> Wait- when I asked you for prologues earlier you'd posted something else?
>
> -Kenny
>
> --
> Kenneth R. Crudup Sr. SW Engineer, Scott County Consulting, Los Angeles
> O: 3630 S. Sepulveda Blvd. #138, L.A., CA 90034-6809 (888) 454-8181
>

Oops. I misspoke. Instead of saying that I copied all of the UART0 functions and made them UART1, I should have said that all of the UART1 functions were copied and changed to UART0.

The code I used as a basis for uart.c was the Crossfire_2138 uart example. Recognize it? (see below)

It worked fine on the Crossfire_2138. So now I'm trying it with 2 uarts running. Not much success. The irony is that the UART that worked on the Crossfire_2138 won't work elsewhere.

suggestions?

wade

------------ start of code ------------
// Copyright (c) 2005 Rowley Associates Limited.
//
// This file may be distributed under the terms of the License Agreement
// provided with this software.
//
// THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
//
// Philips LPC2000 - UART1 Example
//
// Description
// -----------
// This example demonstrates configuring and writing to a UART and generating
// an interrupt on arrival of data. It also demonstrates how to get printf
// output over the UART by implementing __putchar.
//
// To see output:
// - Connect serial cable from UART1/COM1 connector on your target board to your
// host computer.
// - Open CrossStudio's "Terminal Emulator Window". Configure it to 9600 baud,
// 8 data bits, no parity, 1 stop bits. Click "Connect" to start the
// terminal emulator window.
//
////////////////////////////////////////////////////////////////////////////////

#include
#include
#include

static unsigned char rxchar;
(snip)

static void
uartISR(void)
{
/* Read IIR to clear interrupt and find out the cause */
unsigned iir = U1IIR;

/* Handle UART interrupt */
switch ((iir >> 1) & 0x7)
{
case 1:
/* THRE interrupt */
break;
case 2:
/* RDA interrupt */
rxchar = U1RBR;
break;
case 3:
/* RLS interrupt */
break;
case 6:
/* CTI interrupt */
break;
}
}
void
UARTInitialize(unsigned int baud)
{
/* Configure UART */
unsigned int divisor = liblpc2000_get_pclk(liblpc2000_get_cclk(OSCILLATOR_CLOCK_FREQUENCY)) / (16 * baud);
U1LCR = 0x83; /* 8 bit, 1 stop bit, no parity, enable DLAB */
U1DLL = divisor & 0xFF;
U1DLM = (divisor >> 8) & 0xFF;
U1LCR &= ~0x80; /* Disable DLAB */
PINSEL0 = PINSEL0 & ~(0xFFFF << 16) | (0x5555 << 16);
U1FCR = 1;

/* Setup UART RX interrupt */
ctl_set_isr(7, 0, CTL_ISR_TRIGGER_FIXED, uartISR, 0);
ctl_unmask_isr(7);
U1IER = 1;
}

(snip)

int
main(void)
{
int i;
ctl_global_interrupts_enable();
UARTInitialize(19200);
delay(1000);
for(i = 0; ; ++i)
{
printf("Hello World (%d)\n", i);
if (rxchar != 0)
{
if (rxchar == 'q' || rxchar == 'Q')
break;
printf("Key \'%c\' pressed\n", rxchar);
rxchar = 0;
}
delay(1000);
}
printf("Goodbye!\n");
return 0;
}

------------ end of code ------------

> Hmm, I wrote some UART drivers for the 2100 and 2300 series but that's sort
> of linked to CTL. You're welcome to have a look at them and use them if you
> wish. I know they work.
>
> Have you been using ctl_set_isr() to set things up? Common misconception is
> that using ctl_set_isr is somehow related to using the CTL library, which it
> isn't.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>

Give it all up, switch to GCC, and start with the 2148 demo code base that I
know works? :)

--jc

On Wed, Mar 11, 2009 at 2:10 PM, WadeA & RebeccaM Smith
wrote:

> Oops. I misspoke. Instead of saying that I copied all of the UART0
> functions and made them UART1, I should have said that all of the UART1
> functions were copied and changed to UART0.
>
> The code I used as a basis for uart.c was the Crossfire_2138 uart example.
> Recognize it? (see below)
>
> It worked fine on the Crossfire_2138. So now I'm trying it with 2 uarts
> running. Not much success. The irony is that the UART that worked on the
> Crossfire_2138 won't work elsewhere.
>
> suggestions?
>
> wade
>
> ------------ start of code ------------
> // Copyright (c) 2005 Rowley Associates Limited.
> //
> // This file may be distributed under the terms of the License Agreement
> // provided with this software.
> //
> // THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
> // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE.
> //
>
> ////////////////////////////////////////////////////////////////////////////////
> //
> // Philips LPC2000 - UART1 Example
> //
> // Description
> // -----------
> // This example demonstrates configuring and writing to a UART and
> generating
> // an interrupt on arrival of data. It also demonstrates how to get printf
> // output over the UART by implementing __putchar.
> //
> // To see output:
> // - Connect serial cable from UART1/COM1 connector on your target board to
> your
> // host computer.
> // - Open CrossStudio's "Terminal Emulator Window". Configure it to 9600
> baud,
> // 8 data bits, no parity, 1 stop bits. Click "Connect" to start the
> // terminal emulator window.
> //
>
> ////////////////////////////////////////////////////////////////////////////////
>
> #include
> #include
> #include static unsigned char rxchar;
> (snip)
>
> static void
> uartISR(void)
>
> {
> /* Read IIR to clear interrupt and find out the cause */
> unsigned iir = U1IIR;
>
> /* Handle UART interrupt */
> switch ((iir >> 1) & 0x7)
> {
> case 1:
> /* THRE interrupt */
> break;
> case 2:
> /* RDA interrupt */
> rxchar = U1RBR;
> break;
> case 3:
> /* RLS interrupt */
> break;
> case 6:
> /* CTI interrupt */
> break;
> }
> }
>
> void
> UARTInitialize(unsigned int baud)
> {
> /* Configure UART */
> unsigned int divisor > liblpc2000_get_pclk(liblpc2000_get_cclk(OSCILLATOR_CLOCK_FREQUENCY)) / (16 *
> baud);
> U1LCR = 0x83; /* 8 bit, 1 stop bit, no parity, enable DLAB */
> U1DLL = divisor & 0xFF;
> U1DLM = (divisor >> 8) & 0xFF;
> U1LCR &= ~0x80; /* Disable DLAB */
> PINSEL0 = PINSEL0 & ~(0xFFFF << 16) | (0x5555 << 16);
> U1FCR = 1;
>
> /* Setup UART RX interrupt */
> ctl_set_isr(7, 0, CTL_ISR_TRIGGER_FIXED, uartISR, 0);
> ctl_unmask_isr(7);
> U1IER = 1;
> }
>
> (snip)
>
> int
> main(void)
> {
> int i;
> ctl_global_interrupts_enable();
> UARTInitialize(19200);
> delay(1000);
> for(i = 0; ; ++i)
> {
> printf("Hello World (%d)\n", i);
> if (rxchar != 0)
> {
> if (rxchar == 'q' || rxchar == 'Q')
> break;
> printf("Key \'%c\' pressed\n", rxchar);
> rxchar = 0;
> }
> delay(1000);
> }
> printf("Goodbye!\n");
> return 0;
> }
>
> ------------ end of code ------------
>
> > Hmm, I wrote some UART drivers for the 2100 and 2300 series but that's
> sort
> > of linked to CTL. You're welcome to have a look at them and use them if
> you
> > wish. I know they work.
> >
> > Have you been using ctl_set_isr() to set things up? Common misconception
> is
> > that using ctl_set_isr is somehow related to using the CTL library, which
> it
> > isn't.
> >
> > --
> > Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> > CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
> >
>


WadeA & RebeccaM Smith wrote:
> Oops. I misspoke. Instead of saying that I copied all of the UART0 functions and made them UART1, I should have said that all of the UART1 functions were copied and changed to UART0.
>
> The code I used as a basis for uart.c was the Crossfire_2138 uart example. Recognize it? (see below)
>
> It worked fine on the Crossfire_2138. So now I'm trying it with 2 uarts running. Not much success. The irony is that the UART that worked on the Crossfire_2138 won't work elsewhere.
>
> suggestions?
>
> wade
>
I'm not an expert on Crossworks but just a foolish question. What
optimizations do you have set? Did you check the errata sheet for any
MAM conditions?

regards,
Charles
How about I kill off the "__attribute__ ((interrupt ("IRQ")))" and kill off the "VECTORED_IRQ_INTERRUPTS"?

Now timer0, RTC and UART0 have no "__attribute__ ((interrupt ("IRQ")))".

UART1 is NOT initialized.
// ctl_unmask_isr(VIC_CTRL_UART1);

Oh, drat. Now, even with no UART1, dabort!
>From

(breakpoint) initSerMot();
1A9C EB0003A6 bl 0x000293C
timerSleepMS(500); // wait for initSerMot printing to stop
1AA0 E3A00F7D mov r0, #0x00001F4
1AA4 EB0008E3 bl 0x0003E38
__ARMLIB_enableIRQ();
1AA8 EB000AF8 bl 0x0004690 <__ARMLIB_enableIRQ>
(breakpoint NEVER REACHED) moveCase = 15;
1AAC E59F3160 ldr r3, [pc, #+0x160]
1AB0 E3A0200F mov r2, #0x000000F
1AB4 E5C32000 strb r2, [r3]
/* ===================== MAIN LOOP ===================== */
//esp_printf(&U0OutChar,"\r\nENTERING ROBOT MAIN LOOP\r\n");
esp_printf(U0OutChar,"\r\nENTERING ROBOT MAIN LOOP\r\n");
1AB8 E59F0158 ldr r0, [pc, #+0x158]
1ABC E59F1158 ldr r1, [pc, #+0x158]
1AC0 EB000258 bl 0x0002428
1AC4 EAFFFFFF b 0x0001AC8

--- REGISTERS ---
CPU - Current Mode
r0 0x6000005f (really invalid)
...
lr(r14) 0x00001abc

lr contains an address BEYOND the breakpoint set at "movecase = 15;"
(which is NEVER hit) and esp_printf (from rprintf.c from the web) loads 0x6000005f no matter if I put &fnName or just fnName as the first parameter.

In other words, things get royally screwed up as soon as IRQ are enabled.

This is all very confusing. I think I'll go back to the way that at least allowed UART0 to work...

So, any new ideas?

wade
--- In l..., "WadeA & RebeccaM Smith" wrote:
>
> As a matter of fact, I do have VECTORED_IRQ_INTERRUPTS set in Properties (common) Preprocessor Options -> Preprocessor definitions.
>
> However, for UART0 it does not matter how I set that. ???
> I tried it both ways and no problem with UART0. UART1 dies if it exists. Oh, well, I didn't need my sanity anyway.
>
> --- In l..., "Paul Curtis" wrote:
> >
> > Wade,
> >
> > > "Common misconception is that using ctl_set_isr is somehow related to
> > using
> > > the CTL library". Actually, that is EXACTLY what I thought. And since I
> > > wasn't using the CTaskingLibrary, I went and modified the Rowley uart
> > > example code and "manually" set up the VIC.
> > >
> > > OK. The results are in. No change. As long as I do not call
> > > "ctl_unmask_isr(VIC_CTRL_UART1);" everything works as normal. If I call
> > > that and unmask UART1 ISR, la la land, i.e., abort, as soon as I enable
> > > IRQs.
> > >
> > > Ideas? What should I change in the Rowley uart example to make uart1
> > > happy? Is it THAT much different than uart0?
> > > Timer:
> > > ------------ start of code ------------
> > > void timer0_isr(void) __attribute__ ((interrupt ("IRQ")));
> > > void tmr1_ISR(void) __attribute__ ((interrupt ("IRQ")));
> > > void RTC_ISR(void) __attribute__ ((interrupt ("IRQ")));
> >
> > By default the function you pass into ctl_set_isr must not have the IRQ
> > attribute on them, in general.
> >
> > Exception: if you have set VECTORED_IRQ_INTERRUPTS in the LPC2k startup code
> > then they *must* have those attributes as the IRQs are processed using the
> > VIC.
> >
> > --
> > Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> > CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>

*I* have not set any optimizations. Whatever the default optimizations exist in CrossWorks, are as they are for a new solution and project from scratch (with a few "existing files" of the *.h and *.c variety added).

I haven't done anything with MAM other than what the CrossWorks defaults are. Everything worked on the Rowley Crossfire_2138, so I assume it would be OK on the NewMicros Pluga2138 as well.

Maybe Paul Curtis can shed some light on this when he gets back into the office in the morning (it must be late in England).

My Boss is calling me to supper, so I'll be back in the Florida morning as well.

wade

--- In l..., "Charles R. Grenz" wrote:
>
> WadeA & RebeccaM Smith wrote:
> > Oops. I misspoke. Instead of saying that I copied all of the UART0 functions and made them UART1, I should have said that all of the UART1 functions were copied and changed to UART0.
> >
> > The code I used as a basis for uart.c was the Crossfire_2138 uart example. Recognize it? (see below)
> >
> > It worked fine on the Crossfire_2138. So now I'm trying it with 2 uarts running. Not much success. The irony is that the UART that worked on the Crossfire_2138 won't work elsewhere.
> >
> > suggestions?
> >
> > wade
> >
> I'm not an expert on Crossworks but just a foolish question. What
> optimizations do you have set? Did you check the errata sheet for any
> MAM conditions?
>
> regards,
> Charles
>

Lost cause.....time to start over!!!!

> How about I kill off the "__attribute__ ((interrupt ("IRQ")))" and kill
> off the "VECTORED_IRQ_INTERRUPTS"?
>
> Now timer0, RTC and UART0 have no "__attribute__ ((interrupt ("IRQ")))".
>
> UART1 is NOT initialized.
> // ctl_unmask_isr(VIC_CTRL_UART1);
>
> Oh, drat. Now, even with no UART1, dabort!
> From
>
> (breakpoint) initSerMot();
> 1A9C EB0003A6 bl 0x000293C
> timerSleepMS(500); // wait for initSerMot printing to stop
> 1AA0 E3A00F7D mov r0, #0x00001F4
> 1AA4 EB0008E3 bl 0x0003E38
> __ARMLIB_enableIRQ();
> 1AA8 EB000AF8 bl 0x0004690 <__ARMLIB_enableIRQ>
> (breakpoint NEVER REACHED) moveCase = 15;
> 1AAC E59F3160 ldr r3, [pc, #+0x160]
> 1AB0 E3A0200F mov r2, #0x000000F
> 1AB4 E5C32000 strb r2, [r3]
> /* ===================== MAIN LOOP ===================== */
> //esp_printf(&U0OutChar,"\r\nENTERING ROBOT MAIN LOOP\r\n");
> esp_printf(U0OutChar,"\r\nENTERING ROBOT MAIN LOOP\r\n");
> 1AB8 E59F0158 ldr r0, [pc, #+0x158]
> 1ABC E59F1158 ldr r1, [pc, #+0x158]
> 1AC0 EB000258 bl 0x0002428
> 1AC4 EAFFFFFF b 0x0001AC8
>
> --- REGISTERS ---
> CPU - Current Mode
> r0 0x6000005f (really invalid)
> ...
> lr(r14) 0x00001abc
>
> lr contains an address BEYOND the breakpoint set at "movecase = 15;"
> (which is NEVER hit) and esp_printf (from rprintf.c from the web) loads
> 0x6000005f no matter if I put &fnName or just fnName as the first
> parameter.
>
> In other words, things get royally screwed up as soon as IRQ are enabled.
>
> This is all very confusing. I think I'll go back to the way that at least
> allowed UART0 to work...
>
> So, any new ideas?
>
> wade
> --- In l..., "WadeA & RebeccaM Smith"
> wrote:
>>
>> As a matter of fact, I do have VECTORED_IRQ_INTERRUPTS set in Properties
>> (common) Preprocessor Options -> Preprocessor definitions.
>>
>> However, for UART0 it does not matter how I set that. ???
>> I tried it both ways and no problem with UART0. UART1 dies if it
>> exists. Oh, well, I didn't need my sanity anyway.
>>
>> --- In l..., "Paul Curtis" wrote:
>> >
>> > Wade,
>> >
>> > > "Common misconception is that using ctl_set_isr is somehow related
>> to
>> > using
>> > > the CTL library". Actually, that is EXACTLY what I thought. And
>> since I
>> > > wasn't using the CTaskingLibrary, I went and modified the Rowley
>> uart
>> > > example code and "manually" set up the VIC.
>> > >
>> > > OK. The results are in. No change. As long as I do not call
>> > > "ctl_unmask_isr(VIC_CTRL_UART1);" everything works as normal. If I
>> call
>> > > that and unmask UART1 ISR, la la land, i.e., abort, as soon as I
>> enable
>> > > IRQs.
>> > >
>> > > Ideas? What should I change in the Rowley uart example to make
>> uart1
>> > > happy? Is it THAT much different than uart0?
>> > > Timer:
>> > > ------------ start of code ------------
>> > > void timer0_isr(void) __attribute__ ((interrupt ("IRQ")));
>> > > void tmr1_ISR(void) __attribute__ ((interrupt ("IRQ")));
>> > > void RTC_ISR(void) __attribute__ ((interrupt ("IRQ")));
>> >
>> > By default the function you pass into ctl_set_isr must not have the
>> IRQ
>> > attribute on them, in general.
>> >
>> > Exception: if you have set VECTORED_IRQ_INTERRUPTS in the LPC2k
>> startup code
>> > then they *must* have those attributes as the IRQs are processed using
>> the
>> > VIC.
>> >
>> > --
>> > Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
>> > CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>> >
>

My sediments (or is that sentiments) exactly.

Do you have a suggestion?

Initially I want:
Timer0
RTC
Uart0 Comm to outside world
Uart1 Comm to Pololu Low Voltage Dual Serial Motor Controller

Later I want
i2c i/o
spi i/o

Possibly AD and PWM later, but there arent too many pins avaiable on the 24 or 48 pins coming out (NewMicros Tini2138 has 24 pins Pluga2138 has 48 pins).

I plan on taking the Rowley Crossfire2138 Uart example (again) and getting that to work for both uarts. Then I'll add timer0 and RTC. Then the problem will be moot since I'll probably be dead by the time that happens 30 years from now...at the rate I'm making progress.

(sigh) Making a living in ignorance is a tough job, but somebody's gotta do it and I'm the most qualified. ;-)

But I am still open to suggestions, after all:

"Ignorance is cureable, but stupidity is terminal." -- author unknown

wade

--- In l..., dave@... wrote:
> Lost cause.....time to start over!!!!
>


The 2024 Embedded Online Conference