diff --git a/hw/bsp/fomu/board.mk b/hw/bsp/fomu/board.mk index ffd0158c9..70fb66975 100644 --- a/hw/bsp/fomu/board.mk +++ b/hw/bsp/fomu/board.mk @@ -14,7 +14,7 @@ BSP_DIR = hw/bsp/fomu # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/fomu.ld -SRC_S += hw/bsp/fomu/crt0-vexriscv.S +SRC_S += hw/bsp/$(BOARD)/crt0-vexriscv.S INC += \ $(TOP)/$(BSP_DIR)/include @@ -27,5 +27,9 @@ CHIP_FAMILY = eptri FREERTOS_PORT = RISC-V # flash using dfu-util +$(BUILD)/$(BOARD)-firmware.dfu: $(BUILD)/$(BOARD)-firmware.bin + @echo "Create $@" + python $(TOP)/hw/bsp/$(BOARD)/dfu.py -b $^ -D 0x1209:0x5bf0 $@ + flash: $(BUILD)/$(BOARD)-firmware.dfu dfu-util -D $^ diff --git a/hw/bsp/fomu/dfu.py b/hw/bsp/fomu/dfu.py new file mode 100644 index 000000000..32479350c --- /dev/null +++ b/hw/bsp/fomu/dfu.py @@ -0,0 +1,95 @@ +#!/usr/bin/python + +# Written by Antonio Galea - 2010/11/18 +# Updated for DFU 1.1 by Sean Cross - 2020/03/31 +# Distributed under Gnu LGPL 3.0 +# see http://www.gnu.org/licenses/lgpl-3.0.txt + +import sys,struct,zlib,os +from optparse import OptionParser + +DEFAULT_DEVICE="0x1209:0x5bf0" + +def named(tuple,names): + return dict(zip(names.split(),tuple)) +def consume(fmt,data,names): + n = struct.calcsize(fmt) + return named(struct.unpack(fmt,data[:n]),names),data[n:] +def cstring(string): + return string.split('\0',1)[0] +def compute_crc(data): + return 0xFFFFFFFF & -zlib.crc32(data) -1 + +def parse(file,dump_images=False): + print ('File: "%s"' % file) + data = open(file,'rb').read() + crc = compute_crc(data[:-4]) + data = data[len(data)-16:] + suffix = named(struct.unpack('<4H3sBI',data[:16]),'device product vendor dfu ufd len crc') + print ('usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix) + if crc != suffix['crc']: + print ("CRC ERROR: computed crc32 is 0x%08x" % crc) + data = data[16:] + if data: + print ("PARSE ERROR") + +def build(file,data,device=DEFAULT_DEVICE): + # Parse the VID and PID from the `device` argument + v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1)) + + # Generate the DFU suffix, consisting of these fields: + # Field name | Length | Description + # ================+=========+================================ + # bcdDevice | 2 | The release number of this firmware (0xffff - don't care) + # idProduct | 2 | PID of this device + # idVendor | 2 | VID of this device + # bcdDFU | 2 | Version of this DFU spec (0x01 0x00) + # ucDfuSignature | 3 | The characters 'DFU', printed in reverse order + # bLength | 1 | The length of this suffix (16 bytes) + # dwCRC | 4 | A CRC32 of the data, including this suffix + data += struct.pack('<4H3sB',0xffff,d,v,0x0100,b'UFD',16) + crc = compute_crc(data) + # Append the CRC32 of the entire block + data += struct.pack('