Skip to content

Commit 53b2056

Browse files
authored
Merge pull request #362 from Qyriad/features/chipcon-support-ihex
host: chipcon command: support reading from Intel hex
2 parents bb2ed2d + b00c7d2 commit 53b2056

File tree

3 files changed

+31
-12
lines changed

3 files changed

+31
-12
lines changed

host/greatfet/commands/greatfet_chipcon.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
from __future__ import print_function
66

7-
import ast
7+
import io
88
import argparse
99

10+
from intelhex import IntelHex
11+
1012
from greatfet.utils import GreatFETArgumentParser, log_silent, log_verbose
1113

1214

@@ -42,6 +44,8 @@ def main():
4244
parser.add_argument('-E', '--mass-erase', action='store_true', help="Erase the entire flash memory")
4345
parser.add_argument('-w', '--write', metavar='<filename>', type=argparse.FileType('rb'),
4446
help="Write data from file")
47+
parser.add_argument("--bin", action='store_true', default=False,
48+
help="Disable Intel hex detection and flash as-is.")
4549

4650
args = parser.parse_args()
4751

@@ -65,7 +69,7 @@ def main():
6569
mass_erase_flash(chipcon, log_function)
6670

6771
if args.write:
68-
program_flash(chipcon, args.write, args.address, args.erase, args.verify, log_function)
72+
program_flash(chipcon, args.write, args.address, args.erase, args.verify, args.bin, log_function)
6973

7074

7175
def chip_id(programmer):
@@ -83,9 +87,22 @@ def mass_erase_flash(programmer, log_function):
8387
programmer.mass_erase_flash()
8488

8589

86-
def program_flash(programmer, in_file, start_address, erase, verify, log_function):
87-
log_function("Writing data to flash...")
90+
def program_flash(programmer, in_file, start_address, erase, verify, force_bin, log_function):
8891
image_array = in_file.read()
92+
93+
if image_array.startswith(b':') and not force_bin:
94+
95+
print("File type detected as Intel Hex -- converting to binary before flashing...")
96+
print("To force flashing as-is, pass --bin.")
97+
98+
# HACK: The IntelHex class expects a filename or file-like object, but...we've already read the file.
99+
# So let's wrap it in a file-like object. Normally, we'd use io.BytesIO,
100+
# except IntelHex wants strings, not bytes objects. So...
101+
intel_hex = IntelHex(io.StringIO(image_array.decode('ascii')))
102+
image_array = intel_hex.tobinstr()
103+
104+
105+
log_function("Writing data to flash...")
89106
programmer.program_flash(image_array, erase=erase, verify=verify, start=start_address)
90107

91108

host/greatfet/programmers/chipcon.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def write_flash_page(self, linear_address, input_data, erase_page=True):
217217
# should only be included in the routine when the erase_page_1 = 1.
218218
# The pseudo-code does not refer to this parameter!
219219
routine_part1 = [
220-
0x75, 0xAD, ((linear_address >> 8) // FLASH_WORD_SIZE) & 0x7E, # MOV FADDRH, #imm
220+
0x75, 0xAD, ((linear_address >> 8) // FLASH_WORD_SIZE) & 0x7E, # MOV FADDRH, #imm
221221
0x75, 0xAC, 0x00, # MOV FADDRL, #00
222222
]
223223
routine_erase = [
@@ -253,7 +253,7 @@ def write_flash_page(self, linear_address, input_data, erase_page=True):
253253
else:
254254
routine = routine_part1 + routine_part2
255255

256-
self.write_xdata_memory(0xF000, input_data)
256+
self.write_xdata_memory(0xF000, input_data[:FLASH_PAGE_SIZE])
257257
self.write_xdata_memory(0xF000 + FLASH_PAGE_SIZE, routine)
258258
self.run_instruction(0x75, 0xC7, 0x51) # MOV MEMCRT, (bank * 16) + 1
259259
self.set_pc(0xF000 + FLASH_PAGE_SIZE)
@@ -276,12 +276,12 @@ def read_flash_page(self, linear_address):
276276
return self.read_code_memory(linear_address & 0xFFFF, FLASH_PAGE_SIZE)
277277

278278

279-
def read_flash(self, *, start_address=0, length=0):
279+
def read_flash(self, *, start_address=0, length):
280280
""" Read a chunk of flash memory.
281281
282282
Parameters:
283-
length -- The length (in bytes) of the amount of flash memory that you want to read.
284283
start_address -- The address in flash memory you want to begin reading data from.
284+
length -- The length (in bytes) of the amount of flash memory that you want to read.
285285
"""
286286
flash_data = bytearray()
287287
for i in range(start_address, length, FLASH_PAGE_SIZE):
@@ -308,23 +308,24 @@ def program_flash(self, image_array, *, erase=True, verify=True, start=0):
308308
Parameters:
309309
image_array -- The data to be written to the flash.
310310
erase -- Used to specify whether or not the flash needs to be erased before programming.
311-
verify - Used to specify whether or not the data was flashed correctly.
311+
verify -- Used to specify whether or not the data was flashed correctly.
312312
start -- The address to begin writing data to the flash.
313313
"""
314314

315315
if erase:
316316
self.mass_erase_flash()
317317

318318
data = bytearray(image_array)
319-
address = 0
319+
address = start
320+
320321
while data:
321322
time.sleep(0.1)
322323
# Grab a page...
323324
page = data[:FLASH_PAGE_SIZE]
324325
del data[:FLASH_PAGE_SIZE]
325326

326327
# ... and write it to flash.
327-
self.write_flash_page(address, page, False)
328+
self.write_flash_page(address - start, page, False)
328329
address += FLASH_PAGE_SIZE
329330

330331
time.sleep(0.1)

host/setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ def read(fname):
7777
'tqdm',
7878
'cmsis_svd',
7979
'tabulate',
80-
'prompt_toolkit<3.1.0'
80+
'prompt_toolkit<3.1.0',
81+
'intelhex',
8182
],
8283
description='Python library for hardware hacking with the GreatFET',
8384
long_description=read('README.md'),

0 commit comments

Comments
 (0)