diff options
Diffstat (limited to 'df10ch_setup_pkg/firmware.py')
-rw-r--r-- | df10ch_setup_pkg/firmware.py | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/df10ch_setup_pkg/firmware.py b/df10ch_setup_pkg/firmware.py new file mode 100644 index 0000000..24dc577 --- /dev/null +++ b/df10ch_setup_pkg/firmware.py @@ -0,0 +1,135 @@ +# +# Copyright (C) 2010 Andreas Auras +# +# This file is part of the DF10CH Atmolight controller project. +# +# DF10CH Atmolight controller 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. +# +# DF10CH Atmolight controller 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, USA +# +# This file is part of the DF10CH setup program +# + +import array +import fileinput +import string + +class FirmwareFlashError(Exception): + def __init__(self, msg = None): + self.message = msg + + def __str__(self): + return self.message + + +class FlashPage: + + def __init__(self, addr, pageSize): + self.pageSize = pageSize + self.baseAddr = addr - addr % pageSize + self.data = array.array('B', [ 0xFF ] * pageSize) + + def insert(self, addr, value): + self.data[addr % self.pageSize] = value + + def verify(self, data): + for i in range(self.pageSize): + if data[i] != self.data[i]: + raise FirmwareFlashError("verify of flash data against firmware fails at {0:04X}: {1:02X} <> {2:02X}".format(self.baseAddr + i, data[i], self.data[i])) + + def __str__(self): + s = "{0:04X}: ".format(self.baseAddr) + for v in self.data: + s = s + "{0:02X} ".format(v) + return s + + +class FlashMem: + + def __init__(self, fileName, pageSize, targetInfoMustExist = False): + self.pageSize = pageSize + self.pageList = list() + self.lastLookupPage = None + self.target = None + self.version = None + self.loadFromHexFile(fileName) + if targetInfoMustExist and (not self.target or not self.version): + raise FirmwareFlashError("no target and/or version information found!") + + def getPageForAddr(self, addr): + baseAddr = addr - addr % self.pageSize + if self.lastLookupPage and self.lastLookupPage.baseAddr == baseAddr: + return self.lastLookupPage; + for p in self.pageList: + if p.baseAddr == baseAddr: + self.lastLookupPage = p + return p + return None + + def insert(self, addr, value): + p = self.getPageForAddr(addr) + if not p: + p = FlashPage(addr, self.pageSize) + self.pageList.append(p) + p.insert(addr, value) + + def loadFromHexFile(self, fileName): + file = None + try: + file = fileinput.FileInput(fileName) + for line in file: + line = string.rstrip(line) + lineLen = len(line) + if not lineLen: + continue + lineType = line[0:1] + if lineType == "#": + continue + if lineType == "@": + try: + self.target, self.version = string.split(line[1:]) + except: + raise FirmwareFlashError() + continue + if lineLen < 9 or lineType != ":": + raise FirmwareFlashError() + try: + n = int(line[1:3], 16) + addr = int(line[3:7], 16) + type = int(line[7:9], 16) + except: + raise FirmwareFlashError() + if type != 0: + break + if n > 0: + if lineLen < (9 + 2 * n): + raise FirmwareFlashError() + for i in range(n): + try: + data = int(line[i * 2 + 9: i * 2 + 11], 16) + except: + raise FirmwareFlashError() + self.insert(addr + i, data) + except IOError as err: + raise FirmwareFlashError("could not read firmware file '{0}': {1}".format(fileName, err.__str__())) + except FirmwareFlashError: + raise FirmwareFlashError("could not read firmware file '{0}': syntax error at line {1}".format(fileName, file.lineno())) + finally: + if file: + file.close() + +if __name__ == "__main__": + m = FlashMem("10ch_usb_ctrl.hex", 16) + print "target:", m.target, "version:", m.version + for p in m.pageList: + print p
\ No newline at end of file |