From 75ca654c2a3a4cce24459a381311c259ce7ce8a3 Mon Sep 17 00:00:00 2001 From: Christian Cunningham Date: Thu, 24 Mar 2022 22:55:13 -0700 Subject: GPIO Interrupts --- include/cpu/irq.h | 9 ++++++++- include/symbols.h | 10 +++++++++- include/usr/timed.h | 1 + kernel/cpu/irq.c | 30 ++++++++++++++++++++++++++++-- usr/main.c | 28 ++++++++++++---------------- usr/timed.c | 29 ++++++++++++++++++++++++++++- 6 files changed, 86 insertions(+), 21 deletions(-) diff --git a/include/cpu/irq.h b/include/cpu/irq.h index 28e060b..e244cc9 100644 --- a/include/cpu/irq.h +++ b/include/cpu/irq.h @@ -6,7 +6,9 @@ #define SYS_TIMER_1_IRQ 2 #define SYS_TIMER_2_IRQ 3 #define SYS_TIMER_3_IRQ 4 -#define LOCAL_TIMER_IRQ 5 +#define GPIO_BANK_1_IRQ 5 +#define GPIO_BANK_2_IRQ 6 +#define LOCAL_TIMER_IRQ 7 #define MAX_IRQS LOCAL_TIMER_IRQ+1 struct IrqEntry { @@ -24,6 +26,11 @@ struct SysTimerInfo { void* arg; }; +struct GPIOInfo { + unsigned long pin; + unsigned long priority; +}; + static inline void enableirq(void) { asm volatile("cpsie i"); diff --git a/include/symbols.h b/include/symbols.h index b81b1a9..62f4a96 100644 --- a/include/symbols.h +++ b/include/symbols.h @@ -50,7 +50,7 @@ enum IRQ_BASIC_DISABLE = (IRQ_BASE + 0x224), // Peripherals Interrupts - //UART_IRQ = 57, + UART_0_IRQ = 57, GPIO_IRQ_0 = 49, GPIO_IRQ_1 = 50, GPIO_IRQ_2 = 51, @@ -117,6 +117,14 @@ enum #define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038)) #define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040)) #define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044)) +#define GPREN0 ((volatile unsigned int*)(MMIO_BASE+0x0020004C)) +#define GPREN1 ((volatile unsigned int*)(MMIO_BASE+0x00200050)) +#define GPFEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200058)) +#define GPFEN1 ((volatile unsigned int*)(MMIO_BASE+0x0020005C)) +#define GPAREN0 ((volatile unsigned int*)(MMIO_BASE+0x0020007C)) +#define GPAREN1 ((volatile unsigned int*)(MMIO_BASE+0x00200080)) +#define GPAFEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200088)) +#define GPAFEN1 ((volatile unsigned int*)(MMIO_BASE+0x0020008C)) #define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064)) #define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068)) // Controls actuation of pull up/down to ALL GPIO pins. diff --git a/include/usr/timed.h b/include/usr/timed.h index f3f941a..4cccc56 100644 --- a/include/usr/timed.h +++ b/include/usr/timed.h @@ -3,5 +3,6 @@ void loop(void); void loopt(void); +void consumer(void); #endif diff --git a/kernel/cpu/irq.c b/kernel/cpu/irq.c index ae29379..286f78d 100644 --- a/kernel/cpu/irq.c +++ b/kernel/cpu/irq.c @@ -20,7 +20,7 @@ unsigned long c_irq_handler(void) // Check if GPU Interrupt if (source & (1 << 8)) { // Check if UART Interrupt - if(load32(IRQ_PENDING2) & (1 << 25)) { + if(load32(IRQ_PENDING2) & (1 << (UART_0_IRQ-32))) { // Check if UART Interrupt is Masked if(load32(UART0_MIS) & (1<<4)) { // Get the UART data @@ -42,6 +42,13 @@ unsigned long c_irq_handler(void) } } } + if (load32(IRQ_PENDING2) & (1 << (GPIO_IRQ_0-32)) && irqs[GPIO_BANK_1_IRQ].handler != 0) { + struct GPIOInfo* g = irqs[GPIO_BANK_1_IRQ].handler_info; + if (*GPEDS0 & g->pin) { + add_thread(irqs[GPIO_BANK_1_IRQ].handler, 0, g->priority); + *GPEDS0 = g->pin; + } + } // Check if System Time Compare 0 Triggered the Interrupt if (*(volatile unsigned long*)SYS_TIMER_CS & SYS_TIMER_SC_M0 && irqs[SYS_TIMER_0_IRQ].handler != 0) { volatile unsigned long* timer_cs = (volatile unsigned long*)SYS_TIMER_CS; @@ -114,7 +121,18 @@ void subscribe_irq(unsigned long irq_num, void* handler, void* handler_info) if (irq_num >= MAX_IRQS) return; irqs[irq_num].handler = handler; - irqs[irq_num].handler_info = handler_info; + if (irq_num == GPIO_BANK_1_IRQ) { + if (irqs[irq_num].handler_info == 0) + irqs[irq_num].handler_info = handler_info; + else { + struct GPIOInfo* g = irqs[irq_num].handler_info; + struct GPIOInfo* new = handler_info; + g->pin |= new->pin; + g->priority = new->priority; + } + } else { + irqs[irq_num].handler_info = handler_info; + } switch (irq_num) { case UART_IRQ: store32(1<<4, UART0_IMSC); @@ -140,6 +158,11 @@ void subscribe_irq(unsigned long irq_num, void* handler, void* handler_info) store32(0x80, CORE0_TIMER_IRQCNTL); sys0(SYS_ENABLE_CNTV); break; + case GPIO_BANK_1_IRQ: + store32((1 << (49-32)), IRQ_ENABLE2); + struct GPIOInfo* g = irqs[irq_num].handler_info; + *GPREN0 = g->pin; + break; } } @@ -169,5 +192,8 @@ void unsubscribe_irq(unsigned long irq_num) store32(0x00, CORE0_TIMER_IRQCNTL); sys0(SYS_DISABLE_CNTV); break; + case GPIO_BANK_1_IRQ: + store32((1 << (49-32)), IRQ_DISABLE2); + break; } } diff --git a/usr/main.c b/usr/main.c index 0cc25d8..955b328 100644 --- a/usr/main.c +++ b/usr/main.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -35,23 +34,19 @@ static struct UartInfo UART_INFO = { .priority = 2, }; -static unsigned long simulated = 0; - -void producer(void) -{ - draw_string(0, 15, "Producing..."); - sys1(SYS_SEMAPHORE_V, &simulated); - draw_string(0, 15, "Produced! "); -} +static struct GPIOInfo gpinfo = { + .pin = (1<<16), + .priority = 0, +}; -void consumer(void) +void gptest(void) { - add_thread(producer, 0, 4); - while (1) { - draw_string(0, 16, "Consuming..."); - sys1(SYS_SEMAPHORE_P, &simulated); - draw_string(0, 16, "Consumed! "); - } + static unsigned long count = 0; + unsigned long gplev0 = *GPLEV0; + static char str[14]; + draw_hex32(0, 30, gplev0); + char* start = ulong_to_string(count++, str); + draw_string(0, 31, start); } void main(void) @@ -61,6 +56,7 @@ void main(void) subscribe_irq(SYS_TIMER_1_IRQ, loopt, &stime_1); subscribe_irq(SYS_TIMER_2_IRQ, loopt, &stime_2); subscribe_irq(SYS_TIMER_3_IRQ, loopt, &stime_3); + subscribe_irq(GPIO_BANK_1_IRQ, gptest, &gpinfo); add_thread(loop, 0, 8); add_thread(consumer, 0, 3); } diff --git a/usr/timed.c b/usr/timed.c index 9247acf..fd4f923 100644 --- a/usr/timed.c +++ b/usr/timed.c @@ -1,4 +1,5 @@ #define USR_TIMED_C +#include #include #include #include @@ -6,6 +7,25 @@ #include #include +static unsigned long simulated = 0; + +void producer(void) +{ + draw_string(0, 15, "Producing..."); + sys1(SYS_SEMAPHORE_V, &simulated); + draw_string(0, 15, "Produced! "); +} + +void consumer(void) +{ + add_thread(producer, 0, 4); + while (1) { + draw_string(0, 16, "Consuming..."); + sys1(SYS_SEMAPHORE_P, &simulated); + draw_string(0, 16, "Consumed! "); + } +} + void loop(void) { static char str[13]; @@ -22,7 +42,14 @@ void loop(void) draw_string(0, 12, " "); draw_string(0, 12, start); previous++; - wait_msec(3000); + //unsigned long gplev0 = *(volatile unsigned long*)GPLEV0; + //static unsigned long count = 0; + //draw_hex32(0, 13, gplev0); + //if (gplev0 & (1 << 16)) { + // draw_hex32(0, 17, count++); + // add_thread(producer, 0, 4); + //} + wait_msec(30000); add_thread(loop, 0, 3); } -- cgit v1.2.1