Reply by nutleycottage July 11, 20072007-07-11
Hi,

If you don't define VECTORED_IRQ_INTERRUPTS then the default
irq_handler is used. This will handle spurious interrupts and then
call (using bx) the function that is in the VICVectAddr. Using this
technique any function can be an interrupt handler.

If you define VECTORED_IRQ_INTERRUPTS then VICVectAddr is jumped to
(using ldr pc, [pc, #-0xff0]) and as such cannot contain the address
of a regular function - this is what the __attribute__ ((interrupt
("IRQ"))) is for. Note that this is buggy area of GCC (depending on
the version and the optimisation level), the function must be compiled
in ARM mode and the code generated doesn't handle spurious interrupts.

Regards
Michael
>
> ok, i have found a tweak that makes my ISR work.
>
> What i did was removed the following line.
>
> static void IRQ_UART0(void) __attribute__ ((interrupt ("IRQ")));
>
> and also DO NOT define VECTORED_IRQ_INTERRUPTS.
>
> Please correct me if i'm wrong.
>
> It seems that the __attribute__ ((interrupt ("IRQ"))) somehow make a
> wrong entry to my ISR function.
>
> Also, VECTORED_IRQ_INTERRUPTS is defined to point the irq_handler to
> VICVectAddr (ISR location), but somehow it didn't work as i expected.
>
> Anyone experience the same problem?
> Or is there any better solution than this tweak??
> --- In l..., "g_gambler2000" wrote:
> >
> > Yes, i have defined VECTORED_IRQ_INTERRUPTS for the startup.s
> >
> >
> > --- In l..., "Darcy Williams" wrote:
> > >
> > > Have you defined VECTORED_IRQ_INTERRUPTS in your project settings?
> > > You could also declare this within startup.s as "#define
> > > VECTORED_IRQ_INTERRUPTS"
> > >
> > >
> > > --- In l..., "g_gambler2000" wrote:
> > > >
> > > > Ok, i am running code from SYSTEM Mode and i have the I bit
set to 0
> > > > in SYSTEM mode. However, the ISR is still not firing up.
> > > > Do i need to set I=0 in IRQ mode as well??
> > > > Any other suggestion?
> > > >
> > > > By the way, i can get my ISR code running using CodeWarrior IDE.
> > > > So, i think there must be some setting in startup file or Rowley
> > > > Crosswork that i have miss out....
> > > >
> > > >
> > >
>

An Engineer's Guide to the LPC2100 Series

Reply by g_gambler2000 July 11, 20072007-07-11
ok, i have found a tweak that makes my ISR work.

What i did was removed the following line.

static void IRQ_UART0(void) __attribute__ ((interrupt ("IRQ")));

and also DO NOT define VECTORED_IRQ_INTERRUPTS.

Please correct me if i'm wrong.

It seems that the __attribute__ ((interrupt ("IRQ"))) somehow make a
wrong entry to my ISR function.

Also, VECTORED_IRQ_INTERRUPTS is defined to point the irq_handler to
VICVectAddr (ISR location), but somehow it didn't work as i expected.

Anyone experience the same problem?
Or is there any better solution than this tweak??

--- In l..., "g_gambler2000" wrote:
>
> Yes, i have defined VECTORED_IRQ_INTERRUPTS for the startup.s
> --- In l..., "Darcy Williams" wrote:
> >
> > Have you defined VECTORED_IRQ_INTERRUPTS in your project settings?
> > You could also declare this within startup.s as "#define
> > VECTORED_IRQ_INTERRUPTS"
> >
> >
> > --- In l..., "g_gambler2000" wrote:
> > >
> > > Ok, i am running code from SYSTEM Mode and i have the I bit set to 0
> > > in SYSTEM mode. However, the ISR is still not firing up.
> > > Do i need to set I=0 in IRQ mode as well??
> > > Any other suggestion?
> > >
> > > By the way, i can get my ISR code running using CodeWarrior IDE.
> > > So, i think there must be some setting in startup file or Rowley
> > > Crosswork that i have miss out....
> > >
> > >
>
Reply by g_gambler2000 July 10, 20072007-07-10
Yes, i have defined VECTORED_IRQ_INTERRUPTS for the startup.s
--- In l..., "Darcy Williams" wrote:
>
> Have you defined VECTORED_IRQ_INTERRUPTS in your project settings?
> You could also declare this within startup.s as "#define
> VECTORED_IRQ_INTERRUPTS"
> --- In l..., "g_gambler2000" wrote:
> >
> > Ok, i am running code from SYSTEM Mode and i have the I bit set to 0
> > in SYSTEM mode. However, the ISR is still not firing up.
> > Do i need to set I=0 in IRQ mode as well??
> > Any other suggestion?
> >
> > By the way, i can get my ISR code running using CodeWarrior IDE.
> > So, i think there must be some setting in startup file or Rowley
> > Crosswork that i have miss out....
> >
>
Reply by Darcy Williams July 10, 20072007-07-10
Have you defined VECTORED_IRQ_INTERRUPTS in your project settings?
You could also declare this within startup.s as "#define
VECTORED_IRQ_INTERRUPTS"
--- In l..., "g_gambler2000" wrote:
>
> Ok, i am running code from SYSTEM Mode and i have the I bit set to 0
> in SYSTEM mode. However, the ISR is still not firing up.
> Do i need to set I=0 in IRQ mode as well??
> Any other suggestion?
>
> By the way, i can get my ISR code running using CodeWarrior IDE.
> So, i think there must be some setting in startup file or Rowley
> Crosswork that i have miss out....
Reply by g_gambler2000 July 10, 20072007-07-10
Ok, i am running code from SYSTEM Mode and i have the I bit set to 0
in SYSTEM mode. However, the ISR is still not firing up.
Do i need to set I=0 in IRQ mode as well??
Any other suggestion?

By the way, i can get my ISR code running using CodeWarrior IDE.
So, i think there must be some setting in startup file or Rowley
Crosswork that i have miss out....
--- In l..., "Andy Berney" wrote:
>
> When you set up your modes in your startup file (crt.s / startup.s?)
are you
> turning on IRQ/FIQ bits in the CPSR?
> If you set these bits to 1 you disable IRQ/FIQ for that particular mode.
>
> I don't use Rowley but you should see some code similar to:
>
> Mode_USR EQU 0x10
> Mode_FIQ EQU 0x11
> Mode_IRQ EQU 0x12
> Mode_SVC EQU 0x13
> Mode_ABT EQU 0x17
> Mode_UND EQU 0x1B
> Mode_SYS EQU 0x1F
>
> I_Bit EQU 0x80 ; when I bit is set, IRQ is
disabled
> F_Bit EQU 0x40 ; when F bit is set, FIQ is
disabled
>
> ; Enter Supervisor Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
> MOV SP, R0
> SUB R0, R0, #SVC_Stack_Size
>
> ; Enter User Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_USR
> MOV SP, R0
> SUB SL, SP, #USR_Stack_Size
> ; Enter the C code
>
> IMPORT __main
> LDR R0, =__main
> BX R0
>
> The above example is turning the IRQ/FIQ bits on for Supervisor Mode
thereby
> disabling IRQ's and FIQ's in this mode at this time.
> User mode has them turned off - enabling IRQ/FIQ for that mode etc...
>
> Andy
>
> -----Original Message-----
> From: l... [mailto:l...]On
Behalf Of
> g_gambler2000
> Sent: 10 July 2007 09:08
> To: l...
> Subject: [lpc2000] Re: Crosswork UART0 interrupt problem
> Sorry for the incomplete information.
> Here is my complete code but i still cant fire up the interrupt.
> I have defined the VECTORED_IRQ_INTERRUPTS for the startup file.
> Anything else i could be miss out? Btw I am using Rowley Crosswork
1.7.
>
> static void IRQ_UART0(void) __attribute__ ((interrupt ("IRQ")));
>
> static void IRQ_UART0 (void)
> {
> int8 integer;
>
> if ((U0IIR & 0x0F) == 0x04);
> {
> handler function;
> }
> integer=U0IIR;
> integer=U0RBR;
> VICVectAddr = 0x00;
>
> }
>
> /*Intterupt Setting*/
> Uart0_Init(9600);
> libarm_enable_irq();
> VICIntSelect = 0x00000000;
> VICVectCntl1 = 0x20 | 0x06;
> VICVectAddr1 = (uint32)IRQ_UART0; // Set the uart0 interrupt
> VICIntEnable = (1 << 6);
> /*Uart initialization*/
> void
> Uart0_Init(uint32 BAUD)
> {
> PINSEL0 |= (Uart_RX_EN |Uart_TX_EN); //ENABLE TXD0 and RXD0
> U0LCR = 0x83;
> U0DLM = ((Fpclk >> 4)/BAUD) >> 8;
> U0DLL = (((Fpclk >> 4)/BAUD) & 0xff);
> U0LCR = 0x03;
> U0FCR = 0x01;
> U0IER = 0x01;
>
> }
>
> > Did you actually set the interrupt handler up in the VIC and, err,
> enable
> > global interrupts?
> >
> > --
> > Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> > CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
> >
>
>
Reply by Andy Berney July 10, 20072007-07-10
When you set up your modes in your startup file (crt.s / startup.s?) are you
turning on IRQ/FIQ bits in the CPSR?
If you set these bits to 1 you disable IRQ/FIQ for that particular mode.

I don't use Rowley but you should see some code similar to:

Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UND EQU 0x1B
Mode_SYS EQU 0x1F

I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled

; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size

; Enter User Mode and set its Stack Pointer
MSR CPSR_c, #Mode_USR
MOV SP, R0
SUB SL, SP, #USR_Stack_Size
; Enter the C code

IMPORT __main
LDR R0, =__main
BX R0

The above example is turning the IRQ/FIQ bits on for Supervisor Mode thereby
disabling IRQ's and FIQ's in this mode at this time.
User mode has them turned off - enabling IRQ/FIQ for that mode etc...

Andy

-----Original Message-----
From: l... [mailto:l...]On Behalf Of
g_gambler2000
Sent: 10 July 2007 09:08
To: l...
Subject: [lpc2000] Re: Crosswork UART0 interrupt problem
Sorry for the incomplete information.
Here is my complete code but i still cant fire up the interrupt.
I have defined the VECTORED_IRQ_INTERRUPTS for the startup file.
Anything else i could be miss out? Btw I am using Rowley Crosswork 1.7.

static void IRQ_UART0(void) __attribute__ ((interrupt ("IRQ")));

static void IRQ_UART0 (void)
{
int8 integer;

if ((U0IIR & 0x0F) == 0x04);
{
handler function;
}
integer=U0IIR;
integer=U0RBR;
VICVectAddr = 0x00;

}

/*Intterupt Setting*/
Uart0_Init(9600);
libarm_enable_irq();
VICIntSelect = 0x00000000;
VICVectCntl1 = 0x20 | 0x06;
VICVectAddr1 = (uint32)IRQ_UART0; // Set the uart0 interrupt
VICIntEnable = (1 << 6);
/*Uart initialization*/
void
Uart0_Init(uint32 BAUD)
{
PINSEL0 |= (Uart_RX_EN |Uart_TX_EN); //ENABLE TXD0 and RXD0
U0LCR = 0x83;
U0DLM = ((Fpclk >> 4)/BAUD) >> 8;
U0DLL = (((Fpclk >> 4)/BAUD) & 0xff);
U0LCR = 0x03;
U0FCR = 0x01;
U0IER = 0x01;

}

> Did you actually set the interrupt handler up in the VIC and, err,
enable
> global interrupts?
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>
Reply by g_gambler2000 July 10, 20072007-07-10
Sorry for the incomplete information.
Here is my complete code but i still cant fire up the interrupt.
I have defined the VECTORED_IRQ_INTERRUPTS for the startup file.
Anything else i could be miss out? Btw I am using Rowley Crosswork 1.7.
static void IRQ_UART0(void) __attribute__ ((interrupt ("IRQ")));

static void IRQ_UART0 (void)
{
int8 integer;

if ((U0IIR & 0x0F) == 0x04);
{
handler function;
}
integer=U0IIR;
integer=U0RBR;
VICVectAddr = 0x00;

}

/*Intterupt Setting*/
Uart0_Init(9600);
libarm_enable_irq();
VICIntSelect = 0x00000000;
VICVectCntl1 = 0x20 | 0x06;
VICVectAddr1 = (uint32)IRQ_UART0; // Set the uart0 interrupt
VICIntEnable = (1 << 6);

/*Uart initialization*/
void
Uart0_Init(uint32 BAUD)
{
PINSEL0 |= (Uart_RX_EN |Uart_TX_EN); //ENABLE TXD0 and RXD0
U0LCR = 0x83;
U0DLM = ((Fpclk >> 4)/BAUD) >> 8;
U0DLL = (((Fpclk >> 4)/BAUD) & 0xff);
U0LCR = 0x03;
U0FCR = 0x01;
U0IER = 0x01;

}
> Did you actually set the interrupt handler up in the VIC and, err,
enable
> global interrupts?
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>
Reply by Paul Curtis July 9, 20072007-07-09
Hi,

> My Uart0 interrupt cant be triggered. It seems that my program doesn't
> jump to the irq handler.
>
> I have defined "VECTORED_IRQ_INTERRUPTS" and i'm not using any
> optimization.
>
> what else could i miss?? I need help!!
>
> static void IRQ_UART0(void) __attribute__ ((interrupt ("IRQ")));
>
> static void IRQ_UART0(void)
> {
> int8 dummy;
>
> if((U0IIR & 0x0F)==0x04)
> {
> received = 1;
> }
> dummy = U0IIR; //dummy read to clear the interrupt
> dummy = U0RBR;
> VICVectAddr = 0x00;
> }

Did you actually set the interrupt handler up in the VIC and, err, enable
global interrupts?

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
Reply by Tom Walsh July 9, 20072007-07-09
g_gambler2000 wrote:
> Hi,
>
> My Uart0 interrupt cant be triggered. It seems that my program doesn't
> jump to the irq handler.
>
> I have defined "VECTORED_IRQ_ INTERRUPTS" and i'm not using any
> optimization.
>
> what else could i miss?? I need help!!
>

If your interrupt isn't firing, why are you looking at your interrupt
handler code instead of where you did the setup???

Maybe this will help:

=========== setserial.c ========...
...
uart_driver_t * initSerialPort0 (const char * mode)
{ // init hardware and connect to interrupt controller.
uchar dummy;
char tem[128];
bool cableDisconnected = False;
strncpy(tem, mode, 127); strupr(tem);
lpcUartModeSetup(&serialDriverPort0, tem);
// look at cable to see if it is attached before init'izing UART.
// set to GPIO function.
PINSEL0 = (PINSEL0 & ~U0RXD_GPIO_PINMASK);
// dir to input.
IO0DIR = (IO0DIR & ~U0RXD_GPIO_DIR);
cableDisconnected = ((IO0PIN & U0RXD_GPIO_DIR) == 0);
// change to special function: uart0
PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
// disable any interrupts currently enabled.
serialDriverPort0.ier_reg.BYTE8 = 0; U0IER serialDriverPort0.ier_reg.BYTE8;
// wipe fifo clean.
serialDriverPort0.fcr_reg.BYTE8 = 0;
serialDriverPort0.fcr_reg.resetRxFIFO = True;
serialDriverPort0.fcr_reg.resetTxFIFO = True;
serialDriverPort0.fcr_reg.enableFIFO = False;
U0FCR = serialDriverPort0.fcr_reg.BYTE8;
// clear any possible interrupt sources.
dummy = U0IIR; dummy = U0RBR; dummy = U0LSR;
// set the baudrate and char mode.
serialDriverPort0.lcr_reg.divisorLatchEnable = True;
U0LCR = serialDriverPort0.lcr_reg.BYTE8;
U0DLL = (uint8_t) (serialDriverPort0.divisor & 0xff);
U0DLM = (uint8_t) ((serialDriverPort0.divisor >> 8) & 0xff);
serialDriverPort0.lcr_reg.divisorLatchEnable = False;
U0LCR = serialDriverPort0.lcr_reg.BYTE8;
// enable TX & RX FIFOs.
serialDriverPort0.fcr_reg.resetRxFIFO = False;
serialDriverPort0.fcr_reg.resetTxFIFO = False;
serialDriverPort0.fcr_reg.enableFIFO = True;
serialDriverPort0.fcr_reg.RX_trig = FIFO8CHAR;
U0FCR = serialDriverPort0.fcr_reg.BYTE8;
// init the queue pointers.
serialDriverPort0.txWrQue = serialDriverPort0.txRdQue = 0;
serialDriverPort0.rxWrQue = serialDriverPort0.rxRdQue = 0;
serialDriverPort0.txRunning = False;
serialDriverPort0.rxCount = 0;
// fill in the virtual structure.
serialDriverPort0.RXMASK = RXBUFFSIZE_serialPort0-1;
serialDriverPort0.TXMASK = TXBUFFSIZE_serialPort0-1;
serialDriverPort0.rxBuffer = RXBUFF_serialPort0;
serialDriverPort0.txBuffer = TXBUFF_serialPort0;
// fill in user API interface.
serialDriverPort0.init = (void *)initSerialPort0;
serialDriverPort0.Write = serial0Write;
serialDriverPort0.Read = serial0Read;
serialDriverPort0.Putch = serial0Putch;
serialDriverPort0.RxHasData = serial0RxHasData;
serialDriverPort0.RxCharCount = serial0RxCharCount;
serialDriverPort0.Getch = serial0Getch;
// connect our ISR routine to interrupt controller now.
Uart0VectCntl = VIC_ENABLE | VIC_UART0;
Uart0VectAddr = (uint32_t)serial0ISR;
VICIntSelect &= ~VIC_BIT(VIC_UART0);
VICIntEnable |= VIC_BIT(VIC_UART0);
// turn on receiver interrupts now.
serialDriverPort0.ier_reg.rhrEnableInterrupt = True;
serialDriverPort0.ier_reg.thrEnableInterrupt = True;
serialDriverPort0.ier_reg.rlsEnableInterrupt = True;
U0IER = serialDriverPort0.ier_reg.BYTE8;
// say ok to send to this uart now.
booleans.serial0XmitSuspended = False;
booleans.serial0RecvSuspended = False;
// set initial state of the FACP cable connection.
booleans.serial0breakInterrupt = cableDisconnected;
booleans.serial0IsNowDown = cableDisconnected;
serial0RTS (True);
// return a pointer to the driver.
return (void *)(uart_driver_t *) &serialDriverPort0;
}
...
...
============= snip ===============--
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net http://cyberiansoftware.com http://openzipit.org
"Windows? No thanks, I have work to do..."
----------------
Reply by derbaier July 9, 20072007-07-09
--- In l..., "g_gambler2000" wrote:
> Hi,
>
> My Uart0 interrupt cant be triggered. It seems that my program doesn't
> jump to the irq handler.
>
> I have defined "VECTORED_IRQ_INTERRUPTS" and i'm not using any
> optimization.
>
> what else could i miss?? I need help!!

Did you enable the IRQ interrupts,set up an IRQ stack, and add an IRQ
handler in your assembly language startup code?

--Dave