|
20 | 20 | import errno
|
21 | 21 | from array import array
|
22 | 22 | from struct import (pack, unpack)
|
23 |
| -from distutils.spawn import find_executable |
24 | 23 | from shutil import copyfile
|
25 | 24 | from intelhex import IntelHex
|
26 | 25 | from intelhex.compat import asbytes
|
27 | 26 |
|
28 | 27 | from ..config import ConfigException
|
29 | 28 |
|
| 29 | +# The size of the program data in Cypress HEX files is limited to 0x80000000 |
| 30 | +# Higher addresses contain additional metadata (chip protection, eFuse data, etc..) |
| 31 | +CY_PROGRAM_SIZE = 0x80000000 |
| 32 | + |
| 33 | +# The starting address of the program data checksum section |
| 34 | +CY_CHECKSUM_ADDR = 0x90300000 |
| 35 | + |
| 36 | +# The starting address of the .cymeta section (12 bytes) |
| 37 | +# Additional metadata include silicon revision, Silicon/JTAG ID, etc. |
| 38 | +CY_META_ADDR = 0x90500000 |
| 39 | + |
| 40 | +# The address of the silicon ID (4 bytes) |
| 41 | +CY_META_SILICON_ID_ADDR = 0x90500002 |
| 42 | + |
| 43 | +# The address of the metadata checksum (4 bytes) |
| 44 | +CY_META_CHECKSUM_ADDR = 0x90500008 |
| 45 | + |
30 | 46 |
|
31 | 47 | # Patch Cypress hex file:
|
32 | 48 | # - update checksum
|
33 | 49 | # - update metadata
|
34 | 50 | # - align regions to page (256 bytes) boundary
|
35 | 51 | def patch(message_func, ihex, hexf, align=256):
|
36 |
| - #calculate checksum |
| 52 | + update_checksum = False |
| 53 | + update_metadata = False |
| 54 | + |
| 55 | + # calculate checksum of the program section, detect metadata |
37 | 56 | checksum = 0
|
38 | 57 | for start, end in ihex.segments():
|
39 |
| - if start >= 0x090000000: |
| 58 | + if start == CY_CHECKSUM_ADDR: |
| 59 | + # checksum section found in the original hex |
| 60 | + update_checksum = True |
| 61 | + if start == CY_META_ADDR: |
| 62 | + # metadata section found in the original hex |
| 63 | + update_metadata = True |
| 64 | + if start >= CY_PROGRAM_SIZE: |
40 | 65 | continue
|
41 | 66 | segment = ihex.tobinarray(start, end)
|
42 | 67 | checksum += sum(segment)
|
43 | 68 |
|
44 |
| - lowchecksum = checksum & 0x0FFFF |
45 |
| - message_func("Calculated checksum for %s is 0x%04x" % (hexf, lowchecksum)) |
| 69 | + # only update checksum if it was found in the original hex |
| 70 | + if update_checksum: |
| 71 | + lowchecksum = checksum & 0x0FFFF |
| 72 | + message_func("Calculated checksum for %s is 0x%04x" % (hexf, lowchecksum)) |
46 | 73 |
|
47 |
| - # update checksum |
48 |
| - checksum_str = pack('>H', lowchecksum) |
49 |
| - ihex.frombytes(array('B', checksum_str), offset=0x90300000) |
| 74 | + checksum_str = pack('>H', lowchecksum) |
| 75 | + ihex.frombytes(array('B', checksum_str), offset=CY_CHECKSUM_ADDR) |
50 | 76 |
|
51 |
| - # update metadata |
52 |
| - signature = unpack('>L', ihex.tobinstr(start=0x90500002, size=4))[0] |
53 |
| - sigcheck = pack('>L', (checksum + signature) & 0x0FFFF) |
54 |
| - ihex.frombytes(array('B',sigcheck), offset=0x90500008) |
| 77 | + # only update metadata if it was found in the original hex |
| 78 | + if update_metadata: |
| 79 | + signature = unpack('>L', ihex.tobinstr(start=CY_META_SILICON_ID_ADDR, size=4))[0] |
| 80 | + sigcheck = pack('>L', (checksum + signature) & 0x0FFFF) |
| 81 | + ihex.frombytes(array('B',sigcheck), offset=CY_META_CHECKSUM_ADDR) |
55 | 82 |
|
56 | 83 | # align flash segments
|
57 | 84 | align_mask = align - 1
|
58 | 85 | alignments = IntelHex()
|
59 | 86 | for start, end in ihex.segments():
|
60 |
| - if start >= 0x090000000: |
| 87 | + if start >= CY_PROGRAM_SIZE: |
61 | 88 | continue
|
62 | 89 | aligned_start = start & ~align_mask
|
63 | 90 | if start != aligned_start:
|
|
0 commit comments