This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RE: ISR occurs, but DSR does not.


	> 
	> 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;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]