1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
// See LICENSE for license details.
#include <stdio.h>
#include <stdlib.h>
#include "platform.h"
#include <string.h>
#include "encoding.h"
#include <unistd.h>
#include "sifive/devices/clic.h"
#include "clic/clic_driver.h"
#ifndef _SIFIVE_COREPLEXIP_ARTY_H
#error 'local_interrupts' demo only supported for Core IP Eval Kits
#endif
// Global Variable used to show
// software interrupts.
volatile uint32_t g_debouncing;
// vector table defined in init.c
typedef void (*interrupt_function_ptr_t) (void);
extern interrupt_function_ptr_t localISR[CLIC_NUM_INTERRUPTS];
extern void default_handler(void);
//clic data structure
clic_instance_t clic;
const char * instructions_msg = " \
\n\
SiFive, Inc\n\
E21 Core IP Eval Kit 'clic_interrupts' demo.\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));
printf(instructions_msg);
}
void button_0_isr(void)__attribute__((interrupt("SiFive-CLIC-preemptible")));
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));
GPIO_REG(GPIO_OUTPUT_VAL) = GPIO_REG(GPIO_OUTPUT_VAL) ^ (0x1 << RED_LED_OFFSET);
clic_clear_pending(&clic, (LOCALINTIDBASE + LOCAL_INT_BTN_0));
clic_enable_interrupt(&clic, (LOCALINTIDBASE + LOCAL_INT_BTN_0));
}
void button_0_setup(void) {
clic_install_handler(&clic, (LOCALINTIDBASE + LOCAL_INT_BTN_0), button_0_isr);
clic_enable_interrupt(&clic, (LOCALINTIDBASE + LOCAL_INT_BTN_0));
}
void config_gpio() {
// Configure LEDs as outputs.
GPIO_REG(GPIO_INPUT_EN) &= ~((0x1<< RED_LED_OFFSET) | (0x1<< GREEN_LED_OFFSET) | (0x1 << BLUE_LED_OFFSET)) ;
GPIO_REG(GPIO_OUTPUT_EN) |= ((0x1<< RED_LED_OFFSET)| (0x1<< GREEN_LED_OFFSET) | (0x1 << BLUE_LED_OFFSET)) ;
GPIO_REG(GPIO_OUTPUT_VAL) &= ((0x1<< RED_LED_OFFSET) | (0x1<< GREEN_LED_OFFSET)| (0x1 << BLUE_LED_OFFSET)) ;
}
int main(int argc, char **argv)
{
clear_csr(mstatus, MSTATUS_MIE);
clear_csr(mie, IRQ_M_SOFT);
clear_csr(mie, IRQ_M_TIMER);
clic_init(&clic, CLIC_HART0_ADDR,
(interrupt_function_ptr_t*)localISR,
default_handler,
CLIC_NUM_INTERRUPTS,
CLIC_NUM_CONFIG_BITS);
config_gpio();
button_0_setup();
// Enable all global interrupts
set_csr(mstatus, MSTATUS_MIE);
print_instructions();
while(1);
return 0;
}
|