summaryrefslogtreecommitdiff
path: root/software/first
diff options
context:
space:
mode:
authorSilvan Jegen <s.jegen@gmail.com>2019-08-01 18:41:21 +0200
committerSilvan Jegen <s.jegen@gmail.com>2019-08-01 19:11:27 +0200
commitaa72093ffe1abafd605b5ec3b2d50c20b11c14a9 (patch)
tree39eb51dc8ec29d5f75c9c86fb7e171ad24504675 /software/first
parent3f8b15773b76750d0e877fac502277e2d5dcf791 (diff)
Start implementing irq setup and handling
Diffstat (limited to 'software/first')
-rw-r--r--software/first/first.c1
-rw-r--r--software/first/memory_map.inc1
-rw-r--r--software/first/setup_timer_irq.S34
-rw-r--r--software/first/super_blink.h1
4 files changed, 37 insertions, 0 deletions
diff --git a/software/first/first.c b/software/first/first.c
index ede96db..7505d6c 100644
--- a/software/first/first.c
+++ b/software/first/first.c
@@ -14,6 +14,7 @@ int main() {
};
setup_GPIO();
+ setup_timer_irq();
while (!error) {
set_LED(colours[ledNum], ON);
diff --git a/software/first/memory_map.inc b/software/first/memory_map.inc
index e28af43..b532fee 100644
--- a/software/first/memory_map.inc
+++ b/software/first/memory_map.inc
@@ -1,3 +1,4 @@
.equ GPIO_CTRL_ADDR, 0x10012000
.equ MTIME, 0x0200BFF8
+.equ MTIMECMP, 0x02004000
.equ MTIME_FREQUENCY, 33
diff --git a/software/first/setup_timer_irq.S b/software/first/setup_timer_irq.S
new file mode 100644
index 0000000..4ae714f
--- /dev/null
+++ b/software/first/setup_timer_irq.S
@@ -0,0 +1,34 @@
+.section .text
+.align 2
+.global setup_timer_irq
+.include "memory_map.inc"
+
+setup_timer_irq:
+ addi sp, sp, -16 # Allocate stack frame
+ sw ra, 12(sp) # save return address to the stack
+
+ lw t0, irq_handler # load address of irq_handler
+ slli t0, t0, 1 # shift address left by one; LSB will be 0 which is direct mode (what we want)
+ csrw mtvec, t0 # write handler address and mode
+
+ # Here we cannot use csrsi because it can only set up to 5 bits
+ li t0, 0x80 # set 7th bit (indexed from 0)
+ csrw mie, t0 # activate machine timer interrupt
+
+ # write high value to the timercmp just to be sure we don't
+ # trigger an interrupt by mistake
+ li t0, 0x7FFFFFFF # high number
+ li t1, 0xFFFFFFFF # high number
+ li t2, MTIMECMP # load address of timecmp register
+ sw t0, 4(t2) # store the first number to the upper part first
+ sw t1, 0(t2) # then the second to the lower part
+
+ csrsi mstatus, 0x4 # set 3rd bit to activate machine interrupts.
+
+ lw ra, 12(sp) # load return address
+ addi sp, sp, 16 # deallocate stack frame
+ ret
+
+
+irq_handler:
+ mret
diff --git a/software/first/super_blink.h b/software/first/super_blink.h
index 74cc00a..b53d55d 100644
--- a/software/first/super_blink.h
+++ b/software/first/super_blink.h
@@ -9,4 +9,5 @@
void setup_GPIO();
int set_LED(int color, int state);
+void setup_timer_irq();
void delay(int milliseconds);