EmbeddedRelated.com
Forums

Crosswork UART0 interrupt problem

Started by g_gambler2000 July 9, 2007
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;
}
Rgds,
Gan

An Engineer's Guide to the LPC2100 Series

--- 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
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..."
----------------
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
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
>
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
>
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
> >
>
>
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....
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....
> >
>
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....
> > >
> > >
>