external interrupt edge sensitive don't work
2005-03-17 by Sébastien MARION (UMM)
Hello ,
I use an LPC2210 and I would use two external interrupt in edge sensitive but it doesn't work.
My hardware is : the same signal is connect to P0.15(EINT2) in falling edge sensitive , and P0.16(EINT0) in rising edge sensitive.
My code is :
#define REG(addr) (*(volatile _uint32 *)(addr))
#define REGSetBit(addr, mask) (*(volatile _uint32 *)(addr) |= mask)
#define REGClrBit(addr, mask) (*(volatile _uint32 *)(addr) &= (~mask))
void EINT0Interrupt(void) __attribute__ ((interrupt));
void EINT1Interrupt(void) __attribute__ ((interrupt));
void EINT2Interrupt(void) __attribute__ ((interrupt));
void EINT3Interrupt(void) __attribute__ ((interrupt));
void InterruptEnable(_uint8 IntChannel)
{
REG(VICIntEnable) = (1 << IntChannel);
}
void InitIntVectors(void)
{
REG(VICIntSelect) = 0; // set all interrupts as IRQs
REG(VICDefVectAddr) = (_uint32)DefaultInterrupt; // set ISR for non-vectored IRQs
// Init Watchdog Interrupt Function
REG(VICVectAddr0) = (_uint32)WatchdogInterrupt; // set interrupt vector in 0
REG(VICVectCntl0) = VICIrqChWDT | VICVectEnable; // use it for Watchdog Interrupt
// Init Timer0 Interrupt Function
REG(VICVectAddr1) = (_uint32)Timer0Interrupt; // set interrupt vector in 1
REG(VICVectCntl1) = VICIrqChTimer0 | VICVectEnable; // use it for Timer 0 Interrupt
// Init Timer1 Interrupt Function
REG(VICVectAddr2) = (_uint32)Timer1Interrupt; // set interrupt vector in 2
REG(VICVectCntl2) = VICIrqChTimer1 | VICVectEnable; // use it for Timer 1 Interrupt
// Init Uart0 Interrupt Function
REG(VICVectAddr3) = (_uint32)Uart0Interrupt; // set interrupt vector in 3
REG(VICVectCntl3) = VICIrqChUart0 | VICVectEnable; // use it for Uart 0 Interrupt
// Init Uart1 Interrupt Function
REG(VICVectAddr4) = (_uint32)Uart1Interrupt; // set interrupt vector in 4
REG(VICVectCntl4) = VICIrqChUart1 | VICVectEnable; // use it for Uart 1 Interrupt
// Init PWM0 Interrupt Function
REG(VICVectAddr5) = (_uint32)PWM0Interrupt; // set interrupt vector in 5
REG(VICVectCntl5) = VICIrqChPWM0 | VICVectEnable; // use it for PWM0 Interrupt
// Init I2C Interrupt Function
REG(VICVectAddr6) = (_uint32)I2CInterrupt; // set interrupt vector in 6
REG(VICVectCntl6) = VICIrqChI2C | VICVectEnable; // use it for I2C Interrupt
// Init SPI0 Interrupt Function
REG(VICVectAddr7) = (_uint32)SPI0Interrupt; // set interrupt vector in 7
REG(VICVectCntl7) = VICIrqChSPI0 | VICVectEnable; // use it for SPI0 Interrupt
// Init SPI1 Interrupt Function
REG(VICVectAddr8) = (_uint32)SPI1Interrupt; // set interrupt vector in 8
REG(VICVectCntl8) = VICIrqChSPI1 | VICVectEnable; // use it for SPI1 Interrupt
// Init PLL Interrupt Function
REG(VICVectAddr9) = (_uint32)PLLInterrupt; // set interrupt vector in 9
REG(VICVectCntl9) = VICIrqChPLL | VICVectEnable; // use it for PLL Interrupt
// Init RTC Interrupt Function
REG(VICVectAddr10) = (_uint32)RTCInterrupt; // set interrupt vector in 10
REG(VICVectCntl10) = VICIrqChRTC | VICVectEnable; // use it for RTC Interrupt
// Init EINT0 Interrupt Function
REG(VICVectAddr11) = (_uint32)EINT0Interrupt; // set interrupt vector in 11
REG(VICVectCntl11) = VICIrqChEINT0 | VICVectEnable; // use it for EINT0 Interrupt
// Init EINT1 Interrupt Function
REG(VICVectAddr12) = (_uint32)EINT1Interrupt; // set interrupt vector in 12
REG(VICVectCntl12) = VICIrqChEINT1 | VICVectEnable; // use it for EINT1 Interrupt
// Init EINT2 Interrupt Function
REG(VICVectAddr13) = (_uint32)EINT2Interrupt; // set interrupt vector in 13
REG(VICVectCntl13) = VICIrqChEINT2 | VICVectEnable; // use it for EINT2 Interrupt
// Init EINT3 Interrupt Function
REG(VICVectAddr14) = (_uint32)EINT3Interrupt; // set interrupt vector in 14
REG(VICVectCntl14) = VICIrqChEINT3 | VICVectEnable; // use it for EINT3 Interrupt
// Init AD Interrupt Function
REG(VICVectAddr15) = (_uint32)ADInterrupt; // set interrupt vector in 15
REG(VICVectCntl15) = VICIrqChAD | VICVectEnable; // use it for AD Interrupt
}
void EINT0Interrupt(void)
{
_uint8 i;
dLed.f->Set(LEDGREEN);
for(i=0;i<10;i++){};
dLed.f->Set(LEDRED);
REG(EXTINT) = EXTINT0;
// Acknowledge interrupt
REG(VICVectAddr) = 0;
}
void EINT2Interrupt(void)
{
_uint8 i;
dLed.f->Set(LEDRED);
for(i=0;i<10;i++){};
dLed.f->Set(LEDGREEN);
REG(EXTINT) = EXTINT2;
// Acknowledge interrupt
REG(VICVectAddr) = 0;
}
main(void) {
InitIntVectors();
// P0.15 et P0.16 is setting as EINT2 and EINT0
{
_uint32 vpbdiv = REG(SYSCON_VPBDIV);
vpbdiv = REG(SYSCON_VPBDIV); // 2210 Errata VPBDIV.1 work-aroud
REG(SYSCON_VPBDIV) = 0; // 2210 Errata EXTINT.1 work-aroud
// Configure irq on rising edge
REGSetBit(EXTMODE, EXTINT0); // edge sensitive
REGSetBit(EXTPOLAR, EXTINT0);// edge positive
REG(EXTINT) = EXTINT0; // clear interrupt flag
// Configure irq on falling edge
REGSetBit(EXTMODE, EXTINT2); // edge sensitive
REGClrBit(EXTPOLAR, EXTINT2);// edge negative
REG(EXTINT) = EXTINT2; // clear interrupt flag
REG(SYSCON_VPBDIV) = vpbdiv; // 2210 Errata EXTINT.1 work-aroud
InterruptEnable(VICIrqChEINT2); // enable interrupt
InterruptEnable(VICIrqChEINT0); // enable interrupt // Driver SFB : only edge negative needed
}
while(1){};
}
AND THE RESULT IS :
signal in P0.15/16 : ___ _______
|__________| |______--------
_ _ _ _ _ _____ _ _
Led level (high level is for green) : ____| |_| |_| |_| |_| |_| |_| |_| |_------
INSTEAD OF
signal in P0.15/16 : ___ _______
|__________| |______--------
_________ _____
Led level (high level is for green) : _____| |______| ------
if I doesn't active EINT2 it work well in falling edge ....
I dont understand why IRQ is always active even when there's no edge ....
thanks for advance for any idea why the code don't work.
and sorry for my very bad english.
Sebastien.
[Non-text portions of this message have been removed]