📄 lh79524_int_driver.c
字号:
}
/***********************************************************************
*
* Function: irq_close
*
* Purpose: Close the IRQ operation
*
* Processing:
* If init is not TRUE, then return _ERROR to the caller as the
* device was not previously opened. Otherwise, set init to
* FALSE, and return _NO_ERROR to the caller.
*
* Parameters:
* devid: Pointer to IRQ config structure
*
* Outputs: None
*
* Returns: The status of the close operation
*
* Notes: None
*
**********************************************************************/
STATUS irq_close(INT_32 devid)
{
INT_CFG_T *intcfgptr = (INT_CFG_T *) devid;
STATUS status = _ERROR;
INT_32 priority;
if (intcfgptr->init == TRUE)
{
status = _NO_ERROR;
/* Clear VIC registers */
VIC->intenclear = ALL_SOURCES;
VIC->vectoraddr = 0;
for (priority = 0;
priority <= 15; priority++)
{
VIC->vectcntl[priority] = 0;
VIC->vectaddr[priority] = 0;
}
VIC->softintclear = ALL_SOURCES;
VIC->intselect = 0;
VIC->defvectaddr = 0;
VIC->defvectaddr = 0x0;
*((volatile UNS_32 *)ARM_IRQ_VEC) = 0x0;
*((volatile UNS_32 *)ARM_RESERVED_VEC) = 0x0;
/* Disable IRQ */
int_disable_irq();
intcfgptr->init = FALSE;
}
return status;
}
/***********************************************************************
*
* Function: fiq_close
*
* Purpose: Close the FIQ operation
*
* Processing:
* If init is not TRUE, then return _ERROR to the caller as the
* device was not previously opened. Otherwise, set init to
* FALSE, and return _NO_ERROR to the caller.
*
* Parameters:
* devid: Pointer to FIQ config structure
*
* Outputs: None
*
* Returns: The status of the close operation
*
* Notes: None
*
**********************************************************************/
STATUS fiq_close(INT_32 devid)
{
INT_CFG_T *intcfgptr = (INT_CFG_T *) devid;
STATUS status = _ERROR;
if (intcfgptr->init == TRUE)
{
status = _NO_ERROR;
intcfgptr->init = FALSE;
/* Set up FIQ vector address */
*((volatile UNS_32 *)ARM_FIQ_VEC) = (UNS_32)LH79524_default_fiq_handler;
/* Disable FIQ */
int_disable_fiq();
}
return status;
}
/***********************************************************************
*
* Function: swi_close
*
* Purpose: Close the SWI operation
*
* Processing:
* If init is not TRUE, then return _ERROR to the caller as the
* device was not previously opened. Otherwise, set init to
* FALSE, and return _NO_ERROR to the caller.
*
* Parameters:
* devid: Pointer to SWI config structure
*
* Outputs: None
*
* Returns: The status of the close operation
*
* Notes: None
*
**********************************************************************/
STATUS swi_close(INT_32 devid)
{
INT_CFG_T *intcfgptr = (INT_CFG_T *) devid;
STATUS status = _ERROR;
if (intcfgptr->init == TRUE)
{
status = _NO_ERROR;
intcfgptr->init = FALSE;
/* Install SWI vector handler address */
*((volatile UNS_32 *)ARM_SWI_VEC) = (UNS_32)LH79524_default_swi_handler;
}
return status;
}
/***********************************************************************
*
* Function: irq_ioctl
*
* Purpose: IRQ configuration block
*
* Processing:
* This function is a large case block. Based on the passed function
* and option values, set or get the appropriate int timer
* parameter.
*
* Parameters:
* devid: Pointer to IRQ config structure
* cmd: ioctl command
* arg: ioctl argument
*
* Outputs: None
*
* Returns: The status of the ioctl operation
*
* Notes:
* VIC source -
* VIC_EXINT0 = 0, external interrupt 0
* VIC_EXINT1 = 1, external interrupt 1
* VIC_EXINT2 = 2, external interrupt 2
* VIC_EXINT3 = 3, external interrupt 3
* VIC_EXINT4 = 4, external interrupt 4
* VIC_EXINT5 = 5, external interrupt 5
* VIC_EXINT6 = 6, external interrupt 6
* VIC_EXINT7 = 7, external interrupt 7
* VIC_SPAREINT0 = 8, spare interrupt 0
* VIC_COMRX = 9, debug channel receive interrupt
* VIC_COMTX = 10, debug channel transmit interrupt
* VIC_SSPRXTO = 11, SSP receive timeout interrupt
* VIC_CLCD = 12, LCD controller combined interrupt
* VIC_SSPTX = 13, SSP transmit interrupt
* VIC_SSPRX = 14, SSP receive interrupt
* VIC_SSPROR = 15, SSP receive overrun interrupt
* VIC_SSPINT = 16, SSP combined interrupt
* VIC_TIMER0 = 17, counter-timer0 nterrupt
* VIC_TIMER1 = 18, counter-timer1 interrupt
* VIC_TIMER2 = 19, counter-timer2 interrupt
* VIC_TIMER3 = 20, counter-timer3 interrupt
* VIC_UARTRX0 = 21, UART0 Receive interrupt
* VIC_UARTTX0 = 22, UART0 Transmit interrupt
* VIC_UARTINT0 = 23, UART0 combined interrupt
* VIC_UARTINT1 = 24, UART1 combined interrupt
* VIC_UARTINT2 = 25, UART2 combined interrupt
* VIC_DMA = 26, DMA combined interrupt
* VIC_SPAREINT1 = 27, spare interrupt 1
* VIC_SPAREINT2 = 28, spare interrupt 2
* VIC_SPAREINT3 = 29, spare interrupt 3
* VIC_RTCINT = 30, Real-time Clock interrupt 1
* VIC_WDTINT = 31, Watchdog timer interrupt 1
*
**********************************************************************/
STATUS irq_ioctl(INT_32 devid,
INT_32 cmd,
INT_32 arg)
{
INT_CFG_T *intcfgptr = (INT_CFG_T *) devid;
STATUS status = _ERROR;
INT_32 temp;
if (intcfgptr->init == TRUE)
{
status = _NO_ERROR;
switch (cmd)
{
/* Enable global FIQ, arg = 1 enable, arg = 0 disable */
case IRQ_GLOBAL_ENABLE:
if (arg == 1)
{
/* Enable IRQ */
int_enable_irq();
}
else if (arg == 0)
{
/* Disable IRQ */
int_disable_irq();
}
else
{
status = _ERROR;
}
break;
/* Enable specific VIC source as IRQ, arg = specific VIC source
range from 0 - 31 as described in the notes section of the
comments */
case IRQ_ENABLE_SOURCE:
if ((arg >= 0) && (arg <= 31))
{
/* configure source as irq */
VIC->intselect &= (~_SBF((UNS_32)arg, 1));
/* enable int generation for the source */
VIC->intenable |= _SBF((UNS_32)arg, 1);
irq_current_source = arg;
/* Assign default priority as 14 */
VIC->vectcntl[14] = (UNS_32)irq_current_source;
/* Enable VIC control */
VIC->vectcntl[14] |= VIC_VECTCNTL_ENABLE;
}
else
{
status = _ERROR;
}
break;
/* Disable specific VIC, arg = specific VIC source
range from 0 - 31 as described in the notes section of the
comments */
case IRQ_DISABLE_SOURCE:
if ((arg >= 0) && (arg <= 31))
{
/* disable int generation for the source */
VIC->intenclear |= _SBF((UNS_32)arg, 1);
irq_current_source = arg;
}
else
{
status = _ERROR;
}
break;
/* Set up current operation source before
IRQ_SET_PRIORITY */
case IRQ_SET_CURRENT_SOURCE:
if ((arg >= 0) & (arg <= 31))
{
irq_current_source = arg;
}
else
{
status = _ERROR;
}
break;
/* Set the priority of the interruption for current
VIC source, arg from 0 to 15, 0 is the highest
priority, 15 is the lowest. status
holds the current irq source. */
case IRQ_SET_PRIORITY:
if (irq_current_source == VIC_BAD_SOURCE)
{
status = _ERROR;
}
else if ((arg >= 0) & (arg <=15))
{
/* Assign priority */
VIC->vectcntl[arg] = (UNS_32)irq_current_source;
/* Enable VIC control */
VIC->vectcntl[arg] |= VIC_VECTCNTL_ENABLE;
status = irq_current_source;
}
else
{
status = _ERROR;
}
break;
/* Set up IRQ interruption handling routine, arg is the
address of handling routine, this func. can only be called
after IRQ_SET_CURRENT_SOURCE and IRQ_SET_PRIORITY.
status holds the priority of current irq source */
case IRQ_SET_HANDLER:
/* Set up user IRQ interruption handler */
for (temp=0; temp<=15; temp++)
{
if( VIC->vectcntl[temp] == ((UNS_32)irq_current_source |
VIC_VECTCNTL_ENABLE))
{
break;
}
}
VIC->vectaddr[temp] = (UNS_32)arg;
status = temp;
break;
/* Remove IRQ interruption handling routine, arg is the VIC
source, return the priority of VIC source */
case IRQ_REMOVE_HANDLER:
if ((arg >= 0) && (arg <= 31))
{
for (temp=0; temp<=15; temp++)
{
if( VIC->vectcntl[temp] == ((UNS_32)arg |
VIC_VECTCNTL_ENABLE))
{
VIC->vectcntl[temp] = 0x0;
VIC->vectaddr[temp] = 0x0;
status = temp;
break;
}
}
}
else
{
status = _ERROR;
}
break;
case IRQ_GET_STATUS:
switch (arg)
{
/* Return holds the 32 VIC source masked IRQ status,
bit set if corresponding VIC is set as IRQ and
enabled */
case IRQ_GET_ENABLE:
/* return bit is 1 only when enabled and set as IRQ */
status = (VIC->intenable & (~VIC->intselect));
break;
/* Return holds which source is generating IRQ, bit
set if corresponding VIC is set as IRQ and enabled
and there is a int pending */
case IRQ_GET_PENDING:
/* Return pending irq */
status = VIC->irqstatus;
break;
/* Returns raw interruptions that is set as irq */
case IRQ_GET_RAW:
/* Return raw irq */
status = (VIC->rawintr & (~VIC->intselect));
break;
case IRQ_GET_HANDLER:
/* Return irq handler routine address for the source,
arg is the VIC source, IRQ_SET_CURRENT_SOURCE must
be called before this */
if (irq_current_source == VIC_BAD_SOURCE)
{
status = _ERROR;
}
else
{
status = _ERROR;
for (temp=0; temp<=15; temp++)
{
if( VIC->vectcntl[temp] == ((UNS_32)irq_current_source |
VIC_VECTCNTL_ENABLE))
{
status = VIC->vectaddr[temp];
break;
}
}
}
break;
default:
status = _ERROR;
break;
}
default:
status = _ERROR;
break;
}
}
return status;
}
/***********************************************************************
*
* Function: fiq_ioctl
*
* Purpose: FIQ configuration block
*
* Processing:
* This function is a large case block. Based on the passed function
* and option values, set or get the appropriate int timer
* parameter.
*
* Parameters:
* devid: Pointer to FIQ config structure
* cmd: ioctl command
* arg: ioctl argument
*
* Outputs: None
*
* Returns: The status of the ioctl operation
*
* Notes:
* VIC source -
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -