riscv-blink: add example

Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
Sean Cross 2019-06-19 14:33:16 -07:00
parent ac9e39bdcf
commit 36b2794f94
16 changed files with 1505 additions and 0 deletions

119
riscv-blink/Makefile Normal file
View file

@ -0,0 +1,119 @@
GIT_VERSION := $(shell git describe --tags)
# Earlier versions of the Raspberry Pi image only had riscv32-gcc
ifneq (,$(wildcard /usr/bin/riscv32-unknown-elf-gcc))
TRGT ?= riscv32-unknown-elf-
else
TRGT ?= riscv64-unknown-elf-
endif
CC := $(TRGT)gcc
CXX := $(TRGT)g++
OBJCOPY := $(TRGT)objcopy
RM := rm -rf
COPY := cp -a
PATH_SEP := /
ifeq ($(OS),Windows_NT)
COPY := copy
RM := del
PATH_SEP := \\
endif
BASE_DIR := .
LD_DIR := $(BASE_DIR)/ld
LDSCRIPT := $(BASE_DIR)/ld/linker.ld
ADD_CFLAGS := -I$(BASE_DIR)/include -D__vexriscv__ -march=rv32i -mabi=ilp32
ADD_LFLAGS :=
PACKAGE := riscv-blink
LDSCRIPTS := $(LDSCRIPT) $(LD_DIR)/output_format.ld $(LD_DIR)/regions.ld
SRC_DIR := $(BASE_DIR)/src
THIRD_PARTY := $(BASE_DIR)/third_party
DBG_CFLAGS := -ggdb -g -DDEBUG -Wall
DBG_LFLAGS := -ggdb -g -Wall
CFLAGS := $(ADD_CFLAGS) \
-Wall -Wextra \
-ffunction-sections -fdata-sections -fno-common \
-fomit-frame-pointer -Os \
-march=rv32i \
-DGIT_VERSION=u\"$(GIT_VERSION)\" -std=gnu11
CXXFLAGS := $(CFLAGS) -std=c++11 -fno-rtti -fno-exceptions
LFLAGS := $(CFLAGS) $(ADD_LFLAGS) -L$(LD_DIR) \
-nostartfiles \
-Wl,--gc-sections \
-Wl,--no-warn-mismatch \
-Wl,--script=$(LDSCRIPT) \
-Wl,--build-id=none
OBJ_DIR := .obj
CSOURCES := $(wildcard $(SRC_DIR)/*.c) $(wildcard $(THIRD_PARTY)/libbase/*.c) $(wildcard $(THIRD_PARTY)/*.c)
CPPSOURCES := $(wildcard $(SRC_DIR)/*.cpp) $(wildcard $(THIRD_PARTY)/libbase/*.cpp) $(wildcard $(THIRD_PARTY)/*.cpp)
ASOURCES := $(wildcard $(SRC_DIR)/*.S) $(wildcard $(THIRD_PARTY)/libbase/*.S) $(wildcard $(THIRD_PARTY)/*.S)
COBJS := $(addprefix $(OBJ_DIR)/, $(notdir $(CSOURCES:.c=.o)))
CXXOBJS := $(addprefix $(OBJ_DIR)/, $(notdir $(CPPSOURCES:.cpp=.o)))
AOBJS := $(addprefix $(OBJ_DIR)/, $(notdir $(ASOURCES:.S=.o)))
OBJECTS := $(COBJS) $(CXXOBJS) $(AOBJS)
VPATH := $(SRC_DIR) $(THIRD_PARTY) $(THIRD_PARTY)/libbase
QUIET := @
ALL := all
TARGET := $(PACKAGE).elf
CLEAN := clean
$(ALL): $(TARGET) $(PACKAGE).bin $(PACKAGE).ihex
$(OBJECTS): | $(OBJ_DIR)
$(TARGET): $(OBJECTS) $(LDSCRIPTS)
$(QUIET) echo " LD $@"
$(QUIET) $(CC) $(OBJECTS) $(LFLAGS) -o $@
$(PACKAGE).bin: $(TARGET)
$(QUIET) echo " OBJCOPY $@"
$(QUIET) $(OBJCOPY) -O binary $(TARGET) $@
$(PACKAGE).dfu: $(TARGET)
$(QUIET) echo " DFU $@"
$(QUIET) $(COPY) $(PACKAGE).bin $@
$(QUIET) dfu-suffix -v 1209 -p 70b1 -a $@
$(PACKAGE).ihex: $(TARGET)
$(QUIET) echo " IHEX $(PACKAGE).ihex"
$(QUIET) $(OBJCOPY) -O ihex $(TARGET) $@
$(DEBUG): CFLAGS += $(DBG_CFLAGS)
$(DEBUG): LFLAGS += $(DBG_LFLAGS)
CFLAGS += $(DBG_CFLAGS)
LFLAGS += $(DBG_LFLAGS)
$(DEBUG): $(TARGET)
$(OBJ_DIR):
$(QUIET) mkdir $(OBJ_DIR)
$(COBJS) : $(OBJ_DIR)/%.o : %.c $(BASE_DIR)/Makefile
$(QUIET) echo " CC $< $(notdir $@)"
$(QUIET) $(CC) -c $< $(CFLAGS) -o $@ -MMD
$(OBJ_DIR)/%.o: %.cpp
$(QUIET) echo " CXX $< $(notdir $@)"
$(QUIET) $(CXX) -c $< $(CXXFLAGS) -o $@ -MMD
$(OBJ_DIR)/%.o: %.S
$(QUIET) echo " AS $< $(notdir $@)"
$(QUIET) $(CC) -x assembler-with-cpp -c $< $(CFLAGS) -o $@ -MMD
.PHONY: clean
clean:
$(QUIET) echo " RM $(subst /,$(PATH_SEP),$(wildcard $(OBJ_DIR)/*.d))"
-$(QUIET) $(RM) $(subst /,$(PATH_SEP),$(wildcard $(OBJ_DIR)/*.d))
$(QUIET) echo " RM $(subst /,$(PATH_SEP),$(wildcard $(OBJ_DIR)/*.d))"
-$(QUIET) $(RM) $(subst /,$(PATH_SEP),$(wildcard $(OBJ_DIR)/*.o))
$(QUIET) echo " RM $(TARGET) $(PACKAGE).bin $(PACKAGE).symbol $(PACKAGE).ihex $(PACKAGE).dfu"
-$(QUIET) $(RM) $(TARGET) $(PACKAGE).bin $(PACKAGE).symbol $(PACKAGE).ihex $(PACKAGE).dfu
include $(wildcard $(OBJ_DIR)/*.d)

View file

@ -0,0 +1,11 @@
#ifndef CSR_DEFS__H
#define CSR_DEFS__H
#define CSR_MSTATUS_MIE 0x8
#define CSR_IRQ_MASK 0xBC0
#define CSR_IRQ_PENDING 0xFC0
#define CSR_DCACHE_INFO 0xCC0
#endif /* CSR_DEFS__H */

View file

@ -0,0 +1,741 @@
//--------------------------------------------------------------------------------
// Auto-generated by Migen (ae42105) & LiteX (3a72688b) on 2019-06-19 11:30:40
//--------------------------------------------------------------------------------
#ifndef __GENERATED_CSR_H
#define __GENERATED_CSR_H
#include <stdint.h>
#ifdef CSR_ACCESSORS_DEFINED
extern void csr_writeb(uint8_t value, unsigned long addr);
extern uint8_t csr_readb(unsigned long addr);
extern void csr_writew(uint16_t value, unsigned long addr);
extern uint16_t csr_readw(unsigned long addr);
extern void csr_writel(uint32_t value, unsigned long addr);
extern uint32_t csr_readl(unsigned long addr);
#else /* ! CSR_ACCESSORS_DEFINED */
#include <hw/common.h>
#endif /* ! CSR_ACCESSORS_DEFINED */
/* ctrl */
#define CSR_CTRL_BASE 0xe0000000L
#define CSR_CTRL_RESET_ADDR 0xe0000000L
#define CSR_CTRL_RESET_SIZE 1
static inline unsigned char ctrl_reset_read(void) {
unsigned char r = csr_readl(0xe0000000L);
return r;
}
static inline void ctrl_reset_write(unsigned char value) {
csr_writel(value, 0xe0000000L);
}
#define CSR_CTRL_SCRATCH_ADDR 0xe0000004L
#define CSR_CTRL_SCRATCH_SIZE 4
static inline unsigned int ctrl_scratch_read(void) {
unsigned int r = csr_readl(0xe0000004L);
r <<= 8;
r |= csr_readl(0xe0000008L);
r <<= 8;
r |= csr_readl(0xe000000cL);
r <<= 8;
r |= csr_readl(0xe0000010L);
return r;
}
static inline void ctrl_scratch_write(unsigned int value) {
csr_writel(value >> 24, 0xe0000004L);
csr_writel(value >> 16, 0xe0000008L);
csr_writel(value >> 8, 0xe000000cL);
csr_writel(value, 0xe0000010L);
}
#define CSR_CTRL_BUS_ERRORS_ADDR 0xe0000014L
#define CSR_CTRL_BUS_ERRORS_SIZE 4
static inline unsigned int ctrl_bus_errors_read(void) {
unsigned int r = csr_readl(0xe0000014L);
r <<= 8;
r |= csr_readl(0xe0000018L);
r <<= 8;
r |= csr_readl(0xe000001cL);
r <<= 8;
r |= csr_readl(0xe0000020L);
return r;
}
/* picorvspi */
#define CSR_PICORVSPI_BASE 0xe0005000L
#define CSR_PICORVSPI_CFG1_ADDR 0xe0005000L
#define CSR_PICORVSPI_CFG1_SIZE 1
static inline unsigned char picorvspi_cfg1_read(void) {
unsigned char r = csr_readl(0xe0005000L);
return r;
}
static inline void picorvspi_cfg1_write(unsigned char value) {
csr_writel(value, 0xe0005000L);
}
#define CSR_PICORVSPI_CFG2_ADDR 0xe0005004L
#define CSR_PICORVSPI_CFG2_SIZE 1
static inline unsigned char picorvspi_cfg2_read(void) {
unsigned char r = csr_readl(0xe0005004L);
return r;
}
static inline void picorvspi_cfg2_write(unsigned char value) {
csr_writel(value, 0xe0005004L);
}
#define CSR_PICORVSPI_CFG3_ADDR 0xe0005008L
#define CSR_PICORVSPI_CFG3_SIZE 1
static inline unsigned char picorvspi_cfg3_read(void) {
unsigned char r = csr_readl(0xe0005008L);
return r;
}
static inline void picorvspi_cfg3_write(unsigned char value) {
csr_writel(value, 0xe0005008L);
}
#define CSR_PICORVSPI_CFG4_ADDR 0xe000500cL
#define CSR_PICORVSPI_CFG4_SIZE 1
static inline unsigned char picorvspi_cfg4_read(void) {
unsigned char r = csr_readl(0xe000500cL);
return r;
}
static inline void picorvspi_cfg4_write(unsigned char value) {
csr_writel(value, 0xe000500cL);
}
#define CSR_PICORVSPI_STAT1_ADDR 0xe0005010L
#define CSR_PICORVSPI_STAT1_SIZE 1
static inline unsigned char picorvspi_stat1_read(void) {
unsigned char r = csr_readl(0xe0005010L);
return r;
}
#define CSR_PICORVSPI_STAT2_ADDR 0xe0005014L
#define CSR_PICORVSPI_STAT2_SIZE 1
static inline unsigned char picorvspi_stat2_read(void) {
unsigned char r = csr_readl(0xe0005014L);
return r;
}
#define CSR_PICORVSPI_STAT3_ADDR 0xe0005018L
#define CSR_PICORVSPI_STAT3_SIZE 1
static inline unsigned char picorvspi_stat3_read(void) {
unsigned char r = csr_readl(0xe0005018L);
return r;
}
#define CSR_PICORVSPI_STAT4_ADDR 0xe000501cL
#define CSR_PICORVSPI_STAT4_SIZE 1
static inline unsigned char picorvspi_stat4_read(void) {
unsigned char r = csr_readl(0xe000501cL);
return r;
}
/* reboot */
#define CSR_REBOOT_BASE 0xe0006000L
#define CSR_REBOOT_CTRL_ADDR 0xe0006000L
#define CSR_REBOOT_CTRL_SIZE 1
static inline unsigned char reboot_ctrl_read(void) {
unsigned char r = csr_readl(0xe0006000L);
return r;
}
static inline void reboot_ctrl_write(unsigned char value) {
csr_writel(value, 0xe0006000L);
}
#define CSR_REBOOT_ADDR_ADDR 0xe0006004L
#define CSR_REBOOT_ADDR_SIZE 4
static inline unsigned int reboot_addr_read(void) {
unsigned int r = csr_readl(0xe0006004L);
r <<= 8;
r |= csr_readl(0xe0006008L);
r <<= 8;
r |= csr_readl(0xe000600cL);
r <<= 8;
r |= csr_readl(0xe0006010L);
return r;
}
static inline void reboot_addr_write(unsigned int value) {
csr_writel(value >> 24, 0xe0006004L);
csr_writel(value >> 16, 0xe0006008L);
csr_writel(value >> 8, 0xe000600cL);
csr_writel(value, 0xe0006010L);
}
/* rgb */
#define CSR_RGB_BASE 0xe0006800L
#define CSR_RGB_DAT_ADDR 0xe0006800L
#define CSR_RGB_DAT_SIZE 1
static inline unsigned char rgb_dat_read(void) {
unsigned char r = csr_readl(0xe0006800L);
return r;
}
static inline void rgb_dat_write(unsigned char value) {
csr_writel(value, 0xe0006800L);
}
#define CSR_RGB_ADDR_ADDR 0xe0006804L
#define CSR_RGB_ADDR_SIZE 1
static inline unsigned char rgb_addr_read(void) {
unsigned char r = csr_readl(0xe0006804L);
return r;
}
static inline void rgb_addr_write(unsigned char value) {
csr_writel(value, 0xe0006804L);
}
#define CSR_RGB_CTRL_ADDR 0xe0006808L
#define CSR_RGB_CTRL_SIZE 1
static inline unsigned char rgb_ctrl_read(void) {
unsigned char r = csr_readl(0xe0006808L);
return r;
}
static inline void rgb_ctrl_write(unsigned char value) {
csr_writel(value, 0xe0006808L);
}
/* timer0 */
#define CSR_TIMER0_BASE 0xe0002800L
#define CSR_TIMER0_LOAD_ADDR 0xe0002800L
#define CSR_TIMER0_LOAD_SIZE 4
static inline unsigned int timer0_load_read(void) {
unsigned int r = csr_readl(0xe0002800L);
r <<= 8;
r |= csr_readl(0xe0002804L);
r <<= 8;
r |= csr_readl(0xe0002808L);
r <<= 8;
r |= csr_readl(0xe000280cL);
return r;
}
static inline void timer0_load_write(unsigned int value) {
csr_writel(value >> 24, 0xe0002800L);
csr_writel(value >> 16, 0xe0002804L);
csr_writel(value >> 8, 0xe0002808L);
csr_writel(value, 0xe000280cL);
}
#define CSR_TIMER0_RELOAD_ADDR 0xe0002810L
#define CSR_TIMER0_RELOAD_SIZE 4
static inline unsigned int timer0_reload_read(void) {
unsigned int r = csr_readl(0xe0002810L);
r <<= 8;
r |= csr_readl(0xe0002814L);
r <<= 8;
r |= csr_readl(0xe0002818L);
r <<= 8;
r |= csr_readl(0xe000281cL);
return r;
}
static inline void timer0_reload_write(unsigned int value) {
csr_writel(value >> 24, 0xe0002810L);
csr_writel(value >> 16, 0xe0002814L);
csr_writel(value >> 8, 0xe0002818L);
csr_writel(value, 0xe000281cL);
}
#define CSR_TIMER0_EN_ADDR 0xe0002820L
#define CSR_TIMER0_EN_SIZE 1
static inline unsigned char timer0_en_read(void) {
unsigned char r = csr_readl(0xe0002820L);
return r;
}
static inline void timer0_en_write(unsigned char value) {
csr_writel(value, 0xe0002820L);
}
#define CSR_TIMER0_UPDATE_VALUE_ADDR 0xe0002824L
#define CSR_TIMER0_UPDATE_VALUE_SIZE 1
static inline unsigned char timer0_update_value_read(void) {
unsigned char r = csr_readl(0xe0002824L);
return r;
}
static inline void timer0_update_value_write(unsigned char value) {
csr_writel(value, 0xe0002824L);
}
#define CSR_TIMER0_VALUE_ADDR 0xe0002828L
#define CSR_TIMER0_VALUE_SIZE 4
static inline unsigned int timer0_value_read(void) {
unsigned int r = csr_readl(0xe0002828L);
r <<= 8;
r |= csr_readl(0xe000282cL);
r <<= 8;
r |= csr_readl(0xe0002830L);
r <<= 8;
r |= csr_readl(0xe0002834L);
return r;
}
#define CSR_TIMER0_EV_STATUS_ADDR 0xe0002838L
#define CSR_TIMER0_EV_STATUS_SIZE 1
static inline unsigned char timer0_ev_status_read(void) {
unsigned char r = csr_readl(0xe0002838L);
return r;
}
static inline void timer0_ev_status_write(unsigned char value) {
csr_writel(value, 0xe0002838L);
}
#define CSR_TIMER0_EV_PENDING_ADDR 0xe000283cL
#define CSR_TIMER0_EV_PENDING_SIZE 1
static inline unsigned char timer0_ev_pending_read(void) {
unsigned char r = csr_readl(0xe000283cL);
return r;
}
static inline void timer0_ev_pending_write(unsigned char value) {
csr_writel(value, 0xe000283cL);
}
#define CSR_TIMER0_EV_ENABLE_ADDR 0xe0002840L
#define CSR_TIMER0_EV_ENABLE_SIZE 1
static inline unsigned char timer0_ev_enable_read(void) {
unsigned char r = csr_readl(0xe0002840L);
return r;
}
static inline void timer0_ev_enable_write(unsigned char value) {
csr_writel(value, 0xe0002840L);
}
/* touch */
#define CSR_TOUCH_BASE 0xe0005800L
#define CSR_TOUCH_O_ADDR 0xe0005800L
#define CSR_TOUCH_O_SIZE 1
static inline unsigned char touch_o_read(void) {
unsigned char r = csr_readl(0xe0005800L);
return r;
}
static inline void touch_o_write(unsigned char value) {
csr_writel(value, 0xe0005800L);
}
#define CSR_TOUCH_OE_ADDR 0xe0005804L
#define CSR_TOUCH_OE_SIZE 1
static inline unsigned char touch_oe_read(void) {
unsigned char r = csr_readl(0xe0005804L);
return r;
}
static inline void touch_oe_write(unsigned char value) {
csr_writel(value, 0xe0005804L);
}
#define CSR_TOUCH_I_ADDR 0xe0005808L
#define CSR_TOUCH_I_SIZE 1
static inline unsigned char touch_i_read(void) {
unsigned char r = csr_readl(0xe0005808L);
return r;
}
/* usb */
#define CSR_USB_BASE 0xe0004800L
#define CSR_USB_PULLUP_OUT_ADDR 0xe0004800L
#define CSR_USB_PULLUP_OUT_SIZE 1
static inline unsigned char usb_pullup_out_read(void) {
unsigned char r = csr_readl(0xe0004800L);
return r;
}
static inline void usb_pullup_out_write(unsigned char value) {
csr_writel(value, 0xe0004800L);
}
#define CSR_USB_EP_0_OUT_EV_STATUS_ADDR 0xe0004804L
#define CSR_USB_EP_0_OUT_EV_STATUS_SIZE 1
static inline unsigned char usb_ep_0_out_ev_status_read(void) {
unsigned char r = csr_readl(0xe0004804L);
return r;
}
static inline void usb_ep_0_out_ev_status_write(unsigned char value) {
csr_writel(value, 0xe0004804L);
}
#define CSR_USB_EP_0_OUT_EV_PENDING_ADDR 0xe0004808L
#define CSR_USB_EP_0_OUT_EV_PENDING_SIZE 1
static inline unsigned char usb_ep_0_out_ev_pending_read(void) {
unsigned char r = csr_readl(0xe0004808L);
return r;
}
static inline void usb_ep_0_out_ev_pending_write(unsigned char value) {
csr_writel(value, 0xe0004808L);
}
#define CSR_USB_EP_0_OUT_EV_ENABLE_ADDR 0xe000480cL
#define CSR_USB_EP_0_OUT_EV_ENABLE_SIZE 1
static inline unsigned char usb_ep_0_out_ev_enable_read(void) {
unsigned char r = csr_readl(0xe000480cL);
return r;
}
static inline void usb_ep_0_out_ev_enable_write(unsigned char value) {
csr_writel(value, 0xe000480cL);
}
#define CSR_USB_EP_0_OUT_LAST_TOK_ADDR 0xe0004810L
#define CSR_USB_EP_0_OUT_LAST_TOK_SIZE 1
static inline unsigned char usb_ep_0_out_last_tok_read(void) {
unsigned char r = csr_readl(0xe0004810L);
return r;
}
#define CSR_USB_EP_0_OUT_RESPOND_ADDR 0xe0004814L
#define CSR_USB_EP_0_OUT_RESPOND_SIZE 1
static inline unsigned char usb_ep_0_out_respond_read(void) {
unsigned char r = csr_readl(0xe0004814L);
return r;
}
static inline void usb_ep_0_out_respond_write(unsigned char value) {
csr_writel(value, 0xe0004814L);
}
#define CSR_USB_EP_0_OUT_DTB_ADDR 0xe0004818L
#define CSR_USB_EP_0_OUT_DTB_SIZE 1
static inline unsigned char usb_ep_0_out_dtb_read(void) {
unsigned char r = csr_readl(0xe0004818L);
return r;
}
static inline void usb_ep_0_out_dtb_write(unsigned char value) {
csr_writel(value, 0xe0004818L);
}
#define CSR_USB_EP_0_OUT_OBUF_HEAD_ADDR 0xe000481cL
#define CSR_USB_EP_0_OUT_OBUF_HEAD_SIZE 1
static inline unsigned char usb_ep_0_out_obuf_head_read(void) {
unsigned char r = csr_readl(0xe000481cL);
return r;
}
static inline void usb_ep_0_out_obuf_head_write(unsigned char value) {
csr_writel(value, 0xe000481cL);
}
#define CSR_USB_EP_0_OUT_OBUF_EMPTY_ADDR 0xe0004820L
#define CSR_USB_EP_0_OUT_OBUF_EMPTY_SIZE 1
static inline unsigned char usb_ep_0_out_obuf_empty_read(void) {
unsigned char r = csr_readl(0xe0004820L);
return r;
}
#define CSR_USB_EP_0_IN_EV_STATUS_ADDR 0xe0004824L
#define CSR_USB_EP_0_IN_EV_STATUS_SIZE 1
static inline unsigned char usb_ep_0_in_ev_status_read(void) {
unsigned char r = csr_readl(0xe0004824L);
return r;
}
static inline void usb_ep_0_in_ev_status_write(unsigned char value) {
csr_writel(value, 0xe0004824L);
}
#define CSR_USB_EP_0_IN_EV_PENDING_ADDR 0xe0004828L
#define CSR_USB_EP_0_IN_EV_PENDING_SIZE 1
static inline unsigned char usb_ep_0_in_ev_pending_read(void) {
unsigned char r = csr_readl(0xe0004828L);
return r;
}
static inline void usb_ep_0_in_ev_pending_write(unsigned char value) {
csr_writel(value, 0xe0004828L);
}
#define CSR_USB_EP_0_IN_EV_ENABLE_ADDR 0xe000482cL
#define CSR_USB_EP_0_IN_EV_ENABLE_SIZE 1
static inline unsigned char usb_ep_0_in_ev_enable_read(void) {
unsigned char r = csr_readl(0xe000482cL);
return r;
}
static inline void usb_ep_0_in_ev_enable_write(unsigned char value) {
csr_writel(value, 0xe000482cL);
}
#define CSR_USB_EP_0_IN_LAST_TOK_ADDR 0xe0004830L
#define CSR_USB_EP_0_IN_LAST_TOK_SIZE 1
static inline unsigned char usb_ep_0_in_last_tok_read(void) {
unsigned char r = csr_readl(0xe0004830L);
return r;
}
#define CSR_USB_EP_0_IN_RESPOND_ADDR 0xe0004834L
#define CSR_USB_EP_0_IN_RESPOND_SIZE 1
static inline unsigned char usb_ep_0_in_respond_read(void) {
unsigned char r = csr_readl(0xe0004834L);
return r;
}
static inline void usb_ep_0_in_respond_write(unsigned char value) {
csr_writel(value, 0xe0004834L);
}
#define CSR_USB_EP_0_IN_DTB_ADDR 0xe0004838L
#define CSR_USB_EP_0_IN_DTB_SIZE 1
static inline unsigned char usb_ep_0_in_dtb_read(void) {
unsigned char r = csr_readl(0xe0004838L);
return r;
}
static inline void usb_ep_0_in_dtb_write(unsigned char value) {
csr_writel(value, 0xe0004838L);
}
#define CSR_USB_EP_0_IN_IBUF_HEAD_ADDR 0xe000483cL
#define CSR_USB_EP_0_IN_IBUF_HEAD_SIZE 1
static inline unsigned char usb_ep_0_in_ibuf_head_read(void) {
unsigned char r = csr_readl(0xe000483cL);
return r;
}
static inline void usb_ep_0_in_ibuf_head_write(unsigned char value) {
csr_writel(value, 0xe000483cL);
}
#define CSR_USB_EP_0_IN_IBUF_EMPTY_ADDR 0xe0004840L
#define CSR_USB_EP_0_IN_IBUF_EMPTY_SIZE 1
static inline unsigned char usb_ep_0_in_ibuf_empty_read(void) {
unsigned char r = csr_readl(0xe0004840L);
return r;
}
#define CSR_USB_EP_1_IN_EV_STATUS_ADDR 0xe0004844L
#define CSR_USB_EP_1_IN_EV_STATUS_SIZE 1
static inline unsigned char usb_ep_1_in_ev_status_read(void) {
unsigned char r = csr_readl(0xe0004844L);
return r;
}
static inline void usb_ep_1_in_ev_status_write(unsigned char value) {
csr_writel(value, 0xe0004844L);
}
#define CSR_USB_EP_1_IN_EV_PENDING_ADDR 0xe0004848L
#define CSR_USB_EP_1_IN_EV_PENDING_SIZE 1
static inline unsigned char usb_ep_1_in_ev_pending_read(void) {
unsigned char r = csr_readl(0xe0004848L);
return r;
}
static inline void usb_ep_1_in_ev_pending_write(unsigned char value) {
csr_writel(value, 0xe0004848L);
}
#define CSR_USB_EP_1_IN_EV_ENABLE_ADDR 0xe000484cL
#define CSR_USB_EP_1_IN_EV_ENABLE_SIZE 1
static inline unsigned char usb_ep_1_in_ev_enable_read(void) {
unsigned char r = csr_readl(0xe000484cL);
return r;
}
static inline void usb_ep_1_in_ev_enable_write(unsigned char value) {
csr_writel(value, 0xe000484cL);
}
#define CSR_USB_EP_1_IN_LAST_TOK_ADDR 0xe0004850L
#define CSR_USB_EP_1_IN_LAST_TOK_SIZE 1
static inline unsigned char usb_ep_1_in_last_tok_read(void) {
unsigned char r = csr_readl(0xe0004850L);
return r;
}
#define CSR_USB_EP_1_IN_RESPOND_ADDR 0xe0004854L
#define CSR_USB_EP_1_IN_RESPOND_SIZE 1
static inline unsigned char usb_ep_1_in_respond_read(void) {
unsigned char r = csr_readl(0xe0004854L);
return r;
}
static inline void usb_ep_1_in_respond_write(unsigned char value) {
csr_writel(value, 0xe0004854L);
}
#define CSR_USB_EP_1_IN_DTB_ADDR 0xe0004858L
#define CSR_USB_EP_1_IN_DTB_SIZE 1
static inline unsigned char usb_ep_1_in_dtb_read(void) {
unsigned char r = csr_readl(0xe0004858L);
return r;
}
static inline void usb_ep_1_in_dtb_write(unsigned char value) {
csr_writel(value, 0xe0004858L);
}
#define CSR_USB_EP_1_IN_IBUF_HEAD_ADDR 0xe000485cL
#define CSR_USB_EP_1_IN_IBUF_HEAD_SIZE 1
static inline unsigned char usb_ep_1_in_ibuf_head_read(void) {
unsigned char r = csr_readl(0xe000485cL);
return r;
}
static inline void usb_ep_1_in_ibuf_head_write(unsigned char value) {
csr_writel(value, 0xe000485cL);
}
#define CSR_USB_EP_1_IN_IBUF_EMPTY_ADDR 0xe0004860L
#define CSR_USB_EP_1_IN_IBUF_EMPTY_SIZE 1
static inline unsigned char usb_ep_1_in_ibuf_empty_read(void) {
unsigned char r = csr_readl(0xe0004860L);
return r;
}
#define CSR_USB_EP_2_OUT_EV_STATUS_ADDR 0xe0004864L
#define CSR_USB_EP_2_OUT_EV_STATUS_SIZE 1
static inline unsigned char usb_ep_2_out_ev_status_read(void) {
unsigned char r = csr_readl(0xe0004864L);
return r;
}
static inline void usb_ep_2_out_ev_status_write(unsigned char value) {
csr_writel(value, 0xe0004864L);
}
#define CSR_USB_EP_2_OUT_EV_PENDING_ADDR 0xe0004868L
#define CSR_USB_EP_2_OUT_EV_PENDING_SIZE 1
static inline unsigned char usb_ep_2_out_ev_pending_read(void) {
unsigned char r = csr_readl(0xe0004868L);
return r;
}
static inline void usb_ep_2_out_ev_pending_write(unsigned char value) {
csr_writel(value, 0xe0004868L);
}
#define CSR_USB_EP_2_OUT_EV_ENABLE_ADDR 0xe000486cL
#define CSR_USB_EP_2_OUT_EV_ENABLE_SIZE 1
static inline unsigned char usb_ep_2_out_ev_enable_read(void) {
unsigned char r = csr_readl(0xe000486cL);
return r;
}
static inline void usb_ep_2_out_ev_enable_write(unsigned char value) {
csr_writel(value, 0xe000486cL);
}
#define CSR_USB_EP_2_OUT_LAST_TOK_ADDR 0xe0004870L
#define CSR_USB_EP_2_OUT_LAST_TOK_SIZE 1
static inline unsigned char usb_ep_2_out_last_tok_read(void) {
unsigned char r = csr_readl(0xe0004870L);
return r;
}
#define CSR_USB_EP_2_OUT_RESPOND_ADDR 0xe0004874L
#define CSR_USB_EP_2_OUT_RESPOND_SIZE 1
static inline unsigned char usb_ep_2_out_respond_read(void) {
unsigned char r = csr_readl(0xe0004874L);
return r;
}
static inline void usb_ep_2_out_respond_write(unsigned char value) {
csr_writel(value, 0xe0004874L);
}
#define CSR_USB_EP_2_OUT_DTB_ADDR 0xe0004878L
#define CSR_USB_EP_2_OUT_DTB_SIZE 1
static inline unsigned char usb_ep_2_out_dtb_read(void) {
unsigned char r = csr_readl(0xe0004878L);
return r;
}
static inline void usb_ep_2_out_dtb_write(unsigned char value) {
csr_writel(value, 0xe0004878L);
}
#define CSR_USB_EP_2_OUT_OBUF_HEAD_ADDR 0xe000487cL
#define CSR_USB_EP_2_OUT_OBUF_HEAD_SIZE 1
static inline unsigned char usb_ep_2_out_obuf_head_read(void) {
unsigned char r = csr_readl(0xe000487cL);
return r;
}
static inline void usb_ep_2_out_obuf_head_write(unsigned char value) {
csr_writel(value, 0xe000487cL);
}
#define CSR_USB_EP_2_OUT_OBUF_EMPTY_ADDR 0xe0004880L
#define CSR_USB_EP_2_OUT_OBUF_EMPTY_SIZE 1
static inline unsigned char usb_ep_2_out_obuf_empty_read(void) {
unsigned char r = csr_readl(0xe0004880L);
return r;
}
#define CSR_USB_EP_2_IN_EV_STATUS_ADDR 0xe0004884L
#define CSR_USB_EP_2_IN_EV_STATUS_SIZE 1
static inline unsigned char usb_ep_2_in_ev_status_read(void) {
unsigned char r = csr_readl(0xe0004884L);
return r;
}
static inline void usb_ep_2_in_ev_status_write(unsigned char value) {
csr_writel(value, 0xe0004884L);
}
#define CSR_USB_EP_2_IN_EV_PENDING_ADDR 0xe0004888L
#define CSR_USB_EP_2_IN_EV_PENDING_SIZE 1
static inline unsigned char usb_ep_2_in_ev_pending_read(void) {
unsigned char r = csr_readl(0xe0004888L);
return r;
}
static inline void usb_ep_2_in_ev_pending_write(unsigned char value) {
csr_writel(value, 0xe0004888L);
}
#define CSR_USB_EP_2_IN_EV_ENABLE_ADDR 0xe000488cL
#define CSR_USB_EP_2_IN_EV_ENABLE_SIZE 1
static inline unsigned char usb_ep_2_in_ev_enable_read(void) {
unsigned char r = csr_readl(0xe000488cL);
return r;
}
static inline void usb_ep_2_in_ev_enable_write(unsigned char value) {
csr_writel(value, 0xe000488cL);
}
#define CSR_USB_EP_2_IN_LAST_TOK_ADDR 0xe0004890L
#define CSR_USB_EP_2_IN_LAST_TOK_SIZE 1
static inline unsigned char usb_ep_2_in_last_tok_read(void) {
unsigned char r = csr_readl(0xe0004890L);
return r;
}
#define CSR_USB_EP_2_IN_RESPOND_ADDR 0xe0004894L
#define CSR_USB_EP_2_IN_RESPOND_SIZE 1
static inline unsigned char usb_ep_2_in_respond_read(void) {
unsigned char r = csr_readl(0xe0004894L);
return r;
}
static inline void usb_ep_2_in_respond_write(unsigned char value) {
csr_writel(value, 0xe0004894L);
}
#define CSR_USB_EP_2_IN_DTB_ADDR 0xe0004898L
#define CSR_USB_EP_2_IN_DTB_SIZE 1
static inline unsigned char usb_ep_2_in_dtb_read(void) {
unsigned char r = csr_readl(0xe0004898L);
return r;
}
static inline void usb_ep_2_in_dtb_write(unsigned char value) {
csr_writel(value, 0xe0004898L);
}
#define CSR_USB_EP_2_IN_IBUF_HEAD_ADDR 0xe000489cL
#define CSR_USB_EP_2_IN_IBUF_HEAD_SIZE 1
static inline unsigned char usb_ep_2_in_ibuf_head_read(void) {
unsigned char r = csr_readl(0xe000489cL);
return r;
}
static inline void usb_ep_2_in_ibuf_head_write(unsigned char value) {
csr_writel(value, 0xe000489cL);
}
#define CSR_USB_EP_2_IN_IBUF_EMPTY_ADDR 0xe00048a0L
#define CSR_USB_EP_2_IN_IBUF_EMPTY_SIZE 1
static inline unsigned char usb_ep_2_in_ibuf_empty_read(void) {
unsigned char r = csr_readl(0xe00048a0L);
return r;
}
/* version */
#define CSR_VERSION_BASE 0xe0007000L
#define CSR_VERSION_MAJOR_ADDR 0xe0007000L
#define CSR_VERSION_MAJOR_SIZE 1
static inline unsigned char version_major_read(void) {
unsigned char r = csr_readl(0xe0007000L);
return r;
}
#define CSR_VERSION_MINOR_ADDR 0xe0007004L
#define CSR_VERSION_MINOR_SIZE 1
static inline unsigned char version_minor_read(void) {
unsigned char r = csr_readl(0xe0007004L);
return r;
}
#define CSR_VERSION_REVISION_ADDR 0xe0007008L
#define CSR_VERSION_REVISION_SIZE 1
static inline unsigned char version_revision_read(void) {
unsigned char r = csr_readl(0xe0007008L);
return r;
}
#define CSR_VERSION_GITREV_ADDR 0xe000700cL
#define CSR_VERSION_GITREV_SIZE 4
static inline unsigned int version_gitrev_read(void) {
unsigned int r = csr_readl(0xe000700cL);
r <<= 8;
r |= csr_readl(0xe0007010L);
r <<= 8;
r |= csr_readl(0xe0007014L);
r <<= 8;
r |= csr_readl(0xe0007018L);
return r;
}
#define CSR_VERSION_GITEXTRA_ADDR 0xe000701cL
#define CSR_VERSION_GITEXTRA_SIZE 2
static inline unsigned short int version_gitextra_read(void) {
unsigned short int r = csr_readl(0xe000701cL);
r <<= 8;
r |= csr_readl(0xe0007020L);
return r;
}
#define CSR_VERSION_DIRTY_ADDR 0xe0007024L
#define CSR_VERSION_DIRTY_SIZE 1
static inline unsigned char version_dirty_read(void) {
unsigned char r = csr_readl(0xe0007024L);
return r;
}
/* constants */
#define TIMER0_INTERRUPT 0
static inline int timer0_interrupt_read(void) {
return 0;
}
#define USB_INTERRUPT 3
static inline int usb_interrupt_read(void) {
return 3;
}
#define CSR_DATA_WIDTH 8
static inline int csr_data_width_read(void) {
return 8;
}
#define SYSTEM_CLOCK_FREQUENCY 12000000
static inline int system_clock_frequency_read(void) {
return 12000000;
}
#define CONFIG_BITSTREAM_SYNC_HEADER1 2123999870
static inline int config_bitstream_sync_header1_read(void) {
return 2123999870;
}
#define CONFIG_BITSTREAM_SYNC_HEADER2 2125109630
static inline int config_bitstream_sync_header2_read(void) {
return 2125109630;
}
#define CONFIG_CLOCK_FREQUENCY 12000000
static inline int config_clock_frequency_read(void) {
return 12000000;
}
#define CONFIG_CPU_RESET_ADDR 0
static inline int config_cpu_reset_addr_read(void) {
return 0;
}
#define CONFIG_CPU_TYPE "VEXRISCV"
static inline const char * config_cpu_type_read(void) {
return "VEXRISCV";
}
#define CONFIG_CPU_VARIANT "VEXRISCV"
static inline const char * config_cpu_variant_read(void) {
return "VEXRISCV";
}
#define CONFIG_CSR_DATA_WIDTH 8
static inline int config_csr_data_width_read(void) {
return 8;
}
#endif

View file

@ -0,0 +1,16 @@
#ifndef __GENERATED_MEM_H
#define __GENERATED_MEM_H
#define VEXRISCV_DEBUG_BASE 0xf00f0000
#define VEXRISCV_DEBUG_SIZE 0x00000010
#define SRAM_BASE 0x10000000
#define SRAM_SIZE 0x00020000
#define ROM_BASE 0x00000000
#define ROM_SIZE 0x00002000
#define SPIFLASH_BASE 0x20000000
#define SPIFLASH_SIZE 0x00200000
#endif

View file

@ -0,0 +1,52 @@
#ifndef __HW_COMMON_H
#define __HW_COMMON_H
#include <stdint.h>
/* To overwrite CSR accessors, define extern, non-inlined versions
* of csr_read[bwl]() and csr_write[bwl](), and define
* CSR_ACCESSORS_DEFINED.
*/
#ifndef CSR_ACCESSORS_DEFINED
#define CSR_ACCESSORS_DEFINED
#ifdef __ASSEMBLER__
#define MMPTR(x) x
#else /* ! __ASSEMBLER__ */
#define MMPTR(x) (*((volatile unsigned int *)(x)))
static inline void csr_writeb(uint8_t value, uint32_t addr)
{
*((volatile uint8_t *)addr) = value;
}
static inline uint8_t csr_readb(uint32_t addr)
{
return *(volatile uint8_t *)addr;
}
static inline void csr_writew(uint16_t value, uint32_t addr)
{
*((volatile uint16_t *)addr) = value;
}
static inline uint16_t csr_readw(uint32_t addr)
{
return *(volatile uint16_t *)addr;
}
static inline void csr_writel(uint32_t value, uint32_t addr)
{
*((volatile uint32_t *)addr) = value;
}
static inline uint32_t csr_readl(uint32_t addr)
{
return *(volatile uint32_t *)addr;
}
#endif /* ! __ASSEMBLER__ */
#endif /* ! CSR_ACCESSORS_DEFINED */
#endif /* __HW_COMMON_H */

144
riscv-blink/include/irq.h Normal file
View file

@ -0,0 +1,144 @@
#ifndef __IRQ_H
#define __IRQ_H
#ifdef __cplusplus
extern "C" {
#endif
#include <system.h>
#ifdef __picorv32__
// PicoRV32 has a very limited interrupt support, implemented via custom
// instructions. It also doesn't have a global interrupt enable/disable, so
// we have to emulate it via saving and restoring a mask and using 0/~1 as a
// hardware mask.
// Due to all this somewhat low-level mess, all of the glue is implemented in
// the RiscV crt0, and this header is kept as a thin wrapper. Since interrupts
// managed by this layer, do not call interrupt instructions directly, as the
// state will go out of sync with the hardware.
// Read only.
extern unsigned int _irq_pending;
// Read only.
extern unsigned int _irq_mask;
// Read only.
extern unsigned int _irq_enabled;
extern void _irq_enable(void);
extern void _irq_disable(void);
extern void _irq_setmask(unsigned int);
#endif
static inline unsigned int irq_getie(void)
{
#if defined (__lm32__)
unsigned int ie;
__asm__ __volatile__("rcsr %0, IE" : "=r" (ie));
return ie;
#elif defined (__or1k__)
return !!(mfspr(SPR_SR) & SPR_SR_IEE);
#elif defined (__picorv32__)
return _irq_enabled != 0;
#elif defined (__vexriscv__)
return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0;
#elif defined (__minerva__)
return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0;
#else
#error Unsupported architecture
#endif
}
static inline void irq_setie(unsigned int ie)
{
#if defined (__lm32__)
__asm__ __volatile__("wcsr IE, %0" : : "r" (ie));
#elif defined (__or1k__)
if (ie & 0x1)
mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
else
mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_IEE);
#elif defined (__picorv32__)
if (ie & 0x1)
_irq_enable();
else
_irq_disable();
#elif defined (__vexriscv__)
if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE);
#elif defined (__minerva__)
if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE);
#else
#error Unsupported architecture
#endif
}
static inline unsigned int irq_getmask(void)
{
#if defined (__lm32__)
unsigned int mask;
__asm__ __volatile__("rcsr %0, IM" : "=r" (mask));
return mask;
#elif defined (__or1k__)
return mfspr(SPR_PICMR);
#elif defined (__picorv32__)
// PicoRV32 interrupt mask bits are high-disabled. This is the inverse of how
// LiteX sees things.
return ~_irq_mask;
#elif defined (__vexriscv__)
unsigned int mask;
asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK));
return mask;
#elif defined (__minerva__)
unsigned int mask;
asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK));
return mask;
#else
#error Unsupported architecture
#endif
}
static inline void irq_setmask(unsigned int mask)
{
#if defined (__lm32__)
__asm__ __volatile__("wcsr IM, %0" : : "r" (mask));
#elif defined (__or1k__)
mtspr(SPR_PICMR, mask);
#elif defined (__picorv32__)
// PicoRV32 interrupt mask bits are high-disabled. This is the inverse of how
// LiteX sees things.
_irq_setmask(~mask);
#elif defined (__vexriscv__)
asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask));
#elif defined (__minerva__)
asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask));
#else
#error Unsupported architecture
#endif
}
static inline unsigned int irq_pending(void)
{
#if defined (__lm32__)
unsigned int pending;
__asm__ __volatile__("rcsr %0, IP" : "=r" (pending));
return pending;
#elif defined (__or1k__)
return mfspr(SPR_PICSR);
#elif defined (__picorv32__)
return _irq_pending;
#elif defined (__vexriscv__)
unsigned int pending;
asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING));
return pending;
#elif defined (__minerva__)
unsigned int pending;
asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING));
return pending;
#else
#error Unsupported architecture
#endif
}
#ifdef __cplusplus
}
#endif
#endif /* __IRQ_H */

15
riscv-blink/include/rgb.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef _RGB_H_
#define _RGB_H_
void rgb_init(void);
void rgb_set(uint8_t r, uint8_t g, uint8_t b);
// The amount of time to stay off or on
void rgb_on_time(uint8_t ms);
void rgb_off_time(uint8_t ms);
// The amount of time to breathe in/out
void rgb_in_time(uint8_t ms);
void rgb_out_time(uint8_t ms);
#endif /* _RGB_H_ */

View file

@ -0,0 +1,70 @@
#ifndef __SYSTEM_H
#define __SYSTEM_H
#ifdef __cplusplus
extern "C" {
#endif
void flush_cpu_icache(void);
void flush_cpu_dcache(void);
void flush_l2_cache(void);
#ifdef __or1k__
#include <spr-defs.h>
static inline unsigned long mfspr(unsigned long add)
{
unsigned long ret;
__asm__ __volatile__ ("l.mfspr %0,%1,0" : "=r" (ret) : "r" (add));
return ret;
}
static inline void mtspr(unsigned long add, unsigned long val)
{
__asm__ __volatile__ ("l.mtspr %0,%1,0" : : "r" (add), "r" (val));
}
#endif
#if defined(__vexriscv__) || defined(__minerva__)
#include <csr-defs.h>
#define csrr(reg) ({ unsigned long __tmp; \
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
__tmp; })
#define csrw(reg, val) ({ \
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
else \
asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
#define csrs(reg, bit) ({ \
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
asm volatile ("csrrs x0, " #reg ", %0" :: "i"(bit)); \
else \
asm volatile ("csrrs x0, " #reg ", %0" :: "r"(bit)); })
#define csrc(reg, bit) ({ \
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
asm volatile ("csrrc x0, " #reg ", %0" :: "i"(bit)); \
else \
asm volatile ("csrrc x0, " #reg ", %0" :: "r"(bit)); })
#endif
#ifdef __cplusplus
}
#endif
#include <generated/csr.h>
__attribute__((noreturn)) static inline void reboot(void) {
reboot_ctrl_write(0xac);
while (1);
}
__attribute__((noreturn)) static inline void reboot_to_image(uint8_t image_index) {
reboot_ctrl_write(0xac | (image_index & 3) << 0);
while (1);
}
#endif /* __SYSTEM_H */

View file

@ -0,0 +1,16 @@
#ifndef __TIME_H
#define __TIME_H
#ifdef __cplusplus
extern "C" {
#endif
void time_init(void);
int elapsed(int *last_event, int period);
void msleep(int ms);
#ifdef __cplusplus
}
#endif
#endif /* __TIME_H */

55
riscv-blink/ld/linker.ld Normal file
View file

@ -0,0 +1,55 @@
INCLUDE output_format.ld
ENTRY(_start)
__DYNAMIC = 0;
INCLUDE regions.ld
SECTIONS
{
.text :
{
_ftext = .;
*(.text.start)
*(.text .stub .text.* .gnu.linkonce.t.*)
_etext = .;
} > rom
.rodata :
{
. = ALIGN(4);
_frodata = .;
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
*(.srodata)
_erodata = .;
} > rom
.data : AT (ADDR(.rodata) + SIZEOF (.rodata))
{
. = ALIGN(4);
_fdata = .;
*(.data .data.* .gnu.linkonce.d.*)
*(.data1)
_gp = ALIGN(16);
*(.sdata .sdata.* .gnu.linkonce.s.* .sdata2 .sdata2.*)
_edata = ALIGN(16); /* Make sure _edata is >= _gp. */
} > sram
.bss :
{
. = ALIGN(4);
_fbss = .;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
_end = .;
} > sram
}
PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 4);

View file

@ -0,0 +1 @@
OUTPUT_FORMAT("elf32-littleriscv")

View file

@ -0,0 +1,4 @@
MEMORY {
sram : ORIGIN = 0x10000000, LENGTH = 0x00020000
rom : ORIGIN = 0x20040000, LENGTH = 0x100000 /* 1 MBit */
}

View file

@ -0,0 +1,86 @@
.global main
.global isr
.section .text.start
.global _start
_start:
j crt_init
.word 0xb469075a
.word 0x00000020
.section .text
.global trap_entry
trap_entry:
sw x1, - 1*4(sp)
sw x5, - 2*4(sp)
sw x6, - 3*4(sp)
sw x7, - 4*4(sp)
sw x10, - 5*4(sp)
sw x11, - 6*4(sp)
sw x12, - 7*4(sp)
sw x13, - 8*4(sp)
sw x14, - 9*4(sp)
sw x15, -10*4(sp)
sw x16, -11*4(sp)
sw x17, -12*4(sp)
sw x28, -13*4(sp)
sw x29, -14*4(sp)
sw x30, -15*4(sp)
sw x31, -16*4(sp)
addi sp,sp,-16*4
call isr
lw x1 , 15*4(sp)
lw x5, 14*4(sp)
lw x6, 13*4(sp)
lw x7, 12*4(sp)
lw x10, 11*4(sp)
lw x11, 10*4(sp)
lw x12, 9*4(sp)
lw x13, 8*4(sp)
lw x14, 7*4(sp)
lw x15, 6*4(sp)
lw x16, 5*4(sp)
lw x17, 4*4(sp)
lw x28, 3*4(sp)
lw x29, 2*4(sp)
lw x30, 1*4(sp)
lw x31, 0*4(sp)
addi sp,sp,16*4
mret
.text
crt_init:
la sp, _fstack + 4
la a0, trap_entry
csrw mtvec, a0
bss_init:
la a0, _fbss
la a1, _ebss
bss_loop:
beq a0,a1,bss_done
sw zero,0(a0)
add a0,a0,4
j bss_loop
bss_done:
/* Load DATA */
la t0, _erodata
la t1, _fdata
la t2, _edata
3:
lw t3, 0(t0)
sw t3, 0(t1)
/* _edata is aligned to 16 bytes. Use word-xfers. */
addi t0, t0, 4
addi t1, t1, 4
bltu t1, t2, 3b
li a0, 0x880 //880 enable timer + external interrupt sources (until mstatus.MIE is set, they will never trigger an interrupt)
csrw mie,a0
call main
infinite_loop:
j infinite_loop

47
riscv-blink/src/main.c Normal file
View file

@ -0,0 +1,47 @@
#include <irq.h>
#include <time.h>
#include <rgb.h>
#include <generated/csr.h>
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
static void color_wheel(uint8_t WheelPos) {
WheelPos = 255 - WheelPos;
uint8_t r, g, b;
if(WheelPos < 85) {
r = 255 - WheelPos * 3;
g = 0;
b = WheelPos * 3;
}
else if(WheelPos < 170) {
WheelPos -= 85;
r = 0;
g = WheelPos * 3;
b = 255 - WheelPos * 3;
}
else {
WheelPos -= 170;
r =WheelPos * 3;
g = 255 - WheelPos * 3;
b = 0;
}
rgb_set(r, g, b);
}
void isr(void) {
irq_setie(0);
return;
}
void main(void) {
rgb_init();
irq_setie(0);
int i = 0;
while (1) {
i++;
color_wheel(i++);
msleep(80);
}
}

85
riscv-blink/src/rgb.c Normal file
View file

@ -0,0 +1,85 @@
#include <stdint.h>
#include <rgb.h>
#include <generated/csr.h>
enum led_registers {
LEDDCR0 = 8,
LEDDBR = 9,
LEDDONR = 10,
LEDDOFR = 11,
LEDDBCRR = 5,
LEDDBCFR = 6,
LEDDPWRR = 1,
LEDDPWRG = 2,
LEDDPWRB = 3,
};
#define BREATHE_ENABLE (1 << 7)
#define BREATHE_EDGE_ON (0 << 6)
#define BREATHE_EDGE_BOTH (1 << 6)
#define BREATHE_MODE_MODULATE (1 << 5)
#define BREATHE_MODE_FIXED (0 << 5)
// Breathe rate is in 128 ms increments
#define BREATHE_RATE_MS(x) ((((x)+1) / 128 & 7) << 0)
// Blink on/off time is in 32 ms increments
#define BLINK_TIME_MS(x) (((x)) / 32)
#define LEDDEN (1 << 7)
#define FR250 (1 << 6)
#define OUTPUL (1 << 5)
#define OUTSKEW (1 << 4)
#define QUICK_STOP (1 << 3)
#define PWM_MODE_LFSR (1 << 2)
#define PWM_MODE_LINEAR (0 << 2)
static void rgb_write(uint8_t value, uint8_t addr) {
rgb_addr_write(addr);
rgb_dat_write(value);
}
void rgb_init(void) {
// Turn on the RGB block and current enable, as well as enabling led control
rgb_ctrl_write((1 << 0) | (1 << 1) | (1 << 2));
// Enable the LED driver, and set 250 Hz mode.
// Also set quick stop, which we'll use to switch patterns quickly.
rgb_write(LEDDEN | FR250 | QUICK_STOP, LEDDCR0);
// Set clock register to 12 MHz / 64 kHz - 1
rgb_write((12000000/64000)-1, LEDDBR);
rgb_write(BLINK_TIME_MS(32), LEDDONR); // Amount of time to stay "on"
rgb_write(BLINK_TIME_MS(0), LEDDOFR); // Amount of time to stay "off"
rgb_write(BREATHE_ENABLE | BREATHE_MODE_FIXED | BREATHE_RATE_MS(128), LEDDBCRR);
rgb_write(BREATHE_ENABLE | BREATHE_MODE_FIXED | BREATHE_RATE_MS(128), LEDDBCFR);
}
void rgb_set(uint8_t r, uint8_t g, uint8_t b) {
// Note: the LEDD control registers have arbitrary names that
// do not match up with the LEDD pin outputs. Hence this strange
// mapping.
rgb_write(r, LEDDPWRR); // Blue
rgb_write(g, LEDDPWRG); // Red
rgb_write(b, LEDDPWRB); // Green
}
// The amount of time to stay off or on
void rgb_on_time(uint8_t ms) {
rgb_write(BLINK_TIME_MS(ms), LEDDONR); // Amount of time to stay "on"
}
void rgb_off_time(uint8_t ms) {
rgb_write(BLINK_TIME_MS(ms), LEDDOFR); // Amount of time to stay "off"
}
// The amount of time to breathe in/out
void rgb_in_time(uint8_t ms) {
rgb_write(BREATHE_ENABLE| BREATHE_MODE_FIXED | BREATHE_RATE_MS(ms), LEDDBCRR);
}
void rgb_out_time(uint8_t ms) {
rgb_write(BREATHE_ENABLE | BREATHE_MODE_FIXED | BREATHE_RATE_MS(ms), LEDDBCFR);
}

43
riscv-blink/src/time.c Normal file
View file

@ -0,0 +1,43 @@
#include <generated/csr.h>
#include <time.h>
void time_init(void)
{
int t;
timer0_en_write(0);
t = 2*SYSTEM_CLOCK_FREQUENCY;
timer0_reload_write(t);
timer0_load_write(t);
timer0_en_write(1);
}
int elapsed(int *last_event, int period)
{
int t, dt;
timer0_update_value_write(1);
t = timer0_reload_read() - timer0_value_read();
if(period < 0) {
*last_event = t;
return 1;
}
dt = t - *last_event;
if(dt < 0)
dt += timer0_reload_read();
if((dt > period) || (dt < 0)) {
*last_event = t;
return 1;
} else
return 0;
}
void msleep(int ms)
{
timer0_en_write(0);
timer0_reload_write(0);
timer0_load_write(SYSTEM_CLOCK_FREQUENCY/1000*ms);
timer0_en_write(1);
timer0_update_value_write(1);
while(timer0_value_read()) timer0_update_value_write(1);
}