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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
#include <stdio.h>
#include <metal/cpu.h>
#include <metal/led.h>
#include <metal/button.h>
#include <metal/switch.h>
#define RTC_FREQ 32768
struct metal_cpu *cpu0;
struct metal_interrupt *cpu_intr, *tmr_intr;
int tmr_id;
volatile uint32_t timer_isr_flag;
void display_banner (void) {
printf("\n");
printf("\n");
printf(" SIFIVE, INC.\n");
printf("\n");
printf(" 5555555555555555555555555\n");
printf(" 5555 5555\n");
printf(" 5555 5555\n");
printf(" 5555 5555\n");
printf(" 5555 5555555555555555555555\n");
printf(" 5555 555555555555555555555555\n");
printf(" 5555 5555\n");
printf(" 5555 5555\n");
printf(" 5555 5555\n");
printf(" 5555555555555555555555555555 55555\n");
printf(" 55555 555555555 55555\n");
printf(" 55555 55555 55555\n");
printf(" 55555 5 55555\n");
printf(" 55555 55555\n");
printf(" 55555 55555\n");
printf(" 55555 55555\n");
printf(" 55555 55555\n");
printf(" 55555 55555\n");
printf(" 555555555\n");
printf(" 55555\n");
printf(" 5\n");
printf("\n");
printf("\n");
printf("Welcome to the E31/E51 Coreplex IP FPGA Evaluation Kit!\n");
}
void timer_isr (int id, void *data) {
// Disable Timer interrupt
metal_interrupt_disable(tmr_intr, tmr_id);
// Flag showing we hit timer isr
timer_isr_flag = 1;
}
void wait_for_timer(struct metal_led *which_led) {
// clear global timer isr flag
timer_isr_flag = 0;
// Turn on desired LED
metal_led_on(which_led);
// Set timer
metal_cpu_set_mtimecmp(cpu0, metal_cpu_get_mtime(cpu0) + RTC_FREQ);
// Enable Timer interrupt
metal_interrupt_enable(tmr_intr, tmr_id);
// wait till timer triggers and isr is hit
while (timer_isr_flag == 0){};
timer_isr_flag = 0;
// All Off
metal_led_off(which_led);
}
int main (void)
{
int rc, up_cnt, dn_cnt;
struct metal_led *led0_red, *led0_green, *led0_blue;
// This demo will toggle LEDs colors so we define them here
led0_red = metal_led_get_rgb("LD0", "red");
led0_green = metal_led_get_rgb("LD0", "green");
led0_blue = metal_led_get_rgb("LD0", "blue");
if ((led0_red == NULL) || (led0_green == NULL) || (led0_blue == NULL)) {
printf("At least one of LEDs is null.\n");
return 1;
}
// Enable each LED
metal_led_enable(led0_red);
metal_led_enable(led0_green);
metal_led_enable(led0_blue);
// All Off
metal_led_off(led0_red);
metal_led_off(led0_green);
metal_led_off(led0_blue);
// Lets get the CPU and and its interrupt
cpu0 = metal_cpu_get(0);
if (cpu0 == NULL) {
printf("CPU null.\n");
return 2;
}
cpu_intr = metal_cpu_interrupt_controller(cpu0);
if (cpu_intr == NULL) {
printf("CPU interrupt controller is null.\n");
return 3;
}
metal_interrupt_init(cpu_intr);
// display welcome banner
display_banner();
// Setup Timer and its interrupt so we can toggle LEDs on 1s cadence
tmr_intr = metal_cpu_timer_interrupt_controller(cpu0);
if (tmr_intr == NULL) {
printf("TIMER interrupt controller is null.\n");
return 4;
}
metal_interrupt_init(tmr_intr);
tmr_id = metal_cpu_timer_get_interrupt_id(cpu0);
rc = metal_interrupt_register_handler(tmr_intr, tmr_id, timer_isr, cpu0);
if (rc < 0) {
printf("TIMER interrupt handler registration failed\n");
return (rc * -1);
}
// Lastly CPU interrupt
if (metal_interrupt_enable(cpu_intr, 0) == -1) {
printf("CPU interrupt enable failed\n");
return 6;
}
// Red -> Green -> Blue, repeat
while (1) {
// Turn on RED
wait_for_timer(led0_red);
// Turn on Green
wait_for_timer(led0_green);
// Turn on Blue
wait_for_timer(led0_blue);
}
// return
return 0;
}
|