|
1 | | -/* main.c |
| 1 | +/* |
| 2 | + * # sifive-welcome |
| 3 | + * (A simple welcome example which prints SiFive banner and uses board LEDs |
2 | 4 | * |
3 | | - * Copyright (C) 2018 wolfSSL Inc. |
4 | | - * |
5 | | - * This file is part of wolfBoot. |
6 | | - * |
7 | | - * wolfBoot is free software; you can redistribute it and/or modify |
8 | | - * it under the terms of the GNU General Public License as published by |
9 | | - * the Free Software Foundation; either version 2 of the License, or |
10 | | - * (at your option) any later version. |
11 | | - * |
12 | | - * wolfBoot is distributed in the hope that it will be useful, |
13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | - * GNU General Public License for more details. |
16 | | - * |
17 | | - * You should have received a copy of the GNU General Public License |
18 | | - * along with this program; if not, write to the Free Software |
19 | | - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
| 5 | + * Copyright 2018 SiFive, Inc |
20 | 6 | */ |
| 7 | + /* SPDX-License-Identifier: Apache-2.0 */ |
| 8 | + |
| 9 | +#include <stdio.h> |
| 10 | +#include <metal/cpu.h> |
| 11 | +#include <metal/led.h> |
| 12 | +#include <metal/button.h> |
| 13 | +#include <metal/switch.h> |
| 14 | + |
| 15 | +#define RTC_FREQ 32768 |
| 16 | + |
| 17 | +struct metal_cpu *cpu0; |
| 18 | +struct metal_interrupt *cpu_intr, *tmr_intr; |
| 19 | +int tmr_id; |
| 20 | +volatile uint32_t timer_isr_flag; |
| 21 | + |
| 22 | +void display_banner (void) { |
| 23 | + |
| 24 | + printf("\n"); |
| 25 | + printf("\n"); |
| 26 | + printf(" SIFIVE, INC.\n"); |
| 27 | + printf("\n"); |
| 28 | + printf(" 5555555555555555555555555\n"); |
| 29 | + printf(" 5555 5555\n"); |
| 30 | + printf(" 5555 5555\n"); |
| 31 | + printf(" 5555 5555\n"); |
| 32 | + printf(" 5555 5555555555555555555555\n"); |
| 33 | + printf(" 5555 555555555555555555555555\n"); |
| 34 | + printf(" 5555 5555\n"); |
| 35 | + printf(" 5555 5555\n"); |
| 36 | + printf(" 5555 5555\n"); |
| 37 | + printf(" 5555555555555555555555555555 55555\n"); |
| 38 | + printf(" 55555 555555555 55555\n"); |
| 39 | + printf(" 55555 55555 55555\n"); |
| 40 | + printf(" 55555 5 55555\n"); |
| 41 | + printf(" 55555 55555\n"); |
| 42 | + printf(" 55555 55555\n"); |
| 43 | + printf(" 55555 55555\n"); |
| 44 | + printf(" 55555 55555\n"); |
| 45 | + printf(" 55555 55555\n"); |
| 46 | + printf(" 555555555\n"); |
| 47 | + printf(" 55555\n"); |
| 48 | + printf(" 5\n"); |
| 49 | + printf("\n"); |
21 | 50 |
|
22 | | -#include <stdlib.h> |
23 | | -#include <stdint.h> |
24 | | -#include <string.h> |
| 51 | + printf("\n"); |
| 52 | + printf(" Welcome to SiFive!\n"); |
25 | 53 |
|
26 | | -#ifdef PLATFORM_hifive1 |
27 | | -void main(void) { |
28 | | - while(1) |
29 | | - ; |
30 | 54 | } |
31 | | -#endif |
32 | 55 |
|
| 56 | +void timer_isr (int id, void *data) { |
| 57 | + |
| 58 | + // Disable Timer interrupt |
| 59 | + metal_interrupt_disable(tmr_intr, tmr_id); |
| 60 | + |
| 61 | + // Flag showing we hit timer isr |
| 62 | + timer_isr_flag = 1; |
| 63 | +} |
| 64 | + |
| 65 | +void wait_for_timer(struct metal_led *which_led) { |
| 66 | + |
| 67 | + // clear global timer isr flag |
| 68 | + timer_isr_flag = 0; |
| 69 | + |
| 70 | + // Turn on desired LED |
| 71 | + metal_led_on(which_led); |
| 72 | + |
| 73 | + // Set timer |
| 74 | + metal_cpu_set_mtimecmp(cpu0, metal_cpu_get_mtime(cpu0) + RTC_FREQ); |
| 75 | + |
| 76 | + // Enable Timer interrupt |
| 77 | + metal_interrupt_enable(tmr_intr, tmr_id); |
| 78 | + |
| 79 | + // wait till timer triggers and isr is hit |
| 80 | + while (timer_isr_flag == 0){}; |
| 81 | + |
| 82 | + timer_isr_flag = 0; |
| 83 | + |
| 84 | + // Turn off this LED |
| 85 | + metal_led_off(which_led); |
| 86 | +} |
| 87 | + |
| 88 | +int main (void) |
| 89 | +{ |
| 90 | + int rc, up_cnt, dn_cnt; |
| 91 | + struct metal_led *led0_red, *led0_green, *led0_blue; |
| 92 | + |
| 93 | + // This demo will toggle LEDs colors so we define them here |
| 94 | + led0_red = metal_led_get_rgb("LD0", "red"); |
| 95 | + led0_green = metal_led_get_rgb("LD0", "green"); |
| 96 | + led0_blue = metal_led_get_rgb("LD0", "blue"); |
| 97 | + if ((led0_red == NULL) || (led0_green == NULL) || (led0_blue == NULL)) { |
| 98 | + printf("At least one of LEDs is null.\n"); |
| 99 | + return 1; |
| 100 | + } |
| 101 | + |
| 102 | + // Enable each LED |
| 103 | + metal_led_enable(led0_red); |
| 104 | + metal_led_enable(led0_green); |
| 105 | + metal_led_enable(led0_blue); |
| 106 | + |
| 107 | + // All Off |
| 108 | + metal_led_off(led0_red); |
| 109 | + metal_led_off(led0_green); |
| 110 | + metal_led_off(led0_blue); |
| 111 | + |
| 112 | + // Lets get the CPU and and its interrupt |
| 113 | + cpu0 = metal_cpu_get(0); |
| 114 | + if (cpu0 == NULL) { |
| 115 | + printf("CPU null.\n"); |
| 116 | + return 2; |
| 117 | + } |
| 118 | + cpu_intr = metal_cpu_interrupt_controller(cpu0); |
| 119 | + if (cpu_intr == NULL) { |
| 120 | + printf("CPU interrupt controller is null.\n"); |
| 121 | + return 3; |
| 122 | + } |
| 123 | + metal_interrupt_init(cpu_intr); |
| 124 | + |
| 125 | + // display welcome banner |
| 126 | + display_banner(); |
| 127 | + |
| 128 | + // Setup Timer and its interrupt so we can toggle LEDs on 1s cadence |
| 129 | + tmr_intr = metal_cpu_timer_interrupt_controller(cpu0); |
| 130 | + if (tmr_intr == NULL) { |
| 131 | + printf("TIMER interrupt controller is null.\n"); |
| 132 | + return 4; |
| 133 | + } |
| 134 | + metal_interrupt_init(tmr_intr); |
| 135 | + tmr_id = metal_cpu_timer_get_interrupt_id(cpu0); |
| 136 | + rc = metal_interrupt_register_handler(tmr_intr, tmr_id, timer_isr, cpu0); |
| 137 | + if (rc < 0) { |
| 138 | + printf("TIMER interrupt handler registration failed\n"); |
| 139 | + return (rc * -1); |
| 140 | + } |
| 141 | + |
| 142 | + // Lastly CPU interrupt |
| 143 | + if (metal_interrupt_enable(cpu_intr, 0) == -1) { |
| 144 | + printf("CPU interrupt enable failed\n"); |
| 145 | + return 6; |
| 146 | + } |
| 147 | + |
| 148 | + // Red -> Green -> Blue, repeat |
| 149 | + while (1) { |
| 150 | + |
| 151 | + // Turn on RED |
| 152 | + wait_for_timer(led0_red); |
| 153 | + |
| 154 | + // Turn on Green |
| 155 | + wait_for_timer(led0_green); |
| 156 | + |
| 157 | + // Turn on Blue |
| 158 | + wait_for_timer(led0_blue); |
| 159 | + } |
| 160 | + |
| 161 | + // return |
| 162 | + return 0; |
| 163 | +} |
0 commit comments