⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lh7a404_vic_driver.c

📁 在sharp 404开发板的串口测试代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 *     for VIC2 and mask it with the inverted value of the VIC2
 *     interrupt select register. Get the pending interrupt status from
 *     the FIQ status register for VIC2 and mask it with the value of
 *     the VIC2 interrupt select register. 'OR' the two masked values
 *     together to get a pending interrupt bitfield of enabled
 *     interrupts. Mask the 'OR'ed value with the bit fromt the
 *     interrupt source. If the resulting value is not zero, then
 *     return TRUE to the caller. Otherwise, return FALSE.
 * 
 * Parameters:
 *     source : Interrupt source of type VIC_INT_SOURCE_T
 *
 * Outputs: None
 *
 * Returns: Returns TRUE if the interrupt is pending, otherwise FALSE.
 *
 * Notes:
 *     This will only report the pending status of IRQ or FIQ
 *     configured interrupts.
 *
 **********************************************************************/
BOOL_32 vic_int_pending(VIC_INT_SOURCE_T source)
{
    UNS_32 status_irq, status_fiq, pstatus;
    BOOL_32 pending = FALSE;

    if ((source >= VIC_FIRST_VIC1_INTERRUPT) &&
        (source <= VIC_LAST_VIC1_INTERRUPT))
    {
        status_irq = VIC1->irqstatus & ~(VIC1->intsel);
        status_fiq = VIC1->fiqstatus & (VIC1->intsel);
        pstatus = (status_fiq | status_irq) &
            VIC_INT_SELECT((UNS_32)(source));
    }
    else
    {
        status_irq = VIC2->irqstatus & ~(VIC2->intsel);
        status_fiq = VIC2->fiqstatus & (VIC2->intsel);
        pstatus = (status_fiq | status_irq) &
            VIC_INT_SELECT((UNS_32)(source - VIC_FIRST_VIC2_INTERRUPT));
    }

    /* Was the unmasked IRQ or FIQ interrupt pending? */
    if (pstatus != 0)
    {
        /* Yes, it is pending */
        pending = TRUE;
    }

    return pending;
}

/***********************************************************************
 *
 * Function: vic_int_enabled
 *
 * Purpose: Check to see if an interrupt is enabled
 *
 * Processing:
 *     If the interrupt source is in the range of the first VIC, then
 *     check the VIC1 interrupt enabled register masked by the enable
 *     bit for the passed interrupt source. If the bit is set, then
 *     return TRUE to the caller. Otherwise, check the VIC2 interrupt
 *     enabled register masked by the enable bit for the passed
 *     interrupt source, adjusted for the 2nd VIC bit sift. If the bit
 *     is set, then return TRUE to the caller. Otherwise, return FALSE
 *     to the caller.
 * 
 * Parameters:
 *     source : Interrupt source of type VIC_INT_SOURCE_T
 *
 * Outputs: None
 *
 * Returns: Returns TRUE if the interrupt is enabled, otherwise FALSE.
 *
 * Notes: None
 *
 **********************************************************************/
BOOL_32 vic_int_enabled(VIC_INT_SOURCE_T source)
{
    UNS_32 intreg;
    BOOL_32 enabled = FALSE;

    if ((source >= VIC_FIRST_VIC1_INTERRUPT) &&
        (source <= VIC_LAST_VIC1_INTERRUPT))
    {
        intreg = VIC1->inten & VIC_INT_SELECT((UNS_32)source);
    }
    else
    {
        intreg = VIC2->inten & VIC_INT_SELECT((UNS_32)source -
            VIC_FIRST_VIC2_INTERRUPT);
    }

    /* Was the interrupt enabled? */
    if (intreg != 0)
    {
        /* Yes, it is enabled */
        enabled = TRUE;
    }

    return enabled;
}

/***********************************************************************
 *
 * Function: vic_clear_int
 *
 * Purpose: Clears the vectored interrupt (called after a vectored
 *          interrupt)
 *
 * Processing:
 *     If the interrupt source is in the range of the first VIC, then
 *     clear the interrupt from the first VIC. Otherwise, clear the
 *     interrupt from the second VIC. The interrupt is cleared by
 *     reading the vectored address register.
 * 
 * Parameters:
 *     source : Interrupt source of type VIC_INT_SOURCE_T
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void vic_clear_int(VIC_INT_SOURCE_T source)
{
    if ((source >= VIC_FIRST_VIC1_INTERRUPT) &&
        (source <= VIC_LAST_VIC1_INTERRUPT))
    {
        VIC1->vecaddr = 0x00000000;
    }
    else
    {
        VIC2->vecaddr = 0x00000000;
    }
}

/***********************************************************************
*
* Function: vic_arm_irq_dispatcher
*
* Purpose: Default ARM core IRQ interrupt dispatcher
*
* Processing:
*     This interrupt dispatch function is called when an IRQ interrupt
*     is generated at the ARM core. The VIC vectored address register
*     is read for both VICs. If they are the same, then the interrupt
*     source was VIC2 and the handler address (also the VIC2 vectored
*     address register) is used as the function address and called.
*     The VIC(2) is then cleared and the interrupt is exited. If the
*     addresses are not the same, then the interrupt source was VIC1
*     and the handler address (also the VIC1 vectored address register)
*     is used as the function address and called. The VIC(1) is then
*     cleared and the interrupt is exited.
* 
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
***********************************************************************/
#define __arm
//#ifndef __GNUC__
//#ifndef __ICCARM__


//#ifdef __ghs__
//__interrupt void vic_arm_irq_dispatcher(void)
//#endif

//#ifdef __arm
//__irq void vic_arm_irq_dispatcher(void)
void vic_arm_irq_dispatcher(void)
//#endif
{
    PFV vic_vecaddr;

    /* Check VIC1 IRQ status - if it is 0, then there are no VIC1
       interrupts pending. That means, go service VIC2 interrupts
       instead. */
    if (VIC1->irqstatus != 0)
    {
        /* Use VIC1 for the jump address */
        vic_vecaddr = (PFV) VIC1->nv_vecaddr;
    }
    else
    {
        /* Use VIC2 for the jump address */
        vic_vecaddr = (PFV) VIC2->nv_vecaddr;
    }

    /* Jump to interrupt handler */
    vic_vecaddr();
}
//#endif
//#endif

/***********************************************************************
*
* Function: vic1_irq_dispatcher
*
* Purpose: Default IRQ interrupt dispatcher for VIC1
*
* Processing:
*     This function is called by the vic_arm_irq_dispatcher function
*     when a vectored interrupt is configured as a standard IRQ type
*     interrupt and the interrupt source is VIC1. All interrupts for
*     this VIC are checked against the interrupt status and verified
*     that it is not masked. If it is pending and the interrupt
*     function is not 0x00000000, then the interrupt function is
*     called.
* 
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: This dispatcher does not support nesting or prioritization
*
***********************************************************************/
void vic1_irq_dispatcher(void)
{
    UNS_32 selints;
    VIC_INT_SOURCE_T source = VIC_FIRST_VIC1_INTERRUPT;

    /* Get mask for valid IRQ interrupts */
    selints = ~(VIC1->intsel);

    /* Loop through all interrupts looking for the first active
       interrupt */
    while (source <= VIC_LAST_VIC1_INTERRUPT)
    {
        if ((VIC1->irqstatus & selints & VIC_INT_SELECT(source)) != 0)
        {
            if (vic_func_ptrs[source] != (PFV) 0x00000000)
            {
                /* Jump to interrupt handler */
                vic_func_ptrs[source]();
            }

            /* Force loop exit */
            source += VIC_LAST_VIC1_INTERRUPT;
        }
        else
        {
            source++;
        }
    }
}

/***********************************************************************
*
* Function: vic2_irq_dispatcher
*
* Purpose: Default IRQ interrupt dispatcher for VIC2
*
* Processing:
*     This function is called by the vic_arm_irq_dispatcher function
*     when a vectored interrupt is configured as a standard IRQ type
*     interrupt and the interrupt source is VIC2. All interrupts for
*     this VIC are checked against the interrupt status and verified
*     that it is not masked. If it is pending and the interrupt
*     function is not 0x00000000, then the interrupt function is
*     called.
* 
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: This dispatcher does not support nesting or prioritization
*
***********************************************************************/
void vic2_irq_dispatcher(void)
{
	   	UNS_32 selints;
	   // VIC_INT_SOURCE_T source = VIC_FIRST_VIC2_INTERRUPT;

	   	static UNS_32  vic1,vic2,i,tmp;
		
		VIC_INT_SOURCE_T source = VIC_UART2INTR;

		vic1= (0x80008000);  ///read status register
		vic2= (0x8000a000);

		for(i=0;i<32;i++)
		{
			tmp= vic2 & (0x1<<i);
			if (tmp)
				break;
		};

		
		source = i + 32;

	    /* Get mask for valid IRQ interrupts */
	    selints = ~(VIC2->intsel);

	    /* Loop through all interrupts looking for the first active
	       interrupt */
	    while (source <= VIC_LAST_VIC2_INTERRUPT)
	    {
	        if ((VIC2->irqstatus & selints &
	            VIC_INT_SELECT(source - VIC_FIRST_VIC2_INTERRUPT)) != 0)
	        {
	            if (vic_func_ptrs[source] != (PFV) 0x00000000)
	            {
	                /* Jump to interrupt handler */
	                vic_func_ptrs[source]();	///
	            }

	            /* Force loop exit */
	            source += VIC_LAST_VIC2_INTERRUPT;
	        }
	        else
	        {
	            source++;
	        }
	    }
	
		
}













⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -