Browse Source

Cleanup Interrupt for F1S

Use structure to handle the registers access, which simplified the logic
Howard Su 4 years ago
parent
commit
b22b7cbdfe
2 changed files with 38 additions and 70 deletions
  1. 30 50
      bsp/allwinner_tina/libcpu/interrupt.c
  2. 8 20
      bsp/allwinner_tina/libcpu/interrupt.h

+ 30 - 50
bsp/allwinner_tina/libcpu/interrupt.c

@@ -1,7 +1,7 @@
 /*
  * File      : interrupt.c
  * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2017, RT-Thread Development Team
+ * COPYRIGHT (C) 2017-2021, RT-Thread Development Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
  * Change Logs:
  * Date           Author       Notes
  * 2018-02-08     RT-Thread    the first version
+ * 2020-03-02     Howard Su    Use structure to access registers
  */
 
 #include <rthw.h>
@@ -38,9 +39,6 @@ static void rt_hw_interrupt_handler(int vector, void *param)
     rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
 }
 
-#define readl(addr)           (*(volatile unsigned int *)(addr))
-#define writel(value,addr)    (*(volatile unsigned int *)(addr) = (value))
-
 /**
  * This function will initialize hardware interrupt
  */
@@ -63,20 +61,20 @@ void rt_hw_interrupt_init(void)
     /* set base_addr reg */
     INTC->base_addr_reg = 0x00000000;
     /* clear enable */
-    INTC->en_reg0 = 0x00000000;
-    INTC->en_reg1 = 0x00000000;
+    INTC->en_reg[0] = 0x00000000;
+    INTC->en_reg[1] = 0x00000000;
     /* mask interrupt */
-    INTC->mask_reg0 = 0xFFFFFFFF;
-    INTC->mask_reg1 = 0xFFFFFFFF;
+    INTC->mask_reg[0] = 0xFFFFFFFF;
+    INTC->mask_reg[1] = 0xFFFFFFFF;
     /* clear pending */
-    INTC->pend_reg0 = 0x00000000;
-    INTC->pend_reg1 = 0x00000000;
+    INTC->pend_reg[0] = 0x00000000;
+    INTC->pend_reg[1] = 0x00000000;
     /* set priority */
-    INTC->resp_reg0 = 0x00000000;
-    INTC->resp_reg1 = 0x00000000;
+    INTC->resp_reg[0] = 0x00000000;
+    INTC->resp_reg[1] = 0x00000000;
     /* close fiq interrupt */
-    INTC->ff_reg0 = 0x00000000;
-    INTC->ff_reg1 = 0x00000000;
+    INTC->ff_reg[0] = 0x00000000;
+    INTC->ff_reg[1] = 0x00000000;
 }
 
 /**
@@ -85,20 +83,16 @@ void rt_hw_interrupt_init(void)
  */
 void rt_hw_interrupt_mask(int vector)
 {
-    rt_uint32_t mask_addr, data;
-
+    int index;
     if ((vector < 0) || (vector > INTERRUPTS_MAX))
     {
         return;
     }
 
-    mask_addr = (rt_uint32_t)(&INTC->mask_reg0);
-    mask_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
+    index = (vector & 0xE0) != 0;
+    vector = (vector & 0x1F);
 
-    vector &= 0x1F;
-    data = readl(mask_addr);
-    data |= 0x1 << vector;
-    writel(data, mask_addr);
+    INTC->mask_reg[index] |= 1 << vector;
 }
 
 /**
@@ -108,20 +102,16 @@ void rt_hw_interrupt_mask(int vector)
  */
 void rt_hw_interrupt_umask(int vector)
 {
-    rt_uint32_t mask_addr, data;
-
+    int index;
     if ((vector < 0) || (vector > INTERRUPTS_MAX))
     {
         return;
     }
 
-    mask_addr = (rt_uint32_t)(&INTC->mask_reg0);
-    mask_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
+    index = (vector & 0xE0) != 0;
+    vector = (vector & 0x1F);
 
-    vector &= 0x1F;
-    data = readl(mask_addr);
-    data &= ~(0x1 << vector);
-    writel(data, mask_addr);
+    INTC->mask_reg[index] &= ~(1 << vector);
 }
 
 /**
@@ -136,7 +126,7 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
         void *param, const char *name)
 {
     rt_isr_handler_t old_handler = RT_NULL;
-    rt_uint32_t pend_addr, en_addr, data;
+    int index;
 
     if ((vector < 0) || (vector > INTERRUPTS_MAX))
     {
@@ -151,19 +141,11 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
     isr_table[vector].handler = handler;
     isr_table[vector].param = param;
 
-    pend_addr = (rt_uint32_t)(&INTC->pend_reg0);
-    en_addr = (rt_uint32_t)(&INTC->en_reg0);
-    pend_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
-    en_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
+    index = (vector & 0xE0) != 0;
+    vector = (vector & 0x1F);
 
-    vector &= 0x1F;
-    data = readl(pend_addr);
-    data &= ~(0x1 << vector);
-    writel(data, pend_addr);
-
-    data = readl(en_addr);
-    data |= 0x1 << vector;
-    writel(data, en_addr);
+    INTC->pend_reg[index] &= ~(0x1 << vector);
+    INTC->en_reg[index] |= 0x1 << vector;
 
     return old_handler;
 }
@@ -173,7 +155,7 @@ void rt_interrupt_dispatch(rt_uint32_t fiq_irq)
     void *param;
     int vector;
     rt_isr_handler_t isr_func;
-    rt_uint32_t pend_addr, data;
+    int index;
 
     vector = INTC->vector_reg - INTC->base_addr_reg;
     vector = vector >> 2;
@@ -184,13 +166,11 @@ void rt_interrupt_dispatch(rt_uint32_t fiq_irq)
     /* jump to fun */
     isr_func(vector, param);
     /* clear pend bit */
-    pend_addr = (rt_uint32_t)(&INTC->pend_reg0);
-    pend_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
 
-    vector &= 0x1F;
-    data = readl(pend_addr);
-    data &= ~(0x1 << vector);
-    writel(data, pend_addr);
+    index = (vector & 0xE0) != 0;
+    vector = (vector & 0x1F);
+
+    INTC->pend_reg[index] &= ~(0x1 << vector);
 
 #ifdef RT_USING_INTERRUPT_INFO
     isr_table[vector].counter ++;

+ 8 - 20
bsp/allwinner_tina/libcpu/interrupt.h

@@ -1,7 +1,7 @@
 /*
  * File      : interrupt.h
  * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2017, RT-Thread Development Team
+ * COPYRIGHT (C) 2017-2021, RT-Thread Development Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
  * Change Logs:
  * Date           Author       Notes
  * 2018-02-08     RT-Thread    the first version
+ * 2020-03-2      Howard Su    Define same regsiters as an array
  */
 #ifndef __INTERRUPT_H__
 #define __INTERRUPT_H__
@@ -74,34 +75,21 @@ struct tina_intc
     volatile rt_uint32_t base_addr_reg;    /* 0x04 */
     volatile rt_uint32_t reserved0;
     volatile rt_uint32_t nmi_ctrl_reg;     /* 0x0C */
-    volatile rt_uint32_t pend_reg0;        /* 0x10 */
-    volatile rt_uint32_t pend_reg1;        /* 0x14 */
+    volatile rt_uint32_t pend_reg[2];        /* 0x10, 0x14 */
     volatile rt_uint32_t reserved1[2];
-    volatile rt_uint32_t en_reg0;          /* 0x20 */
-    volatile rt_uint32_t en_reg1;          /* 0x24 */
+    volatile rt_uint32_t en_reg[2];          /* 0x20, 0x24 */
     volatile rt_uint32_t reserved2[2];
-    volatile rt_uint32_t mask_reg0;        /* 0x30 */
-    volatile rt_uint32_t mask_reg1;        /* 0x34 */
+    volatile rt_uint32_t mask_reg[2];        /* 0x30, 0x34 */
     volatile rt_uint32_t reserved3[2];
-    volatile rt_uint32_t resp_reg0;        /* 0x40 */
-    volatile rt_uint32_t resp_reg1;        /* 0x44 */
+    volatile rt_uint32_t resp_reg[2];        /* 0x40, 0x44 */
     volatile rt_uint32_t reserved4[2];
-    volatile rt_uint32_t ff_reg0;          /* 0x50 */
-    volatile rt_uint32_t ff_reg1;          /* 0x54 */
+    volatile rt_uint32_t ff_reg[2];          /* 0x50, 0x54 */
     volatile rt_uint32_t reserved5[2];
-    volatile rt_uint32_t prio_reg0;        /* 0x60 */
-    volatile rt_uint32_t prio_reg1;        /* 0x64 */
-    volatile rt_uint32_t prio_reg2;        /* 0x68 */
-    volatile rt_uint32_t prio_reg3;        /* 0x6C */
+    volatile rt_uint32_t prio_reg[4];        /* 0x60 - 0x6c */
 } ;
 
 typedef struct tina_intc *tina_intc_t;
 
 #define INTC ((tina_intc_t)INTC_BASE_ADDR)
 
-void rt_hw_interrupt_init(void);
-void rt_hw_interrupt_mask(int vector);
-void rt_hw_interrupt_umask(int vector);
-rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, const char *name);
-
 #endif /* __INTERRUPT_H__ */