This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
RE: ISR occurs, but DSR does not.
- To: "'Jonathan Larmour'" <jlarmour at redhat dot com>
- Subject: RE: [ECOS] ISR occurs, but DSR does not.
- From: "Trenton D. Adams" <tadams at extremeeng dot com>
- Date: Wed, 4 Jul 2001 14:01:34 -0600
- Cc: "'eCos discussion'" <ecos-discuss at sources dot redhat dot com>
- Organization: Extreme Engineering
>
> At a guess the interrupt is not being acked properly
> causing it to loop doing the ISR because it will keep
> regenerating the interrupt when interrupts are re-enabled.
>
> Also you have to return
> CYG_ISR_HANDLED|CYG_ISR_CALL_DSR from your ISR for it
> to call the DSR.
Wouldn't this cause my CYG_TRACE to print to the screen several times?
I'm sure I'm clearing the interrupt properly. If I didn't clear it
properly on the PCMCIA controller side, I would get a whole bunch of
interrupts really quickly. Even if this happens, my DSRs are still used
every time.
Below are my two ISRs and DSRs.
// This ISR is called when a CompactFlash board is inserted
static int
cf_detect_isr(cyg_vector_t vector, cyg_addrword_t data,
HAL_SavedRegisters *regs)
{
CYG_TRACE0 (1, "CD isr\n");
// Mask only the CD irqs
//*(unsigned *)PCIMR &= ~EDB7XXX_CF_DETECT_MASK;
cyg_interrupt_mask(EDB7XXX_CF_DETECT); // Mask until DSR
handles IRQ
return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
}
// This DSR handles the board insertion
static void
cf_detect_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t
data)
{
unsigned long new_state = *(unsigned*)PCCIILR;
struct cf_slot *slot = (struct cf_slot *)data;
if ((new_state & EDB7XXX_CF_DETECT_MASK) == EDB7XXX_CF_PRESENT)
{
slot->state = CF_SLOT_STATE_Inserted;
}
else
{
slot->state = CF_SLOT_STATE_Removed; // Implies powered up,
etc.
}
CYG_TRACE2 (1, "Card Detect Fired!\n"
"IILR = %x\n"
"ISR = %x",
*(unsigned *)PCCIILR,
*(unsigned *)PCISR);
/*
clear CD1 and/or CD2 that occured in the controller
*/
*(unsigned *)PCICR = EDB7XXX_CF_DETECT_MASK;
cyg_interrupt_acknowledge(EDB7XXX_CF_DETECT);
cyg_interrupt_unmask(EDB7XXX_CF_DETECT);
//*(unsigned *)PCIMR |= EDB7XXX_CF_DETECT_MASK;
}
// This ISR is called when the card interrupt occurs
static int
cf_irq_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters
*regs)
{
CYG_TRACE0 (1, "FIQ isr\n");
// Mask all FIQ irqs that occured from the CL-PS6700
//*(unsigned *)PCIMR &= EDB7XXX_CF_DETECT_MASK;
cyg_drv_interrupt_mask(EDB7XXX_CF_IRQ);
return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
}
// This DSR handles the card interrupt
static void
cf_irq_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
struct cf_slot *slot = (struct cf_slot *)data;
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
cyg_bool was_ctrlc_int;
#endif
CYG_TRACE2 (1, "Something on FIQ Fired!\n"
"IILR = %x\n"
"ISR = %x",
*(unsigned *)PCCIILR,
*(unsigned *)PCISR);
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
was_ctrlc_int = HAL_CTRLC_CHECK(vector, data);
if (!was_ctrlc_int) // Fall through and run normal code
#endif
// Process interrupt
(slot->irq_handler.handler)(vector, count,
slot->irq_handler.param);
/*
clear all interrupts that occured in the controller
except for CD1 and CD2
*/
*(unsigned *)PCICR = *(unsigned*)PCISR & ~EDB7XXX_CF_DETECT_MASK;
// Clear interrupt
cyg_drv_interrupt_acknowledge(EDB7XXX_CF_IRQ);
// Allow interrupts to happen again
cyg_drv_interrupt_unmask(EDB7XXX_CF_IRQ);
//*(unsigned *)PCIMR |= ~EDB7XXX_CF_DETECT_MASK;
}