summaryrefslogtreecommitdiff
path: root/df10ch_setup_pkg/firmware.py
diff options
context:
space:
mode:
Diffstat (limited to 'df10ch_setup_pkg/firmware.py')
-rw-r--r--df10ch_setup_pkg/firmware.py135
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