Skip to content

Commit 743127e

Browse files
authored
Merge branch 'master' into program-full-sectors
2 parents 0b573f3 + 293c122 commit 743127e

File tree

3 files changed

+69
-13
lines changed

3 files changed

+69
-13
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ Optionally, an additional `desc.tgz` file may be included in the SPI flash itsel
5050
"bver": "2.0.0",
5151
"update": "https://tinyfpga.com/update/tinyfpga-bx",
5252
"addrmap": {
53-
"bootloader": "0x00000+131542",
54-
"userimage": "0x30000+131542",
55-
"userdata": "0x50000+710000",
56-
"desc.tgz": "0xFC000+16000"
53+
"bootloader": "0x00000-0x2FFFF",
54+
"userimage": "0x30000-0x4FFFF",
55+
"userdata": "0x50000-0xFBFFF",
56+
"desc.tgz": "0xFC000-0xFFFFF"
5757
}
5858
}
5959
```

programmer/tinyprog/__init__.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import platform
33
import re
44
import struct
5+
import time
56

67
from functools import reduce
78
from pkg_resources import get_distribution, DistributionNotFound
@@ -504,6 +505,19 @@ def program_sectors(self, addr, data):
504505
for offset in range(0, len(data), sector_size):
505506
current_addr = addr + offset
506507
current_write_data = data[offset:offset + sector_size]
508+
509+
# Determine if we need to write this sector at all
510+
current_flash_data = self.read(
511+
current_addr,
512+
sector_size,
513+
disable_progress=True,
514+
max_length=sector_size)
515+
516+
if current_flash_data == current_write_data:
517+
# skip this sector since it matches
518+
pbar.update(sector_size)
519+
continue
520+
507521
self.erase(current_addr, sector_size, disable_progress=True)
508522

509523
minor_sector_size = 256
@@ -519,7 +533,6 @@ def program_sectors(self, addr, data):
519533
# Due to the way SPI flash works, writing 0xff *without
520534
# erasing* should be a no-opt, because 0xff is what you
521535
# get after erasing, and you can only write 0 bits.
522-
#
523536
current_minor_addr = current_addr + minor_offset
524537

525538
if (((current_minor_addr % minor_sector_size) == 0) and
@@ -533,11 +546,15 @@ def program_sectors(self, addr, data):
533546
minor_write_data.extend(padding)
534547
assert(len(minor_write_data) == minor_sector_size)
535548

536-
self.write(
537-
current_addr + minor_offset,
538-
minor_write_data,
539-
disable_progress=True,
540-
max_length=256)
549+
# if the minor data is all 0xFF then it will match
550+
# the erased bits and doesn't need to be re-sent
551+
if minor_write_data != chr(0xFF) * len(minor_write_data):
552+
self.write(
553+
current_addr + minor_offset,
554+
minor_write_data,
555+
disable_progress=True,
556+
max_length=256)
557+
541558
minor_read_data = self.read(
542559
current_addr + minor_offset,
543560
len(minor_write_data),
@@ -600,3 +617,12 @@ def program_bitstream_fast(self, addr, bitstream):
600617
self.wake()
601618
self.progress(str(len(bitstream)) + " bytes to program")
602619
return self.program_fast(addr, bitstream)
620+
621+
def program_security_page(self, page, data):
622+
self.progress("Waking up SPI flash")
623+
self.wake()
624+
self.progress("Erasing security page " + str(page))
625+
self.erase_security_register_page(page)
626+
self.progress(str(len(data)) + " bytes to program")
627+
return self.program_security_register_page(page, data)
628+

programmer/tinyprog/__main__.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,10 @@ def parse_int(str_value):
266266
"--meta",
267267
action="store_true",
268268
help="dump out the metadata for all connected boards in JSON")
269+
parser.add_argument(
270+
"--security",
271+
type=str,
272+
help="update the security page in the flash at address addr")
269273
parser.add_argument(
270274
"--update-bootloader",
271275
action="store_true",
@@ -372,6 +376,7 @@ def parse_int(str_value):
372376
# program the flash memory
373377
if (args.program is not None) or (
374378
args.program_userdata is not None) or (
379+
args.security is not None) or (
375380
args.program_image is not None):
376381
boot_fpga = False
377382

@@ -381,6 +386,7 @@ def progress(info):
381386

382387
with active_port:
383388
fpga = TinyProg(active_port, progress)
389+
force = False
384390

385391
if args.program is not None:
386392
print(" Programming %s with %s" % (
@@ -390,6 +396,7 @@ def progress(info):
390396

391397
if args.addr is not None:
392398
addr = parse_int(args.addr)
399+
force = True
393400
else:
394401
addr = fpga.meta.userimage_addr_range()[0]
395402

@@ -400,7 +407,7 @@ def progress(info):
400407
print(" Bootloader not active")
401408
sys.exit(1)
402409

403-
if check_if_overwrite_bootloader(
410+
if force or check_if_overwrite_bootloader(
404411
addr, len(bitstream),
405412
fpga.meta.userimage_addr_range()):
406413
boot_fpga = True
@@ -417,6 +424,7 @@ def progress(info):
417424

418425
if args.addr is not None:
419426
addr = parse_int(args.addr)
427+
force = True
420428
else:
421429
addr = fpga.meta.userdata_addr_range()[0]
422430

@@ -427,7 +435,7 @@ def progress(info):
427435
print(" Bootloader not active")
428436
sys.exit(1)
429437

430-
if check_if_overwrite_bootloader(
438+
if force or check_if_overwrite_bootloader(
431439
addr, len(bitstream),
432440
fpga.meta.userdata_addr_range()):
433441
boot_fpga = True
@@ -444,6 +452,7 @@ def progress(info):
444452

445453
if args.addr is not None:
446454
addr = parse_int(args.addr)
455+
force = True
447456
else:
448457
addr = fpga.meta.userimage_addr_range()[0]
449458

@@ -454,7 +463,7 @@ def progress(info):
454463
print(" Bootloader not active")
455464
sys.exit(1)
456465

457-
if check_if_overwrite_bootloader(
466+
if force or check_if_overwrite_bootloader(
458467
addr, len(bitstream),
459468
(fpga.meta.userimage_addr_range()[0],
460469
fpga.meta.userdata_addr_range()[1])):
@@ -463,6 +472,27 @@ def progress(info):
463472
if not fpga.program_bitstream(addr, bitstream):
464473
sys.exit(1)
465474

475+
if args.security is not None:
476+
print(" Programming %s security page with %s" % (
477+
active_port, args.security))
478+
479+
data = open(args.security, 'r').read()
480+
481+
if args.addr is not None:
482+
addr = parse_int(args.addr)
483+
else:
484+
addr = 1
485+
486+
if addr < 0:
487+
print(" Negative write addr: {}".format(addr))
488+
sys.exit(1)
489+
if not fpga.is_bootloader_active():
490+
print(" Bootloader not active")
491+
sys.exit(1)
492+
493+
if not fpga.program_security_page(addr, data):
494+
sys.exit(1)
495+
466496
if boot_fpga:
467497
fpga.boot()
468498
print("")

0 commit comments

Comments
 (0)