1 /* Copyright 2019 SiFive, Inc */
2 /* SPDX-License-Identifier: Apache-2.0 */
7 #include <metal/button.h>
8 #include <metal/switch.h>
10 #define RTC_FREQ 32768
12 struct metal_cpu *cpu0;
13 struct metal_interrupt *cpu_intr, *tmr_intr;
15 volatile uint32_t timer_isr_flag;
17 void display_banner (void) {
21 printf(" SIFIVE, INC.\n");
23 printf(" 5555555555555555555555555\n");
24 printf(" 5555 5555\n");
25 printf(" 5555 5555\n");
26 printf(" 5555 5555\n");
27 printf(" 5555 5555555555555555555555\n");
28 printf(" 5555 555555555555555555555555\n");
29 printf(" 5555 5555\n");
30 printf(" 5555 5555\n");
31 printf(" 5555 5555\n");
32 printf(" 5555555555555555555555555555 55555\n");
33 printf(" 55555 555555555 55555\n");
34 printf(" 55555 55555 55555\n");
35 printf(" 55555 5 55555\n");
36 printf(" 55555 55555\n");
37 printf(" 55555 55555\n");
38 printf(" 55555 55555\n");
39 printf(" 55555 55555\n");
40 printf(" 55555 55555\n");
41 printf(" 555555555\n");
47 printf(" Welcome to SiFive!\n");
51 void timer_isr (int id, void *data) {
53 // Disable Timer interrupt
54 metal_interrupt_disable(tmr_intr, tmr_id);
56 // Flag showing we hit timer isr
60 void wait_for_timer(struct metal_led *which_led) {
62 // clear global timer isr flag
65 // Turn on desired LED
66 metal_led_on(which_led);
69 metal_cpu_set_mtimecmp(cpu0, metal_cpu_get_mtime(cpu0) + RTC_FREQ);
71 // Enable Timer interrupt
72 metal_interrupt_enable(tmr_intr, tmr_id);
74 // wait till timer triggers and isr is hit
75 while (timer_isr_flag == 0){};
80 metal_led_off(which_led);
85 int rc, up_cnt, dn_cnt;
86 struct metal_led *led0_red, *led0_green, *led0_blue;
88 // This demo will toggle LEDs colors so we define them here
89 led0_red = metal_led_get_rgb("LD0", "red");
90 led0_green = metal_led_get_rgb("LD0", "green");
91 led0_blue = metal_led_get_rgb("LD0", "blue");
92 if ((led0_red == NULL) || (led0_green == NULL) || (led0_blue == NULL)) {
93 printf("At least one of LEDs is null.\n");
98 metal_led_enable(led0_red);
99 metal_led_enable(led0_green);
100 metal_led_enable(led0_blue);
103 metal_led_off(led0_red);
104 metal_led_off(led0_green);
105 metal_led_off(led0_blue);
107 // Lets get the CPU and and its interrupt
108 cpu0 = metal_cpu_get(0);
110 printf("CPU null.\n");
113 cpu_intr = metal_cpu_interrupt_controller(cpu0);
114 if (cpu_intr == NULL) {
115 printf("CPU interrupt controller is null.\n");
118 metal_interrupt_init(cpu_intr);
120 // display welcome banner
123 // Setup Timer and its interrupt so we can toggle LEDs on 1s cadence
124 tmr_intr = metal_cpu_timer_interrupt_controller(cpu0);
125 if (tmr_intr == NULL) {
126 printf("TIMER interrupt controller is null.\n");
129 metal_interrupt_init(tmr_intr);
130 tmr_id = metal_cpu_timer_get_interrupt_id(cpu0);
131 rc = metal_interrupt_register_handler(tmr_intr, tmr_id, timer_isr, cpu0);
133 printf("TIMER interrupt handler registration failed\n");
137 // Lastly CPU interrupt
138 if (metal_interrupt_enable(cpu_intr, 0) == -1) {
139 printf("CPU interrupt enable failed\n");
143 // Red -> Green -> Blue, repeat
147 wait_for_timer(led0_red);
150 wait_for_timer(led0_green);
153 wait_for_timer(led0_blue);