]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_GCC/main.c
Added the "full" demo to the RISC-V_RV32_SiFive_HiFive1_GCC demo - backup check in...
[freertos] / FreeRTOS / Demo / RISC-V_RV32_SiFive_HiFive1_GCC / main.c
index 6013912ee8e465235cd90c44c15b0ebb7022bf6d..ffb6c207f03f40e934a837f5e0f7c77af87f29f4 100644 (file)
@@ -1,4 +1,3 @@
-#if 1\r
 /*\r
  * FreeRTOS Kernel V10.2.1\r
  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
@@ -35,7 +34,6 @@
 #include <metal/led.h>\r
 #include <metal/button.h>\r
 \r
-\r
 /******************************************************************************\r
  * This project provides two demo applications.  A simple blinky style project,\r
  * and a more comprehensive test and demo application.  The\r
 \r
 #warning Also test in QEMU and add instructions above.\r
 \r
+/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,\r
+or 0 to run the more comprehensive test and demo application. */\r
+#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY     0\r
+\r
 /* Index to first HART (there is only one). */\r
 #define mainHART_0             0\r
 \r
-/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,\r
-or 0 to run the more comprehensive test and demo application. */\r
-#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY     1\r
+/* Register addresses within the PLIC. */\r
+#define mainPLIC_PENDING_0 ( * ( ( volatile uint32_t * ) 0x0C001000UL ) )\r
+#define mainPLIC_PENDING_1 ( * ( ( volatile uint32_t * ) 0x0C001004UL ) )\r
+#define mainPLIC_ENABLE_0  ( * ( ( volatile uint32_t * ) 0x0C002000UL ) )\r
+#define mainPLIC_ENABLE_1  ( * ( ( volatile uint32_t * ) 0x0C002004UL ) )\r
 \r
 /*\r
  * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.\r
@@ -111,8 +115,8 @@ static void prvSetupHardware( void )
 struct metal_cpu *pxCPU;\r
 struct metal_interrupt *pxInterruptController;\r
 \r
-       /* Initialise the red LED. */\r
-       pxLED = metal_led_get_rgb( "LD0", "red" );\r
+       /* Initialise the blue LED. */\r
+       pxLED = metal_led_get_rgb( "LD0", "blue" );\r
        configASSERT( pxLED );\r
        metal_led_enable( pxLED );\r
        metal_led_off( pxLED );\r
@@ -123,6 +127,14 @@ struct metal_interrupt *pxInterruptController;
        pxInterruptController = metal_cpu_interrupt_controller( pxCPU );\r
        configASSERT( pxInterruptController );\r
        metal_interrupt_init( pxInterruptController );\r
+\r
+       /* Set all interrupt enable bits to 0. */\r
+       mainPLIC_ENABLE_0 = 0UL;\r
+       mainPLIC_ENABLE_1 = 0UL;\r
+\r
+       /* Clear all pending interrupts. */\r
+       mainPLIC_PENDING_0 = 0UL;\r
+       mainPLIC_PENDING_1 = 0UL;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -184,15 +196,41 @@ void vApplicationTickHook( void )
 \r
 void vAssertCalled( void )\r
 {\r
+static struct metal_led *pxRedLED = NULL;\r
+volatile uint32_t ul;\r
+\r
        taskDISABLE_INTERRUPTS();\r
-       for( ;; );\r
+\r
+       /* Initialise the red LED. */\r
+       pxRedLED = metal_led_get_rgb( "LD0", "red" );\r
+       configASSERT( pxRedLED );\r
+       metal_led_enable( pxRedLED );\r
+       metal_led_off( pxRedLED );\r
+\r
+       /* Flash the red LED to indicate that assert was hit - interrupts are off\r
+       here to prevent any further tick interrupts or context switches, so the\r
+       delay is implemented as a crude loop. */\r
+       for( ;; )\r
+       {\r
+               for( ul = 0; ul < 0x1ffff; ul++ )\r
+               {\r
+                       __asm volatile( "nop" );\r
+               }\r
+               metal_led_toggle( pxRedLED );\r
+       }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+volatile uint32_t ulMEPC = 0UL, ulMCAUSE = 0UL, ulPending0Register = 0UL, ulPending1Register = 0UL;\r
+\r
 void handle_trap( void )\r
 {\r
 #warning Not implemented.\r
 \r
+       __asm volatile( "csrr %0, mepc" : "=r"( ulMEPC ) );\r
+       __asm volatile( "csrr %0, mcause" : "=r"( ulMCAUSE ) );\r
+       ulPending0Register = mainPLIC_PENDING_0;\r
+       ulPending1Register = mainPLIC_PENDING_1;\r
        configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 );\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -201,103 +239,13 @@ void vToggleLED( void )
 {\r
        metal_led_toggle( pxLED );\r
 }\r
+/*-----------------------------------------------------------*/\r
 \r
-\r
-\r
-\r
-#else\r
-\r
-static void prvSetupTimerInterrupt( void )\r
+void *malloc( size_t xSize )\r
 {\r
-       int rc, up_cnt, dn_cnt;\r
-\r
-    // Setup Timer and its interrupt so we can toggle LEDs on 1s cadence\r
-    tmr_intr = metal_cpu_timer_interrupt_controller(pxCPU);\r
-    if (tmr_intr == NULL) {\r
-        printf("TIMER interrupt controller is  null.\n");\r
-        return 4;\r
-    }\r
-    metal_interrupt_init(tmr_intr);\r
-    tmr_id = metal_cpu_timer_get_interrupt_id(pxCPU);\r
-    rc = metal_interrupt_register_handler(tmr_intr, tmr_id, timer_isr, pxCPU);\r
-    if (rc < 0) {\r
-        printf("TIMER interrupt handler registration failed\n");\r
-        return (rc * -1);\r
-    }\r
-\r
-    // Lastly CPU interrupt\r
-    if (metal_interrupt_enable(pxInterruptController, 0) == -1) {\r
-        printf("CPU interrupt enable failed\n");\r
-        return 6;\r
-    }\r
-\r
-    // Red -> Green -> Blue, repeat\r
-    while (1) {\r
-\r
-        // Turn on RED\r
-        wait_for_timer(pxLED);\r
-\r
-        // Turn on Green\r
-        wait_for_timer(led0_green);\r
-\r
-        // Turn on Blue\r
-        wait_for_timer(led0_blue);\r
-    }\r
-\r
-    // return\r
-    return 0;\r
+       configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 );\r
+       return NULL;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 \r
-#include <stdio.h>\r
-#include <metal/cpu.h>\r
-#include <metal/led.h>\r
-#include <metal/button.h>\r
-#include <metal/switch.h>\r
-\r
-#define RTC_FREQ    32768\r
-\r
-struct metal_cpu *pxCPU;\r
-struct metal_interrupt *pxInterruptController, *tmr_intr;\r
-int tmr_id;\r
-volatile uint32_t timer_isr_flag;\r
-\r
-\r
-void timer_isr (int id, void *data) {\r
-\r
-    // Disable Timer interrupt\r
-    metal_interrupt_disable(tmr_intr, tmr_id);\r
-\r
-    // Flag showing we hit timer isr\r
-    timer_isr_flag = 1;\r
-}\r
-\r
-void wait_for_timer(struct metal_led *which_led) {\r
-\r
-    // clear global timer isr flag\r
-    timer_isr_flag = 0;\r
-\r
-    // Turn on desired LED\r
-    metal_led_on(which_led);\r
-\r
-    // Set timer\r
-    metal_cpu_set_mtimecmp(pxCPU, metal_cpu_get_mtime(pxCPU) + RTC_FREQ);\r
-\r
-    // Enable Timer interrupt\r
-    metal_interrupt_enable(tmr_intr, tmr_id);\r
-\r
-    // wait till timer triggers and isr is hit\r
-    while (timer_isr_flag == 0){};\r
-\r
-    timer_isr_flag = 0;\r
-\r
-    // Turn off this LED\r
-    metal_led_off(which_led);\r
-}\r
-\r
-\r
-\r
-#endif\r
-\r
-\r