Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

add --join option #81

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 68 additions & 30 deletions utils/uf2conv.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,52 @@ def is_hex(buf):
return True
return False

def uf2_blocks(buf):
numblocks = len(buf) // 512
outp = []
for blockno in range(numblocks):
ptr = blockno * 512
block = buf[ptr:ptr + 512]
hd = struct.unpack(b"<IIIIIIII", block[0:32])
if hd[0] != UF2_MAGIC_START0 or hd[1] != UF2_MAGIC_START1:
print("Skipping block at " + ptr + "; bad magic")
continue
outp.append(block)
return outp

def concat_uf2(buf):
blocks = uf2_blocks(buf)
numblocks = {}
for block in blocks:
hd = struct.unpack(b"<IIIIIIII", block[0:32])
fam = hd[7]
if fam not in numblocks: numblocks[fam] = 0
numblocks[fam] += 1

blockno = {}
outp = []
for block in blocks:
hd = struct.unpack(b"<IIIIIIII", block[0:32])
fam = hd[7]
if fam not in blockno: blockno[fam] = 0
newblock = block[0:5*4] + struct.pack(b"<II", blockno[fam], numblocks[fam]) + block[7*4:]
outp.append(newblock)
blockno[fam] += 1
return b"".join(outp)

def convert_from_uf2(buf):
global appstartaddr
global familyid
numblocks = len(buf) // 512
curraddr = None
currfamilyid = None
families_found = {}
prev_flag = None
all_flags_same = True
outp = []
for blockno in range(numblocks):
ptr = blockno * 512
block = buf[ptr:ptr + 512]
ptr = 0
for block in uf2_blocks(buf):
ptr += 512
hd = struct.unpack(b"<IIIIIIII", block[0:32])
if hd[0] != UF2_MAGIC_START0 or hd[1] != UF2_MAGIC_START1:
print("Skipping block at " + ptr + "; bad magic")
continue
if hd[2] & 1:
# NO-flash flag set; skip block
continue
Expand Down Expand Up @@ -87,24 +116,25 @@ def convert_from_uf2(buf):
prev_flag = hd[2]
if prev_flag != hd[2]:
all_flags_same = False
if blockno == (numblocks - 1):
print("--- UF2 File Header Info ---")
families = load_families()
for family_hex in families_found.keys():
family_short_name = ""
for name, value in families.items():
if value == family_hex:
family_short_name = name
print("Family ID is {:s}, hex value is 0x{:08x}".format(family_short_name,family_hex))
print("Target Address is 0x{:08x}".format(families_found[family_hex]))
if all_flags_same:
print("All block flag values consistent, 0x{:04x}".format(hd[2]))
else:
print("Flags were not all the same")
print("----------------------------")
if len(families_found) > 1 and familyid == 0x0:
outp = []
appstartaddr = 0x0

print("--- UF2 File Header Info ---")
families = load_families()
for family_hex in families_found.keys():
family_short_name = ""
for name, value in families.items():
if value == family_hex:
family_short_name = name
print("Family ID is {:s}, hex value is 0x{:08x}".format(family_short_name,family_hex))
print("Target Address is 0x{:08x}".format(families_found[family_hex]))
if all_flags_same:
print("All block flag values consistent, 0x{:04x}".format(hd[2]))
else:
print("Flags were not all the same")
print("----------------------------")
if len(families_found) > 1 and familyid == 0x0:
outp = []
appstartaddr = 0x0

return b"".join(outp)

def convert_to_carray(file_content):
Expand Down Expand Up @@ -273,7 +303,7 @@ def error(msg):
print(msg, file=sys.stderr)
sys.exit(1)
parser = argparse.ArgumentParser(description='Convert to UF2 or flash directly.')
parser.add_argument('input', metavar='INPUT', type=str, nargs='?',
parser.add_argument('input', metavar='INPUT', type=str, nargs='*',
help='input file (HEX, BIN or UF2)')
parser.add_argument('-b', '--base', dest='base', type=str,
default="0x2000",
Expand All @@ -297,6 +327,8 @@ def error(msg):
help='convert binary file to a C array, not UF2')
parser.add_argument('-i', '--info', action='store_true',
help='display header information from UF2, do not convert')
parser.add_argument('-j', '--join', action='store_true',
help='concatenate multiple UF2 files into one')
args = parser.parse_args()
appstartaddr = int(args.base, 0)

Expand All @@ -313,14 +345,20 @@ def error(msg):
if args.list:
list_drives()
else:
if not args.input:
error("Need input file")
with open(args.input, mode='rb') as f:
inpbuf = f.read()
if len(args.input) == 0:
error("Need input file(s)")
inpbuf = b""
for fn in args.input:
with open(fn, mode='rb') as f:
inpbuf += f.read()
from_uf2 = is_uf2(inpbuf)
ext = "uf2"
if args.deploy:
outbuf = inpbuf
elif args.join:
if not from_uf2:
error("--join requires UF2 files")
outbuf = concat_uf2(inpbuf)
elif from_uf2 and not args.info:
outbuf = convert_from_uf2(inpbuf)
ext = "bin"
Expand Down