From 07d1d30b47f725ef53f90245e92271e6c689e7f5 Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Thu, 30 Apr 2020 23:49:57 +0100 Subject: [PATCH 01/10] Initial ecp5 uf2 support --- Makefile | 111 +++++++- README.md | 20 +- hw/bsp/colorlight_5a_75b/README.md | 3 + hw/bsp/colorlight_5a_75b/board.mk | 4 + hw/bsp/colorlight_5a_75b/board_config.h | 16 ++ hw/chip/ecp5/family.c | 251 ++++++++++++++++++ hw/chip/ecp5/family.mk | 143 ++++++++++ hw/chip/ecp5/spi.c | 215 +++++++++++++++ hw/chip/ecp5/spi.h | 30 +++ hw/chip/ecp5/vexriscv/default.mk | 6 + hw/chip/ecp5/vexriscv/linker.ld | 61 +++++ hw/chip/ecp5/vexriscv/pinning_options.h | 29 ++ hw/chip/mimxrt10xx/family.mk | 12 +- .../mimxrt10xx/mimxrt101x/MIMXRT1011DAE5A.mk | 2 - .../mimxrt10xx/mimxrt102x/MIMXRT1021DAG5A.mk | 2 - lib/tinyusb | 2 +- src/main.c | 4 +- src/msc.c | 11 +- src/usb_descriptors.c | 4 +- 19 files changed, 897 insertions(+), 29 deletions(-) create mode 100644 hw/bsp/colorlight_5a_75b/README.md create mode 100644 hw/bsp/colorlight_5a_75b/board.mk create mode 100644 hw/bsp/colorlight_5a_75b/board_config.h create mode 100644 hw/chip/ecp5/family.c create mode 100644 hw/chip/ecp5/family.mk create mode 100644 hw/chip/ecp5/spi.c create mode 100644 hw/chip/ecp5/spi.h create mode 100644 hw/chip/ecp5/vexriscv/default.mk create mode 100644 hw/chip/ecp5/vexriscv/linker.ld create mode 100644 hw/chip/ecp5/vexriscv/pinning_options.h diff --git a/Makefile b/Makefile index 6813ec2..652df90 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,100 @@ -TINYUSB_PATH ?= lib/tinyusb +# This is the root makefile. It calls in the following files; +# 1) hw/bsp/ /board.mk +# (Sets details of the family, member and variant, and compiler to use) +# +# 2) hw/chip/ / / .mk +# Sets external directories if these were not set on the command line +# Includes specific files for that variant +# +# 3) hw/chip/ /family.mk +# Main build script for specific family(*) +# +# Note that for step (3) some builds defer the main build process to tinyuf2, in +# which case $(TINYUSB_PATH)/tools/top.mk and $(TINYUSB_PATH)/examples/rules.mk +# perform the build step rather than the family script. # Force using the local board directory TOP := $(shell realpath `pwd`) -include $(TINYUSB_PATH)/examples/make.mk -INC += \ - hw \ - hw/bsp \ - hw/bsp/$(BOARD) \ - src \ - lib/tinyusb/tools \ - _build/build-$(BOARD) +TINYUSB_PATH ?= $(TOP)/lib/tinyusb -SRC_C = \ - $(addprefix $(CURRENT_PATH)/, $(wildcard src/*.c)) +#-------------- Select the board to build for. ------------ +BOARD_LIST = $(sort $(subst /.,,$(subst $(TOP)/hw/bsp/,,$(wildcard $(TOP)/hw/bsp/*/.)))) -CFLAGS += -Wno-unused-parameter +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/build-$(BOARD) + +# Board specific define +include $(TOP)/hw/bsp/$(BOARD)/board.mk + +#-------------- Cross Compiler ------------ +# Can be set by board, default to ARM GCC +CROSS_COMPILE ?= arm-none-eabi- + +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +OBJCOPY = $(CROSS_COMPILE)objcopy +SIZE = $(CROSS_COMPILE)size +MKDIR = mkdir +SED = sed +CP = cp +RM = rm + +#-------------- Source files and compiler flags -------------- + +# Include all source C in board folder +#SRC_C += hw/bsp/board.c +SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/hw/bsp/$(BOARD)/*.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 + +# This causes lots of warning with nrf5x build due to nrfx code +# CFLAGS += -Wcast-align + +# Debugging/Optimization +ifeq ($(DEBUG), 1) + CFLAGS += -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 @@ -24,5 +103,13 @@ $(BUILD)/uf2_version.h: Makefile OBJ += $(BUILD)/uf2_version.h include $(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/$(TUF2_CHIP_VARIANT).mk +include $(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/family.mk + +ifndef OVERRIDE_TINYUSB_RULES include $(TINYUSB_PATH)/tools/top.mk include $(TINYUSB_PATH)/examples/rules.mk +endif + +print-%: + @echo $* is $($*) + diff --git a/README.md b/README.md index 9849527..7a13ec4 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,20 @@ Specify the board you want to build for: $ make BOARD=mimxrt1010_evk +Currently NXP MIMXRT101x, MIMXRT102x and vexriscv running on ecp5 colorlight_5a_75 boards are supported. + +## 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; @@ -52,8 +66,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. \ No newline at end of file +* `BOARD_LED_ON_UF2_START`: Should the LED be on or off at UF2 boot? Default is off. Not relevant to ecp5/vexriscv. \ No newline at end of file diff --git a/hw/bsp/colorlight_5a_75b/README.md b/hw/bsp/colorlight_5a_75b/README.md new file mode 100644 index 0000000..8334f13 --- /dev/null +++ b/hw/bsp/colorlight_5a_75b/README.md @@ -0,0 +1,3 @@ +To deploy on colorlight... + +...to be completed. \ No newline at end of file diff --git a/hw/bsp/colorlight_5a_75b/board.mk b/hw/bsp/colorlight_5a_75b/board.mk new file mode 100644 index 0000000..36100ca --- /dev/null +++ b/hw/bsp/colorlight_5a_75b/board.mk @@ -0,0 +1,4 @@ +TUF2_CHIP_FAMILY = ecp5 +TUF2_CHIP_MEMBER = vexriscv +TUF2_CHIP_VARIANT = default +CROSS_COMPILE ?= riscv64-unknown-elf- diff --git a/hw/bsp/colorlight_5a_75b/board_config.h b/hw/bsp/colorlight_5a_75b/board_config.h new file mode 100644 index 0000000..3dfd73e --- /dev/null +++ b/hw/bsp/colorlight_5a_75b/board_config.h @@ -0,0 +1,16 @@ +#ifndef _BOARD_CONFIG_H_ +#define _BOARD_CONFIG_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 0x800000 + +// LED +#define PIN_LED 0 +#define LED_STATE_ON 0 + +#endif diff --git a/hw/chip/ecp5/family.c b/hw/chip/ecp5/family.c new file mode 100644 index 0000000..bfec45b --- /dev/null +++ b/hw/chip/ecp5/family.c @@ -0,0 +1,251 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Dave Marples + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include + +#include "tusb.h" +#include "bsp.h" +#include "csr.h" +#include "irq.h" +#include "spi.h" +#include "uart.h" + +volatile uint32_t system_ticks = 0; + +// Indicator that no Sector is currently cached +#define NO_CACHE 0xffffffff + +#define MIN(a,b) ((a>>Flush: %08x\n", _flash_sector_addr); + + _burn_sector(); + _flash_sector_dirty = false; +} +// --------------------------------------------------------------------------------------------- +uint32_t board_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) +{ + uint32_t src = lba2addr(block); + memcpy(dest, (uint8_t*) src, FILESYSTEM_BLOCK_SIZE * num_blocks); + return 0; +} +// --------------------------------------------------------------------------------------------- +uint32_t board_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) + +{ + uint32_t const addr = lba2addr(lba); + uint32_t const len = num_blocks*FILESYSTEM_BLOCK_SIZE; + + /* Flush any old cache and get the original content of the sector */ + if (!SAME_SECTOR(addr,_flash_sector_addr)) + { + board_flash_flush(); + printf("Read: %08x\n",ADDR_SECTOR(addr)); + _flash_sector_addr = ADDR_SECTOR(addr); + _flash_sector_dirty = false; + memcpy(_flash_cache, (uint8_t*) ADDR_SECTOR(addr), SECTOR_SIZE); + } + + if (memcmp(&_flash_cache[ADDR_OFFSET(addr)],src,len)!=0) + { + printf("Write to cache: %08x (%x) (%d) [lba was %d]\n",addr,ADDR_OFFSET(addr),num_blocks,lba); + for (uint32_t t=0; t<256; t++) + { + printf("%02X %02X %c ",_flash_cache[ADDR_OFFSET(addr+t)],src[t],_flash_cache[ADDR_OFFSET(addr+t)]!=src[t]?'*':' '); + } + /* Now update the right part of this sector with the new data */ + memcpy(&_flash_cache[ADDR_OFFSET(addr)],src,len); + _flash_sector_dirty = true; + } + else + { + printf("Cachewrite skipped: %08x (%x) (%d) [lba was %d]\n",addr,ADDR_OFFSET(addr),num_blocks,lba); + } + + return 0; +} +// --------------------------------------------------------------------------------------------- +void isr(void) +{ + unsigned int irqs; + irqs = irq_pending() & irq_getmask(); + + if (irqs & (1 << USB_INTERRUPT)) + { + tud_int_handler(0); + } + + if (irqs & (1 << TIMER0_INTERRUPT)) + { + system_ticks++; + timer0_ev_pending_write(1); + } + + if(irqs & (1 << UART_INTERRUPT)) + uart_isr(); +} +// --------------------------------------------------------------------------------------------- +uint32_t board_millis(void) +{ + return system_ticks; +} +// --------------------------------------------------------------------------------------------- +void board_reset(void) + +{ + board_flash_flush(); + ctrl_reset_write(1); +} +// --------------------------------------------------------------------------------------------- +void board_led_write(bool state) +{ + gpio_out_write((gpio_out_read()&(~(1<> $(@:.o=.P); \ + $(RM) $(@:.o=.d) + +# ASM sources lower case .s +vpath %.s . $(TOP) +$(BUILD)/obj/%.o: %.s + $(QUIET)echo AS $(notdir $@) + $(QUIET)$(CC) -x assembler-with-cpp $(ASFLAGS) -c -o $@ $< + +# ASM sources upper case .S +vpath %.S . $(TOP) +$(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: + rm -rf $(BUILD) diff --git a/hw/chip/ecp5/spi.c b/hw/chip/ecp5/spi.c new file mode 100644 index 0000000..70c0626 --- /dev/null +++ b/hw/chip/ecp5/spi.c @@ -0,0 +1,215 @@ +#include +#include +#include + +// This file originates from Greg Davills' modifications to the foboot code. + +#include "spi.h" + +enum pin { + PIN_MOSI = 0, + PIN_CLK = 1, + PIN_CS = 2, + PIN_MISO_EN = 3, + PIN_MISO = 4, // Value is ignored +}; + +void spiBegin(void) { + lxspi_bitbang_write((0 << PIN_CLK) | (0 << PIN_CS)); +} + +void spiEnd(void) { + lxspi_bitbang_write((0 << PIN_CLK) | (1 << PIN_CS)); +} + +static void spi_single_tx(uint8_t out) { + int bit; + + for (bit = 7; bit >= 0; bit--) { + if (out & (1 << bit)) { + lxspi_bitbang_write((0 << PIN_CLK) | (1 << PIN_MOSI)); + lxspi_bitbang_write((1 << PIN_CLK) | (1 << PIN_MOSI)); + lxspi_bitbang_write((0 << PIN_CLK) | (1 << PIN_MOSI)); + } else { + lxspi_bitbang_write((0 << PIN_CLK) | (0 << PIN_MOSI)); + lxspi_bitbang_write((1 << PIN_CLK) | (0 << PIN_MOSI)); + lxspi_bitbang_write((0 << PIN_CLK) | (0 << PIN_MOSI)); + } + } +} + +static uint8_t spi_single_rx(void) { + int bit = 0; + uint8_t in = 0; + + lxspi_bitbang_write((1 << PIN_MISO_EN) | (0 << PIN_CLK)); + + while (bit++ < 8) { + lxspi_bitbang_write((1 << PIN_MISO_EN) | (1 << PIN_CLK)); + in = (in << 1) | lxspi_miso_read(); + lxspi_bitbang_write((1 << PIN_MISO_EN) | (0 << PIN_CLK)); + } + + return in; +} + +static uint8_t spi_read_status(void) { + uint8_t val; + + spiBegin(); + spi_single_tx(0x05); + val = spi_single_rx(); + spiEnd(); + return val; +} + +int spiIsBusy(void) { + return spi_read_status() & (1 << 0); +} + +__attribute__((used)) +uint32_t spi_id; + +__attribute__((used)) +uint32_t spiId(void) { + spi_id = 0; + + spiBegin(); + spi_single_tx(0x90); // Read manufacturer ID + spi_single_tx(0x00); // Dummy byte 1 + spi_single_tx(0x00); // Dummy byte 2 + spi_single_tx(0x00); // Dummy byte 3 + spi_id = (spi_id << 8) | spi_single_rx(); // Manufacturer ID + spi_id = (spi_id << 8) | spi_single_rx(); // Device ID + spiEnd(); + + spiBegin(); + spi_single_tx(0x9f); // Read device id + (void)spi_single_rx(); // Manufacturer ID (again) + spi_id = (spi_id << 8) | spi_single_rx(); // Memory Type + spi_id = (spi_id << 8) | spi_single_rx(); // Memory Size + spiEnd(); + + return spi_id; +} + +int spiBeginErase4(uint32_t erase_addr) { + // Enable Write-Enable Latch (WEL) + spiBegin(); + spi_single_tx(0x06); + spiEnd(); + + spiBegin(); + spi_single_tx(0x20); + spi_single_tx(erase_addr >> 16); + spi_single_tx(erase_addr >> 8); + spi_single_tx(erase_addr >> 0); + spiEnd(); + return 0; +} + +int spiBeginErase32(uint32_t erase_addr) { + // Enable Write-Enable Latch (WEL) + spiBegin(); + spi_single_tx(0x06); + spiEnd(); + + spiBegin(); + spi_single_tx(0x52); + spi_single_tx(erase_addr >> 16); + spi_single_tx(erase_addr >> 8); + spi_single_tx(erase_addr >> 0); + spiEnd(); + return 0; +} + +int spiBeginErase64(uint32_t erase_addr) { + // Enable Write-Enable Latch (WEL) + spiBegin(); + spi_single_tx(0x06); + spiEnd(); + + spiBegin(); + spi_single_tx(0xD8); + spi_single_tx(erase_addr >> 16); + spi_single_tx(erase_addr >> 8); + spi_single_tx(erase_addr >> 0); + spiEnd(); + return 0; +} + +int spiBeginWrite(uint32_t addr, const void *v_data, unsigned int count) { + const uint8_t write_cmd = 0x02; + const uint8_t *data = v_data; + unsigned int i; + + // Enable Write-Enable Latch (WEL) + spiBegin(); + spi_single_tx(0x06); + spiEnd(); + + spiBegin(); + spi_single_tx(write_cmd); + spi_single_tx(addr >> 16); + spi_single_tx(addr >> 8); + spi_single_tx(addr >> 0); + for (i = 0; (i < count) && (i < 256); i++) + { + spi_single_tx(*data++); + } + spiEnd(); + + return i; +} + +uint8_t spiReset(void) { + // Writing 0xff eight times is equivalent to exiting QPI mode, + // or if CFM mode is enabled it will terminate CFM and return + // to idle. + unsigned int i; + spiBegin(); + for (i = 0; i < 8; i++) + spi_single_tx(0xff); + spiEnd(); + + // Some SPI parts require this to wake up + spiBegin(); + spi_single_tx(0xab); // Read electronic signature + spiEnd(); + + return 0; +} + +int spiInit(void) { + + // Ensure CS is deasserted and the clock is high + lxspi_bitbang_write((0 << PIN_CLK) | (1 << PIN_CS)); + + // Disable memory-mapped mode and enable bit-bang mode + lxspi_bitbang_en_write(1); + + // Reset the SPI flash, which will return it to SPI mode even + // if it's in QPI mode, and ensure the chip is accepting commands. + spiReset(); + + spiId(); + + return 0; +} + +void spiHold(void) { + spiBegin(); + spi_single_tx(0xb9); + spiEnd(); + +} +void spiUnhold(void) { + spiBegin(); + spi_single_tx(0xab); + spiEnd(); +} + +void spiFree(void) { + // Re-enable memory-mapped mode + lxspi_bitbang_en_write(0); +} diff --git a/hw/chip/ecp5/spi.h b/hw/chip/ecp5/spi.h new file mode 100644 index 0000000..b439b19 --- /dev/null +++ b/hw/chip/ecp5/spi.h @@ -0,0 +1,30 @@ +#ifndef BB_SPI_H_ +#define BB_SPI_H_ + +#include + +void spiPause(void); +void spiBegin(void); +void spiEnd(void); + +int spiRead(uint32_t addr, uint8_t *data, unsigned int count); +int spiIsBusy(void); +int spiBeginErase4(uint32_t erase_addr); +int spiBeginErase32(uint32_t erase_addr); +int spiBeginErase64(uint32_t erase_addr); +int spiBeginWrite(uint32_t addr, const void *data, unsigned int count); +void spiEnableQuad(void); + +uint32_t spiId(void); + +int spiWrite(uint32_t addr, const uint8_t *data, unsigned int count); +uint8_t spiReset(void); +int spiInit(void); + +void spiHold(void); +void spiUnhold(void); +void spiSwapTxRx(void); + +void spiFree(void); + +#endif /* BB_SPI_H_ */ diff --git a/hw/chip/ecp5/vexriscv/default.mk b/hw/chip/ecp5/vexriscv/default.mk new file mode 100644 index 0000000..ee3ecdc --- /dev/null +++ b/hw/chip/ecp5/vexriscv/default.mk @@ -0,0 +1,6 @@ +LITEX_DIR ?= $(shell realpath ~/Develop/ulx3s/litex/litex/litex/soc/software/) +SOC_DIR ?= $(shell realpath ~/Develop/ulx3s/litex/litex-boards/litex_boards/targets/soc_basesoc_colorlight_5a_75b/software) + +SRC_S += $(LITEX_DIR)/libbase/crt0-vexriscv.S + +LD_FILE = -T$(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/linker.ld -L$(SOC_DIR)/include -L$(LITEX_DIR) diff --git a/hw/chip/ecp5/vexriscv/linker.ld b/hw/chip/ecp5/vexriscv/linker.ld new file mode 100644 index 0000000..15697c1 --- /dev/null +++ b/hw/chip/ecp5/vexriscv/linker.ld @@ -0,0 +1,61 @@ +INCLUDE generated/output_format.ld +ENTRY(_start) + +__DYNAMIC = 0; + +INCLUDE generated/regions.ld + +SECTIONS +{ + .text : + { + _ftext = .; + *crt0*(.text) + *(.text .stub .text.* .gnu.linkonce.t.*) + _etext = .; + } > main_ram + + .rodata : + { + . = ALIGN(4); + _frodata = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + _erodata = .; + } > main_ram + + .data : + { + . = ALIGN(4); + _fdata = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + _gp = ALIGN(16); + *(.sdata .sdata.* .gnu.linkonce.s.*) + _edata = .; + } > main_ram + + .bss : + { + . = ALIGN(4); + _fbss = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = .; + _end = .; + } > main_ram + + .flash : + { + _fstart = .; + _fend = .; + } > spiflash +} + +PROVIDE(_fstack = ORIGIN(main_ram) + LENGTH(main_ram) - 4); +PROVIDE(_flash_start = _fstart); diff --git a/hw/chip/ecp5/vexriscv/pinning_options.h b/hw/chip/ecp5/vexriscv/pinning_options.h new file mode 100644 index 0000000..5d9eebb --- /dev/null +++ b/hw/chip/ecp5/vexriscv/pinning_options.h @@ -0,0 +1,29 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Dave Marples + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _PINNING_OPTIONS_H_ +#define _PINNING_OPTIONS_H_ + +#endif diff --git a/hw/chip/mimxrt10xx/family.mk b/hw/chip/mimxrt10xx/family.mk index ccf4d1b..e5d336e 100644 --- a/hw/chip/mimxrt10xx/family.mk +++ b/hw/chip/mimxrt10xx/family.mk @@ -30,11 +30,21 @@ SRC_C += \ $(MCU_DIR)/drivers/fsl_lpuart.c INC += \ + -Ihw \ + -Ihw/bsp \ + -Ihw/bsp/$(BOARD) \ + -Isrc \ + -Ilib/tinyusb/tools \ + -I_build/build-$(BOARD) \ hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER) \ $(TOP)/$(MCU_DIR) \ $(TOP)/$(MCU_DIR)/drivers \ $(TOP)/$(MCU_DIR)/project_template \ - $(TOP)/$(MCU_DIR)/../../CMSIS/Include \ + $(TOP)/$(MCU_DIR)/../../CMSIS/Include + +SRC_C = \ + $(addprefix $(CURRENT_PATH)/, $(wildcard src/*.c)) + # For TinyUSB port source VENDOR = nxp diff --git a/hw/chip/mimxrt10xx/mimxrt101x/MIMXRT1011DAE5A.mk b/hw/chip/mimxrt10xx/mimxrt101x/MIMXRT1011DAE5A.mk index 4bdfbaa..4e383e8 100644 --- a/hw/chip/mimxrt10xx/mimxrt101x/MIMXRT1011DAE5A.mk +++ b/hw/chip/mimxrt10xx/mimxrt101x/MIMXRT1011DAE5A.mk @@ -1,7 +1,5 @@ MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1011 -include hw/chip/$(TUF2_CHIP_FAMILY)/family.mk - CFLAGS += -DCPU_MIMXRT1011DAE5A ifeq ($(VARIANT), ram) diff --git a/hw/chip/mimxrt10xx/mimxrt102x/MIMXRT1021DAG5A.mk b/hw/chip/mimxrt10xx/mimxrt102x/MIMXRT1021DAG5A.mk index 22182bf..b1366b7 100644 --- a/hw/chip/mimxrt10xx/mimxrt102x/MIMXRT1021DAG5A.mk +++ b/hw/chip/mimxrt10xx/mimxrt102x/MIMXRT1021DAG5A.mk @@ -1,7 +1,5 @@ MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1021 -include hw/chip/$(TUF2_CHIP_FAMILY)/family.mk - CFLAGS += -DCPU_MIMXRT1021DAG5A SRC_C += $(MCU_DIR)/system_MIMXRT1021.c diff --git a/lib/tinyusb b/lib/tinyusb index 6781d58..520df6b 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 6781d58449c96f19d29ba0a2f73df7ccb8948786 +Subproject commit 520df6bb5350b5c998bbae754a13ed44b5286e69 diff --git a/src/main.c b/src/main.c index 060594d..6bb3184 100644 --- a/src/main.c +++ b/src/main.c @@ -65,9 +65,9 @@ int main(void) board_check_tinyuf2_start(); - tusb_init(); + printf("TinyUF2 running\r\n"); - printf("Hello TinyUF2!\r\n"); + tusb_init(); while (1) { tud_task(); diff --git a/src/msc.c b/src/msc.c index e3f1539..61f8832 100644 --- a/src/msc.c +++ b/src/msc.c @@ -30,6 +30,8 @@ #include "uf2.h" #include "tusb.h" +#define RESET_MILLIS (1000) + #if CFG_TUD_MSC #define SERIAL0 (*(uint32_t *)0x0080A00C) @@ -279,7 +281,8 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* // this happens when we're trying to re-flash CURRENT.UF2 file previously // copied from a device; we still want to count these blocks to reset properly } else { - printf("uf2 write, target: 0x%08lX, size: %ld, block %ld, num blocks %ld\r\n", bl->targetAddr, bl->payloadSize, bl->blockNo, bl->numBlocks); + //printf("uf2 write, target: 0x%08lX, size: %ld, block %ld, num blocks %ld\r\n", bl->targetAddr, bl->payloadSize, bl->blockNo, bl->numBlocks); + board_flash_write_blocks(bl->data, (bl->targetAddr - BOARD_FLASH_BASE) / UF2_PAYLOAD_SIZE, 1); if (bl->numBlocks) { @@ -298,12 +301,12 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* if (write_state.numWritten >= write_state.numBlocks) { board_flash_flush(); - reset_millis = board_millis() + 30; + reset_millis = board_millis() + RESET_MILLIS; } } } else { - // reset 300ms after last block received - reset_millis = board_millis() + 300; + // reset after last block received + reset_millis = board_millis() + RESET_MILLIS; } } diff --git a/src/usb_descriptors.c b/src/usb_descriptors.c index 9adde51..6be453e 100644 --- a/src/usb_descriptors.c +++ b/src/usb_descriptors.c @@ -135,7 +135,7 @@ enum uint8_t const desc_configuration[] = { // interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), #if CFG_TUD_CDC // Interface number, string index, EP notification address and size, EP data address (out, in) and size. @@ -182,7 +182,7 @@ static uint16_t _desc_str[32]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -uint16_t const *tud_descriptor_string_cb(uint8_t index) +uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { uint8_t chr_count; From 490898b88f012c7ec42223b7195006fe9fc63bb7 Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Fri, 1 May 2020 00:00:06 +0100 Subject: [PATCH 02/10] Print cleanup --- hw/chip/ecp5/family.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/hw/chip/ecp5/family.c b/hw/chip/ecp5/family.c index bfec45b..0de932c 100644 --- a/hw/chip/ecp5/family.c +++ b/hw/chip/ecp5/family.c @@ -98,7 +98,7 @@ static void _burn_sector(void) spiBeginErase4(flash_ofs); while(spiIsBusy()); - printf("Burn Offset %8x %d\n",flash_ofs, SECTOR_SIZE); + //printf("Burn Offset %8x %d\n",flash_ofs, SECTOR_SIZE); /* We can only write 256 octets at a time, so batch them up */ uint32_t r=SECTOR_SIZE; @@ -113,7 +113,7 @@ static void _burn_sector(void) } while (r); spiFree(); - printf("Burn complete\n"); + //printf("Burn complete\n"); } // --------------------------------------------------------------------------------------------- void board_flash_flush(void) @@ -121,7 +121,7 @@ void board_flash_flush(void) if ((_flash_sector_addr == NO_CACHE) || (_flash_sector_dirty == false)) return; - printf(">>>Flush: %08x\n", _flash_sector_addr); + //printf(">>>Flush: %08x\n", _flash_sector_addr); _burn_sector(); _flash_sector_dirty = false; @@ -144,7 +144,7 @@ uint32_t board_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num if (!SAME_SECTOR(addr,_flash_sector_addr)) { board_flash_flush(); - printf("Read: %08x\n",ADDR_SECTOR(addr)); + //printf("Read: %08x\n",ADDR_SECTOR(addr)); _flash_sector_addr = ADDR_SECTOR(addr); _flash_sector_dirty = false; memcpy(_flash_cache, (uint8_t*) ADDR_SECTOR(addr), SECTOR_SIZE); @@ -152,10 +152,10 @@ uint32_t board_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num if (memcmp(&_flash_cache[ADDR_OFFSET(addr)],src,len)!=0) { - printf("Write to cache: %08x (%x) (%d) [lba was %d]\n",addr,ADDR_OFFSET(addr),num_blocks,lba); + //printf("Write to cache: %08x (%x) (%d) [lba was %d]\n",addr,ADDR_OFFSET(addr),num_blocks,lba); for (uint32_t t=0; t<256; t++) { - printf("%02X %02X %c ",_flash_cache[ADDR_OFFSET(addr+t)],src[t],_flash_cache[ADDR_OFFSET(addr+t)]!=src[t]?'*':' '); + //printf("%02X %02X %c ",_flash_cache[ADDR_OFFSET(addr+t)],src[t],_flash_cache[ADDR_OFFSET(addr+t)]!=src[t]?'*':' '); } /* Now update the right part of this sector with the new data */ memcpy(&_flash_cache[ADDR_OFFSET(addr)],src,len); @@ -163,7 +163,7 @@ uint32_t board_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num } else { - printf("Cachewrite skipped: %08x (%x) (%d) [lba was %d]\n",addr,ADDR_OFFSET(addr),num_blocks,lba); + //printf("Cachewrite skipped: %08x (%x) (%d) [lba was %d]\n",addr,ADDR_OFFSET(addr),num_blocks,lba); } return 0; From 97c206314a8838a5c628a2e85ff468f1eb2985d6 Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Sat, 2 May 2020 00:33:44 +0100 Subject: [PATCH 03/10] Working system using PROGRAMN to enter application --- hw/bsp/bsp.h | 9 +- hw/bsp/colorlight_5a_75b/README.md | 11 ++- hw/chip/ecp5/family.c | 31 ++++--- hw/chip/ecp5/vexriscv/crt0-vexriscv-rom.S | 89 +++++++++++++++++++ hw/chip/ecp5/vexriscv/default.mk | 4 +- .../vexriscv/{linker.ld => linker-ram.ld} | 0 hw/chip/ecp5/vexriscv/linker-rom.ld | 74 +++++++++++++++ src/main.c | 11 ++- 8 files changed, 211 insertions(+), 18 deletions(-) create mode 100644 hw/chip/ecp5/vexriscv/crt0-vexriscv-rom.S rename hw/chip/ecp5/vexriscv/{linker.ld => linker-ram.ld} (100%) create mode 100644 hw/chip/ecp5/vexriscv/linker-rom.ld diff --git a/hw/bsp/bsp.h b/hw/bsp/bsp.h index f1150ad..ed29c23 100644 --- a/hw/bsp/bsp.h +++ b/hw/bsp/bsp.h @@ -58,8 +58,13 @@ #endif #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 // If you want multiple taps (i.e. more than two) diff --git a/hw/bsp/colorlight_5a_75b/README.md b/hw/bsp/colorlight_5a_75b/README.md index 8334f13..a4494bf 100644 --- a/hw/bsp/colorlight_5a_75b/README.md +++ b/hw/bsp/colorlight_5a_75b/README.md @@ -1,3 +1,10 @@ -To deploy on colorlight... +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/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. + + -...to be completed. \ No newline at end of file diff --git a/hw/chip/ecp5/family.c b/hw/chip/ecp5/family.c index 0de932c..f9eddbb 100644 --- a/hw/chip/ecp5/family.c +++ b/hw/chip/ecp5/family.c @@ -32,8 +32,18 @@ #include "spi.h" #include "uart.h" +#define DEBUG 1 + +#ifdef DEBUG +#define DBG(...) printf(__VA_ARGS__) +#else +#define DBG(...) {} +#endif + volatile uint32_t system_ticks = 0; +extern void file_loading(void); + // Indicator that no Sector is currently cached #define NO_CACHE 0xffffffff @@ -98,7 +108,7 @@ static void _burn_sector(void) spiBeginErase4(flash_ofs); while(spiIsBusy()); - //printf("Burn Offset %8x %d\n",flash_ofs, SECTOR_SIZE); + DBG("Burn Offset %8x %d\n",flash_ofs, SECTOR_SIZE); /* We can only write 256 octets at a time, so batch them up */ uint32_t r=SECTOR_SIZE; @@ -113,7 +123,7 @@ static void _burn_sector(void) } while (r); spiFree(); - //printf("Burn complete\n"); + DBG("Burn complete\n"); } // --------------------------------------------------------------------------------------------- void board_flash_flush(void) @@ -121,7 +131,7 @@ void board_flash_flush(void) if ((_flash_sector_addr == NO_CACHE) || (_flash_sector_dirty == false)) return; - //printf(">>>Flush: %08x\n", _flash_sector_addr); + DBG(">>>Flush: %08x\n", _flash_sector_addr); _burn_sector(); _flash_sector_dirty = false; @@ -139,12 +149,15 @@ uint32_t board_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num { uint32_t const addr = lba2addr(lba); uint32_t const len = num_blocks*FILESYSTEM_BLOCK_SIZE; + + /* Someone is trying to load something, let the user know */ + file_loading(); /* Flush any old cache and get the original content of the sector */ if (!SAME_SECTOR(addr,_flash_sector_addr)) { board_flash_flush(); - //printf("Read: %08x\n",ADDR_SECTOR(addr)); + DBG("\nRead: %08x [lba %d]\n",ADDR_SECTOR(addr),lba); _flash_sector_addr = ADDR_SECTOR(addr); _flash_sector_dirty = false; memcpy(_flash_cache, (uint8_t*) ADDR_SECTOR(addr), SECTOR_SIZE); @@ -152,18 +165,14 @@ uint32_t board_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num if (memcmp(&_flash_cache[ADDR_OFFSET(addr)],src,len)!=0) { - //printf("Write to cache: %08x (%x) (%d) [lba was %d]\n",addr,ADDR_OFFSET(addr),num_blocks,lba); - for (uint32_t t=0; t<256; t++) - { - //printf("%02X %02X %c ",_flash_cache[ADDR_OFFSET(addr+t)],src[t],_flash_cache[ADDR_OFFSET(addr+t)]!=src[t]?'*':' '); - } + DBG("W"); /* Now update the right part of this sector with the new data */ memcpy(&_flash_cache[ADDR_OFFSET(addr)],src,len); _flash_sector_dirty = true; } else { - //printf("Cachewrite skipped: %08x (%x) (%d) [lba was %d]\n",addr,ADDR_OFFSET(addr),num_blocks,lba); + DBG("S"); } return 0; @@ -197,7 +206,9 @@ uint32_t board_millis(void) void board_reset(void) { + DBG("Reset request\n"); board_flash_flush(); + board_delay_ms(500); ctrl_reset_write(1); } // --------------------------------------------------------------------------------------------- diff --git a/hw/chip/ecp5/vexriscv/crt0-vexriscv-rom.S b/hw/chip/ecp5/vexriscv/crt0-vexriscv-rom.S new file mode 100644 index 0000000..8fd27d5 --- /dev/null +++ b/hw/chip/ecp5/vexriscv/crt0-vexriscv-rom.S @@ -0,0 +1,89 @@ +.global main +.global isr +.global _start + +_start: + j crt_init + nop + nop + nop + nop + nop + nop + nop + +.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 + +data_init: + la a0, _sidata + la a1, _sdata + la a2, _edata + bge a1, a2, end_init_data +loop_init_data: + lw a3, 0(a0) + sw a3, 0(a1) + addi a0, a0, 4 + addi a1, a1, 4 + blt a1, a2, loop_init_data +end_init_data: + +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: + + 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 +infinit_loop: + j infinit_loop diff --git a/hw/chip/ecp5/vexriscv/default.mk b/hw/chip/ecp5/vexriscv/default.mk index ee3ecdc..bb8475e 100644 --- a/hw/chip/ecp5/vexriscv/default.mk +++ b/hw/chip/ecp5/vexriscv/default.mk @@ -1,6 +1,6 @@ LITEX_DIR ?= $(shell realpath ~/Develop/ulx3s/litex/litex/litex/soc/software/) SOC_DIR ?= $(shell realpath ~/Develop/ulx3s/litex/litex-boards/litex_boards/targets/soc_basesoc_colorlight_5a_75b/software) -SRC_S += $(LITEX_DIR)/libbase/crt0-vexriscv.S +SRC_S += $(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/crt0-vexriscv-rom.S -LD_FILE = -T$(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/linker.ld -L$(SOC_DIR)/include -L$(LITEX_DIR) +LD_FILE = -T$(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/linker-rom.ld -L$(SOC_DIR)/include -L$(LITEX_DIR) diff --git a/hw/chip/ecp5/vexriscv/linker.ld b/hw/chip/ecp5/vexriscv/linker-ram.ld similarity index 100% rename from hw/chip/ecp5/vexriscv/linker.ld rename to hw/chip/ecp5/vexriscv/linker-ram.ld diff --git a/hw/chip/ecp5/vexriscv/linker-rom.ld b/hw/chip/ecp5/vexriscv/linker-rom.ld new file mode 100644 index 0000000..1e4ddcf --- /dev/null +++ b/hw/chip/ecp5/vexriscv/linker-rom.ld @@ -0,0 +1,74 @@ +INCLUDE generated/output_format.ld +ENTRY(_start) + +__DYNAMIC = 0; + +INCLUDE generated/regions.ld + +SECTIONS +{ + .text : + { + _ftext = .; + *(.text .stub .text.* .gnu.linkonce.t.*) + _etext = .; + } > rom + + .got : + { + _GLOBAL_OFFSET_TABLE_ = .; + *(.got) + } > rom + + .got.plt : + { + *(.got.plt) + } > rom + + .rodata : + { + . = ALIGN(4); + _frodata = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + . = ALIGN(4); + _erodata = .; + _sidata = _erodata; + } > rom + + .data : AT ( _sidata ) + { + . = ALIGN(4); + _sdata = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + *(.sdata .sdata* .eh_frame* .gnu.linkonce.s.*) + _edata = .; + } > sram + + .bss : + { + . = ALIGN(4); + _fbss = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = .; + . = ALIGN(8); + _heapstart = .; + } > sram + + .flash : + { + _fstart = .; + _fend = .; + } > spiflash + +} + +PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 4); +PROVIDE(_flash_start = _fstart); diff --git a/src/main.c b/src/main.c index 6bb3184..9b007c4 100644 --- a/src/main.c +++ b/src/main.c @@ -30,8 +30,9 @@ #include "bsp.h" #include "tusb.h" +#include "uf2_version.h" -static uint32_t blink_interval_ms = BOARD_BLINK_INTERVAL; +volatile uint32_t blink_interval_ms = BOARD_BLINK_INTERVAL; uint32_t reset_millis = 0; @@ -58,6 +59,12 @@ void reset_task(void) board_reset(); } +void file_loading(void) + +{ + blink_interval_ms = BOARD_LOADING_INTERVAL; +} + int main(void) { board_check_app_start(); @@ -65,7 +72,7 @@ int main(void) board_check_tinyuf2_start(); - printf("TinyUF2 running\r\n"); + printf("TinyUF2 running (Version " UF2_VERSION_BASE ", Created " __TIME__ " on " __DATE__ "\r\n"); tusb_init(); From 2df372bf90fe9dab8f170bfacf8404ae78fcd5b5 Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Sun, 3 May 2020 00:55:33 +0100 Subject: [PATCH 04/10] Addition of two-image booting (application or uf2 booter) --- hw/bsp/bsp.h | 8 ++++ hw/bsp/colorlight_5a_75b/board_config.h | 3 +- hw/chip/ecp5/family.c | 58 ++++++++++++++++++++++--- 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/hw/bsp/bsp.h b/hw/bsp/bsp.h index ed29c23..56e86b4 100644 --- a/hw/bsp/bsp.h +++ b/hw/bsp/bsp.h @@ -67,6 +67,14 @@ #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 100 +#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 diff --git a/hw/bsp/colorlight_5a_75b/board_config.h b/hw/bsp/colorlight_5a_75b/board_config.h index 3dfd73e..ac39fee 100644 --- a/hw/bsp/colorlight_5a_75b/board_config.h +++ b/hw/bsp/colorlight_5a_75b/board_config.h @@ -7,10 +7,9 @@ #define BOARD_ID "Colorlight_5a_75b" // Board flash -#define BOARD_FLASH_SIZE 0x800000 +#define BOARD_FLASH_SIZE 0x400000 // LED -#define PIN_LED 0 #define LED_STATE_ON 0 #endif diff --git a/hw/chip/ecp5/family.c b/hw/chip/ecp5/family.c index f9eddbb..021b4a1 100644 --- a/hw/chip/ecp5/family.c +++ b/hw/chip/ecp5/family.c @@ -32,7 +32,7 @@ #include "spi.h" #include "uart.h" -#define DEBUG 1 +//#define DEBUG 1 #ifdef DEBUG #define DBG(...) printf(__VA_ARGS__) @@ -40,6 +40,8 @@ #define DBG(...) {} #endif +enum { IO_LED, IO_HWRESET, IO_RED, IO_GREEN, IO_BLUE, IO_BUTTON } iopins; + volatile uint32_t system_ticks = 0; extern void file_loading(void); @@ -203,18 +205,37 @@ uint32_t board_millis(void) return system_ticks; } // --------------------------------------------------------------------------------------------- +static void _hard_reset(bool active) + +{ + gpio_out_write((gpio_in_read()&(~(1<=tflash) + { + board_led_write(flash=!flash); + tflash = board_millis()+BOARD_BOOTING_INTERVAL; + } + + if (!_button_pressed()) + { + // Button isn't pressed, so let's pack up and boot + board_led_write(false); + board_reset(); + } + } return; // stay in bootloader } // --------------------------------------------------------------------------------------------- From d2f98a79161bdc5dd0a39e99cb8fdbb1a35abdf5 Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Mon, 4 May 2020 00:11:43 +0100 Subject: [PATCH 05/10] Addition of hf2 support for ecp5 from kbeckmann --- Makefile | 15 +++++------ README.md | 3 ++- hw/bsp/bsp.h | 1 + hw/bsp/colorlight_5a_75b/board_config.h | 1 + hw/bsp/pergola/board.mk | 13 --------- hw/chip/ecp5/family.c | 35 ++++++++++++++++++++++--- hw/chip/ecp5/family.mk | 12 ++++----- hw/chip/ecp5/vexriscv/default.mk | 4 +-- hw/chip/mimxrt10xx/family.c | 17 +++++++++++- hw/chip/mimxrt10xx/family.mk | 34 ++++++++++++++++-------- src/hid.c | 3 +-- 11 files changed, 90 insertions(+), 48 deletions(-) diff --git a/Makefile b/Makefile index 652df90..5b5fe91 100644 --- a/Makefile +++ b/Makefile @@ -14,12 +14,12 @@ # perform the build step rather than the family script. # Force using the local board directory -TOP := $(shell realpath `pwd`) +MFTOP := $(shell realpath `pwd`) -TINYUSB_PATH ?= $(TOP)/lib/tinyusb +TINYUSB_PATH ?= $(MFTOP)/lib/tinyusb #-------------- Select the board to build for. ------------ -BOARD_LIST = $(sort $(subst /.,,$(subst $(TOP)/hw/bsp/,,$(wildcard $(TOP)/hw/bsp/*/.)))) +BOARD_LIST = $(sort $(subst /.,,$(subst $(MFTOP)/hw/bsp/,,$(wildcard $(MFTOP)/hw/bsp/*/.)))) ifeq ($(filter $(BOARD),$(BOARD_LIST)),) $(info You must provide a BOARD parameter with 'BOARD=', supported boards are:) @@ -39,7 +39,7 @@ __check_defined = \ BUILD = _build/build-$(BOARD) # Board specific define -include $(TOP)/hw/bsp/$(BOARD)/board.mk +include $(MFTOP)/hw/bsp/$(BOARD)/board.mk #-------------- Cross Compiler ------------ # Can be set by board, default to ARM GCC @@ -58,7 +58,7 @@ RM = rm # Include all source C in board folder #SRC_C += hw/bsp/board.c -SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/hw/bsp/$(BOARD)/*.c)) +SRC_C += $(subst $(MFTOP)/,,$(wildcard $(MFTOP)/hw/bsp/$(BOARD)/*.c)) # Compiler Flags which are generic across all targets CFLAGS += \ @@ -102,8 +102,8 @@ $(BUILD)/uf2_version.h: Makefile OBJ += $(BUILD)/uf2_version.h -include $(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/$(TUF2_CHIP_VARIANT).mk -include $(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/family.mk +include $(MFTOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/$(TUF2_CHIP_VARIANT).mk +include $(MFTOP)/hw/chip/$(TUF2_CHIP_FAMILY)/family.mk ifndef OVERRIDE_TINYUSB_RULES include $(TINYUSB_PATH)/tools/top.mk @@ -112,4 +112,3 @@ endif print-%: @echo $* is $($*) - diff --git a/README.md b/README.md index 7a13ec4..603396c 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,8 @@ Specify the board you want to build for: $ make BOARD=mimxrt1010_evk -Currently NXP MIMXRT101x, MIMXRT102x and vexriscv running on ecp5 colorlight_5a_75 boards are supported. +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 diff --git a/hw/bsp/bsp.h b/hw/bsp/bsp.h index 56e86b4..188cf33 100644 --- a/hw/bsp/bsp.h +++ b/hw/bsp/bsp.h @@ -86,6 +86,7 @@ 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_init(void); diff --git a/hw/bsp/colorlight_5a_75b/board_config.h b/hw/bsp/colorlight_5a_75b/board_config.h index ac39fee..c50671d 100644 --- a/hw/bsp/colorlight_5a_75b/board_config.h +++ b/hw/bsp/colorlight_5a_75b/board_config.h @@ -8,6 +8,7 @@ // Board flash #define BOARD_FLASH_SIZE 0x400000 +#define BOARD_FLASH_PAGE_SIZE 256 // LED #define LED_STATE_ON 0 diff --git a/hw/bsp/pergola/board.mk b/hw/bsp/pergola/board.mk index ba80eb4..d2a87f3 100644 --- a/hw/bsp/pergola/board.mk +++ b/hw/bsp/pergola/board.mk @@ -1,16 +1,3 @@ TUF2_CHIP_FAMILY = mimxrt10xx TUF2_CHIP_MEMBER = mimxrt101x TUF2_CHIP_VARIANT = MIMXRT1011DAE5A - -$(BUILD)/$(BOARD)-firmware-padded.bin: $(BUILD)/$(BOARD)-firmware.bin - dd if=/dev/zero of=$(BUILD)/$(BOARD)-firmware-padded.bin bs=1 count=1024 - cat $(BUILD)/$(BOARD)-firmware.bin >> $(BUILD)/$(BOARD)-firmware-padded.bin - -$(BUILD)/$(BOARD)-firmware-padded.uf2: $(BUILD)/$(BOARD)-firmware-padded.bin - @echo CREATE $@ - $(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 - diff --git a/hw/chip/ecp5/family.c b/hw/chip/ecp5/family.c index 021b4a1..d9fcd0a 100644 --- a/hw/chip/ecp5/family.c +++ b/hw/chip/ecp5/family.c @@ -42,6 +42,9 @@ enum { IO_LED, IO_HWRESET, IO_RED, IO_GREEN, IO_BLUE, IO_BUTTON } iopins; +/* Indicator of if next reboot is to be to bootloader or app */ +bool rebootToBootloader = false; + volatile uint32_t system_ticks = 0; extern void file_loading(void); @@ -205,10 +208,19 @@ uint32_t board_millis(void) return system_ticks; } // --------------------------------------------------------------------------------------------- -static void _hard_reset(bool active) +static void _reset(bool active) + +/* We can either reset *this* firmware or boot the application - that's decided here */ { - gpio_out_write((gpio_in_read()&(~(1<> $(BUILD)/$(BOARD)-firmware-padded.bin + +$(BUILD)/$(BOARD)-firmware-padded.uf2: $(BUILD)/$(BOARD)-firmware-padded.bin + @echo CREATE $@ + $(PYTHON) $(MFTOP)/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 diff --git a/src/hid.c b/src/hid.c index 21d9dc3..530b2a4 100644 --- a/src/hid.c +++ b/src/hid.c @@ -47,7 +47,6 @@ #endif extern const char infoUf2File[]; -extern uint32_t _bootloader_dbl_tap; typedef struct { const uint8_t *buf_in; @@ -220,7 +219,7 @@ void process_core(HID_InBuffer *pkt) { reset_millis = board_millis() + 30; break; case HF2_CMD_RESET_INTO_BOOTLOADER: - _bootloader_dbl_tap = DBL_TAP_MAGIC; + board_reset_to_bootloader(true); board_flash_flush(); reset_millis = board_millis() + 30; break; From c678f6d6c337f1723fda74610834b52b634fd668 Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Mon, 4 May 2020 12:49:44 +0100 Subject: [PATCH 06/10] Various tidying --- hw/bsp/bsp.h | 8 +- hw/bsp/colorlight_5a_75b/board_config.h | 4 +- hw/chip/ecp5/family.c | 163 +++++++++++++++--------- hw/chip/ecp5/vexriscv/linker-ram.ld | 3 +- hw/chip/ecp5/vexriscv/linker-rom.ld | 3 +- hw/chip/mimxrt10xx/family.c | 23 ++++ src/main.c | 28 +--- src/uf2.h | 2 +- 8 files changed, 145 insertions(+), 89 deletions(-) diff --git a/hw/bsp/bsp.h b/hw/bsp/bsp.h index 188cf33..2e343d8 100644 --- a/hw/bsp/bsp.h +++ b/hw/bsp/bsp.h @@ -57,6 +57,8 @@ #define BOARD_TAP_WAIT 500 #endif +#define BOARD_OFF_INTERVAL 0 + #ifndef BOARD_BLINK_INTERVAL // Define this for a different blinking interval in mS while on standby #define BOARD_BLINK_INTERVAL 500 @@ -69,7 +71,7 @@ // 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 100 +#define BOARD_BOOTING_INTERVAL 50 #endif // Length of time board needs boot button held down for to enter uf2 mode @@ -80,7 +82,7 @@ // #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); @@ -88,7 +90,7 @@ uint32_t board_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num 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); diff --git a/hw/bsp/colorlight_5a_75b/board_config.h b/hw/bsp/colorlight_5a_75b/board_config.h index c50671d..dabd5a6 100644 --- a/hw/bsp/colorlight_5a_75b/board_config.h +++ b/hw/bsp/colorlight_5a_75b/board_config.h @@ -1,5 +1,6 @@ #ifndef _BOARD_CONFIG_H_ #define _BOARD_CONFIG_H_ +#include "mem.h" // Basic Data #define VENDOR_NAME "Orbcode" @@ -7,8 +8,9 @@ #define BOARD_ID "Colorlight_5a_75b" // Board flash -#define BOARD_FLASH_SIZE 0x400000 +#define BOARD_FLASH_SIZE SPIFLASH_SIZE #define BOARD_FLASH_PAGE_SIZE 256 +#include "mem.h" // LED #define LED_STATE_ON 0 diff --git a/hw/chip/ecp5/family.c b/hw/chip/ecp5/family.c index d9fcd0a..9602c89 100644 --- a/hw/chip/ecp5/family.c +++ b/hw/chip/ecp5/family.c @@ -31,10 +31,11 @@ #include "irq.h" #include "spi.h" #include "uart.h" +#include "uf2.h" -//#define DEBUG 1 +//#define FAMILY_DEBUG 1 -#ifdef DEBUG +#ifdef FAMILY_DEBUG #define DBG(...) printf(__VA_ARGS__) #else #define DBG(...) {} @@ -42,12 +43,18 @@ enum { IO_LED, IO_HWRESET, IO_RED, IO_GREEN, IO_BLUE, IO_BUTTON } iopins; -/* Indicator of if next reboot is to be to bootloader or app */ -bool rebootToBootloader = false; +// Indicator of if next reboot is to be to bootloader or app +static bool rebootToBootloader = false; -volatile uint32_t system_ticks = 0; +// Overall time maintenance +static volatile uint32_t _system_ticks = 0; -extern void file_loading(void); +// Flag indicating boot mode (set up in the linker file +extern uint32_t _bootloader_dbl_tap; + +// Led flashing support +static uint32_t _next_blink_event; /* Time in ticks for next blink crossover */ +static uint32_t _blink_interval; /* Addition of ticks for next event */ // Indicator that no Sector is currently cached #define NO_CACHE 0xffffffff @@ -80,16 +87,13 @@ static uint8_t _flash_cache[SECTOR_SIZE] __attribute__((aligned(4))); // --------------------------------------------------------------------------------------------- -static inline uint32_t add2flashOfs(uint32_t addr) - -/* Turn absolute address into offset into flash */ +// --------------------------------------------------------------------------------------------- -{ - return addr-FLASH_BASE; -} +// Flashing Related code // --------------------------------------------------------------------------------------------- -static inline uint32_t lba2addr(uint32_t block) +// --------------------------------------------------------------------------------------------- +static inline uint32_t _lba2addr(uint32_t block) /* Turn LBA into address in memory (by implication, in the flash) */ @@ -108,7 +112,7 @@ static void _burn_sector(void) return; } - uint32_t flash_ofs = add2flashOfs(_flash_sector_addr); + uint32_t flash_ofs = _flash_sector_addr - FLASH_BASE; spiInit(); spiBeginErase4(flash_ofs); while(spiIsBusy()); @@ -144,7 +148,7 @@ void board_flash_flush(void) // --------------------------------------------------------------------------------------------- uint32_t board_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { - uint32_t src = lba2addr(block); + uint32_t src = _lba2addr(block); memcpy(dest, (uint8_t*) src, FILESYSTEM_BLOCK_SIZE * num_blocks); return 0; } @@ -152,11 +156,11 @@ uint32_t board_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blo uint32_t board_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) { - uint32_t const addr = lba2addr(lba); + uint32_t const addr = _lba2addr(lba); uint32_t const len = num_blocks*FILESYSTEM_BLOCK_SIZE; /* Someone is trying to load something, let the user know */ - file_loading(); + _blink_interval = BOARD_LOADING_INTERVAL; /* Flush any old cache and get the original content of the sector */ if (!SAME_SECTOR(addr,_flash_sector_addr)) @@ -183,29 +187,13 @@ uint32_t board_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num return 0; } // --------------------------------------------------------------------------------------------- -void isr(void) -{ - unsigned int irqs; - irqs = irq_pending() & irq_getmask(); - - if (irqs & (1 << USB_INTERRUPT)) - { - tud_int_handler(0); - } - - if (irqs & (1 << TIMER0_INTERRUPT)) - { - system_ticks++; - timer0_ev_pending_write(1); - } +// --------------------------------------------------------------------------------------------- - if(irqs & (1 << UART_INTERRUPT)) - uart_isr(); -} // --------------------------------------------------------------------------------------------- -uint32_t board_millis(void) +// --------------------------------------------------------------------------------------------- +static void _led_write(bool state) { - return system_ticks; + gpio_out_write((gpio_out_read()&(~(1<=_next_blink_event)) + { + _led_write(led_state=!led_state); + _next_blink_event=_system_ticks+_blink_interval; + } + } + + if(irqs & (1 << UART_INTERRUPT)) + uart_isr(); } // --------------------------------------------------------------------------------------------- -void _init_io(void) +// --------------------------------------------------------------------------------------------- +// +// External Interface +// +// --------------------------------------------------------------------------------------------- +// --------------------------------------------------------------------------------------------- +uint32_t board_millis(void) +/* Return time since board start in mS */ + { - _reset(false); - gpio_oe_write( (1<=tflash) - { - board_led_write(flash=!flash); - tflash = board_millis()+BOARD_BOOTING_INTERVAL; - } if (!_button_pressed()) { // Button isn't pressed, so let's pack up and boot - board_led_write(false); + _blink_interval = BOARD_OFF_INTERVAL; + _led_write(false); board_reset(); } } + _blink_interval = BOARD_BLINK_INTERVAL; return; // stay in bootloader } // --------------------------------------------------------------------------------------------- diff --git a/hw/chip/ecp5/vexriscv/linker-ram.ld b/hw/chip/ecp5/vexriscv/linker-ram.ld index 15697c1..bec4d76 100644 --- a/hw/chip/ecp5/vexriscv/linker-ram.ld +++ b/hw/chip/ecp5/vexriscv/linker-ram.ld @@ -57,5 +57,6 @@ SECTIONS } > spiflash } -PROVIDE(_fstack = ORIGIN(main_ram) + LENGTH(main_ram) - 4); +_bootloader_dbl_tap = ORIGIN(main_ram) + LENGTH(main_ram) - 4; +PROVIDE(_fstack = ORIGIN(main_ram) + LENGTH(main_ram) - 8); PROVIDE(_flash_start = _fstart); diff --git a/hw/chip/ecp5/vexriscv/linker-rom.ld b/hw/chip/ecp5/vexriscv/linker-rom.ld index 1e4ddcf..49e733f 100644 --- a/hw/chip/ecp5/vexriscv/linker-rom.ld +++ b/hw/chip/ecp5/vexriscv/linker-rom.ld @@ -70,5 +70,6 @@ SECTIONS } -PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 4); +_bootloader_dbl_tap = ORIGIN(sram) + LENGTH(sram) - 4; +PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 8); PROVIDE(_flash_start = _fstart); diff --git a/hw/chip/mimxrt10xx/family.c b/hw/chip/mimxrt10xx/family.c index 4e5f551..0f7a82f 100644 --- a/hw/chip/mimxrt10xx/family.c +++ b/hw/chip/mimxrt10xx/family.c @@ -36,6 +36,7 @@ #include "fsl_iomuxc.h" volatile uint32_t system_ticks = 0; +volatile uint32_t blink_interval_ms = BOARD_BLINK_INTERVAL; // FLASH #define NO_CACHE 0xffffffff @@ -426,6 +427,28 @@ void board_check_app_start(void) asm("bx %0" ::"r"(app_start_address)); } +void board_led_blinking_task(void) +{ + static uint32_t start_ms = 0; + static bool led_state = false; + + if (board_millis() - start_ms < blink_interval_ms) + return; + + start_ms += blink_interval_ms; + + led_state = !led_state; + board_led_write(led_state); +} + +void board_file_loading(void) + +// Called when a file loading process has started to fast-flash the LED + +{ + blink_interval_ms = BOARD_LOADING_INTERVAL; +} + void board_check_tinyuf2_start(void) { register uint32_t app_start_address = *(uint32_t *)(APP_START_ADDRESS + 4); diff --git a/src/main.c b/src/main.c index 0c0c27b..8877bd3 100644 --- a/src/main.c +++ b/src/main.c @@ -33,24 +33,8 @@ #include "uf2_version.h" #include "hid.h" -volatile uint32_t blink_interval_ms = BOARD_BLINK_INTERVAL; - uint32_t reset_millis = 0; -void led_blinking_task(void) -{ - static uint32_t start_ms = 0; - static bool led_state = false; - - if (board_millis() - start_ms < blink_interval_ms) - return; - - start_ms += blink_interval_ms; - - led_state = !led_state; - board_led_write(led_state); -} - void reset_task(void) { if (!reset_millis) @@ -60,18 +44,14 @@ void reset_task(void) board_reset(); } -void file_loading(void) - -{ - blink_interval_ms = BOARD_LOADING_INTERVAL; -} - int main(void) { board_check_app_start(); board_init(); - board_check_tinyuf2_start(); +#ifdef reset_task + dfsdfdsfsd +#endif printf("TinyUF2 running (Version " UF2_VERSION_BASE ", Created " __TIME__ " on " __DATE__ "\r\n"); @@ -80,7 +60,7 @@ int main(void) while (1) { tud_task(); hf2_hid_task(); - led_blinking_task(); + board_led_blinking_task(); reset_task(); } diff --git a/src/uf2.h b/src/uf2.h index 41ceb5f..cf1652b 100644 --- a/src/uf2.h +++ b/src/uf2.h @@ -62,7 +62,7 @@ static inline bool is_uf2_block(void *data) #define UDI_MSC_BLOCK_SIZE 512L // Needs to be more than ~4200 (to force FAT16) -#define NUM_FAT_BLOCKS 65535 +#define NUM_FAT_BLOCKS ((BOARD_FLASH_SIZE+UDI_MSC_BLOCK_SIZE-1)/UDI_MSC_BLOCK_SIZE) #define CONCAT_1(a, b) a##b #define CONCAT_0(a, b) CONCAT_1(a, b) From 54c5064db8dc07aec547dde42eeb89a03eded127 Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Tue, 5 May 2020 23:47:41 +0100 Subject: [PATCH 07/10] Various small changes as a result of integration test --- Makefile | 25 ++++++++++++++++--- hw/chip/mimxrt10xx/family.c | 12 ++++----- hw/chip/mimxrt10xx/family.mk | 19 -------------- .../mimxrt102x/MIMXRT1021xxxxx_flexspi_nor.ld | 13 +++++----- src/main.c | 14 +++++------ src/uf2.h | 4 +-- 6 files changed, 41 insertions(+), 46 deletions(-) diff --git a/Makefile b/Makefile index 5b5fe91..db977be 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ __check_defined = \ $(error Undefined make flag: $1$(if $2, ($2)))) # Build directory -BUILD = _build/build-$(BOARD) +BUILD = _build/$(BOARD) # Board specific define include $(MFTOP)/hw/bsp/$(BOARD)/board.mk @@ -81,12 +81,17 @@ CFLAGS += \ -Wno-unused-parameter \ -Wunreachable-code -# This causes lots of warning with nrf5x build due to nrfx code -# CFLAGS += -Wcast-align +INC += $(MFTOP)/hw \ + $(MFTOP)/hw/bsp \ + $(MFTOP)/hw/bsp/$(BOARD) \ + $(MFTOP)/src \ + $(TINYUSB_PATH)/tools \ + $(BUILD) \ + $(MFTOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER) \ # Debugging/Optimization ifeq ($(DEBUG), 1) - CFLAGS += -Og -ggdb + CFLAGS += -g3 -Og -ggdb else CFLAGS += -Os endif @@ -110,5 +115,17 @@ include $(TINYUSB_PATH)/tools/top.mk include $(TINYUSB_PATH)/examples/rules.mk endif +$(BUILD)/$(BOARD)-firmware-padded.bin: $(BUILD)/$(BOARD)-firmware.bin + dd if=/dev/zero of=$(BUILD)/$(BOARD)-firmware-padded.bin bs=1 count=1024 + cat $(BUILD)/$(BOARD)-firmware.bin >> $(BUILD)/$(BOARD)-firmware-padded.bin + +$(BUILD)/$(BOARD)-firmware-padded.uf2: $(BUILD)/$(BOARD)-firmware-padded.bin + @echo CREATE $@ + $(PYTHON) $(MFTOP)/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 $($*) diff --git a/hw/chip/mimxrt10xx/family.c b/hw/chip/mimxrt10xx/family.c index 0f7a82f..de70ca3 100644 --- a/hw/chip/mimxrt10xx/family.c +++ b/hw/chip/mimxrt10xx/family.c @@ -38,6 +38,9 @@ volatile uint32_t system_ticks = 0; volatile uint32_t blink_interval_ms = BOARD_BLINK_INTERVAL; +// Variable that will be kept across reboots +extern uint32_t _bootloader_dbl_tap; + // FLASH #define NO_CACHE 0xffffffff @@ -385,8 +388,6 @@ void USB_OTG1_IRQHandler(void) #include "uf2.h" -extern uint32_t _bootloader_dbl_tap; - void board_reset_to_bootloader(bool toBootloader) /* Called to ensure that next reset is into bootloader */ @@ -413,7 +414,9 @@ void board_check_app_start(void) register uint32_t app_start_address = *(uint32_t *)(APP_START_ADDRESS + 4); if (_bootloader_dbl_tap != DBL_TAP_MAGIC_QUICK_BOOT) - return; + { + return; + } _bootloader_dbl_tap = 0; @@ -488,10 +491,7 @@ void board_check_tinyuf2_start(void) #endif board_delay_ms(BOARD_TAP_WAIT); - -#ifdef BOARD_LED_ON_UF2_START board_led_write(false); -#endif // If we made to here then we should boot into the application _bootloader_dbl_tap = DBL_TAP_MAGIC_QUICK_BOOT; diff --git a/hw/chip/mimxrt10xx/family.mk b/hw/chip/mimxrt10xx/family.mk index 367854f..42a216a 100644 --- a/hw/chip/mimxrt10xx/family.mk +++ b/hw/chip/mimxrt10xx/family.mk @@ -33,13 +33,6 @@ SRC_C += \ $(MCU_DIR)/drivers/fsl_lpuart.c INC += \ - hw \ - hw/bsp \ - hw/bsp/$(BOARD) \ - src \ - lib/tinyusb/tools \ - _build/build-$(BOARD) \ - hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER) \ $(TINYUSB_PATH)/$(MCU_DIR) \ $(TINYUSB_PATH)/$(MCU_DIR)/drivers \ $(TINYUSB_PATH)/$(MCU_DIR)/project_template \ @@ -64,15 +57,3 @@ else -DXIP_EXTERNAL_FLASH=1 \ -DXIP_BOOT_HEADER_ENABLE=1 endif - -$(BUILD)/$(BOARD)-firmware-padded.bin: $(BUILD)/$(BOARD)-firmware.bin - dd if=/dev/zero of=$(BUILD)/$(BOARD)-firmware-padded.bin bs=1 count=1024 - cat $(BUILD)/$(BOARD)-firmware.bin >> $(BUILD)/$(BOARD)-firmware-padded.bin - -$(BUILD)/$(BOARD)-firmware-padded.uf2: $(BUILD)/$(BOARD)-firmware-padded.bin - @echo CREATE $@ - $(PYTHON) $(MFTOP)/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 diff --git a/hw/chip/mimxrt10xx/mimxrt102x/MIMXRT1021xxxxx_flexspi_nor.ld b/hw/chip/mimxrt10xx/mimxrt102x/MIMXRT1021xxxxx_flexspi_nor.ld index 0b83a18..d282965 100644 --- a/hw/chip/mimxrt10xx/mimxrt102x/MIMXRT1021xxxxx_flexspi_nor.ld +++ b/hw/chip/mimxrt10xx/mimxrt102x/MIMXRT1021xxxxx_flexspi_nor.ld @@ -1,6 +1,6 @@ ENTRY(Reset_Handler) -_minimum_stack_size = 64K; +_minimum_stack_size = 12K; _minimum_heap_size = 0; MEMORY @@ -9,12 +9,11 @@ MEMORY FLASH_IVT (rx) : ORIGIN = 0x60001000, LENGTH = 4K FLASH_ISR (rx) : ORIGIN = 0x60002000, LENGTH = 1K FLASH_TEXT (rx) : ORIGIN = 0x60002400, LENGTH = 27K - RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 32K - OCRAM (rwx) : ORIGIN = 0x20200000, LENGTH = 64K + OCRAM (rwx) : ORIGIN = 0x20200000, LENGTH = 32K } -__StackTop = ORIGIN(OCRAM) + LENGTH(OCRAM); -_bootloader_dbl_tap = ORIGIN(RAM) + LENGTH(RAM) - 4; +__StackTop = ORIGIN(OCRAM) + LENGTH(OCRAM) - 8; +_bootloader_dbl_tap = ORIGIN(OCRAM) + LENGTH(OCRAM) - 4; __RAM_VECTOR_TABLE_SIZE_BYTES = 0; SECTIONS @@ -79,7 +78,7 @@ SECTIONS . = ALIGN(4); __data_end__ = .; /* define a global symbol at data end */ - } > RAM + } > OCRAM /* Uninitialized data section */ .bss : @@ -93,7 +92,7 @@ SECTIONS . = ALIGN(4); __bss_end__ = .; PROVIDE(end = .); - } > RAM + } > OCRAM .heap : { diff --git a/src/main.c b/src/main.c index 8877bd3..feaa5e1 100644 --- a/src/main.c +++ b/src/main.c @@ -45,23 +45,21 @@ void reset_task(void) } int main(void) + { board_check_app_start(); board_init(); board_check_tinyuf2_start(); -#ifdef reset_task - dfsdfdsfsd -#endif - printf("TinyUF2 running (Version " UF2_VERSION_BASE ", Created " __TIME__ " on " __DATE__ "\r\n"); + //printf("TinyUF2 running (Version " UF2_VERSION_BASE ", Created " __TIME__ " on " __DATE__ "\r\n"); tusb_init(); while (1) { - tud_task(); - hf2_hid_task(); - board_led_blinking_task(); - reset_task(); + tud_task(); + hf2_hid_task(); + board_led_blinking_task(); + reset_task(); } return 0; diff --git a/src/uf2.h b/src/uf2.h index cf1652b..ba82f4c 100644 --- a/src/uf2.h +++ b/src/uf2.h @@ -61,8 +61,8 @@ static inline bool is_uf2_block(void *data) // Static block size for all memories #define UDI_MSC_BLOCK_SIZE 512L -// Needs to be more than ~4200 (to force FAT16) -#define NUM_FAT_BLOCKS ((BOARD_FLASH_SIZE+UDI_MSC_BLOCK_SIZE-1)/UDI_MSC_BLOCK_SIZE) +// Needs to be more than ~4200 (to force FAT16), and big enough for the biggest uf2 file... +#define NUM_FAT_BLOCKS 65535 #define CONCAT_1(a, b) a##b #define CONCAT_0(a, b) CONCAT_1(a, b) From 35427ac4562ecac92d570126689f5d3903818f23 Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Wed, 6 May 2020 16:50:52 +0100 Subject: [PATCH 08/10] Edits for release following integration test --- Makefile | 217 ++++++++++++++---- hw/bsp/colorlight_5a_75b/README.md | 2 +- hw/bsp/colorlight_5a_75b/board.mk | 11 +- hw/bsp/mimxrt1010_evk/board.mk | 8 +- hw/bsp/mimxrt1020_evk/board.mk | 10 +- hw/bsp/pergola/board.mk | 4 + hw/bsp/pergola_ram/board.mk | 6 +- hw/bsp/versiboard2/board.mk | 4 + hw/chip/ecp5/family.c | 9 + hw/chip/ecp5/family.mk | 154 ++----------- hw/chip/ecp5/vexriscv/default.mk | 7 +- hw/chip/mimxrt10xx/family.mk | 30 +-- .../mimxrt10xx/mimxrt101x/MIMXRT1011DAE5A.mk | 14 +- .../mimxrt10xx/mimxrt102x/MIMXRT1021DAG5A.mk | 8 +- src/hid.c | 7 +- src/main.c | 17 +- src/msc.c | 8 +- src/uf2.h | 7 +- 18 files changed, 284 insertions(+), 239 deletions(-) diff --git a/Makefile b/Makefile index db977be..5dbbc44 100644 --- a/Makefile +++ b/Makefile @@ -1,25 +1,32 @@ # This is the root makefile. It calls in the following files; +# # 1) hw/bsp/ /board.mk +# Configuration of the board details. # (Sets details of the family, member and variant, and compiler to use) # # 2) hw/chip/ / / .mk +# Configuration of the specific chip details. # Sets external directories if these were not set on the command line -# Includes specific files for that variant +# Includes specific files and link options for that variant # # 3) hw/chip/ /family.mk -# Main build script for specific family(*) +# 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. # -# Note that for step (3) some builds defer the main build process to tinyuf2, in -# which case $(TINYUSB_PATH)/tools/top.mk and $(TINYUSB_PATH)/examples/rules.mk -# perform the build step rather than the family script. +# All of the configuration for a specific board is stored in the board file. -# Force using the local board directory -MFTOP := $(shell realpath `pwd`) +TOP := ./ +TINYUSB_PATH ?= $(TOP)/lib/tinyusb -TINYUSB_PATH ?= $(MFTOP)/lib/tinyusb +# Set to 1 to get noisy makefile output +V ?= 0 #-------------- Select the board to build for. ------------ -BOARD_LIST = $(sort $(subst /.,,$(subst $(MFTOP)/hw/bsp/,,$(wildcard $(MFTOP)/hw/bsp/*/.)))) + +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:) @@ -38,27 +45,30 @@ __check_defined = \ # Build directory BUILD = _build/$(BOARD) -# Board specific define -include $(MFTOP)/hw/bsp/$(BOARD)/board.mk - -#-------------- Cross Compiler ------------ -# Can be set by board, default to ARM GCC -CROSS_COMPILE ?= arm-none-eabi- - -CC = $(CROSS_COMPILE)gcc -CXX = $(CROSS_COMPILE)g++ -OBJCOPY = $(CROSS_COMPILE)objcopy -SIZE = $(CROSS_COMPILE)size -MKDIR = mkdir -SED = sed -CP = cp -RM = rm - -#-------------- Source files and compiler flags -------------- - -# Include all source C in board folder -#SRC_C += hw/bsp/board.c -SRC_C += $(subst $(MFTOP)/,,$(wildcard $(MFTOP)/hw/bsp/$(BOARD)/*.c)) +# 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 += \ @@ -79,15 +89,60 @@ CFLAGS += \ -Wsign-compare \ -Wmissing-format-attribute \ -Wno-unused-parameter \ - -Wunreachable-code + -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,-Map=$@.map -Wl,-cref -Wl,-gc-sections + +# Debugging/Optimization +ifeq ($(DEBUG), 1) +LDFLAGS += specs=rdimon.specs +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 -INC += $(MFTOP)/hw \ - $(MFTOP)/hw/bsp \ - $(MFTOP)/hw/bsp/$(BOARD) \ - $(MFTOP)/src \ - $(TINYUSB_PATH)/tools \ - $(BUILD) \ - $(MFTOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER) \ +# 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) @@ -105,23 +160,91 @@ UF2_VERSION_BASE = $(shell git describe --always --tags) $(BUILD)/uf2_version.h: Makefile @echo "#define UF2_VERSION_BASE \"$(UF2_VERSION_BASE)\""> $@ -OBJ += $(BUILD)/uf2_version.h +# Assembly files can be name with upper case .S, convert it to .s +SRC_S := $(SRC_S:.S=.s) -include $(MFTOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/$(TUF2_CHIP_VARIANT).mk -include $(MFTOP)/hw/chip/$(TUF2_CHIP_FAMILY)/family.mk +# 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)) -ifndef OVERRIDE_TINYUSB_RULES -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 - dd if=/dev/zero of=$(BUILD)/$(BOARD)-firmware-padded.bin bs=1 count=1024 - cat $(BUILD)/$(BOARD)-firmware.bin >> $(BUILD)/$(BOARD)-firmware-padded.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 $@ - $(PYTHON) $(MFTOP)/tools/uf2/utils/uf2conv.py -b $(BOARD_FLASH_BASE) -f $(UF2_FAMILY) -c -o $@ $^ + $(QUIET)$(PYTHON) $(TOP)/tools/uf2/utils/uf2conv.py -b $(BOARD_FLASH_BASE) -f $(UF2_FAMILY) -c -o $@ $^ padded-bin: $(BUILD)/$(BOARD)-firmware-padded.bin diff --git a/hw/bsp/colorlight_5a_75b/README.md b/hw/bsp/colorlight_5a_75b/README.md index a4494bf..4485471 100644 --- a/hw/bsp/colorlight_5a_75b/README.md +++ b/hw/bsp/colorlight_5a_75b/README.md @@ -2,7 +2,7 @@ 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/build-colorlight_5a_75b/colorlight_5a_75b-firmware.bin +./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. diff --git a/hw/bsp/colorlight_5a_75b/board.mk b/hw/bsp/colorlight_5a_75b/board.mk index 36100ca..1eb377b 100644 --- a/hw/bsp/colorlight_5a_75b/board.mk +++ b/hw/bsp/colorlight_5a_75b/board.mk @@ -1,4 +1,7 @@ -TUF2_CHIP_FAMILY = ecp5 -TUF2_CHIP_MEMBER = vexriscv -TUF2_CHIP_VARIANT = default -CROSS_COMPILE ?= riscv64-unknown-elf- +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 diff --git a/hw/bsp/mimxrt1010_evk/board.mk b/hw/bsp/mimxrt1010_evk/board.mk index d2a87f3..3f76f61 100644 --- a/hw/bsp/mimxrt1010_evk/board.mk +++ b/hw/bsp/mimxrt1010_evk/board.mk @@ -1,3 +1,7 @@ -TUF2_CHIP_FAMILY = mimxrt10xx -TUF2_CHIP_MEMBER = mimxrt101x +TUF2_CHIP_FAMILY = mimxrt10xx +TUF2_CHIP_MEMBER = mimxrt101x TUF2_CHIP_VARIANT = MIMXRT1011DAE5A +APP_START_ADDRESS ?= 0x6000C000 +BOARD_FLASH_BASE ?= 0x60000000 +UF2_FAMILY ?= 0x4FB2D5BD +TUSB_MCU ?= OPT_MCU_MIMXRT10XX diff --git a/hw/bsp/mimxrt1020_evk/board.mk b/hw/bsp/mimxrt1020_evk/board.mk index 8c783eb..de6ed61 100644 --- a/hw/bsp/mimxrt1020_evk/board.mk +++ b/hw/bsp/mimxrt1020_evk/board.mk @@ -1,3 +1,7 @@ -TUF2_CHIP_FAMILY = mimxrt10xx -TUF2_CHIP_MEMBER = mimxrt102x -TUF2_CHIP_VARIANT = MIMXRT1021DAG5A +TUF2_CHIP_FAMILY = mimxrt10xx +TUF2_CHIP_MEMBER = mimxrt102x +TUF2_CHIP_VARIANT = MIMXRT1021DAG5A +APP_START_ADDRESS ?= 0x6000C000 +BOARD_FLASH_BASE ?= 0x60000000 +UF2_FAMILY ?= 0x4FB2D5BD +TUSB_MCU ?= OPT_MCU_MIMXRT10XX diff --git a/hw/bsp/pergola/board.mk b/hw/bsp/pergola/board.mk index d2a87f3..3536109 100644 --- a/hw/bsp/pergola/board.mk +++ b/hw/bsp/pergola/board.mk @@ -1,3 +1,7 @@ TUF2_CHIP_FAMILY = mimxrt10xx TUF2_CHIP_MEMBER = mimxrt101x TUF2_CHIP_VARIANT = MIMXRT1011DAE5A +APP_START_ADDRESS ?= 0x6000C000 +BOARD_FLASH_BASE ?= 0x60000000 +UF2_FAMILY ?= 0x4FB2D5BD +TUSB_MCU ?= OPT_MCU_MIMXRT10XX diff --git a/hw/bsp/pergola_ram/board.mk b/hw/bsp/pergola_ram/board.mk index f3530b3..33f4c6d 100644 --- a/hw/bsp/pergola_ram/board.mk +++ b/hw/bsp/pergola_ram/board.mk @@ -2,10 +2,14 @@ TUF2_CHIP_FAMILY = mimxrt10xx TUF2_CHIP_MEMBER = mimxrt101x TUF2_CHIP_VARIANT = MIMXRT1011DAE5A +BOARD_FLASH_BASE ?= 0x60000000 +UF2_FAMILY ?= 0x4FB2D5BD +TUSB_MCU ?= OPT_MCU_MIMXRT10XX + VARIANT = ram APP_START_ADDRESS = 0x60000000 # Program directly to RAM using the imx USB ROM bootloader. # Set IMX_USB_LOADER to the path to your imx_usb_loader/imx_usb binary ram: $(BUILD)/$(BOARD)-firmware.bin - $(IMX_USB_LOADER) -c ./hw/bsp/pergola_ram + $(IMX_USB_LOADER) -c $(TOP)/hw/bsp/pergola_ram diff --git a/hw/bsp/versiboard2/board.mk b/hw/bsp/versiboard2/board.mk index 8c783eb..dc95b0f 100644 --- a/hw/bsp/versiboard2/board.mk +++ b/hw/bsp/versiboard2/board.mk @@ -1,3 +1,7 @@ TUF2_CHIP_FAMILY = mimxrt10xx TUF2_CHIP_MEMBER = mimxrt102x TUF2_CHIP_VARIANT = MIMXRT1021DAG5A +APP_START_ADDRESS ?= 0x6000C000 +BOARD_FLASH_BASE ?= 0x60000000 +UF2_FAMILY ?= 0x4FB2D5BD +TUSB_MCU ?= OPT_MCU_MIMXRT10XX diff --git a/hw/chip/ecp5/family.c b/hw/chip/ecp5/family.c index 9602c89..8d96744 100644 --- a/hw/chip/ecp5/family.c +++ b/hw/chip/ecp5/family.c @@ -61,6 +61,15 @@ static uint32_t _blink_interval; /* Addition of ticks #define MIN(a,b) ((a> 24) + | (((u) & 0x00ff0000) >> 8) + | (((u) & 0x0000ff00) << 8) + | (((u) & 0x000000ff) << 24)); +} + // Sectors are 4K and individual writable parts are 256 bytes maximum. We hold the // 4K until the sector changes, then write it back to flash if it's changed. We // explicitly don't write it back if it hasn't changed, in the (mistaken?) belief diff --git a/hw/chip/ecp5/family.mk b/hw/chip/ecp5/family.mk index c5c4589..d921795 100644 --- a/hw/chip/ecp5/family.mk +++ b/hw/chip/ecp5/family.mk @@ -1,143 +1,25 @@ -GIT_VERSION := $(shell git rev-parse --short HEAD) -OVERRIDE_TINYUSB_RULES = 1 -CROSS_COMPILE = riscv64-unknown-elf- -UF2_FAMILY = 0x35504345 +# This file contains elements that are specific to this family of chips. +# Elements that are generic should go into a higher level makefile. +# Elements which are specific to a chip should go into the lower level mk file. + -CDEFINES = -D__vexriscv__ -DNO_FLOAT -CDEFINES += -DGIT_VERSION=u\"$(GIT_VERSION)\" -DUF2_VERSION_BASE=\"$(GIT_VERSION)\" -std=gnu11 -CDEFINES += -DUINT16_MAX=65535 CFLAGS += \ - $(CDEFINES) \ - -march=rv32im -mabi=ilp32 \ - -nostdinc \ - -nostartfiles \ - -fno-common \ - -ffreestanding \ - -fomit-frame-pointer + -DUINT16_MAX=65535 \ + -D__vexriscv__ \ + -DNO_FLOAT \ + -march=rv32im \ + -mabi=ilp32 \ + -nostdlib -SRC_C += \ - hw/chip/$(TUF2_CHIP_FAMILY)/family.c \ - hw/chip/$(TUF2_CHIP_FAMILY)/spi.c +SRC_C += -INC += \ - -Isrc \ - -Ihw/bsp \ - -I$(LITEX_DIR)/include \ - -I$(LITEX_DIR)/include/base \ - -I$(SOC_DIR)/include \ - -I$(SOC_DIR)/include/generated \ - -I$(SOC_DIR)/include/hw \ - -Ihw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER) \ - -Ihw/bsp/$(BOARD) \ - -I$(BUILD) \ - -I$(TINYUSB_PATH)/src +INC += -I$(LITEX_DIR)/include \ + -I$(LITEX_DIR)/include/base \ + -I$(SOC_DIR)/include \ + -I$(SOC_DIR)/include/generated LIBS += -L$(SOC_DIR)/libbase -lbase-nofloat -# For TinyUSB port source - -CFG_TUSB_MCU = OPT_MCU_VALENTYUSB_EPTRI -CFLAGS += \ - -DBOARD_FLASH_BASE=0x20080000 \ - -DAPP_START_ADDRESS=0x20080000 \ - -DINDEX_URL=$(INDEX_URL) \ - -DVOLUME_LABEL=\"$(VOLUME_LABEL)\" \ - -DVENDOR_NAME=\"Orbcode\" \ - -DUF2_FAMILY=$(UF2_FAMILY) \ - -DCFG_TUSB_MCU=$(CFG_TUSB_MCU) - -SRC_C += \ - $(TINYUSB_PATH)/src/class/msc/msc_device.c \ - $(TINYUSB_PATH)/src/class/cdc/cdc_device.c \ - $(TINYUSB_PATH)/src/class/hid/hid_device.c \ - $(TINYUSB_PATH)/src/common/tusb_fifo.c \ - $(TINYUSB_PATH)/src/device/usbd_control.c \ - $(TINYUSB_PATH)/src/device/usbd.c \ - $(TINYUSB_PATH)/src/portable/valentyusb/eptri/dcd_eptri.c \ - $(TINYUSB_PATH)/src/tusb.c - -SRC_C += \ - $(addprefix $(MFTOP)/, $(wildcard src/*.c)) - -# 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 += $(addprefix $(BUILD)/obj/, $(SRC_C:.c=.o)) - -# Setup AS Flags starting with CFLAGS contents -ASFLAGS += $(CFLAGS) - -# Setup LD Flags starting including CFLAGS contents -LDFLAGS += $(CFLAGS) $(LD_FILE) - -# 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: - rm -rf $(BUILD) +# Configuration for TinyUSB +VENDOR = valentyusb +CHIP_FAMILY = eptri diff --git a/hw/chip/ecp5/vexriscv/default.mk b/hw/chip/ecp5/vexriscv/default.mk index a228d18..6bcad4b 100644 --- a/hw/chip/ecp5/vexriscv/default.mk +++ b/hw/chip/ecp5/vexriscv/default.mk @@ -1,6 +1,9 @@ LITEX_DIR ?= $(shell realpath ~/Develop/ulx3s/litex/litex/litex/soc/software/) SOC_DIR ?= $(shell realpath ~/Develop/ulx3s/litex/litex-boards/litex_boards/targets/soc_basesoc_colorlight_5a_75b/software) -SRC_S += $(MFTOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/crt0-vexriscv-rom.S +SRC_S += $(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/crt0-vexriscv-rom.S -LD_FILE = -T$(MFTOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/linker-rom.ld -L$(SOC_DIR)/include -L$(LITEX_DIR) +LD_FILE = -T$(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/linker-rom.ld -L$(SOC_DIR)/include -L$(LITEX_DIR) + + +CROSS_COMPILE ?= riscv64-unknown-elf- diff --git a/hw/chip/mimxrt10xx/family.mk b/hw/chip/mimxrt10xx/family.mk index 42a216a..bf8aaee 100644 --- a/hw/chip/mimxrt10xx/family.mk +++ b/hw/chip/mimxrt10xx/family.mk @@ -1,5 +1,6 @@ -APP_START_ADDRESS ?= 0x6000C000 -BOARD_FLASH_BASE ?= 0x60000000 +# This file contains elements that are specific to this family of chips. +# Elements that are generic should go into a higher level makefile. +# Elements which are specific to a chip should go into the lower level mk file. CFLAGS += \ -mthumb \ @@ -9,20 +10,11 @@ CFLAGS += \ -mfpu=fpv5-d16 \ -D__ARMVFP__=0 -D__ARMFPV5__=0 \ -D__START=main \ - -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX \ -D__STARTUP_CLEAR_BSS CFLAGS += -Wno-error=unused-parameter -CFLAGS += \ - -DAPP_START_ADDRESS=$(APP_START_ADDRESS) \ - -DBOARD_FLASH_BASE=$(BOARD_FLASH_BASE) \ - -DUF2_FAMILY=0x4FB2D5BD - SRC_C += \ - hw/chip/$(TUF2_CHIP_FAMILY)/family.c \ - hw/chip/$(TUF2_CHIP_FAMILY)/flexspi_nor_flash_ops.c \ - hw/chip/$(TUF2_CHIP_FAMILY)/flexspi_nor_config.c \ $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ $(MCU_DIR)/project_template/clock_config.c \ $(MCU_DIR)/drivers/fsl_clock.c \ @@ -33,21 +25,15 @@ SRC_C += \ $(MCU_DIR)/drivers/fsl_lpuart.c INC += \ - $(TINYUSB_PATH)/$(MCU_DIR) \ - $(TINYUSB_PATH)/$(MCU_DIR)/drivers \ - $(TINYUSB_PATH)/$(MCU_DIR)/project_template \ - $(TINYUSB_PATH)/$(MCU_DIR)/../../CMSIS/Include - -SRC_C += \ - $(addprefix $(CURRENT_PATH)/, $(wildcard src/*.c)) - + -I$(MCU_DIR) \ + -I$(MCU_DIR)/drivers \ + -I$(MCU_DIR)/project_template \ + -I$(MCU_DIR)/../../CMSIS/Include # For TinyUSB port source -VENDOR = nxp +VENDOR = nxp CHIP_FAMILY = transdimension -VARIANT ?= flash - ifeq ($(VARIANT), ram) CFLAGS += \ -DXIP_EXTERNAL_FLASH=0 \ diff --git a/hw/chip/mimxrt10xx/mimxrt101x/MIMXRT1011DAE5A.mk b/hw/chip/mimxrt10xx/mimxrt101x/MIMXRT1011DAE5A.mk index 4e383e8..c5f8bd9 100644 --- a/hw/chip/mimxrt10xx/mimxrt101x/MIMXRT1011DAE5A.mk +++ b/hw/chip/mimxrt10xx/mimxrt101x/MIMXRT1011DAE5A.mk @@ -1,15 +1,15 @@ -MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1011 +MCU_DIR = $(TINYUSB_PATH)/hw/mcu/nxp/sdk/devices/MIMXRT1011 CFLAGS += -DCPU_MIMXRT1011DAE5A -ifeq ($(VARIANT), ram) - LD_FILE = ../../hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/MIMXRT1011xxxxx_ram.ld -else - LD_FILE = ../../hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/MIMXRT1011xxxxx_flexspi_nor.ld -endif - SRC_C += $(MCU_DIR)/system_MIMXRT1011.c SRC_S += $(MCU_DIR)/gcc/startup_MIMXRT1011.S +ifeq ($(VARIANT), ram) + LD_FILE = -T$(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/MIMXRT1011xxxxx_ram.ld +else + LD_FILE = -T$(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/MIMXRT1011xxxxx_flexspi_nor.ld +endif + diff --git a/hw/chip/mimxrt10xx/mimxrt102x/MIMXRT1021DAG5A.mk b/hw/chip/mimxrt10xx/mimxrt102x/MIMXRT1021DAG5A.mk index b1366b7..69ab950 100644 --- a/hw/chip/mimxrt10xx/mimxrt102x/MIMXRT1021DAG5A.mk +++ b/hw/chip/mimxrt10xx/mimxrt102x/MIMXRT1021DAG5A.mk @@ -1,4 +1,8 @@ -MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1021 +# This file contains elements that are specific to _this_ type +# of chip only. Things that are generic to multiple chips +# go into higher level mk files. + +MCU_DIR = $(TINYUSB_PATH)/hw/mcu/nxp/sdk/devices/MIMXRT1021 CFLAGS += -DCPU_MIMXRT1021DAG5A @@ -6,5 +10,5 @@ SRC_C += $(MCU_DIR)/system_MIMXRT1021.c SRC_S += $(MCU_DIR)/gcc/startup_MIMXRT1021.S -LD_FILE = ../../hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/MIMXRT1021xxxxx_flexspi_nor.ld +LD_FILE = -T$(TOP)/hw/chip/$(TUF2_CHIP_FAMILY)/$(TUF2_CHIP_MEMBER)/MIMXRT1021xxxxx_flexspi_nor.ld diff --git a/src/hid.c b/src/hid.c index 530b2a4..6f5dd43 100644 --- a/src/hid.c +++ b/src/hid.c @@ -154,7 +154,7 @@ void send_hf2_response(HID_InBuffer *pkt, uint32_t size) { static void checksum_pages(HID_InBuffer *pkt, int start, int num) { for (int i = 0; i < num; ++i) { - uint8_t *data = (uint8_t *)start + i * BOARD_FLASH_PAGE_SIZE; + uint8_t *data = (uint8_t *)(long)(start + i * BOARD_FLASH_PAGE_SIZE); uint16_t crc = 0; for (int j = 0; j < BOARD_FLASH_PAGE_SIZE; ++j) { crc = add_crc(*data++, crc); @@ -215,13 +215,14 @@ void process_core(HID_InBuffer *pkt) { return; case HF2_CMD_RESET_INTO_APP: + board_reset_to_bootloader(false); board_flash_flush(); - reset_millis = board_millis() + 30; + reset_delay( RESET_DELAY_MS ); break; case HF2_CMD_RESET_INTO_BOOTLOADER: board_reset_to_bootloader(true); board_flash_flush(); - reset_millis = board_millis() + 30; + reset_delay( RESET_DELAY_MS ); break; case HF2_CMD_START_FLASH: // userspace app should reboot into bootloader on this command; we just ignore it diff --git a/src/main.c b/src/main.c index feaa5e1..6d1cc6d 100644 --- a/src/main.c +++ b/src/main.c @@ -33,9 +33,14 @@ #include "uf2_version.h" #include "hid.h" -uint32_t reset_millis = 0; +// Global timestamp +static uint32_t reset_millis; + void reset_task(void) + +/* Check to see if reset should be performed */ + { if (!reset_millis) return; @@ -44,6 +49,14 @@ void reset_task(void) board_reset(); } +void reset_delay( uint32_t reset_delay_ms ) + +/* Defer reset into the future */ + +{ + reset_millis = board_millis() + reset_delay_ms; +} + int main(void) { @@ -51,8 +64,6 @@ int main(void) board_init(); board_check_tinyuf2_start(); - //printf("TinyUF2 running (Version " UF2_VERSION_BASE ", Created " __TIME__ " on " __DATE__ "\r\n"); - tusb_init(); while (1) { diff --git a/src/msc.c b/src/msc.c index 61f8832..034abc1 100644 --- a/src/msc.c +++ b/src/msc.c @@ -30,8 +30,6 @@ #include "uf2.h" #include "tusb.h" -#define RESET_MILLIS (1000) - #if CFG_TUD_MSC #define SERIAL0 (*(uint32_t *)0x0080A00C) @@ -300,13 +298,13 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* if (write_state.numWritten >= write_state.numBlocks) { board_flash_flush(); - - reset_millis = board_millis() + RESET_MILLIS; + + reset_delay( RESET_DELAY_MS ); } } } else { // reset after last block received - reset_millis = board_millis() + RESET_MILLIS; + reset_delay( RESET_DELAY_MS ); } } diff --git a/src/uf2.h b/src/uf2.h index ba82f4c..565862c 100644 --- a/src/uf2.h +++ b/src/uf2.h @@ -70,13 +70,15 @@ static inline bool is_uf2_block(void *data) #define MAX_BLOCKS (BOARD_FLASH_SIZE / UF2_PAYLOAD_SIZE + 100) +// Delay in MS after last block before reset +#define RESET_DELAY_MS (100) + typedef struct { uint32_t numBlocks; uint32_t numWritten; uint8_t writtenMask[MAX_BLOCKS / 8 + 1]; } WriteState; -extern uint32_t reset_millis; // Configuration for HF2 HID support #ifndef HF2_USE_HID @@ -91,4 +93,7 @@ extern uint32_t reset_millis; #define HF2_USE_HID_EXT 0 #endif +// Reset the board this many ms into the future +void reset_delay( uint32_t reset_delay_ms ); + #endif // UF2_H_ From da7884734c217709b5c7f8d10e023080e060eabb Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Thu, 7 May 2020 23:46:04 +0100 Subject: [PATCH 09/10] Tidy and update of project cross-reference --- hw/chip/ecp5/family.c | 226 +++++++++++++++++++------------ hw/chip/ecp5/vexriscv/default.mk | 1 + 2 files changed, 137 insertions(+), 90 deletions(-) diff --git a/hw/chip/ecp5/family.c b/hw/chip/ecp5/family.c index 8d96744..b7203a2 100644 --- a/hw/chip/ecp5/family.c +++ b/hw/chip/ecp5/family.c @@ -33,7 +33,7 @@ #include "uart.h" #include "uf2.h" -//#define FAMILY_DEBUG 1 +/* #define FAMILY_DEBUG 1 */ #ifdef FAMILY_DEBUG #define DBG(...) printf(__VA_ARGS__) @@ -43,25 +43,27 @@ enum { IO_LED, IO_HWRESET, IO_RED, IO_GREEN, IO_BLUE, IO_BUTTON } iopins; -// Indicator of if next reboot is to be to bootloader or app +enum { COLOUR_OFF, COLOUR_RED, COLOUR_GREEN, COLOUR_YELLOW, COLOUR_BLUE, COLOUR_MAGENTA, COLOUR_CYAN, COLOUR_WHITE } colours; + +/* Indicator of if next reboot is to be to bootloader or app */ static bool rebootToBootloader = false; -// Overall time maintenance +/* Overall time maintenance */ static volatile uint32_t _system_ticks = 0; -// Flag indicating boot mode (set up in the linker file +/* Flag indicating boot mode (set up in the linker file */ extern uint32_t _bootloader_dbl_tap; -// Led flashing support +/* Led flashing support */ static uint32_t _next_blink_event; /* Time in ticks for next blink crossover */ static uint32_t _blink_interval; /* Addition of ticks for next event */ -// Indicator that no Sector is currently cached +/* Indicator that no Sector is currently cached */ #define NO_CACHE 0xffffffff #define MIN(a,b) ((a> 24) @@ -70,11 +72,12 @@ int32_t __bswapsi2 (int32_t u) | (((u) & 0x000000ff) << 24)); } -// Sectors are 4K and individual writable parts are 256 bytes maximum. We hold the -// 4K until the sector changes, then write it back to flash if it's changed. We -// explicitly don't write it back if it hasn't changed, in the (mistaken?) belief -// that most sectors don't change from flash to flash...which is completely dependent -// on their type of content. +/* Sectors are 4K and individual writable parts are 256 bytes maximum. We hold the + * 4K until the sector changes, then write it back to flash if it's changed. We + * explicitly don't write it back if it hasn't changed, in the (mistaken?) belief + * that most sectors don't change from flash to flash...which is completely dependent + * on their type of content. + */ #define SECTOR_SIZE 0x1000 /* 4K Sector */ #define SECTOR_SIZE_MASK (SECTOR_SIZE-1) /* Mask for in-sector offset */ @@ -94,14 +97,86 @@ static bool _flash_sector_dirty = false; static uint32_t _flash_sector_addr = NO_CACHE; static uint8_t _flash_cache[SECTOR_SIZE] __attribute__((aligned(4))); +/* Record of set bits */ +static uint32_t gpio_stat; + +/* --------------------------------------------------------------------------------------------- */ +/* --------------------------------------------------------------------------------------------- */ +/* + * Board handling code + */ +/* --------------------------------------------------------------------------------------------- */ +/* --------------------------------------------------------------------------------------------- */ +static void _gpio_wr(uint32_t clrBits, uint32_t setBits ) + +/* Cleanly write to gpio */ + +{ + irq_setie(0); + gpio_stat = (gpio_stat&(~clrBits))|setBits; + gpio_out_write(gpio_stat); + irq_setie(1); +} +/* --------------------------------------------------------------------------------------------- */ +static void _led_write(bool state) + +/* Control the primary board LED */ + +{ + _gpio_wr((1< Date: Fri, 8 May 2020 01:09:41 +0100 Subject: [PATCH 10/10] Fix silly isr issue --- hw/chip/ecp5/family.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/chip/ecp5/family.c b/hw/chip/ecp5/family.c index b7203a2..969cb24 100644 --- a/hw/chip/ecp5/family.c +++ b/hw/chip/ecp5/family.c @@ -112,10 +112,11 @@ static void _gpio_wr(uint32_t clrBits, uint32_t setBits ) /* Cleanly write to gpio */ { + uint32_t is = irq_getie(); irq_setie(0); gpio_stat = (gpio_stat&(~clrBits))|setBits; gpio_out_write(gpio_stat); - irq_setie(1); + irq_setie(is); } /* --------------------------------------------------------------------------------------------- */ static void _led_write(bool state)