Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Riscv ecp5 #12

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
260 changes: 243 additions & 17 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,28 +1,254 @@
TINYUSB_PATH ?= lib/tinyusb
# This is the root makefile. It calls in the following files;
#
# 1) hw/bsp/ <BOARD> /board.mk
# Configuration of the board details.
# (Sets details of the family, member and variant, and compiler to use)
#
# 2) hw/chip/ <FAMILY> / <MEMBER> / <VARIANT>.mk
# Configuration of the specific chip details.
# Sets external directories if these were not set on the command line
# Includes specific files and link options for that variant
#
# 3) hw/chip/ <FAMILY> /family.mk
# Configuration of the chip family details.
#
# In general, things go in this file if they are generic to the whole of tinyufs,
# into the family makefile if they are generic across a family, and the variant
# file for chip specifics.
#
# All of the configuration for a specific board is stored in the board file.

# Force using the local board directory
TOP := $(shell realpath `pwd`)
include $(TINYUSB_PATH)/examples/make.mk
TOP := ./
TINYUSB_PATH ?= $(TOP)/lib/tinyusb

INC += \
hw \
hw/bsp \
hw/bsp/$(BOARD) \
src \
lib/tinyusb/tools \
_build/build-$(BOARD)
# Set to 1 to get noisy makefile output
V ?= 0

SRC_C = \
$(addprefix $(CURRENT_PATH)/, $(wildcard src/*.c))
#-------------- Select the board to build for. ------------

CFLAGS += -Wno-unused-parameter
BOARD_LIST = $(sort $(subst /.,,$(subst $(TOP)/hw/bsp/,,$(wildcard $(TOP)/hw/bsp/*/.))))

ifeq ($(filter $(BOARD),$(BOARD_LIST)),)
$(info You must provide a BOARD parameter with 'BOARD=', supported boards are:)
$(foreach b,$(BOARD_LIST),$(info - $(b)))
$(error Invalid BOARD specified)
endif

# Handy check parameter function
check_defined = \
$(strip $(foreach 1,$1, \
$(call __check_defined,$1,$(strip $(value 2)))))
__check_defined = \
$(if $(value $1),, \
$(error Undefined make flag: $1$(if $2, ($2))))

# Build directory
BUILD = _build/$(BOARD)

# Get Board identifier and specific defines
include $(TOP)/hw/bsp/$(BOARD)/board.mk

#-------------- Source files generic across all targets --------------

SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/hw/bsp/$(BOARD)/*.c))
SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/src/*.c))
SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/*.c))

# TinyUSB Stack source
SRC_C += \
$(TINYUSB_PATH)/src/tusb.c \
$(TINYUSB_PATH)/src/common/tusb_fifo.c \
$(TINYUSB_PATH)/src/device/usbd.c \
$(TINYUSB_PATH)/src/device/usbd_control.c \
$(TINYUSB_PATH)/src/class/cdc/cdc_device.c \
$(TINYUSB_PATH)/src/class/dfu/dfu_rt_device.c \
$(TINYUSB_PATH)/src/class/hid/hid_device.c \
$(TINYUSB_PATH)/src/class/midi/midi_device.c \
$(TINYUSB_PATH)/src/class/msc/msc_device.c \
$(TINYUSB_PATH)/src/class/net/net_device.c \
$(TINYUSB_PATH)/src/class/usbtmc/usbtmc_device.c \
$(TINYUSB_PATH)/src/class/vendor/vendor_device.c \
$(TINYUSB_PATH)/src/portable/$(VENDOR)/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c

# Compiler Flags which are generic across all targets
CFLAGS += \
-fdata-sections \
-ffunction-sections \
-fsingle-precision-constant \
-fno-strict-aliasing \
-Wdouble-promotion \
-Wstrict-prototypes \
-Wall \
-Wextra \
-Werror \
-Werror-implicit-function-declaration \
-Wfloat-equal \
-Wundef \
-Wshadow \
-Wwrite-strings \
-Wsign-compare \
-Wmissing-format-attribute \
-Wno-unused-parameter \
-Wunreachable-code \
-ffreestanding

# Compiler flags for defining UF2 configuration
CFLAGS += \
-DAPP_START_ADDRESS=$(APP_START_ADDRESS) \
-DBOARD_FLASH_BASE=$(BOARD_FLASH_BASE) \
-DUF2_FAMILY=$(UF2_FAMILY) \
-DCFG_TUSB_MCU=$(TUSB_MCU)

LDFLAGS += $(CFLAGS) -fshort-enums -Wl,$(LD_FILE) -Wl,[email protected] -Wl,-cref -Wl,-gc-sections

# Debugging/Optimization
ifeq ($(DEBUG), 1)
LDFLAGS += specs=rdimon.specs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes arm-none-eabi-gcc: error: specs=rdimon.specs: No such file or directory for me. Sorry but what does this do? never seen this before :). I'm on gcc 9.3.0.

else
LDFLAGS += -specs=nosys.specs -specs=nano.specs
endif

ASFLAGS += $(CFLAGS)

# Include directories which are generic across all targets
INC += -I$(TOP)/hw \
-I$(TOP)/hw/bsp \
-I$(TOP)/hw/bsp/$(BOARD) \
-I$(TOP)/src \
-I$(BUILD) \
-I$(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER) \
-I$(TINYUSB_PATH)/tools \
-I$(TINYUSB_PATH)/src

# Bring in the chip and family files

include $(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/$(TUF2_CHIP_VARIANT).mk
include $(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/family.mk

# Can be set by board, default to ARM GCC (done after chip and family in case it's set there)
CROSS_COMPILE ?= arm-none-eabi-

LIBS +=

###############################################################################################
# Shouldn't be too much to mess with below here...
###############################################################################################

# Tool selection
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
OBJCOPY = $(CROSS_COMPILE)objcopy
SIZE = $(CROSS_COMPILE)size
MKDIR = mkdir
SED = sed
CP = cp
RM = rm

# Debugging/Optimization
ifeq ($(DEBUG), 1)
CFLAGS += -g3 -Og -ggdb
else
CFLAGS += -Os
endif

# TUSB Logging option
ifneq ($(LOG),)
CFLAGS += -DCFG_TUSB_DEBUG=$(LOG)
endif

UF2_VERSION_BASE = $(shell git describe --always --tags)
$(BUILD)/uf2_version.h: Makefile
@echo "#define UF2_VERSION_BASE \"$(UF2_VERSION_BASE)\""> $@

# Assembly files can be name with upper case .S, convert it to .s
SRC_S := $(SRC_S:.S=.s)

# Due to GCC LTO bug https://bugs.launchpad.net/gcc-arm-embedded/+bug/1747966
# assembly file should be placed first in linking order
OBJ += $(addprefix $(BUILD)/obj/, $(SRC_S:.s=.o))
OBJ += $(BUILD)/uf2_version.h
OBJ += $(addprefix $(BUILD)/obj/, $(SRC_C:.c=.o))

include $(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/$(TUF2_CHIP_VARIANT).mk
include $(TINYUSB_PATH)/tools/top.mk
include $(TINYUSB_PATH)/examples/rules.mk
# Verbose mode
ifeq ("$(V)","1")
QUIET=
else
QUIET=@
endif

# Set all as default goal
.DEFAULT_GOAL := all
all: $(BUILD)/$(BOARD)-firmware.bin $(BUILD)/$(BOARD)-firmware.hex size

uf2: $(BUILD)/$(BOARD)-firmware.uf2

OBJ_DIRS = $(sort $(dir $(OBJ)))
$(OBJ): | $(OBJ_DIRS)
$(OBJ_DIRS):
$(QUIET)$(MKDIR) -p $@

$(BUILD)/$(BOARD)-firmware.elf: $(OBJ)
$(QUIET)echo LINK $@
$(QUIET)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(LIBS) -Wl,--end-group -Wl,-Map=$(BUILD)/$(BOARD)-firmware.map

$(BUILD)/$(BOARD)-firmware.bin: $(BUILD)/$(BOARD)-firmware.elf
$(QUIET)echo CREATE $@
$(QUIET)$(OBJCOPY) -O binary $^ $@

$(BUILD)/$(BOARD)-firmware.hex: $(BUILD)/$(BOARD)-firmware.elf
$(QUIET)echo CREATE $@
$(QUIET)$(OBJCOPY) -O ihex $^ $@

$(BUILD)/$(BOARD)-firmware.uf2: $(BUILD)/$(BOARD)-firmware.hex
$(QUIET)echo CREATE $@
$(PYTHON) $(MFTOP)/tools/uf2/utils/uf2conv.py -f $(UF2_FAMILY) -c -o $@ $^

# We set vpath to point to the top of the tree so that the source files
# can be located. By following this scheme, it allows a single build rule
# to be used to compile all .c files.
vpath %.c . $(MFTOP)
$(BUILD)/obj/%.o: %.c
$(QUIET)echo CC $(notdir $@)
$(QUIET)$(CC) $(CFLAGS) $(INC) -c -MD -o $@ $<
$(QUIET)# The following fixes the dependency file.
$(QUIET)# See http://make.paulandlesley.org/autodep.html for details.
$(QUIET)# Regex adjusted from the above to play better with Windows paths, etc.
$(QUIET)$(CP) $(@:.o=.d) $(@:.o=.P); \
$(SED) -e 's/#.*//' -e 's/^.*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $(@:.o=.d) >> $(@:.o=.P); \
$(RM) $(@:.o=.d)

# ASM sources lower case .s
vpath %.s . $(MFTOP)
$(BUILD)/obj/%.o: %.s
$(QUIET)echo AS $(notdir $@)
$(QUIET)$(CC) -x assembler-with-cpp $(ASFLAGS) -c -o $@ $<

# ASM sources upper case .S
vpath %.S . $(MFTOP)
$(BUILD)/obj/%.o: %.S
$(QUIET)echo AS $(notdir $@)
$(QUIET)$(CC) -x assembler-with-cpp $(ASFLAGS) -c -o $@ $<

size: $(BUILD)/$(BOARD)-firmware.elf
-$(QUIET)echo ''
$(QUIET)$(SIZE) $<
-$(QUIET)echo ''

clean:
$(QUIET)rm -rf $(BUILD)

$(BUILD)/$(BOARD)-firmware-padded.bin: $(BUILD)/$(BOARD)-firmware.bin
$(QUIET)dd if=/dev/zero of=$(BUILD)/$(BOARD)-firmware-padded.bin bs=1 count=1024
$(QUIET)cat $(BUILD)/$(BOARD)-firmware.bin >> $(BUILD)/$(BOARD)-firmware-padded.bin

$(BUILD)/$(BOARD)-firmware-padded.uf2: $(BUILD)/$(BOARD)-firmware-padded.bin
@echo CREATE $@
$(QUIET)$(PYTHON) $(TOP)/tools/uf2/utils/uf2conv.py -b $(BOARD_FLASH_BASE) -f $(UF2_FAMILY) -c -o $@ $^

padded-bin: $(BUILD)/$(BOARD)-firmware-padded.bin

padded-uf2: $(BUILD)/$(BOARD)-firmware-padded.uf2

print-%:
@echo $* is $($*)
21 changes: 18 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ Specify the board you want to build for:

$ make BOARD=mimxrt1010_evk

Currently NXP MIMXRT101x, MIMXRT102x and vexriscv (running on ecp5) chips are supported, running on
mimxrt1011_evk, mixmrt1020_evk, versiboard2, pergola and colorlight_5a_75 boards.

## Use

To enter tinyuf2;

* on MIMXRT push the reset button once, then again within the timeframe of 200-500mS.

* on ECP5 it's integration dependent, but generally just hold down the reset button while the board boots.

It might take a few attempts to get entry right, but in all cases when you're in tinyuf2 you will see a LED flashing at 500mS on,
500mS off and a drive TinyUF2 will appear. Drag and drop an appropriately formatted UF2 file onto this drive and, once it's
flashed into the memory, the board will automatically reboot.

## Filesystem Structure

The filesystem is structured as follows;
Expand Down Expand Up @@ -52,8 +67,8 @@ In general non-standard options are frowned upon because it changes the user exp

* `VOLUME_LABEL`: Volume Label for the tinyUF2 drive. Default is `UF2BOOT`.

* `BOARD_TAP_WAIT`: How long to wait for double-tap entry into bootloader before performing regular boot. Default is 500mS.
* `BOARD_TAP_WAIT`: How long to wait for double-tap entry into bootloader before performing regular boot. Default is 500mS. Note that this is not used on ecp5/vexriscv, which comes directly into the tinyuf2 loader, rather than with a delay.

* `BOARD_BLINK_INTERVAL`: Blinking interval while in tinyUF2. Default is 500uS on/off.
* `BOARD_BLINK_INTERVAL`: Blinking interval while in tinyUF2. Default is 500mS on/off.

* `BOARD_LED_ON_UF2_START`: Should the LED be on or off at UF2 boot? Default is off.
* `BOARD_LED_ON_UF2_START`: Should the LED be on or off at UF2 boot? Default is off. Not relevant to ecp5/vexriscv.
24 changes: 20 additions & 4 deletions hw/bsp/bsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,24 +57,40 @@
#define BOARD_TAP_WAIT 500
#endif

#define BOARD_OFF_INTERVAL 0

#ifndef BOARD_BLINK_INTERVAL
// Define this for a different blinking interval in mS
#define BOARD_BLINK_INTERVAL 500
// Define this for a different blinking interval in mS while on standby
#define BOARD_BLINK_INTERVAL 500
#endif

// Define this for a different blinking interval in mS while loading
#ifndef BOARD_LOADING_INTERVAL
#define BOARD_LOADING_INTERVAL 200
#endif

// Define this for a blinking interval while booting (set to 10 Hz to by outside primary photosensitive epilepsy region)
#ifndef BOARD_BOOTING_INTERVAL
#define BOARD_BOOTING_INTERVAL 50
#endif

// Length of time board needs boot button held down for to enter uf2 mode
#define BOARD_BOOTING_WAIT 1000

// If you want multiple taps (i.e. more than two)
// define this to the correct value
// #define BOARD_MULTITAP_COUNT 4

// If you want the LED on while in UF2 boot wait mode
// #define BOARD_LED_ON_UF2_START
#define BOARD_LED_ON_UF2_START

void board_flash_flush(void);
uint32_t board_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks);
uint32_t board_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks);
uint32_t board_millis(void);
void board_reset_to_bootloader(bool toBootloader);
void board_reset(void);
void board_led_write(bool state);
void board_led_blinking_task(void);
void board_init(void);
void board_delay_ms(uint32_t ms);
void board_check_app_start(void);
Expand Down
10 changes: 10 additions & 0 deletions hw/bsp/colorlight_5a_75b/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
To deploy on colorlight this can be integrated as a replacement bios.

Simply call up the compiled application as the bios file, as follows;

./colorlight_5a_75b.py --revision=7.0m --integrated-rom-size=32000 --integrated-sram-size=8192 --uart-baudrate=115200 --with-debug=usb --csr-csv soc_basesoc_colorlight_5a_75b/csr.csv --integrated-sram-size=16384 --ecppack-bootaddr=0x80000 --integrated-rom-file=tinyuf2/_build/colorlight_5a_75b/colorlight_5a_75b-firmware.bin

...this will then boot by default and spin up a USB drive to copy firmware to.



7 changes: 7 additions & 0 deletions hw/bsp/colorlight_5a_75b/board.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
TUF2_CHIP_FAMILY = ecp5
TUF2_CHIP_MEMBER = vexriscv
TUF2_CHIP_VARIANT = default
APP_START_ADDRESS ?= 0x20080000
BOARD_FLASH_BASE ?= 0x20080000
UF2_FAMILY ?= 0x35504345
TUSB_MCU = OPT_MCU_VALENTYUSB_EPTRI
18 changes: 18 additions & 0 deletions hw/bsp/colorlight_5a_75b/board_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef _BOARD_CONFIG_H_
#define _BOARD_CONFIG_H_
#include "mem.h"

// Basic Data
#define VENDOR_NAME "Orbcode"
#define PRODUCT_NAME "Colorlight_5a_75b"
#define BOARD_ID "Colorlight_5a_75b"

// Board flash
#define BOARD_FLASH_SIZE SPIFLASH_SIZE
#define BOARD_FLASH_PAGE_SIZE 256
#include "mem.h"

// LED
#define LED_STATE_ON 0

#endif
Loading