From 3a0fe398cb944939099522e65634fd9979abd015 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sun, 13 Oct 2013 23:10:20 +0200 Subject: Add generic support for parsing of ihex sections Signed-off-by: Michael Buesch --- libtoprammer/chip.py | 7 + .../chips/microchip16/pic24f04ka200dip14.py | 11 +- .../chips/microchip8/microchip8_18_common.py | 14 +- .../chips/microchip8/microchip8_singlePMarea.py | 16 ++- .../chips/microchip8/microchip8_splittedPMarea.py | 14 +- libtoprammer/chips/microchip8/pic12f629dip8.py | 3 +- libtoprammer/chips/microchip8/pic12f629sip6.py | 3 +- libtoprammer/chips/microchip8/pic16f630dip14.py | 1 - libtoprammer/chips/microchip8/pic16f630sip6.py | 1 - libtoprammer/ihex.py | 156 +++++++++++++++++++++ libtoprammer/util.py | 11 +- toprammer | 69 +++++---- toprammer-gui | 110 ++++++++++----- 13 files changed, 325 insertions(+), 91 deletions(-) create mode 100644 libtoprammer/ihex.py diff --git a/libtoprammer/chip.py b/libtoprammer/chip.py index 7a37c37..7fa9ba8 100644 --- a/libtoprammer/chip.py +++ b/libtoprammer/chip.py @@ -24,6 +24,7 @@ from util import * from layout_generator import * from user_interface import * from generic_algorithms import * +from ihex import * class Chip: @@ -195,6 +196,12 @@ class Chip: self.printDebug("Default chip shutdown") GenericAlgorithms(self).simpleVoltageShutdown() + def getIHexInterpreter(self): + # Returns the IHEX file interpreter. + # This defaults to the non-section interpreter. + # Override me in the subclass, if required. + return IHexInterpreter() + def readSignature(self): # Override me in the subclass, if required. self.throwError("Signature reading not supported") diff --git a/libtoprammer/chips/microchip16/pic24f04ka200dip14.py b/libtoprammer/chips/microchip16/pic24f04ka200dip14.py index d9aee5d..7211aaa 100644 --- a/libtoprammer/chips/microchip16/pic24f04ka200dip14.py +++ b/libtoprammer/chips/microchip16/pic24f04ka200dip14.py @@ -44,10 +44,15 @@ class Chip_Pic24f04ka200dip14(Chip_Microchip16_common): fuseBytes=16 * 2 ) self.configWordAddr = 0xF80000 - self.programMemoryByteAddressRange = [(0, 2 * self.flashPageSize)] - self.configWordByteAddressRange = [(2 * self.configWordAddr, 2 * self.configWordAddr + 1)] - # self.osccalBackupAddr = self.userIDLocationAddr + self.userIDLocationSize + + def getIHexInterpreter(self): + inter = IHexInterpreter() + inter.progmemRanges = [ AddressRange(0, 2 * self.flashPageSize) ] + inter.fuseRanges = [ AddressRange(2 * self.configWordAddr, + 2 * self.configWordAddr + 1) ] + return inter + def sendWriteFlashInstr(self): ''' ''' diff --git a/libtoprammer/chips/microchip8/microchip8_18_common.py b/libtoprammer/chips/microchip8/microchip8_18_common.py index 3e743c9..8510ec9 100644 --- a/libtoprammer/chips/microchip8/microchip8_18_common.py +++ b/libtoprammer/chips/microchip8/microchip8_18_common.py @@ -70,7 +70,7 @@ class Chip_Microchip8_18_common(Chip): deviceIDLength = 2 voltageVDD = 5 voltageVPP = 12 - + def __init__(self, chipPackage, chipPinVCC, chipPinsVPP, chipPinGND, signature, @@ -92,9 +92,15 @@ class Chip_Microchip8_18_common(Chip): self.isInPmMode = False self.BufferedBytes = 0 self.Image = "" - self.programMemoryByteAddressRange = [(0, self.flashPageSize)] - self.configWordByteAddressRange = [(self.configWordAddr, self.configWordAddr + self.fuseBytes)] - self.userIDLocationByteAddressRange = [(self.userIDLocationAddr, self.userIDLocationAddr + self.userIDLocationSize)] + + def getIHexInterpreter(self): + inter = IHexInterpreter() + inter.progmemRanges = [ AddressRange(0, self.flashPageSize) ] + inter.fuseRanges = [ AddressRange(self.configWordAddr, + self.configWordAddr + self.fuseBytes) ] + inter.uilRanges = [ AddressRange(self.userIDLocationAddr, + self.userIDLocationAddr + self.userIDLocationSize) ] + return inter def enterPM(self, force=False): if self.isInPmMode and not force: diff --git a/libtoprammer/chips/microchip8/microchip8_singlePMarea.py b/libtoprammer/chips/microchip8/microchip8_singlePMarea.py index bd720c0..fbe4f34 100644 --- a/libtoprammer/chips/microchip8/microchip8_singlePMarea.py +++ b/libtoprammer/chips/microchip8/microchip8_singlePMarea.py @@ -46,10 +46,18 @@ class microchip8_singlePMarea(Chip_Microchip8_common): self.osccalAddr = self.flashPageSize - 1 self.userIDLocationAddr = self.flashPageSize self.osccalBackupAddr = self.userIDLocationAddr + self.userIDLocationSize - self.programMemoryByteAddressRange = [(0, 2 * self.flashPageSize)] - self.configWordByteAddressRange = [(2 * self.configWordAddr, 2 * self.configWordAddr + 1), (2 * 0xFFF, 2 * 0xFFF + 1)] - self.userIDLocationByteAddressRange = [(2 * self.userIDLocationAddr, 2 * (self.userIDLocationAddr + self.userIDLocationSize) - 1)] - + + def getIHexInterpreter(self): + inter = IHexInterpreter() + inter.progmemRanges = [ AddressRange(0, 2 * self.flashPageSize) ] + inter.fuseRanges = [ AddressRange(2 * self.configWordAddr, + 2 * self.configWordAddr + 1), + AddressRange(2 * 0xFFF, + 2 * 0xFFF + 1) ] + inter.uilRanges = [ AddressRange(2 * self.userIDLocationAddr, + 2 * (self.userIDLocationAddr + self.userIDLocationSize) - 1) ] + return inter + def setPC(self, address): while(self.PC != address): self.incrementPC(1) diff --git a/libtoprammer/chips/microchip8/microchip8_splittedPMarea.py b/libtoprammer/chips/microchip8/microchip8_splittedPMarea.py index dd3902f..3e40f58 100644 --- a/libtoprammer/chips/microchip8/microchip8_splittedPMarea.py +++ b/libtoprammer/chips/microchip8/microchip8_splittedPMarea.py @@ -56,10 +56,16 @@ class microchip8_splittedPMarea(Chip_Microchip8_common): self.userIDLocationAddr = self.logicalFlashProgramMemorySize self.deviceIDAddr = self.logicalFlashProgramMemorySize + 0x06 self.configWordAddr = self.logicalFlashProgramMemorySize + 0x07 - self.programMemoryByteAddressRange = [(0, 2 * self.flashPageSize)] - self.configWordByteAddressRange = [(2 * self.configWordAddr, 2 * self.configWordAddr + 1)] - self.userIDLocationByteAddressRange = [(2 * self.userIDLocationAddr, 2 * (self.userIDLocationAddr + self.userIDLocationSize) - 1)] - + + def getIHexInterpreter(self): + inter = IHexInterpreter() + inter.progmemRanges = [ AddressRange(0, 2 * self.flashPageSize) ] + inter.fuseRanges = [ AddressRange(2 * self.configWordAddr, + 2 * self.configWordAddr + 1) ] + inter.uilRanges = [ AddressRange(2 * self.userIDLocationAddr, + 2 * (self.userIDLocationAddr + self.userIDLocationSize) - 1) ] + return inter + def incrementPC(self, count): for address in range(0, count): self.sendCommand(0, 0, 0, self.CMD_INCREMENT_ADDRESS) diff --git a/libtoprammer/chips/microchip8/pic12f629dip8.py b/libtoprammer/chips/microchip8/pic12f629dip8.py index efbb6c3..bce3939 100644 --- a/libtoprammer/chips/microchip8/pic12f629dip8.py +++ b/libtoprammer/chips/microchip8/pic12f629dip8.py @@ -49,8 +49,7 @@ class Chip_Pic12F629dip8(microchip8_splittedPMarea): ) self.configWordAddr = 0x2007 self.osccalAddr = self.flashPageSize - 1 - # self.configWordByteAddressRange = self.configWordByteAddressRange.append((2*0xFFF, 2*0xFFF+1)) - + fuseDesc = ( BitDescription(0, "FOSC[0], 0=LP, 100=INTOSC"), BitDescription(1, "FOSC[1]"), diff --git a/libtoprammer/chips/microchip8/pic12f629sip6.py b/libtoprammer/chips/microchip8/pic12f629sip6.py index 2777449..70a1298 100644 --- a/libtoprammer/chips/microchip8/pic12f629sip6.py +++ b/libtoprammer/chips/microchip8/pic12f629sip6.py @@ -49,8 +49,7 @@ class Chip_Pic12F629sip6(microchip8_splittedPMarea): ) self.configWordAddr = 0x2007 self.osccalAddr = self.flashPageSize - 1 - # self.configWordByteAddressRange = self.configWordByteAddressRange.append((2*0xFFF, 2*0xFFF+1)) - + fuseDesc = ( BitDescription(0, "FOSC[0], 0=LP, 100=INTOSC"), BitDescription(1, "FOSC[1]"), diff --git a/libtoprammer/chips/microchip8/pic16f630dip14.py b/libtoprammer/chips/microchip8/pic16f630dip14.py index 32f6c73..399b446 100644 --- a/libtoprammer/chips/microchip8/pic16f630dip14.py +++ b/libtoprammer/chips/microchip8/pic16f630dip14.py @@ -49,7 +49,6 @@ class Chip_Pic16F630dip14(microchip8_splittedPMarea): ) self.configWordAddr = 0x2007 self.osccalAddr = self.flashPageSize - 1 - # self.configWordByteAddressRange = self.configWordByteAddressRange.append((2*0xFFF, 2*0xFFF+1)) fuseDesc = ( BitDescription(0, "FOSC[0], 0=LP, 100=INTOSC"), diff --git a/libtoprammer/chips/microchip8/pic16f630sip6.py b/libtoprammer/chips/microchip8/pic16f630sip6.py index 47d0c84..37406f8 100644 --- a/libtoprammer/chips/microchip8/pic16f630sip6.py +++ b/libtoprammer/chips/microchip8/pic16f630sip6.py @@ -49,7 +49,6 @@ class Chip_Pic16F630sip6(microchip8_splittedPMarea): ) self.configWordAddr = 0x2007 self.osccalAddr = self.flashPageSize - 1 - # self.configWordByteAddressRange = self.configWordByteAddressRange.append((2*0xFFF, 2*0xFFF+1)) fuseDesc = ( BitDescription(0, "FOSC[0], 0=LP, 100=INTOSC"), diff --git a/libtoprammer/ihex.py b/libtoprammer/ihex.py new file mode 100644 index 0000000..c837d85 --- /dev/null +++ b/libtoprammer/ihex.py @@ -0,0 +1,156 @@ +""" +# TOP2049 Open Source programming suite +# +# IHEX file layout +# +# Copyright (c) 2013 Michael Buesch +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +""" + +from util import * + + +class AddressRange(object): + """Address range type.""" + + def __init__(self, startAddress = 0, endAddress = -1): + # endAddress of -1 means "to the end of the image". + assert(startAddress >= 0) + assert(endAddress >= -1) + assert(startAddress <= endAddress or endAddress == -1) + self.startAddress = startAddress + self.endAddress = endAddress + + def overlaps(self, other): + """Check if self overlaps with other.""" + if (other.startAddress <= self.endAddress or self.endAddress < 0) and\ + (other.endAddress >= self.startAddress or other.endAddress < 0): + return True + return False + + @classmethod + def overlapsAny(cls, addressRangeList, addressRange): + """Check if 'addressRange' overlaps with any + AddressRange in 'addressRangeList'""" + return any(r.overlaps(addressRange) for r in addressRangeList) + +class IHexInterpreter(object): + """Generic interpreter for a cumulative IHEX file. + This class must be subclassed to be usable.""" + + # Definition of the address ranges. + # For each memory area type, several possible address + # ranges can be defined. They are tried first to last. + # Override these in the subclass. + progmemRanges = None + eepromRanges = None + fuseRanges = None + lockRanges = None + ramRanges = None + uilRanges = None + + # Definition of default memory values. + # Override these in the subclass. + progmemDefaultBytes = b"\xFF" + eepromDefaultBytes = b"\xFF" + fuseDefaultBytes = b"\xFF" + lockDefaultBytes = b"\xFF" + ramDefaultBytes = b"\x00" + uilDefaultBytes = b"\xFF" + + def __init__(self): + self.__ihexData = None + self.__progmem = None + self.__eeprom = None + self.__fusebits = None + self.__lockbits = None + self.__ram = None + self.__uil = None + + def cumulativeSupported(self): + """Returns True, if parsing of cumulative IHEX files + is supported by the implementation.""" + return self.progmemRanges or\ + self.eepromRanges or\ + self.fuseRanges or\ + self.lockRanges or\ + self.ramRanges or\ + self.uilRanges + + def interpret(self, ihexData): + self.__ihexData = ihexData + usedRanges = [] + self.__progmem = self.tryExtract(ihexData, self.progmemDefaultBytes, + usedRanges, self.progmemRanges) + self.__eeprom = self.tryExtract(ihexData, self.eepromDefaultBytes, + usedRanges, self.eepromRanges) + self.__fusebits = self.tryExtract(ihexData, self.fuseDefaultBytes, + usedRanges, self.fuseRanges) + self.__lockbits = self.tryExtract(ihexData, self.lockDefaultBytes, + usedRanges, self.lockRanges) + self.__ram = self.tryExtract(ihexData, self.ramDefaultBytes, + usedRanges, self.ramRanges) + self.__uil = self.tryExtract(ihexData, self.uilDefaultBytes, + usedRanges, self.uilRanges) + + def tryExtract(self, ihexData, defaultBytes, alreadyUsedRanges, tryRanges): + if not tryRanges: + return None + for tryRange in tryRanges: + if AddressRange.overlapsAny(alreadyUsedRanges, tryRange): + continue + image = IO_ihex().toBinary(ihexData, + addressRange = tryRange, + defaultBytes = defaultBytes) + if not image: + continue + alreadyUsedRanges.append(tryRange) + return image + return None + + def getRaw(self, defaultBytes=b"\xFF"): + return IO_ihex().toBinary(self.__ihexData, + defaultBytes = defaultBytes) + + def getProgmem(self, dontInterpretSections=False): + if dontInterpretSections: + return self.getRaw(defaultBytes = self.progmemDefaultBytes) + return self.__progmem + + def getEEPROM(self, dontInterpretSections=False): + if dontInterpretSections: + return self.getRaw(defaultBytes = self.eepromDefaultBytes) + return self.__eeprom + + def getFusebits(self, dontInterpretSections=False): + if dontInterpretSections: + return self.getRaw(defaultBytes = self.fuseDefaultBytes) + return self.__fusebits + + def getLockbits(self, dontInterpretSections=False): + if dontInterpretSections: + return self.getRaw(defaultBytes = self.lockDefaultBytes) + return self.__lockbits + + def getRAM(self, dontInterpretSections=False): + if dontInterpretSections: + return self.getRaw(defaultBytes = self.ramDefaultBytes) + return self.__ram + + def getUIL(self, dontInterpretSections=False): + if dontInterpretSections: + return self.getRaw(defaultBytes = self.uilDefaultBytes) + return self.__uil diff --git a/libtoprammer/util.py b/libtoprammer/util.py index 91ec21e..3dcb5c0 100644 --- a/libtoprammer/util.py +++ b/libtoprammer/util.py @@ -155,11 +155,12 @@ class IO_ihex(object): return False return True - def toBinary(self, ihexData, minMaxAddr=None): + def toBinary(self, ihexData, addressRange=None, defaultBytes=b"\xFF"): + #TODO defaultBytes bin = [] checksumWarned = False doublewriteWarned = False - addrBias = minMaxAddr[0] if minMaxAddr else 0 + addrBias = addressRange.startAddress if addressRange else 0 try: lines = ihexData.splitlines() hiAddr = 0 @@ -202,10 +203,10 @@ class IO_ihex(object): raise TOPException("Invalid IHEX format (inval ELAR)") hiAddr = (int(line[9:11], 16) << 8) | int(line[11:13], 16) continue - if(minMaxAddr and addr < minMaxAddr[0]): + if addressRange and addr < addressRange.startAddress: + continue + if addressRange and addr > addressRange.endAddress: continue - if(minMaxAddr and addr > minMaxAddr[1]): - continue if type == self.TYPE_DATA: if len(bin) < addr - addrBias + count: # Reallocate bin += [b'\xFF'] * (addr - addrBias + count - len(bin)) diff --git a/toprammer b/toprammer index a8c736a..c240a1c 100755 --- a/toprammer +++ b/toprammer @@ -4,7 +4,7 @@ # # Commandline utility # -# Copyright (c) 2009-2010 Michael Buesch +# Copyright (c) 2009-2013 Michael Buesch # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -85,12 +85,14 @@ def usage(): print " auto Autodetect. (input only)" print " bin Raw binary data" print " ihex Intel hex" + print " ihex-raw Raw Intel hex (don't interpret sections)" print " ahex Hex with ASCII dump" IO_handlers = { - "bin" : IO_binary, - "ihex" : IO_ihex, - "ahex" : IO_ahex, + "bin" : IO_binary, + "ihex" : IO_ihex, + "ihex-raw" : IO_ihex, + "ahex" : IO_ahex, } def fileOut(filename, fmtString, data): @@ -101,7 +103,7 @@ def fileOut(filename, fmtString, data): else: open(filename, "w+b").write(data) -def fileIn(filename, fmtString, minMaxAddr=None): +def fileIn(top, action, filename, fmtString): if filename == "-": data = sys.stdin.read() else: @@ -110,10 +112,29 @@ def fileIn(filename, fmtString, minMaxAddr=None): handler = IO_autodetect(data)() else: handler = IO_handlers[fmtString]() - if(handler.__class__.__name__== "IO_ihex"): - return handler.toBinary(data, minMaxAddr) - else: - return handler.toBinary(data) + if isinstance(handler, IO_ihex): + interp = top.getChip().getIHexInterpreter() + interp.interpret(data) + if interp.cumulativeSupported(): + readRaw = fmtString.endswith("-raw") + else: + readRaw = True + if action == "write-prog": + binData = interp.getProgmem(dontInterpretSections = readRaw) + elif action == "write-eeprom": + binData = interp.getEEPROM(dontInterpretSections = readRaw) + elif action == "write-fuse": + binData = interp.getFusebits(dontInterpretSections = readRaw) + elif action == "write-lock": + binData = interp.getLockbits(dontInterpretSections = readRaw) + elif action == "write-ram": + binData = interp.getRAM(dontInterpretSections = readRaw) + elif action == "write-uil": + binData = interp.getUIL(dontInterpretSections = readRaw) + else: + assert(0) + return binData + return handler.toBinary(data) def main(argv): opt_verbose = 1 @@ -227,10 +248,10 @@ def main(argv): if opt_action != "print-list" and not opt_chipID: print "-c|--chip-id is mandatory!" return 1 - if not opt_informat in ("auto", "bin", "ihex", "ahex"): + if not opt_informat in ("auto", "bin", "ihex", "ihex-raw", "ahex"): print "Invalid -I|--in-format" return 1 - if not opt_outformat in ("bin", "ihex", "ahex"): + if not opt_outformat in ("bin", "ihex", "ihex-raw", "ahex"): print "Invalid -O|--out-format" return 1 @@ -259,43 +280,29 @@ def main(argv): elif opt_action == "read-prog": fileOut(opt_file, opt_outformat, top.readProgmem()) elif opt_action == "write-prog": - if(hasattr(top.getChip(),'programMemoryByteAddressRange')): #FIXME UGLY! - for minMaxAddr in top.getChip().programMemoryByteAddressRange: - print "trying %x, %x\n" % minMaxAddr - image = fileIn(opt_file, opt_informat, minMaxAddr) - if(len(image)>0): - break - else: - image = fileIn(opt_file, opt_informat) + image = fileIn(top, opt_action, opt_file, opt_informat) top.writeProgmem(image) elif opt_action == "read-eeprom": fileOut(opt_file, opt_outformat, top.readEEPROM()) elif opt_action == "write-eeprom": - top.writeEEPROM(fileIn(opt_file, opt_informat)) + top.writeEEPROM(fileIn(top, opt_action, opt_file, opt_informat)) elif opt_action == "read-fuse": fileOut(opt_file, opt_outformat, top.readFuse()) elif opt_action == "write-fuse": - if(hasattr(top.getChip(),'configWordByteAddressRange')): #FIXME UGLY! - for minMaxAddr in top.getChip().configWordByteAddressRange: - print "trying %x, %x\n" % minMaxAddr - image = fileIn(opt_file, opt_informat, minMaxAddr) - if(len(image)>0): - break - else: - image = fileIn(opt_file, opt_informat) + image = fileIn(top, opt_action, opt_file, opt_informat) top.writeFuse(image) elif opt_action == "read-lock": fileOut(opt_file, opt_outformat, top.readLockbits()) elif opt_action == "write-lock": - top.writeLockbits(fileIn(opt_file, opt_informat)) + top.writeLockbits(fileIn(top, opt_action, opt_file, opt_informat)) elif opt_action == "read-ram": fileOut(opt_file, opt_outformat, top.readRAM()) elif opt_action == "write-ram": - top.writeRAM(fileIn(opt_file, opt_informat)) + top.writeRAM(fileIn(top, opt_action, opt_file, opt_informat)) elif opt_action == "read-uil": fileOut(opt_file, opt_outformat, top.readUserIdLocation()) elif opt_action == "write-uil": - top.writeUserIdLocation(fileIn(opt_file, opt_informat)) + top.writeUserIdLocation(fileIn(top, opt_action, opt_file, opt_informat)) else: print "No action specified" top.shutdownChip() diff --git a/toprammer-gui b/toprammer-gui index 492eb49..169e85d 100755 --- a/toprammer-gui +++ b/toprammer-gui @@ -1353,6 +1353,9 @@ class BufferWidget(QWidget): def setRawData(self, data): return False + def setDataWithIHexInterpreter(self, interp, readRaw): + return False + def clear(self): pass @@ -1574,17 +1577,52 @@ class BitBufferWidget(BufferWidget): def clear(self): self.loadImage(None) +class ProgmemBufferWidget(ImageBufferWidget): + def __init__(self, mainWindow): + ImageBufferWidget.__init__(self, mainWindow, "program memory") + + def setDataWithIHexInterpreter(self, interp, readRaw): + return self.setRawData(interp.getProgmem(dontInterpretSections = readRaw)) + +class EEPROMBufferWidget(ImageBufferWidget): + def __init__(self, mainWindow): + ImageBufferWidget.__init__(self, mainWindow, "(E)EPROM memory") + + def setDataWithIHexInterpreter(self, interp, readRaw): + return self.setRawData(interp.getEEPROM(dontInterpretSections = readRaw)) + +class RAMBufferWidget(ImageBufferWidget): + def __init__(self, mainWindow): + ImageBufferWidget.__init__(self, mainWindow, "RAM memory") + + def setDataWithIHexInterpreter(self, interp, readRaw): + return self.setRawData(interp.getRAM(dontInterpretSections = readRaw)) + +class FuseBufferWidget(BitBufferWidget): + def __init__(self, mainWindow): + BitBufferWidget.__init__(self, mainWindow, "fuse bits", "fuseDesc") + + def setDataWithIHexInterpreter(self, interp, readRaw): + return self.setRawData(interp.getFusebits(dontInterpretSections = readRaw)) + +class LockBufferWidget(BitBufferWidget): + def __init__(self, mainWindow): + BitBufferWidget.__init__(self, mainWindow, "lock bits", "lockbitDesc") + + def setDataWithIHexInterpreter(self, interp, readRaw): + return self.setRawData(interp.getLockbits(dontInterpretSections = readRaw)) + class BufferTabWidget(QTabWidget): def __init__(self, mainWindow): QTabWidget.__init__(self, mainWindow) self.mainWindow = mainWindow self.infoBuffer = InfoBufferWidget(mainWindow, "chip info") - self.progmemBuffer = ImageBufferWidget(mainWindow, "program memory") - self.eepromBuffer = ImageBufferWidget(mainWindow, "(E)EPROM memory") - self.fuseBuffer = BitBufferWidget(mainWindow, "fuse bits", "fuseDesc") - self.lockBuffer = BitBufferWidget(mainWindow, "lock bits", "lockbitDesc") - self.ramBuffer = ImageBufferWidget(mainWindow, "RAM memory") + self.progmemBuffer = ProgmemBufferWidget(mainWindow) + self.eepromBuffer = EEPROMBufferWidget(mainWindow) + self.fuseBuffer = FuseBufferWidget(mainWindow) + self.lockBuffer = LockBufferWidget(mainWindow) + self.ramBuffer = RAMBufferWidget(mainWindow) self.setTabPosition(self.South) self.__addBufferTab(self.infoBuffer, readOnly=True) @@ -2348,42 +2386,46 @@ class MainWindow(QMainWindow): return try: if ".bin" in extensions: - data = IO_binary().toBinary(dataIn) # no-op + handler = IO_binary() elif ".ahex" in extensions: - data = IO_ahex().toBinary(dataIn) - elif (not extensions or ".ihex" in extensions): # auto - if ".ihex" in extensions: - handler = IO_ihex() - else: - handler = IO_autodetect(dataIn)() - #FIXME UGLY! - if(handler.__class__.__name__== "IO_ihex"): - if(bufWidget.__class__.__name__=='ImageBufferWidget' and hasattr(self.chip,'programMemoryByteAddressRange')): - for minMaxAddr in self.chip.programMemoryByteAddressRange: - print "trying %x, %x\n" % minMaxAddr - data = handler.toBinary(dataIn, minMaxAddr) - if(len(data)>0): - break - elif(bufWidget.__class__.__name__ =='BitBufferWidget' and hasattr(self.chip,'configWordByteAddressRange')): - for minMaxAddr in self.chip.configWordByteAddressRange: - print "trying %x, %x\n" % minMaxAddr - data = handler.toBinary(dataIn, minMaxAddr) - if(len(data)>0): - break - print "failed" - else: - data = handler.toBinary(dataIn) - else: - data = handler.toBinary(dataIn) + handler = IO_ahex() + elif ".ihex" in extensions: + handler = IO_ihex() + elif not extensions: # auto + handler = IO_autodetect(dataIn)() else: assert(0) + if isinstance(handler, IO_ihex): + interp = self.chip.getIHexInterpreter() + interp.interpret(dataIn) + if interp.cumulativeSupported(): + res = QMessageBox.question(self, + "Parse IHEX sections?", + "This IHEX file might contain sections for " + "the different memory areas (progmem, eeprom, etc...).\n" + "\n" + "Should the sections be interpreted?\n" + "\n" + "If 'Yes' is selected, only the section corresponding " + "to the current buffer is extracted from the IHEX file.\n" + "If 'No' is selected, the IHEX file will be read " + "in raw mode and all of its data will be " + "put into the current buffer.", + QMessageBox.Yes | QMessageBox.No, + QMessageBox.Yes) + readRaw = (res != QMessageBox.Yes) + else: + readRaw = True + ok = bufWidget.setDataWithIHexInterpreter(interp, readRaw) + else: + ok = bufWidget.setRawData(handler.toBinary(dataIn)) + if not ok: + QMessageBox.critical(self, "Failed to load data", + "Failed to load the file into the buffer") except (TOPException), e: QMessageBox.critical(self, "Failed to convert data", "Failed to convert the input file data to binary\n%s" % str(e)) return - if not bufWidget.setRawData(data): - QMessageBox.critical(self, "Failed to load data", - "Failed to load the file into the buffer") def saveBuffer(self): bufWidget = self.bufferTab.getCurrentBuffer() -- cgit v1.2.3