From 41646e44a6d553397c2f91950b1e07371729c8a1 Mon Sep 17 00:00:00 2001 From: Rex McKinnon Date: Sun, 6 Mar 2022 14:07:13 -0800 Subject: [PATCH] Added --device flag to specify device to be programmed --- software/picchick/cli.py | 12 ++++--- software/picchick/devices.py | 67 ++++++++++++++++++++++++++++++++++++ software/picchick/hexfile.py | 18 ++++++---- 3 files changed, 86 insertions(+), 11 deletions(-) create mode 100644 software/picchick/devices.py diff --git a/software/picchick/cli.py b/software/picchick/cli.py index 0f2bb83..6cd8db5 100755 --- a/software/picchick/cli.py +++ b/software/picchick/cli.py @@ -42,16 +42,16 @@ parser.add_argument('--write', nargs=2, metavar=('addr', 'word'), - help='write word to specified address or chunk of memory') + help='write word to specified address') parser.add_argument('--erase', nargs='?', const='all', metavar='addr', help='erase device or specified address') -# parser.add_argument('-d', '--device', -# metavar='dev', -# help='device to be programmed') +parser.add_argument('-d', '--device', + metavar='chipID', + help='device to be programmed') parser.add_argument('-p', '--port', metavar='port', help='programmer serial port') @@ -90,12 +90,14 @@ def parseArgv(): if args.hexfile is None: print(f"Missing argument: hexfile") sys.exit(1) + elif args.device is None: + print("Missing argument: -d, --device chipID") elif not os.path.isfile(args.hexfile): print(f"Could not find hexfile: { args.hexfile}") sys.exit(1) else: print(f"Using hexfile: { args.hexfile }") - hex_decoder = hexfile.HexfileDecoder(args.hexfile) + hex_decoder = hexfile.HexfileDecoder(args.hexfile, args.device) # We now have all the hexfile reqs, so take care of the actions # that only require the hexfile diff --git a/software/picchick/devices.py b/software/picchick/devices.py new file mode 100644 index 0000000..e1c65f9 --- /dev/null +++ b/software/picchick/devices.py @@ -0,0 +1,67 @@ +import configparser +import pathlib + + +class MemoryRange: + + size = None + start = None + end = None + + def configure(self, size=None, addr_range=None): + + if size and not addr_range: + self.size = int(size, base=16) + self.start = 0 + self.end = self.size - 1 + + if addr_range and not size: + self.start = int(addr_range.split('-')[0], base=16) + self.end = int(addr_range.split('-')[1], base=16) + self.size = self.end - self.start + 1 + + +# This class holds the device data needed for flashing etc. +class Device: + + flash = MemoryRange() + config = MemoryRange() + + def __init__(self, chip_id): + + self.chip_id = chip_id.upper() + + def readDeviceFile(self, ccpath): + self.device_file_path = ccpath / 'pic/dat/ini' / (self.chip_id.lower() + '.ini') + self.device_file = configparser.ConfigParser(strict=False) + self.device_file.read(self.device_file_path) + self.flash.configure(size=self.device_file.get(self.chip_id, 'ROMSIZE')) + self.config.configure(addr_range=self.device_file.get(self.chip_id, 'CONFIG')) + + +XC8_COMMON_PATHS = [ + '/opt/microchip/xc8' +] + +# This class handles searching the local filesystem for the xc8 compiler so +# we can use its device files +class XC8Manager: + + # xc8_paths = [] + + def findXC8Installs(): + + found_installs = [] + + for common_path in XC8_COMMON_PATHS: + path = pathlib.Path(common_path) + + if path.is_dir(): + found_installs += [p for p in path.iterdir() if p.is_dir()] + + # self.xc8_paths += found_installs + return found_installs + + + + diff --git a/software/picchick/hexfile.py b/software/picchick/hexfile.py index 4f4e926..f288dfc 100644 --- a/software/picchick/hexfile.py +++ b/software/picchick/hexfile.py @@ -1,21 +1,27 @@ import copy -PFM_START = 0x0000 -USER_ID_START = 0x8000 -CONFIG_WORD_START = 0x8007 +from . import devices + +# PFM_START = 0x0000 +# USER_ID_START = 0x8000 +# CONFIG_WORD_START = 0x8007 class HexfileDecoder: - def __init__(self, path): + def __init__(self, path, device): self.path = path + + self.device = devices.Device(device) + self.device.readDeviceFile(devices.XC8Manager.findXC8Installs()[0]) + self.ascii_records = self._readHexfile(path) self.records = self._decodeAsciiRecords(self.ascii_records) self.word_list = self._decodeWordsFromRecords(self.records) - self.userflash_words = [addr for addr in self.word_list.keys() if addr < USER_ID_START] - self.config_words = [addr for addr in self.word_list.keys() if addr > USER_ID_START] + self.userflash_words = [addr for addr in self.word_list.keys() if addr <= self.device.flash.end] + self.config_words = [addr for addr in self.word_list.keys() if addr > self.device.flash.end] self.memory = self._separateRows(self.word_list)