PSOC6.py: do not require metadata during HEX merging

Replace hard-coded numeric offsets of PSoC 6 hex file sections
with sensible constants.
Do not attempt to update the checksum and metadata contents
if the sections are not found in the original HEX file.
pull/9646/head
Volodymyr Medvid 2019-01-22 15:40:22 -08:00 committed by adbridge
parent 3fa2fb21cc
commit ecc9aa7bf2
1 changed files with 40 additions and 13 deletions

View File

@ -20,44 +20,71 @@ import subprocess
import errno import errno
from array import array from array import array
from struct import (pack, unpack) from struct import (pack, unpack)
from distutils.spawn import find_executable
from shutil import copyfile from shutil import copyfile
from intelhex import IntelHex from intelhex import IntelHex
from intelhex.compat import asbytes from intelhex.compat import asbytes
from ..config import ConfigException from ..config import ConfigException
# The size of the program data in Cypress HEX files is limited to 0x80000000
# Higher addresses contain additional metadata (chip protection, eFuse data, etc..)
CY_PROGRAM_SIZE = 0x80000000
# The starting address of the program data checksum section
CY_CHECKSUM_ADDR = 0x90300000
# The starting address of the .cymeta section (12 bytes)
# Additional metadata include silicon revision, Silicon/JTAG ID, etc.
CY_META_ADDR = 0x90500000
# The address of the silicon ID (4 bytes)
CY_META_SILICON_ID_ADDR = 0x90500002
# The address of the metadata checksum (4 bytes)
CY_META_CHECKSUM_ADDR = 0x90500008
# Patch Cypress hex file: # Patch Cypress hex file:
# - update checksum # - update checksum
# - update metadata # - update metadata
# - align regions to page (256 bytes) boundary # - align regions to page (256 bytes) boundary
def patch(message_func, ihex, hexf, align=256): def patch(message_func, ihex, hexf, align=256):
#calculate checksum update_checksum = False
update_metadata = False
# calculate checksum of the program section, detect metadata
checksum = 0 checksum = 0
for start, end in ihex.segments(): for start, end in ihex.segments():
if start >= 0x090000000: if start == CY_CHECKSUM_ADDR:
# checksum section found in the original hex
update_checksum = True
if start == CY_META_ADDR:
# metadata section found in the original hex
update_metadata = True
if start >= CY_PROGRAM_SIZE:
continue continue
segment = ihex.tobinarray(start, end) segment = ihex.tobinarray(start, end)
checksum += sum(segment) checksum += sum(segment)
# only update checksum if it was found in the original hex
if update_checksum:
lowchecksum = checksum & 0x0FFFF lowchecksum = checksum & 0x0FFFF
message_func("Calculated checksum for %s is 0x%04x" % (hexf, lowchecksum)) message_func("Calculated checksum for %s is 0x%04x" % (hexf, lowchecksum))
# update checksum
checksum_str = pack('>H', lowchecksum) checksum_str = pack('>H', lowchecksum)
ihex.frombytes(array('B', checksum_str), offset=0x90300000) ihex.frombytes(array('B', checksum_str), offset=CY_CHECKSUM_ADDR)
# update metadata # only update metadata if it was found in the original hex
signature = unpack('>L', ihex.tobinstr(start=0x90500002, size=4))[0] if update_metadata:
signature = unpack('>L', ihex.tobinstr(start=CY_META_SILICON_ID_ADDR, size=4))[0]
sigcheck = pack('>L', (checksum + signature) & 0x0FFFF) sigcheck = pack('>L', (checksum + signature) & 0x0FFFF)
ihex.frombytes(array('B',sigcheck), offset=0x90500008) ihex.frombytes(array('B',sigcheck), offset=CY_META_CHECKSUM_ADDR)
# align flash segments # align flash segments
align_mask = align - 1 align_mask = align - 1
alignments = IntelHex() alignments = IntelHex()
for start, end in ihex.segments(): for start, end in ihex.segments():
if start >= 0x090000000: if start >= CY_PROGRAM_SIZE:
continue continue
aligned_start = start & ~align_mask aligned_start = start & ~align_mask
if start != aligned_start: if start != aligned_start: