aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Cunningham <cc@localhost>2022-03-24 22:55:13 -0700
committerChristian Cunningham <cc@localhost>2022-03-24 22:55:13 -0700
commit75ca654c2a3a4cce24459a381311c259ce7ce8a3 (patch)
tree2549dd19a9bd1484f8ca48246d4bf4b40b937f42
parentc5b6f1611ea1f4685ef02f65fc0362f9c22c344f (diff)
GPIO Interrupts
-rw-r--r--include/cpu/irq.h9
-rw-r--r--include/symbols.h10
-rw-r--r--include/usr/timed.h1
-rw-r--r--kernel/cpu/irq.c30
-rw-r--r--usr/main.c28
-rw-r--r--usr/timed.c29
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 <cpu.h>
#include <globals.h>
#include <graphics/lfb.h>
#include <symbols.h>
@@ -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 <cpu.h>
#include <globals.h>
#include <graphics/lfb.h>
#include <symbols.h>
@@ -6,6 +7,25 @@
#include <usr/timed.h>
#include <util/time.h>
+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);
}