This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

[LPC2129] nested interrupts with RealView

Hello everyone, this is my first time I'm programming any microcontroller, my task is probably quite simple - I have to use nested interrupts. I'm using interrupt from Timer0 nad ADC. I have to run ADC interrupt during executing Timer0 ISR. I've read AN1381 document and many others but I still have problem. I've tried to use intrinsic functions __enable_irq and __disable_irq, wrapper for nested interrupt functions (exactly like in example from Keil), and i still have the same problem - ADC ISR is executed after Timer0 interrupt. I've also tried to use embedded assembler functions. Below is my actual code:

main.c:

#include <LPC21xx.H>

void initVIC(void);
void initTimer0(void);
void initADC(void);
void initUART(void);
void initGPIO(void);
int sendchar(int);
void sendUART(float);

//*****************************************************************************************************************************

__irq void irqTimer0(void)
{ int i; __enable_irq(); ADCR |= 0x01200000; for(i = 0; i < 10000; i++); __disable_irq(); T0IR = 0x00000001; VICVectAddr = 0;
}

extern void adc_irq (void);
void irqADC(void)
{ float Uout; IO1SET = 0x00010000; Uout = ((ADDR>>6)&0x3FF)*3.3/1023; ADCR &= ~0x01000000; ADCR &= ~0x00200000; sendUART(Uout); VICVectAddr = 0;

}

//*****************************************************************************************************************************

int main(void)
{

initVIC(); initTimer0(); initADC(); initUART(); initGPIO();

while(1) {

}
}

//*****************************************************************************************************************************

void initVIC (void)
{ VICVectAddr0 = (unsigned int) irqTimer0; VICVectCntl0 = 0x00000024;

VICVectAddr1 = (unsigned long)adc_irq; VICVectCntl1 = 0x00000032;

VICIntEnable |= 0x00040010;
}

void initTimer0(void)
{ T0PR = 14999; T0MCR = 0x00000003; T0MR0 = 100; T0TCR = 0x00000002; T0TCR = 0x00000001;
}

void initADC(void)
{ ADCR = 0x00000300;
}

void initUART(void)...
void initGPIO(void)...
int sendchar(int)...
void sendUART(float)... I'm sure that these functions are correct so I'v reduced them

nest_irq.s: exactly like in Keil's example

PRESERVE8

AREA NEST_IRQ, CODE, READONLY

ARM

IMPORT irqADC

EXPORT adc_irq

adc_irq

PUSH {R0-R3,R12,LR}

MRS LR, SPSR

PUSH {LR}

MSR CPSR_c, #0x1F

PUSH {LR}

BL irqADC

POP {LR}

MSR CPSR_c, #0x92

POP {LR}

MSR SPSR_cxsf, LR

; VICVectAddr = 0;

MOV R0,#0

STR R0,[R0,#-0xFD0]

POP {R0-R3,R12,LR}

SUBS R15,R14,#0x0004

END

I'll be very grateful if someone could post a code wher nested interrupts are working properly and also for every comment that may help to solve my problem.

Parents
  • First off, you say you have to use nested interrupts, but do not explain why. "Have to" is a very common description for problems where the poster in reality do not "have to", but are quickly running in the wrong direction caused by an earlier incorrect decision/assumption. Always motivating your requests can greatly improve the quality of the answers you receive.

    Secondly, the VIC irq slot 0 (your timer) has higher priority than VIC irq slot 1 (your ADC). Why not give the ADC the higher priority if you want it to win over the timer.

    But if you have only two interrupts, you specify that one FIQ (Fast Interrupt reQuest) in which case it can directly interrupt without the overhead of you manually allowing nesting interrupts. A FIQ handler will have the best possible response time.

Reply
  • First off, you say you have to use nested interrupts, but do not explain why. "Have to" is a very common description for problems where the poster in reality do not "have to", but are quickly running in the wrong direction caused by an earlier incorrect decision/assumption. Always motivating your requests can greatly improve the quality of the answers you receive.

    Secondly, the VIC irq slot 0 (your timer) has higher priority than VIC irq slot 1 (your ADC). Why not give the ADC the higher priority if you want it to win over the timer.

    But if you have only two interrupts, you specify that one FIQ (Fast Interrupt reQuest) in which case it can directly interrupt without the overhead of you manually allowing nesting interrupts. A FIQ handler will have the best possible response time.

Children