|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright (c) 2006-2019, RT-Thread Development Team
|
|
|
+ * Copyright (c) 2006-2020, RT-Thread Development Team
|
|
|
*
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
*
|
|
@@ -17,8 +17,9 @@
|
|
|
#include <rtthread.h>
|
|
|
#include <rthw.h>
|
|
|
#include <exception.h>
|
|
|
-
|
|
|
-#define MAX_INTR 32
|
|
|
+#include <drivers/pin.h>
|
|
|
+#include "ls2k1000.h"
|
|
|
+#include "interrupt.h"
|
|
|
|
|
|
static struct rt_irq_desc irq_handle_table[MAX_INTR];
|
|
|
|
|
@@ -27,17 +28,141 @@ static void rt_hw_interrupt_handler(int vector, void *param)
|
|
|
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
|
|
|
}
|
|
|
|
|
|
+static void liointc_init(void)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ /* Router for LIOINTC0, to Core 0, INT0 (CPU IP2) */
|
|
|
+ for (i = 0; i < 32; i ++)
|
|
|
+ {
|
|
|
+ HWREG8(LIOINTC0_BASE + i) = LIOINTC_COREx_INTy(0, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Router for LIOINTC1, to Core 0, INT1 (CPU IP3) */
|
|
|
+ for (i = 0; i < 32; i ++)
|
|
|
+ {
|
|
|
+ HWREG8(LIOINTC1_BASE + i) = LIOINTC_COREx_INTy(0, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Disable all IRQs */
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_DISABLE) = 0xffffffff;
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_DISABLE) = 0xffffffff;
|
|
|
+
|
|
|
+ /* Set all IRQs to low level triggered (Default?) */
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) = 0x0;
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) = 0x0;
|
|
|
+
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) = 0x0;
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) = 0x0;
|
|
|
+}
|
|
|
+
|
|
|
+//set irq mode
|
|
|
+void liointc_set_irq_mode(int irq, int mode)
|
|
|
+{
|
|
|
+ if(irq < 32)
|
|
|
+ {
|
|
|
+ if(mode == PIN_IRQ_MODE_RISING)
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x0 << (irq));
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq));
|
|
|
+ }
|
|
|
+ else if(mode == PIN_IRQ_MODE_FALLING)
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq));
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq));
|
|
|
+ }
|
|
|
+ else if(mode == PIN_IRQ_MODE_HIGH_LEVEL)
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq));
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x0 << (irq));
|
|
|
+ }
|
|
|
+ else if(mode == PIN_IRQ_MODE_LOW_LEVEL)
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x0 << (irq));
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x0 << (irq));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq));
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(mode == PIN_IRQ_MODE_RISING)
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x0 << (irq - 32));
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq - 32));
|
|
|
+ }
|
|
|
+ else if(mode == PIN_IRQ_MODE_FALLING)
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq - 32));
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq - 32));
|
|
|
+ }
|
|
|
+ else if(mode == PIN_IRQ_MODE_HIGH_LEVEL)
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq - 32));
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x0 << (irq - 32));
|
|
|
+ }
|
|
|
+ else if(mode == PIN_IRQ_MODE_LOW_LEVEL)
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x0 << (irq - 32));
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x0 << (irq - 32));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq - 32));
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq - 32));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void liointc_isr(rt_ubase_t reg_base, rt_ubase_t isr_base,
|
|
|
+ int irq_base)
|
|
|
+{
|
|
|
+ rt_uint32_t isr, tmp;
|
|
|
+ int intx;
|
|
|
+ /* Mask to clear ISR */
|
|
|
+ isr = HWREG32(isr_base);
|
|
|
+
|
|
|
+ tmp = isr;
|
|
|
+ /* Handle each of them */
|
|
|
+ while (tmp)
|
|
|
+ {
|
|
|
+ rt_isr_handler_t irq_func;
|
|
|
+ void *param;
|
|
|
+ int irq;
|
|
|
+
|
|
|
+ intx = __rt_ffs(isr) - 1;
|
|
|
+ tmp &= ~(1 << intx);
|
|
|
+
|
|
|
+ irq = intx + irq_base;
|
|
|
+
|
|
|
+ irq_func = irq_handle_table[irq].handler;
|
|
|
+ param = irq_handle_table[irq].param;
|
|
|
+ irq_func(irq, param);
|
|
|
+#ifdef RT_USING_INTERRUPT_INFO
|
|
|
+ irq_handle_table[irq].counter++;
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Enable them again */
|
|
|
+ HWREG32(reg_base + LIOINTC_REG_INTC_ENABLE) = isr;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* This function will initialize hardware interrupt
|
|
|
*/
|
|
|
void rt_hw_interrupt_init(void)
|
|
|
{
|
|
|
rt_uint32_t idx;
|
|
|
+
|
|
|
rt_memset(irq_handle_table, 0x00, sizeof(irq_handle_table));
|
|
|
for (idx = 0; idx < MAX_INTR; idx ++)
|
|
|
{
|
|
|
irq_handle_table[idx].handler = rt_hw_interrupt_handler;
|
|
|
}
|
|
|
+
|
|
|
+ liointc_init();
|
|
|
}
|
|
|
|
|
|
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
|
|
@@ -56,34 +181,57 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
|
|
|
irq_handle_table[vector].param = param;
|
|
|
}
|
|
|
|
|
|
+ if(vector <= 32)
|
|
|
+ {
|
|
|
+ mips_unmask_cpu_irq(2);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ mips_unmask_cpu_irq(3);
|
|
|
+ }
|
|
|
+
|
|
|
return old_handler;
|
|
|
}
|
|
|
|
|
|
-void rt_hw_timer_handler(void);
|
|
|
-
|
|
|
void rt_do_mips_cpu_irq(rt_uint32_t ip)
|
|
|
{
|
|
|
void *param;
|
|
|
rt_isr_handler_t irq_func;
|
|
|
-
|
|
|
- if (ip == 7) {
|
|
|
+ if (ip == 7)
|
|
|
+ {
|
|
|
rt_hw_timer_handler();
|
|
|
- } else {
|
|
|
- irq_func = irq_handle_table[ip].handler;
|
|
|
- param = irq_handle_table[ip].param;
|
|
|
-
|
|
|
- /* do interrupt */
|
|
|
- irq_func(ip, param);
|
|
|
+ }
|
|
|
+ else if (ip == 2)
|
|
|
+ {
|
|
|
+ liointc_isr(LIOINTC0_BASE, CORE0_INTISR0, LIOINTC0_IRQBASE);
|
|
|
+ }
|
|
|
+ else if (ip == 3)
|
|
|
+ {
|
|
|
+ liointc_isr(LIOINTC1_BASE, CORE0_INTISR1, LIOINTC1_IRQBASE);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void rt_hw_interrupt_umask(int irq)
|
|
|
{
|
|
|
- mips_unmask_cpu_irq(irq);
|
|
|
+ if(irq < LIOINTC0_IRQBASE + 32)
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_ENABLE) = (1 << irq);
|
|
|
+ }
|
|
|
+ else if(irq < LIOINTC1_IRQBASE + 32)
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_ENABLE) = (1 << (irq - 32));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void rt_hw_interrupt_mask(int irq)
|
|
|
{
|
|
|
- mips_mask_cpu_irq(irq);
|
|
|
+ if(irq < LIOINTC0_IRQBASE + 32)
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_DISABLE) = (1 << irq);
|
|
|
+ }
|
|
|
+ else if(irq < LIOINTC1_IRQBASE + 32)
|
|
|
+ {
|
|
|
+ HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_DISABLE) = (1 << (irq - 32));
|
|
|
+ }
|
|
|
}
|
|
|
/*@}*/
|