summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile14
-rw-r--r--bsp/env/freedom-e300-arty/openocd.cfg16
-rw-r--r--bsp/env/freedom-e300-hifive1/openocd.cfg2
-rw-r--r--software/demo_gpio/demo_gpio.c54
4 files changed, 57 insertions, 29 deletions
diff --git a/Makefile b/Makefile
index ffc2e77..bd715d2 100644
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,10 @@ help :
@echo " run_openocd [BOARD=$(DEFAULT_BOARD)]:"
@echo " run_gdb [PROGRAM=$(DEFAULT_PROGRAM) BOARD=$(DEFAULT_BOARD)]:"
@echo " Launch OpenOCD or GDB seperately"
- @echo ""
+ @echo ""
+ @echo " dasm [PROGRAM=$(DEFAULT_BOARD)]:"
+ @echo " Generates the dissassembly output of objdump -D to stdout."
+ @echo ""
@echo " For more information, visit dev.sifive.com"
@@ -88,13 +91,14 @@ PROGRAM ?= $(DEFAULT_PROGRAM)
PROGRAM_DIR = $(srcdir)/software/$(PROGRAM)
PROGRAM_ELF = $(srcdir)/software/$(PROGRAM)/$(PROGRAM)
-.PHONY: software
-software:
- $(MAKE) -C $(PROGRAM_DIR)
-
+.PHONY: software_clean
software_clean:
$(MAKE) -C $(PROGRAM_DIR) clean
+.PHONY: software
+software: software_clean
+ $(MAKE) -C $(PROGRAM_DIR)
+
dasm: software
$(toolchain_dest)/bin/riscv32-unknown-elf-objdump -D $(PROGRAM_ELF)
diff --git a/bsp/env/freedom-e300-arty/openocd.cfg b/bsp/env/freedom-e300-arty/openocd.cfg
index 251dc52..f4b28ed 100644
--- a/bsp/env/freedom-e300-arty/openocd.cfg
+++ b/bsp/env/freedom-e300-arty/openocd.cfg
@@ -1,6 +1,16 @@
adapter_khz 10000
-source [find interface/ftdi/olimex-arm-usb-tiny-h.cfg]
+#source [find interface/ftdi/olimex-arm-usb-tiny-h.cfg]
+
+interface ftdi
+ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H"
+ftdi_vid_pid 0x15ba 0x002a
+
+ftdi_layout_init 0x0808 0x0a1b
+ftdi_layout_signal nSRST -oe 0x0200
+ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100
+ftdi_layout_signal LED -data 0x0800
+#
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913
@@ -12,5 +22,9 @@ $_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-ar
flash bank my_first_flash fespi 0x20000000 0 0 0 $_TARGETNAME
init
#reset
+if {[ info exists pulse_srst]} {
+ ftdi_set_signal nSRST 0
+ ftdi_set_signal nSRST z
+}
halt
#flash protect 0 64 last off
diff --git a/bsp/env/freedom-e300-hifive1/openocd.cfg b/bsp/env/freedom-e300-hifive1/openocd.cfg
index b0a8e26..b531e9c 100644
--- a/bsp/env/freedom-e300-hifive1/openocd.cfg
+++ b/bsp/env/freedom-e300-hifive1/openocd.cfg
@@ -31,4 +31,4 @@ if {[ info exists pulse_srst]} {
sleep 1500
}
halt
-flash protect 0 64 last off
+#flash protect 0 64 last off
diff --git a/software/demo_gpio/demo_gpio.c b/software/demo_gpio/demo_gpio.c
index dec91b5..00bc8cd 100644
--- a/software/demo_gpio/demo_gpio.c
+++ b/software/demo_gpio/demo_gpio.c
@@ -7,6 +7,7 @@
#include "plic_driver.h"
#include "encoding.h"
#include <unistd.h>
+#include "stdatomic.h"
#define RTC_FREQUENCY 32768
@@ -25,12 +26,6 @@ function_ptr_t g_ext_interrupt_handlers[PLIC_NUM_INTERRUPTS];
plic_instance_t g_plic;
-// Simple variables for LEDs, buttons, etc.
-volatile unsigned int* g_output_vals = (unsigned int *) (GPIO_BASE_ADDR + GPIO_OUTPUT_VAL);
-volatile unsigned int* g_input_vals = (unsigned int *) (GPIO_BASE_ADDR + GPIO_INPUT_VAL);
-volatile unsigned int* g_output_en = (unsigned int *) (GPIO_BASE_ADDR + GPIO_OUTPUT_EN);
-volatile unsigned int* g_pullup_en = (unsigned int *) (GPIO_BASE_ADDR + GPIO_PULLUP_EN);
-volatile unsigned int* g_input_en = (unsigned int *) (GPIO_BASE_ADDR + GPIO_INPUT_EN);
/*Entry Point for PLIC Interrupt Handler*/
void handle_m_ext_interrupt(){
@@ -60,12 +55,12 @@ void handle_m_time_interrupt(){
*mtimecmp = then;
// read the current value of the LEDS and invert them.
- uint32_t leds = *g_output_vals;
-
- *g_output_vals ^= ((0x1 << RED_LED_OFFSET) |
- (0x1 << GREEN_LED_OFFSET) |
- (0x1 << BLUE_LED_OFFSET));
+ uint32_t leds = GPIO_REG(GPIO_OUTPUT_VAL);
+ GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << RED_LED_OFFSET) |
+ (0x1 << GREEN_LED_OFFSET) |
+ (0x1 << BLUE_LED_OFFSET));
+
// Re-enable the timer interrupt.
set_csr(mie, MIP_MTIP);
@@ -101,6 +96,8 @@ const char * instructions_msg = " \
SiFive E-Series Software Development Kit 'demo_gpio' program.\n\
Every 1.5 second, the Timer Interrupt will invert the LEDs.\n\
(Arty Dev Kit Only): Press Buttons 0, 1, 2 to Set the LEDs.\n\
+Pin 19 (HiFive1) or A5 (Arty Dev Kit) is being bit-banged\n\
+for GPIO speed demonstration.\n\
\n\
";
@@ -114,7 +111,7 @@ void print_instructions() {
void button_0_handler(void) {
// Red LED on
- * g_output_vals |= (0x1 << RED_LED_OFFSET);
+ GPIO_REG(GPIO_OUTPUT_VAL) |= (0x1 << RED_LED_OFFSET);
// Clear the GPIO Pending interrupt by writing 1.
GPIO_REG(GPIO_RISE_IP) = (0x1 << BUTTON_0_OFFSET);
@@ -124,7 +121,7 @@ void button_0_handler(void) {
void button_1_handler(void) {
// Green LED On
- * g_output_vals |= (1 << GREEN_LED_OFFSET);
+ GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << GREEN_LED_OFFSET);
// Clear the GPIO Pending interrupt by writing 1.
GPIO_REG(GPIO_RISE_IP) = (0x1 << BUTTON_1_OFFSET);
@@ -135,7 +132,7 @@ void button_1_handler(void) {
void button_2_handler(void) {
// Blue LED On
- * g_output_vals |= (1 << BLUE_LED_OFFSET);
+ GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << BLUE_LED_OFFSET);
GPIO_REG(GPIO_RISE_IP) = (0x1 << BUTTON_2_OFFSET);
@@ -204,16 +201,19 @@ int main(int argc, char **argv)
// can be used as both Inputs and Outputs.
#ifdef HAS_BOARD_BUTTONS
- * g_output_en &= ~((0x1 << BUTTON_0_OFFSET) | (0x1 << BUTTON_1_OFFSET) | (0x1 << BUTTON_2_OFFSET));
- * g_pullup_en &= ~((0x1 << BUTTON_0_OFFSET) | (0x1 << BUTTON_1_OFFSET) | (0x1 << BUTTON_2_OFFSET));
- * g_input_en |= ((0x1 << BUTTON_0_OFFSET) | (0x1 << BUTTON_1_OFFSET) | (0x1 << BUTTON_2_OFFSET));
+ GPIO_REG(GPIO_OUTPUT_EN) &= ~((0x1 << BUTTON_0_OFFSET) | (0x1 << BUTTON_1_OFFSET) | (0x1 << BUTTON_2_OFFSET));
+ GPIO_REG(GPIO_PULLUP_EN) &= ~((0x1 << BUTTON_0_OFFSET) | (0x1 << BUTTON_1_OFFSET) | (0x1 << BUTTON_2_OFFSET));
+ GPIO_REG(GPIO_INPUT_EN) |= ((0x1 << BUTTON_0_OFFSET) | (0x1 << BUTTON_1_OFFSET) | (0x1 << BUTTON_2_OFFSET));
#endif
- * g_input_en &= ~((0x1<< RED_LED_OFFSET) | (0x1<< GREEN_LED_OFFSET) | (0x1 << BLUE_LED_OFFSET)) ;
- * g_output_en |= ((0x1<< RED_LED_OFFSET)| (0x1<< GREEN_LED_OFFSET) | (0x1 << BLUE_LED_OFFSET)) ;
- * g_output_vals |= (0x1 << BLUE_LED_OFFSET) ;
- * g_output_vals &= ~((0x1<< RED_LED_OFFSET) | (0x1<< GREEN_LED_OFFSET)) ;
+ GPIO_REG(GPIO_INPUT_EN) &= ~((0x1<< RED_LED_OFFSET) | (0x1<< GREEN_LED_OFFSET) | (0x1 << BLUE_LED_OFFSET)) ;
+ GPIO_REG(GPIO_OUTPUT_EN) |= ((0x1<< RED_LED_OFFSET)| (0x1<< GREEN_LED_OFFSET) | (0x1 << BLUE_LED_OFFSET)) ;
+ GPIO_REG(GPIO_OUTPUT_VAL) |= (0x1 << BLUE_LED_OFFSET) ;
+ GPIO_REG(GPIO_OUTPUT_VAL) &= ~((0x1<< RED_LED_OFFSET) | (0x1<< GREEN_LED_OFFSET)) ;
+ // For Bit-banging with Atomics demo.
+ GPIO_REG(GPIO_OUTPUT_EN) |= (0x1 << PIN_19_OFFSET);
+
/**************************************************************************
* Set up the PLIC
*
@@ -225,7 +225,17 @@ int main(int argc, char **argv)
reset_demo();
- while (1);
+ /**************************************************************************
+ * Demonstrate fast GPIO bit-banging.
+ * One can bang it faster than this if you know
+ * the entire OUTPUT_VAL that you want to write, but
+ * Atomics give a quick way to control a single bit.
+ *************************************************************************/
+ uint32_t mask = (1 << PIN_19_OFFSET);
+
+ while (1){
+ atomic_fetch_xor_explicit(&GPIO_REG(GPIO_OUTPUT_VAL), mask, memory_order_relaxed);
+ }
return 0;