ligang |
06-14-2010 11:41 PM |
What's wrong with the interrupt?
I am debugging an Linux device driver which contains an external interrupt. The driver can receive this interrupt but shows a strange response.
CPU is S3C2410 (ARM9).
1.Add driver module to kernal:
Code:
insmod cc2420_driver.ko
2.Interrupt response:
Code:
scl_CC2420 interrupt, at pin 67
irq event 67: bogus return value 17
[<c0027dfc>] (dump_stack+0x0/0x14) from [<c00614ac>] (__report_bad_irq+0x38/0x9)[<c0061474>] (__report_bad_irq+0x0/0x94) from [<c0061580>] (note_interrupt+0x78) r4:c02efb94
[<c0061508>] (note_interrupt+0x0/0x26c) from [<c00622b4>] (handle_edge_irq+0x12)[<c0062194>] (handle_edge_irq+0x0/0x144) from [<c0038ab0>] (s3c_irq_demux_extin) r6:c0315a98 r5:00000015 r4:00000000
[<c0038a20>] (s3c_irq_demux_extint8+0x0/0xa4) from [<c0023044>] (asm_do_IRQ+0x4) r4:c02ef184
[<c0023000>] (asm_do_IRQ+0x0/0x5c) from [<c0023a44>] (__irq_svc+0x24/0xa0)
Exception stack(0xc02e5f54 to 0xc02e5f9c)
5f40: c306ee20 ffffffff f410000c
5f60: 80000013 c00249cc c02e4000 c001ff28 c02e7c78 3001e64c 41129200 3001e618
5f80: c02e5fa8 c02e5f9c c02e5f9c c0024a2c c0024a38 80000013 ffffffff
r7:c02e7c78 r6:00000020 r5:f4000000 r4:ffffffff
[<c00249cc>] (default_idle+0x0/0x78) from [<c0024a8c>] (cpu_idle+0x48/0x64)
[<c0024a44>] (cpu_idle+0x0/0x64) from [<c023501c>] (rest_init+0x50/0x60)
r5:c02ffda8 r4:c0313fdc
[<c0234fcc>] (rest_init+0x0/0x60) from [<c0008930>] (start_kernel+0x27c/0x2e4)
[<c00086b4>] (start_kernel+0x0/0x2e4) from [<30008034>] (0x30008034)
handlers:
[<bf00822c>] (basicRfRecvPacket+0x0/0x840 [cc2420_send])
3.Relatd source code:
3.1 extern interrupt initialization
Code:
gpiovalue = (~(EINT8_23)) & ioread32(S3C2410_INTMOD);^M
iowrite32(gpiovalue, S3C2410_INTMOD); // IRQ^M
^M
// Enable EINT8_23 interrupt^M
gpiovalue = ioread32(S3C2410_INTMSK);^M
#ifdef _DEBUG^M
printk("S3C2410_INTMSK(before) = %X\n", gpiovalue);^M
#endif^M
gpiovalue &= (~(EINT8_23)); ^M
iowrite32(gpiovalue, S3C2410_INTMSK); ^M
#ifdef _DEBUG^M
printk("S3C2410_INTMSK(after) = %X\n",ioread32(S3C2410_INTMSK));^M
#endif^M
^M
// enable FIFOP interrupt^M
gpiovalue = ioread32(S3C2410_EINTMASK);^M
gpiovalue &= (~(1<<23));^M
iowrite32(gpiovalue, S3C2410_EINTMASK); ^M
#ifdef _DEBUG^M
printk("S3C2410_EINTMASK = %X\n",ioread32(S3C2410_EINTMASK));^M
#endif^M
^M
// setting the external interrupt triggered format^M
//gpiovalue = ioread32(rEXINT2)&(~(0xFF00F000));^M
#ifdef _DEBUG^M
printk("rEXINT2(before) = 0X%X\n",gpiovalue);^M
#endif^M
//gpiovalue |= INTTRI_FIFOP; // | INTTRI_FIFO | INTTRI_EINT11;^M
gpiovalue=0x40000000;^M
iowrite32(gpiovalue,rEXINT2);^M
#ifdef _DEBUG^M
printk("rEXINT2 = 0X%X\n",ioread32(rEXINT2));^M
#endif
DISABLE_FIFOP_INT();
3.2 register the interrupt
Code:
reval = request_irq(IRQ_EINT23, basicRfRecvPacket, SA_INTERRUPT, SPI_NAME, NULL);^M
if (reval)^M
{^M
#ifdef _DEBUG ^M
printk(KERN_ALERT "request_irq IRQ_EINT23 failed\n");^M
#endif ^M
}
3.3 interrupt service handler
Code:
static irqreturn_t basicRfRecvPacket(int irq, void * dev_id)^M
{^M
u8 length;^M
u16 fcf, sequence, PanId, destAddr, srcAddr, rssi;^M
//#ifdef _DEBUG ^M
printk(KERN_ALERT "\nmscl_CC2420 interrupt, at pin %d\n", irq);^M
//#endif ^M
DISABLE_FIFOP_INT();^M
^M
// check if RXFIFO is overflow^M
if (FIFOP_IS_1 && FIFO_IS_1)^M
{^M
FASTSPI_STROBE(CC2420_SFLUSHRX);^M
DELAY(100);^M
FASTSPI_STROBE(CC2420_SFLUSHRX);^M
DELAY(100);^M
ENABLE_FIFOP_INT();^M
return;^M
}^M
FASTSPI_READ_FIFO_BYTE(length); ^M
FASTSPI_READ_FIFO_NO_WAIT(&fcf, 2);^M
FASTSPI_READ_FIFO_NO_WAIT(&sequence, 2);^M
FASTSPI_READ_FIFO_NO_WAIT(&PanId, 2);^M
FASTSPI_READ_FIFO_NO_WAIT(&destAddr, 2);^M
FASTSPI_READ_FIFO_NO_WAIT(&srcAddr, 2);^M
FASTSPI_READ_FIFO_NO_WAIT(pRxBuffer, 4);^M
FASTSPI_READ_FIFO_NO_WAIT(&rssi, 2);^M
//#ifdef _DEBUG^M
printk("-- Length = 0x%X\n", length);^M
printk("-- fcf = 0x%X\n", fcf);^M
printk("-- sequence = 0x%X\n", sequence);^M
printk("-- PanId = 0x%X\n", PanId);^M
printk("-- destAddr = 0x%X\n", destAddr);^M
printk("-- srcAddr = 0x%X\n", srcAddr);^M
printk("-- pRxBuffer = %s\n", pRxBuffer);^M
printk("-- rssi = %d\n", rssi);^M
//#endif^M
// for test, these two pins will immediately go low when all datas have been received ^M
while (FIFO_IS_1||SFD_IS_1) ;^M
if (FIFOP_IS_1 && FIFO_IS_1)^M
{^M
FASTSPI_STROBE(CC2420_SFLUSHRX);^M
DELAY(1);^M
FASTSPI_STROBE(CC2420_SFLUSHRX);^M
DELAY(1);^M
ENABLE_FIFOP_INT();^M
return; ^M
}^M
ENABLE_FIFOP_INT();^M
}^M
|