EmbeddedRelated.com
Forums

those crazy interrupts (2138)

Started by WadeA & RebeccaM Smith March 10, 2009
Well, the next logical step would be to comment out the one line that
enables the interrupt in the VIC and see what happens. If it doesn't go to
ta-ta land, then you know it's without question related to interrupt
handling. If it still does... consider an exorcism.

--jc

On Wed, Mar 11, 2009 at 10:37 AM, WadeA & RebeccaM Smith
wrote:

> Good point. I was looking at pin numbers and not considering 2 locations
> per pin. I fixed that. Still goes into la la land when I allow UART1 to
> initialize.
>
> Please feel free to point out any other possibilities.
> --- In l... , "J.C. Wren"
> wrote:
> >
> > I am suspicious of your pin select calculations. According to the
> > datasheet, these should be bits 17:16 for TXD1 and 19:18 for RXD1. You
> seem
> > to be altering bits 11:10 and 9:8. However, I don't know if UART1
> actually
> > requires the pin select block to be configured for it to operate
> internally
> > (as in: the UART works, but it just looks like nothing is connected).
> >
> > --jc
> >
> > On Wed, Mar 11, 2009 at 8:23 AM, WadeA & RebeccaM Smith
> > wrote:
>
> >
> > > Well, as I said, UART1 was a duplicate of UART0 -- all functions.
> > > And there was no prototype defined for UART0, which has been faithfully
> > > spitting out at 19200. It does not matter if I have the
> "__attribute(IRQ)"
> > > or NOT for UART0. It DOES matter if I have them for timer0 and RTC
> (pabort
> > > if it dont have them).
> > >
> > > The only thing that IS consistent is that if I initialize UART1 I get
> > > either a pabort or dabort.
> > > (insert favorite frustration expression here)
> > >
> > > I added LOTS more detail showing bit patterns and VIC slots
> > >
> > > /* VIC assignments (more detail)
> > > * Addr/Cntl 0 = timer0
> > > * VIC_CTRL_TIMER0 (0x00000004)
> > > * VIC_TIMER0 (0x00000010)
> > >
> > > * Addr/Cntl 1 = i2c (not enabled)
> > > * VIC_CTRL_I2C0 (0x00000009)
> > > * VIC_I2C0 (0x00000200)
> > > * Addr/Cntl 2 = spi (not enabled)
> > > * VIC_CTRL_SPI0 (0x0000000A)
> > > * VIC_SPI0 (0x00000400)
> > > * Addr/Cntl 3 = timer1 (not enabled)
> > > * VIC_CTRL_TIMER1 (0x00000005)
> > > * VIC_TIMER1 (0x00000020)
> > > * Addr/Cntl 4 = uart0
> > > * VIC_CTRL_UART0 (0x00000006)
> > > * VIC_UART0 (0x00000040)
> > > * Addr/Cntl 5 = uart1
> > > * VIC_CTRL_UART1 (0x00000007)
> > > * VIC_UART1 (0x00000080)
> > > * Addr/Cntl 6 = RTC
> > > * VIC_CTRL_RTC (0x0000000D)
> > > * VIC_RTC (0x00002000)
> > > * Addr/Cntl 7+= n/a
> > > */
> > >
> > > ------------ start of code ------------
> > > void timer0_isr(void) __attribute__ ((interrupt ("IRQ")));
> > > void tmr1_ISR(void) __attribute__ ((interrupt ("IRQ")));
> > > void RTC_ISR(void) __attribute__ ((interrupt ("IRQ")));
> > >
> > > void RTC_ISR(void)
> > > {
> > > mySeconds++; /* ### for DEBUG */
> > >
> > > /* other code here */
> > > /* ### for DEBUG = PROOF that it is working */
> > > if (IO1PIN & YEL_LED)
> > > IO1CLR = YEL_LED;
> > > else
> > > IO1SET = YEL_LED;
> > >
> > > ILR = ILR_RTCCIF + ILR_RTCALF; /* clear possible intrs */
> > > VICVectAddr = 0x0;
> > > }
> > >
> > > void timerInit(void)
> > > {
> > > (snip)
> > > VICVectCntl0 = VIC_CTRL_ENABLE + VIC_CTRL_TIMER0; /* (0x00000020) +
> > > (0x00000004) */
> > > VICVectAddr0 = (INTU32)timer0_isr;
> > > VICIntSelect = 0;
> > > VICIntEnable = VIC_TIMER0; /* Enable timer 0 interrupt VIC_TIMER0
> > > (0x00000010) */
> > >
> > > #if 0 // NOT INCLUDED, but shown just to be complete
> > > (snip)
> > > VICVectCntl3 = VIC_CTRL_ENABLE + VIC_CTRL_TIMER1; /* 0x25 */
> > > VICVectAddr3 = (INTU32)tmr1_ISR;
> > > VICIntSelect &= ~VIC_TIMER1;
> > > VICIntEnable = VIC_TIMER1; /* enable timer1 interrupt VIC_TIMER1
> > > (0x00000020) */
> > > (snip)
> > > #endif
> > >
> > > /******* Init the Real Time Clock *******/
> > > /* generate 32768 clock from PCLK */
> > > PREFRAC = pclk / 32768;
> > > PREINT = (int) (pclk / 32768) - 1;
> > > CCR = CCR_CTCRST; /* 0x02 Reset the clock */
> > > CIIR = 0x00000001; /* Enable seconds counter interrupt */
> > > (snip Y/M/D H:M:S setup)
> > > VICVectCntl6 = VIC_CTRL_ENABLE + VIC_CTRL_RTC; /* 2d */
> > > VICVectAddr6 = (unsigned int)RTC_ISR;
> > > VICIntSelect = 0;
> > > VICIntEnable = VIC_RTC; /* enable RTC interrupt VIC_RTC (0x00002000) */
> > >
> > > ILR = ILR_RTCCIF; /* 0x01 clear interrupts on ILR */
> > > AMR = 0xFF; /* mask off Alarm Match Interrupt */
> > >
> > > /* Clock Control Register for RTC */
> > > CCR = CCR_CLKEN; /* 0x01 + connected to PCLK */
> > > } /* end of timerInit() */
> > > ------------ end of code ------------
> > >
> > > ------------ start of code ------------
> > > // the following two lines may or may not be in the code
> > > void uart0ISR(void) __attribute__ ((interrupt ("IRQ")));
> > > void uart1ISR(void) __attribute__ ((interrupt ("IRQ")));
> > > // the above 2 lines have no effect on UART0 nor UART1
> > > // UART0 still works and UART1 still aborts (cuss!)
> > >
> > > void uart0ISR(void)
> > > {
> > > (snip)
> > > }
> > >
> > > void uart1ISR(void)
> > > {
> > > (snip)
> > > }
> > >
> > > void U0Initialize(INTU32 baud)
> > > {
> > > /* Configure UART0 */
> > > unsigned int dummy;
> > > unsigned int divisor > > > liblpc2000_get_pclk(liblpc2000_get_cclk(OSCILLATOR_CLOCK_FREQUENCY)) /
> (16 *
> > > baud);
> > > U0LCR = 0x83; /* 8 bit, 1 stop bit, no parity, enable DLAB */
> > > U0DLL = divisor & 0xFF;
> > > U0DLM = (divisor >> 8) & 0xFF;
> > > U0LCR &= ~0x80; /* Disable DLAB */
> > > PINSEL0 = (PINSEL0 & (0xFFFFFFF0)) | (PINSEL0_P0_0TXD0 +
> PINSEL0_P0_1RXD0);
> > > /* 0x0005 */
> > > U0FCR = U0FCR_FIFO_Enable;
> > >
> > > /* Setup UART0 RX interrupt */
> > > VICVectCntl4 = VIC_CTRL_ENABLE + VIC_CTRL_UART0; /* 0x25; */
> > > VICVectAddr4 = (INTU32)uart0ISR;
> > > VICIntSelect = 0;
> > > VICIntEnable = VIC_UART0; /* enable uart0 interrupt 0x00000040 */
> > > U0IER = U0IER_RBR_Interrupt_Enable;
> > > dummy = U0IIR; /* Read IIR to clear interrupt "Just In Case" */
> > > }
> > >
> > > void U1Initialize(INTU32 baud)
> > > {
> > > /* Configure UART1 */
> > > unsigned int dummy;
> > > 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 & (0xFFFFF0FF)) | (PINSEL0_P0_8TXD1 +
> PINSEL0_P0_9RXD1);
> > > U1FCR = U1FCR_FIFO_Enable;
> > >
> > > /* Setup UART RX interrupt */
> > > VICVectCntl5 = VIC_CTRL_ENABLE + VIC_CTRL_UART1; /* 27; */
> > > VICVectAddr5 = (INTU32)uart1ISR;
> > > VICIntSelect = 0;
> > > VICIntEnable = VIC_UART1; /* enable uart1 interrupt */
> > > U1IER = U1IER_RBR_Interrupt_Enable;
> > > dummy = U1IIR; /* Read IIR to clear interrupt 0x00000080 */
> > > }
> > > ------------ end of code ------------
> > >
> > > OK, so someone with more brains that I have (i.e., everyone reading
> this)
> > > could you PLEASE tell me where I have lost it (regarding the
> interrupts,
> > > since the other areas of my life are too numerous to mention)?
> > >
> > > "If it's not one thing it's another." -- author unknown
> > >
> > > wade
> > >
> > > --- In l... > 40yahoogroups.com>, Kenneth Crudup
> > > wrote:
> > > >
> > > >
> > > > On Tue, 10 Mar 2009, WadeA & RebeccaM Smith wrote:
> > > >
> > > > > static void uart1ISR(void)
> > > >
> > > > Ah, never mind. It'd appeared as if you'd been victim to
> > > "__attribute(IRQ)".
> > > >
> > > > -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

I initialize everything first (including the default isr in processorInit()) and THEN I turn on the interrupts by calling "__ARMLIB_enableIRQ();"

Since my problem is aborts occurring whenever I call "__ARMLIB_enableIRQ();", my reasoning is that making sure that I "clear" interrupts "just in case" before I actually let the interrupts loose to ravage my code. My "just in case" is not helpful. Drat!

But, I'm still open to any ideas that get me running ... other than someone pursuing me with a big stick.

wade
--- In l..., "Zdravko" wrote:
>
> --- In l..., "WadeA & RebeccaM Smith" wrote:
> >
> > dummy = U1IIR; /* Read IIR to clear interrupt "Just In Case" */
>
> It's bad idea to do this after the IRQ's are enabled at UART and VIC. Do you have a Default IRQ handler?
>
> Regards
> Zdravko
>

Like as in comment out one or more of the following?

VICVectCntl5 = VIC_CTRL_ENABLE + VIC_CTRL_UART1; /* 27 */

VICIntEnable = VIC_UART1; /* enable uart1 interrupt 0x00000080 */

OK, I commented out
//VICIntEnable = VIC_UART1; /* enable uart1 interrupt 0x00000080 */

That acts JUST like commenting out the whole initialization. And all those other cute little functions run happy as ever.

Please 'scuze my ignernts, but now whut?
UART1 code is a copy of UART0 code with the names changed to protect the ignorant (me). UART0 works. So I am having trouble trying to see what I CAN change to get UART1 working.

HELP!

On the other hand I think the exorcism may have been easier to deal with.

I'll try the Paul Curtis solution for the interrupt setup and see if that helps any. But in the meantime, anyone feel free to find the evil code, hidden somewhere, that sneaks out to shatter my remaining sanity.

wade

--- In l..., "J.C. Wren" wrote:
>
> Well, the next logical step would be to comment out the one line that
> enables the interrupt in the VIC and see what happens. If it doesn't go to
> ta-ta land, then you know it's without question related to interrupt
> handling. If it still does... consider an exorcism.
>
> --jc

I'd try Paul's suggestion of using ctl_set_isr... It saves a lot of
messing around with VIC registers.

#include

ctl_set_isr(5, 0, CTL_ISR_TRIGGER_FIXED, uart1ISR, 0);
ctl_unmask_isr(5);

You don't need to set any VIC registers at all.

--
Tim Mitchell

In the line " VICIntEnable = VIC_UART1;", Where is the code that actually
defines these two values? Something you wrote/copied, or is it in a
provided file?

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.

--jc

On Wed, Mar 11, 2009 at 11:00 AM, Tim Mitchell wrote:

> I'd try Paul's suggestion of using ctl_set_isr... It saves a lot of
> messing around with VIC registers.
>
> #include ctl_set_isr(5, 0, CTL_ISR_TRIGGER_FIXED, uart1ISR, 0);
> ctl_unmask_isr(5);
>
> You don't need to set any VIC registers at all.
>
> --
> Tim Mitchell
>
>
>


"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")));

ctl_set_isr(VIC_CTRL_TIMER0, 0, CTL_ISR_TRIGGER_FIXED, timer0_isr, 0); // 4,0,...
ctl_unmask_isr(VIC_CTRL_TIMER0);

ctl_set_isr(VIC_CTRL_RTC, 6, CTL_ISR_TRIGGER_FIXED, RTC_ISR, 0); // 0x0d,6,...
ctl_unmask_isr(VIC_CTRL_RTC);
------------ end of code ------------

UART:
------------ start of code ------------
void uart0ISR(void) __attribute__ ((interrupt ("IRQ")));
void uart1ISR(void) __attribute__ ((interrupt ("IRQ")));

ctl_set_isr(VIC_CTRL_UART0, 4, CTL_ISR_TRIGGER_FIXED, uart0ISR, 0); // 6,4,...
ctl_unmask_isr(VIC_CTRL_UART0);

ctl_set_isr(VIC_CTRL_UART1, 5, CTL_ISR_TRIGGER_FIXED, uart1ISR, 0); // 7,5,...
ctl_unmask_isr(VIC_CTRL_UART1);
------------ end of code ------------

--- In l..., "Paul Curtis" wrote:
>
> Wade,
>
> > Paul, ol' buddy! Pal!
> > (Huh? Why, yes, I am going to ask you something. How did you guess?)
> >
> > Oh great guru of Crossworks, any pointers to find why calling
> > "__ARMLIB_enableIRQ();" causes aborts only after UART1 gets initialized?
> > Any registers I can look at to track it down?
> > How about a temporary brain transplant? I promise I give yours back to
> you
> > after a brief time. ;-)
>
> 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
>

I appended the VIC values to my LPC213x.h file, so I don't have to remember the right values.

#define VIC_WDT (0x00000001)
#define VIC_UNDEF01 (0x00000002)
#define VIC_ARMCore0 (0x00000004)
#define VIC_ARMCore1 (0x00000008)
#define VIC_TIMER0 (0x00000010)
#define VIC_TIMER1 (0x00000020)
#define VIC_UART0 (0x00000040)
#define VIC_UART1 (0x00000080)
#define VIC_PWM0 (0x00000100)
#define VIC_I2C0 (0x00000200)
#define VIC_SPI0 (0x00000400)
#define VIC_SPI1_SSP (0x00000800)
#define VIC_PLL (0x00001000)
#define VIC_RTC (0x00002000)

#define VIC_CTRL_ENABLE (0x00000020)
#define VIC_CTRL_WDT (0x00000000)
#define VIC_CTRL_ARMCore0 (0x00000002)
#define VIC_CTRL_ARMCore1 (0x00000003)
#define VIC_CTRL_TIMER0 (0x00000004)
#define VIC_CTRL_TIMER1 (0x00000005)
#define VIC_CTRL_UART0 (0x00000006)
#define VIC_CTRL_UART1 (0x00000007)
#define VIC_CTRL_I2C0 (0x00000009)
#define VIC_CTRL_SPI0 (0x0000000A)
#define VIC_CTRL_SPI1_SSP (0x0000000B)
#define VIC_CTRL_PLL (0x0000000C)
#define VIC_CTRL_RTC (0x0000000D)

OK, see any problems? These have worked in demo programs. But if you see a problem with any of them ...
--- In l..., "J.C. Wren" wrote:
>
> In the line " VICIntEnable = VIC_UART1;", Where is the code that actually
> defines these two values? Something you wrote/copied, or is it in a
> provided file?
>
> 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.
>
> --jc
>
> On Wed, Mar 11, 2009 at 11:00 AM, Tim Mitchell wrote:
>
> > I'd try Paul's suggestion of using ctl_set_isr... It saves a lot of
> > messing around with VIC registers.
> >
> > #include
> >
> > ctl_set_isr(5, 0, CTL_ISR_TRIGGER_FIXED, uart1ISR, 0);
> > ctl_unmask_isr(5);
> >
> > You don't need to set any VIC registers at all.
> >
> > --
> > Tim Mitchell
> >
> >
> >
>
>

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

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
On Wed, 11 Mar 2009, J.C. Wren wrote:

> These are carnivorous hamsters, so we feed them the local children who
> trespass on to my lawn. I used to yell 'Get of my lawn, you damn kids!'
> but this method is more environmentally sound.

Hmmmm .... do the hamsters leave much bone residue? The less, the better;
the cops get all silly when it comes to missing kids, even if they really
screw up one's well-maintained lawn ....

-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