📄 lh79524_int_driver.c
字号:
* 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 fiq_ioctl(INT_32 devid,
INT_32 cmd,
INT_32 arg)
{
INT_CFG_T *intcfgptr = (INT_CFG_T *) devid;
STATUS status = _ERROR;
if (intcfgptr->init == TRUE)
{
status = _NO_ERROR;
switch (cmd)
{
/* Enable global FIQ, arg = 1 enable, arg = 0 disable */
case FIQ_GLOBAL_ENABLE:
if (arg == 1)
{
/* Enable FIQ */
int_enable_fiq();
}
else if (arg == 0)
{
/* Disable FIQ */
int_disable_fiq();
}
else
{
status = _ERROR;
}
break;
/* Enable specific VIC source as FIQ, arg = specific VIC source
range from 0 - 31 as described in the notes section of the
comments */
case FIQ_ENABLE_SOURCE:
if ((arg >= 0) && (arg <= 31))
{
/* configure source as fiq */
VIC->intselect |= _SBF((UNS_32)arg, 1);
/* enable int generation for the source */
VIC->intenable |= _SBF((UNS_32)arg, 1);
}
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 FIQ_DISABLE_SOURCE:
if ((arg >= 0) && (arg <= 31))
{
/* disable int generation for the source */
VIC->intenclear |= _SBF((UNS_32)arg, 1);
}
else
{
status = _ERROR;
}
break;
/* Set up FIQ interruption handling routine, arg is the
address of handling routine */
case FIQ_SET_HANDLER:
/* Set up user FIQ interruption handler */
LH79524_fiq_handler_addr = (UNS_32)arg;
break;
/* Remove FIQ interruption handling routine, no arg */
case FIQ_REMOVE_HANDLER:
/* Set up FIQ handler as default address */
LH79524_fiq_handler_addr =
(UNS_32)LH79524_default_fiq_handler;
break;
case FIQ_GET_STATUS:
switch (arg)
{
/* Return holds the 32 VIC source masked FIQ status,
bit set if corresponding VIC is set as FIQ and
enabled */
case FIQ_GET_ENABLE:
/* return bit is 1 only when enabled and set as FIQ */
status = (VIC->intenable & VIC->intselect);
break;
/* Return holds which source is generating FIQ, bit
set if corresponding VIC is set as FIQ and enabled
and there is a int pending */
case FIQ_GET_PENDING:
/* Return pending fiq */
status = VIC->fiqstatus;
break;
/* Returns raw interruptions that is set as fiq */
case FIQ_GET_RAW:
/* Return raw fiq */
status = (VIC->rawintr & VIC->intselect);
break;
case FIQ_GET_HANDLER:
/* Return fiq handler routine address */
status = *((volatile UNS_32 *)ARM_FIQ_VEC);
break;
default:
status = _ERROR;
break;
}
default:
status = _ERROR;
break;
}
}
return status;
}
/***********************************************************************
*
* Function: swi_ioctl
*
* Purpose: SWI 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 SWI 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 swi_ioctl(INT_32 devid,
INT_32 cmd,
INT_32 arg)
{
INT_CFG_T *intcfgptr = (INT_CFG_T *) devid;
STATUS status = _ERROR;
if (intcfgptr->init == TRUE)
{
status = _NO_ERROR;
switch (cmd)
{
/* Enable specific VIC source as SWI, arg = VIC source */
case SWI_ENABLE_SOURCE:
VIC->softint |= _SBF((UNS_32)arg, 1);
break;
/* Disable specific VIC source as SWI, arg = VIC source */
case SWI_DISABLE_SOURCE:
VIC->softintclear |= _SBF((UNS_32)arg, 1);
break;
/* Set up SWI interruption handling routine, arg = handler
addr */
case SWI_SET_HANDLER:
LH79524_swi_handler_addr = (UNS_32)arg;
break;
/* Remove SWI interruption handling routine, no arg */
case SWI_REMOVE_HANDLER:
LH79524_swi_handler_addr =
(UNS_32)LH79524_default_swi_handler;
break;
case SWI_GET_STATUS:
switch (arg)
{
/* Return holds the 32 VIC source masked SWI status,
bit set if corresponding VIC is set as SWI and
enabled */
case SWI_GET_ENABLE:
status = VIC->softint;
break;
/* Return holds which source is generating SWI, bit
set if corresponding VIC is set as SWI and enabled
and there is a int pending */
case SWI_GET_PENDING:
/* Return pending swi fiq */
status = (VIC->rawintr & VIC->softint);
break;
case SWI_GET_HANDLER:
/* Get the current SWI handler address */
status = *((volatile UNS_32 *)ARM_SWI_VEC);
break;
default:
status = _ERROR;
break;
}
default:
status = _ERROR;
break;
}
}
return status;
}
/***********************************************************************
*
* Function: int_read
*
* Purpose: INT read function (stub only)
*
* Processing:
* Return 0 to the caller.
*
* Parameters:
* devid: Pointer to int timer config structure
* buffer: Pointer to data buffer to copy to
* max_bytes: Number of bytes to read
*
* Outputs: None
*
* Returns: Number of bytes actually read (always 0)
*
* Notes: None
*
**********************************************************************/
INT_32 int_read(INT_32 devid,
void *buffer,
INT_32 max_bytes)
{
return 0;
}
/***********************************************************************
*
* Function: int_write
*
* Purpose: INT write function (stub only)
*
* Processing:
* Return 0 to the caller.
*
* Parameters:
* devid: Pointer to int timer config structure
* buffer: Pointer to data buffer to copy from
* n_bytes: Number of bytes to write
*
* Outputs: None
*
* Returns: Number of bytes actually written (always 0)
*
* Notes: None
*
**********************************************************************/
INT_32 int_write(INT_32 devid,
void *buffer,
INT_32 n_bytes)
{
return 0;
}
/**********************************************************************
*
* Function: init_irq_interrupts()
*
* Purpose:
* Put the VIC interface in a state where interrupts can be
* installed.
*
* Processing:
* See comments below.
*
* Parameters:
* None
*
* Outputs:
* None
*
* Returns:
* Non-zero upon error. Otherwise return 0.
*
* Notes:
* This function must be called before setting up any device
* interrupts.
*
*********************************************************************/
INT_32 init_irq_interrupts(void)
{
/* Open IRQ */
if ((dev_irq = irq_open(0,0)) == 0x0)
{
/* Error opening the device */
return 2;
}
int_enable_irq();
return 0;
}
/**********************************************************************
*
* Function: create_irq_interrupt()
*
* Purpose:
* Instantiate a hardware interrupt vector
*
* Processing:
* Set the VIC controller regaisters so that the specified
* interrupt can recieve service.
*
* Parameters:
* source - Which interrupt to use
* vector - Where to put the interrupt handler in the table
* handler - Pointer to (void (*p)(void)) irq handler
*
* Outputs: VIC registers
*
* Returns:
* Non-zero value if the parameters do not make sense or if
* the interrupt device has not been opened. Otherwise
* return 0.
*
* Notes:
* none
*
*********************************************************************/
INT_32 create_irq_interrupt(UNS_32 source, UNS_32 vector, PFV handler)
{
if(!dev_irq)
return -1;
if ((source <= 31) && (vector <=15))
{
/* configure source as irq */
VIC->intselect &= (~_SBF(source, 1));
/* enable int generation for the source */
VIC->intenable |= _SBF(source, 1);
/* Assign priority */
VIC->vectcntl[vector] = source;
/* Enable VIC control */
VIC->vectcntl[vector] |= VIC_VECTCNTL_ENABLE;
VIC->vectaddr[vector] = (UNS_32)handler;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -