summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Connelly <david.connelly@sifive.com>2019-03-04 10:50:41 -0500
committerDavid Connelly <david.connelly@sifive.com>2019-03-04 10:57:27 -0500
commitd916cf5f6326c798e400a9fe0db6ad776f9a861f (patch)
tree5b6d23b230e0c38f9428d8381b2c369bc14c2a85
parent13bc9767e23880849142526638a7d4a1110e5a4c (diff)
coreplexip-welcome example updated using freedom metal
-rw-r--r--README.md4
-rw-r--r--software/coreplexip-welcome/Makefile4
-rw-r--r--software/coreplexip-welcome/README.md2
-rw-r--r--software/coreplexip-welcome/coreplexip-welcome.c156
4 files changed, 165 insertions, 1 deletions
diff --git a/README.md b/README.md
index 2484c5f..0feac4f 100644
--- a/README.md
+++ b/README.md
@@ -79,7 +79,9 @@ of Freedom E SDK.
- Demonstrates how to register a handler for and trigger a local interrupt
- example-pmp
- Demonstrates how to configure a Physical Memory Protection (PMP) region
-
+ - coreplexip-welcome
+ - Prints the SiFive banner and blinks LEDs
+
#### (Deprecated) Legacy Freedom E SDK Library ####
As we transition to supporting SiFive targets and examples with the new Freedom Metal
diff --git a/software/coreplexip-welcome/Makefile b/software/coreplexip-welcome/Makefile
new file mode 100644
index 0000000..f9c9ead
--- /dev/null
+++ b/software/coreplexip-welcome/Makefile
@@ -0,0 +1,4 @@
+coreplexip-welcome: coreplexip-welcome.c
+
+clean:
+ rm -f coreplexip-welcome coreplexip-welcome.hex
diff --git a/software/coreplexip-welcome/README.md b/software/coreplexip-welcome/README.md
new file mode 100644
index 0000000..5ea36ef
--- /dev/null
+++ b/software/coreplexip-welcome/README.md
@@ -0,0 +1,2 @@
+# coreplexip-welcome
+A simple "CoreplexIP Welcome" example which prints SiFive banner and uses board LEDs.
diff --git a/software/coreplexip-welcome/coreplexip-welcome.c b/software/coreplexip-welcome/coreplexip-welcome.c
new file mode 100644
index 0000000..a975b1c
--- /dev/null
+++ b/software/coreplexip-welcome/coreplexip-welcome.c
@@ -0,0 +1,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;
+}