summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew Barbier <dbarbi1@gmail.com>2018-07-02 15:23:10 -0500
committerDrew Barbier <dbarbi1@gmail.com>2018-07-02 15:23:10 -0500
commitff3a78a64798c8cce7f2a10256a26a3e91c0351c (patch)
tree77a5d4384ce212e7a9fbfed111d068fcf6a3a15f
parent482cb468dd680cd268e483a9b160acb222d1cc3f (diff)
add busy wait and extra buttons/irq
-rw-r--r--software/clic_vectored/clic_vectored.c68
1 files changed, 52 insertions, 16 deletions
diff --git a/software/clic_vectored/clic_vectored.c b/software/clic_vectored/clic_vectored.c
index db2435d..38a564e 100644
--- a/software/clic_vectored/clic_vectored.c
+++ b/software/clic_vectored/clic_vectored.c
@@ -1,5 +1,4 @@
// See LICENSE for license details.
-
#include <stdio.h>
#include <stdlib.h>
#include "platform.h"
@@ -8,6 +7,7 @@
#include <unistd.h>
#include "sifive/devices/clic.h"
#include "clic/clic_driver.h"
+#include "sifive/devices/clint.h"
#ifndef _SIFIVE_COREPLEXIP_ARTY_H
#error 'local_interrupts' demo only supported for Core IP Eval Kits
@@ -27,31 +27,34 @@ clic_instance_t clic;
const char * instructions_msg = " \
\n\
- SiFive, Inc\n\
- E21 Core IP Eval Kit 'clic_interrupts' demo.\n\
+ SiFive, Inc\n\
+ E21 Core IP Eval Kit 'clic_vectored' demo.\n\
+ This demo uses buttons 0, 1, and 2 on the\n\
+ Arty board to trigger vectored clic interrupts.\n\
\n\
-The Buttons 0-3 and Switch 3 are enabled as local\n\
-interrupts sources. A .5 s 'debounce' timer is used \n\
-between these interrupts. Software interrupts are\n\
-used to print a message while debouncing.\n\
-Note the priority of the interrupts sources.\n\
\n";
void print_instructions() {
+ write (STDERR_FILENO, instructions_msg, strlen(instructions_msg));
+}
- //write (STDERR_FILENO, instructions_msg, strlen(instructions_msg));
- printf(instructions_msg);
+//busy wait for the specified time
+void wait_ms(uint64_t ms) {
+ static const uint64_t ms_tick = RTC_FREQ/1000;
+ volatile uint64_t * mtime = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME);
+ uint64_t then = (ms_tick * ms) + *mtime;
+ while(*mtime<then);
}
void button_0_isr(void) __attribute__((interrupt));
void button_0_isr(void) {
// Toggle Red LED
-
- const char button_0_msg[] = "Button 0 was pressed. Toggle Red.\n";
- write (STDOUT_FILENO, button_0_msg, strlen(button_0_msg));
+ printf("Button 0 was pressed. Toggle Red.\n");
+ GPIO_REG(GPIO_OUTPUT_VAL) = GPIO_REG(GPIO_OUTPUT_VAL) ^ (0x1 << RED_LED_OFFSET);
+ wait_ms(500);
+ clic_enable_interrupt(&clic, (LOCALINTIDBASE + LOCAL_INT_BTN_0));
GPIO_REG(GPIO_OUTPUT_VAL) = GPIO_REG(GPIO_OUTPUT_VAL) ^ (0x1 << RED_LED_OFFSET);
- clic_clear_pending(&clic, (LOCALINTIDBASE + LOCAL_INT_BTN_0));
}
void button_0_setup(void) {
@@ -59,6 +62,36 @@ void button_0_setup(void) {
clic_enable_interrupt(&clic, (LOCALINTIDBASE + LOCAL_INT_BTN_0));
}
+void button_1_isr(void) __attribute__((interrupt));
+void button_1_isr(void) {
+ // Toggle Red LED
+ printf("Button 1 was pressed. Toggle Blue.\n");
+ GPIO_REG(GPIO_OUTPUT_VAL) = GPIO_REG(GPIO_OUTPUT_VAL) ^ (0x1 << BLUE_LED_OFFSET);
+ wait_ms(500);
+ clic_enable_interrupt(&clic, (LOCALINTIDBASE + LOCAL_INT_BTN_1));
+ GPIO_REG(GPIO_OUTPUT_VAL) = GPIO_REG(GPIO_OUTPUT_VAL) ^ (0x1 << BLUE_LED_OFFSET);
+}
+
+void button_1_setup(void) {
+ clic_install_handler(&clic, (LOCALINTIDBASE + LOCAL_INT_BTN_1), button_1_isr);
+ clic_enable_interrupt(&clic, (LOCALINTIDBASE + LOCAL_INT_BTN_1));
+}
+
+void button_2_isr(void) __attribute__((interrupt));
+void button_2_isr(void) {
+ // Toggle Red LED
+ printf("Button 2 was pressed. Toggle Green.\n");
+ GPIO_REG(GPIO_OUTPUT_VAL) = GPIO_REG(GPIO_OUTPUT_VAL) ^ (0x1 << GREEN_LED_OFFSET);
+ wait_ms(500);
+ clic_enable_interrupt(&clic, (LOCALINTIDBASE + LOCAL_INT_BTN_2));
+ GPIO_REG(GPIO_OUTPUT_VAL) = GPIO_REG(GPIO_OUTPUT_VAL) ^ (0x1 << GREEN_LED_OFFSET);
+}
+
+void button_2_setup(void) {
+ clic_install_handler(&clic, (LOCALINTIDBASE + LOCAL_INT_BTN_2), button_2_isr);
+ clic_enable_interrupt(&clic, (LOCALINTIDBASE + LOCAL_INT_BTN_2));
+}
+
void config_gpio() {
// Configure LEDs as outputs.
GPIO_REG(GPIO_INPUT_EN) &= ~((0x1<< RED_LED_OFFSET) | (0x1<< GREEN_LED_OFFSET) | (0x1 << BLUE_LED_OFFSET)) ;
@@ -72,16 +105,19 @@ int main(int argc, char **argv)
clear_csr(mie, IRQ_M_SOFT);
clear_csr(mie, IRQ_M_TIMER);
-
+ //initialize clic registers and vector table
clic_init(&clic, CLIC_HART0_ADDR,
(interrupt_function_ptr_t*)localISR,
default_handler,
CLIC_NUM_INTERRUPTS,
CLIC_NUM_CONFIG_BITS);
-
+ //initialize gpio and buttons.
+ //each button registers an interrupt handler
config_gpio();
button_0_setup();
+ button_1_setup();
+ button_2_setup();
// Enable all global interrupts
set_csr(mstatus, MSTATUS_MIE);