diff options
Diffstat (limited to 'df10ch_setup_pkg')
-rw-r--r-- | df10ch_setup_pkg/areas_dlg.py | 296 | ||||
-rw-r--r-- | df10ch_setup_pkg/bright_dlg.py | 1 | ||||
-rw-r--r-- | df10ch_setup_pkg/device_dlg.py | 89 | ||||
-rw-r--r-- | df10ch_setup_pkg/device_drv.py | 93 | ||||
-rw-r--r-- | df10ch_setup_pkg/layout_dlg.py | 87 | ||||
-rw-r--r-- | df10ch_setup_pkg/map_dlg.py | 1 | ||||
-rw-r--r-- | df10ch_setup_pkg/white_cal_dlg.py | 1 |
7 files changed, 432 insertions, 136 deletions
diff --git a/df10ch_setup_pkg/areas_dlg.py b/df10ch_setup_pkg/areas_dlg.py index 3eeb8c7..11d59f0 100644 --- a/df10ch_setup_pkg/areas_dlg.py +++ b/df10ch_setup_pkg/areas_dlg.py @@ -21,15 +21,36 @@ # from Tkinter import * +import Image +import ImageTk +import ImageDraw import device_drv class AreasDialog: def __init__(self, master=None, **args): + self.width = args["width"] + self.height = args["height"] + self.parent = master self.root = Canvas(master, **args) self.selectedArea = None self.selectCallbacks = list() + self.edgeWeighting = -1 + + def cvX(self, x): + return int((self.cvWidth * x) / self.aWidth) - def configAreas(self, numAreas): + def cvY(self, y): + return int((self.cvHeight * y) / self.aHeight) + + def cvXY(self, l): + r = list() + for i in range(0, len(l), 2): + r.append(self.cvX(l[i])) + r.append(self.cvY(l[i + 1])) + return r + + def configAreas(self, numAreas, overscan, analyzeSize): + self.edgeWeighting = -1 nTopLeft = numAreas[device_drv.AreaIndex("TopLeft")] nTopRight = numAreas[device_drv.AreaIndex("TopRight")] nBottomLeft = numAreas[device_drv.AreaIndex("BottomLeft")] @@ -41,168 +62,288 @@ class AreasDialog: nRight = numAreas[device_drv.AreaIndex("Right")] cv = self.root - size = 0 - width = int(cv["width"]) - height = int(cv["height"]) + + # Calculate overscan and resulting canvas size + ovx = (self.width * overscan) / 1000 + ovy = (self.height * overscan) / 1000 + width = self.width - 2 * ovx + height = self.height - 2 * ovy + self.cvWidth = width + self.cvHeight = height + + # Apply overscan and canvas size + cv["width"] = width + cv["height"] = height + cv["background"] = "black" + self.parent["padx"] = ovx + self.parent["pady"] = ovy + self.parent["background"] = "cyan" + # Calculate analyze window size + aWidth = (analyzeSize + 1) * 64 + aHeight = (aWidth * self.height) / self.width + self.aWidth = aWidth + self.aHeight = aHeight + + # Calculate number of areas for each border sTop = nTop + nTopLeft + nTopRight + sBottom = nBottom + nBottomLeft + nBottomRight + sLeft = nLeft + nTopLeft + nBottomLeft + sRight = nRight + nTopRight + nBottomRight + self.sTop = sTop + self.sBottom = sBottom + self.sLeft = sLeft + self.sRight = sRight + + # Calculate area width for each border if sTop: - topSize = int(width / sTop) - topSizeEnd = width - topSize * (sTop - 1) - if not size or topSize < size: - size = topSize + topSizeX = int(aWidth / sTop) + topLastX = int((aWidth * (sTop - 1)) / sTop) + else: + topSizeX = 0 + topLastX = 0 - sBottom = nBottom + nBottomLeft + nBottomRight if sBottom: - bottomSize = int(width / sBottom) - bottomSizeEnd = width - bottomSize * (sBottom - 1) - if not size or bottomSize < size: - size = bottomSize - - sLeft = nLeft + nTopLeft + nBottomLeft + bottomSizeX = int(aWidth / sBottom) + bottomLastX = int((aWidth * (sBottom - 1)) / sBottom) + else: + bottomSizeX = 0 + bottomLastX = 0 + if sLeft: - leftSize = int(height / sLeft) - leftSizeEnd = height - leftSize * (sLeft - 1) - if not size or leftSize < size: - size = leftSize - - sRight = nRight + nTopRight + nBottomRight + leftSizeY = int(aHeight / sLeft) + leftLastY = int((aHeight * (sLeft - 1)) / sLeft) + else: + leftSizeY = 0 + leftLastY = 0 + if sRight: - rightSize = int(height / sRight) - rightSizeEnd = height - rightSize * (sRight - 1) - if not size or rightSize < size: - size = rightSize - - if not size or int(width / 2) < size: - size = int(width / 2) - if not size or int(height / 2) < size: - size = int(height / 2) + rightSizeY = int(aHeight / sRight) + rightLastY = int((aHeight * (sRight - 1)) / sRight) + else: + rightSizeY = 0 + rightLastY = 0 + + # Calculate depth (border towards center length) for each border + topSizeY = int(aHeight / 2) + if leftSizeY and leftSizeY < topSizeY: + topSizeY = leftSizeY + if rightSizeY and rightSizeY < topSizeY: + topSizeY = rightSizeY + + bottomSizeY = aHeight - int(aHeight / 2) + if leftLastY > bottomSizeY: + bottomSizeY = leftLastY + if rightLastY > bottomSizeY: + bottomSizeY = rightLastY + + leftSizeX = int(aWidth / 2) + if topSizeX and topSizeX < leftSizeX: + leftSizeX = topSizeX + if bottomSizeX and bottomSizeX < leftSizeX: + leftSizeX = bottomSizeX + + rightSizeX = aWidth - int(aWidth / 2) + if topLastX > rightSizeX: + rightSizeX = topLastX + if bottomLastX > rightSizeX: + rightSizeX = bottomLastX + pTop = [ None ] * nTop x = 0 # top left corner if nTopLeft: - pTopLeft = [ 0, 0, topSize, 0, topSize, size, size, size, size, leftSize, 0, leftSize ] - x = topSize + pTopLeft = [ 0, 0, topSizeX, 0, topSizeX, topSizeY, leftSizeX, topSizeY, leftSizeX, leftSizeY, 0, leftSizeY ] + x = topSizeX elif nTop == 1: - pTop[0] = [ 0, 0, width, 0, width - size, size, size, size ] + pTop[0] = [ 0, 0, aWidth, 0, rightSizeX, topSizeY, leftSizeX, topSizeY ] elif nTop > 1: - pTop[0] = [ 0, 0, topSize, 0, topSize, size, size, size ] + pTop[0] = [ 0, 0, topSizeX, 0, topSizeX, topSizeY, leftSizeX, topSizeY ] # top right corner if nTopRight: - pTopRight = [ width, 0, width, rightSize, width - size, rightSize, width - size, size, width - topSizeEnd, size, width - topSizeEnd, 0 ] + pTopRight = [ aWidth, 0, aWidth, rightSizeY, rightSizeX, rightSizeY, rightSizeX, topSizeY, topLastX, topSizeY, topLastX, 0 ] elif nTop > 1: - pTop[nTop - 1] = [ width, 0, width - size, size, width - topSizeEnd, size, width - topSizeEnd, 0 ] + pTop[nTop - 1] = [ aWidth, 0, rightSizeX, topSizeY, topLastX, topSizeY, topLastX, 0 ] # top for i in range(nTop): + x2 = int((aWidth * (i + nTopLeft + 1)) / sTop) if pTop[i] == None: - pTop[i] = [ x, 0, x + topSize, 0, x + topSize, size, x, size ] - x = x + topSize + pTop[i] = [ x, 0, x2, 0, x2, topSizeY, x, topSizeY ] + x = x2 pBottom = [ None ] * nBottom x = 0 # bottom left corner if nBottomLeft: - pBottomLeft = [ 0, height, 0, height - leftSizeEnd, size, height - leftSizeEnd, size, height - size, bottomSize, height - size, bottomSize, height ] - x = bottomSize + pBottomLeft = [ 0, aHeight, 0, leftLastY, leftSizeX, leftLastY, leftSizeX, bottomSizeY, bottomSizeX, bottomSizeY, bottomSizeX, aHeight ] + x = bottomSizeX elif nBottom == 1: - pBottom[0] = [ 0, height, size, height - size, width - size, height - size, width, height ] + pBottom[0] = [ 0, aHeight, leftSizeX, bottomSizeY, rightSizeX, bottomSizeY, aWidth, aHeight ] elif nBottom > 1: - pBottom[0] = [ 0, height, size, height - size, bottomSize, height - size, bottomSize, height ] + pBottom[0] = [ 0, aHeight, leftSizeX, bottomSizeY, bottomSizeX, bottomSizeY, bottomSizeX, aHeight ] # bottom right corner if nBottomRight: - pBottomRight = [ width, height, width - bottomSizeEnd, height, width - bottomSizeEnd, height - size, width - size, height - size, width - size, height - rightSizeEnd, width, height - rightSizeEnd ] + pBottomRight = [ aWidth, aHeight, bottomLastX, aHeight, bottomLastX, bottomSizeY, rightSizeX, bottomSizeY, rightSizeX, rightLastY, aWidth, rightLastY ] elif nBottom > 1: - pBottom[nBottom - 1] = [ width, height, width - bottomSizeEnd, height, width - bottomSizeEnd, height - size, width - size, height - size ] + pBottom[nBottom - 1] = [ aWidth, aHeight, bottomLastX, aHeight, bottomLastX, bottomSizeY, rightSizeX, bottomSizeY ] # bottom for i in range(nBottom): + x2 = int((aWidth * (i + nBottomLeft + 1)) / sBottom) if pBottom[i] == None: - pBottom[i] = [ x, height, x, height - size, x + bottomSize, height - size, x + bottomSize, height ] - x = x + bottomSize + pBottom[i] = [ x, aHeight, x, bottomSizeY, x2, bottomSizeY, x2, aHeight ] + x = x2 pLeft = [ None ] * nLeft y = 0 # left top corner if nTopLeft: - y = leftSize + y = leftSizeY elif nLeft == 1: - pLeft[0] = [ 0, 0, size, size, size, height - size, 0, height ] + pLeft[0] = [ 0, 0, leftSizeX, topSizeY, leftSizeX, bottomSizeY, 0, aHeight ] elif nLeft > 1: - pLeft[0] = [ 0, 0, size, size, size, leftSize, 0, leftSize ] + pLeft[0] = [ 0, 0, leftSizeX, topSizeY, leftSizeX, leftSizeY, 0, leftSizeY ] # left bottom corner if not nBottomLeft and nLeft > 1: - pLeft[nLeft - 1] = [ 0, height, 0, height - leftSizeEnd, size, height - leftSizeEnd, size, height - size ] + pLeft[nLeft - 1] = [ 0, aHeight, 0, leftLastY, leftSizeX, leftLastY, leftSizeX, bottomSizeY ] # left for i in range(nLeft): + y2 = int((aHeight * (i + nTopLeft + 1)) / sLeft) if pLeft[i] == None: - pLeft[i] = [ 0, y, size, y, size, y + leftSize, 0, y + leftSize ] - y = y + leftSize + pLeft[i] = [ 0, y, leftSizeX, y, leftSizeX, y2, 0, y2 ] + y = y2 pRight = [ None ] * nRight y = 0 # right top corner if nTopRight: - y = rightSize + y = rightSizeY elif nRight == 1: - pRight[0] = [ width, 0, width, height, width - size, height - size, width - size, size ] + pRight[0] = [ aWidth, 0, aWidth, aHeight, rightSizeX, bottomSizeY, rightSizeX, topSizeY ] elif nRight > 1: - pRight[0] = [ width, 0, width, rightSize, width - size, rightSize, width - size, size ] + pRight[0] = [ aWidth, 0, aWidth, rightSizeY, rightSizeX, rightSizeY, rightSizeX, topSizeY ] # right bottom corner if not nBottomRight and nRight > 1: - pRight[nRight - 1] = [ width, height, width - size, height - size, width - size, height - rightSizeEnd, width, height - rightSizeEnd ] + pRight[nRight - 1] = [ aWidth, aHeight, rightSizeX, bottomSizeY, rightSizeX, rightLastY, aWidth, rightLastY ] # right for i in range(nRight): + y2 = int((aHeight * (i + nTopRight + 1)) / sRight) if pRight[i] == None: - pRight[i] = [ width, y, width, y + rightSize, width - size, y + rightSize, width - size, y ] - y = y + rightSize + pRight[i] = [ width, y, width, y2, rightSizeX, y2, rightSizeX, y ] + y = y2 # center if nCenter: - pCenter = [ size, size, width - size, size, width - size, height - size, size, height - size ] + pCenter = [ leftSizeX, topSizeY, rightSizeX, topSizeY, rightSizeX, bottomSizeY, leftSizeX, bottomSizeY ] # Build canvas items cv.delete(ALL) + + self.weightImg = Image.new("L", (width, height), color="black") + self.weightDraw = ImageDraw.Draw(self.weightImg) + cv.weightImg = ImageTk.PhotoImage(self.weightImg) + self.weightImgId = cv.create_image(0, 0, image=cv.weightImg, anchor=NW, state=HIDDEN) if nTopLeft: - cv.create_polygon(pTopLeft, tags="TopLeft") + cv.create_polygon(self.cvXY(pTopLeft), tags="TopLeft") if nTopRight: - cv.create_polygon(pTopRight, tags="TopRight") + cv.create_polygon(self.cvXY(pTopRight), tags="TopRight") if nBottomLeft: - cv.create_polygon(pBottomLeft, tags="BottomLeft") + cv.create_polygon(self.cvXY(pBottomLeft), tags="BottomLeft") if nBottomRight: - cv.create_polygon(pBottomRight, tags="BottomRight") + cv.create_polygon(self.cvXY(pBottomRight), tags="BottomRight") if nCenter: - cv.create_polygon(pCenter, tags="Center") + cv.create_polygon(self.cvXY(pCenter), tags="Center") for i in range(nTop): - cv.create_polygon(pTop[i], tags="Top-{0}".format(i + 1)) + cv.create_polygon(self.cvXY(pTop[i]), tags="Top-{0}".format(i + 1)) for i in range(nBottom): - cv.create_polygon(pBottom[i], tags="Bottom-{0}".format(i + 1)) + cv.create_polygon(self.cvXY(pBottom[i]), tags="Bottom-{0}".format(i + 1)) for i in range(nLeft): - cv.create_polygon(pLeft[i], tags="Left-{0}".format(i + 1)) + cv.create_polygon(self.cvXY(pLeft[i]), tags="Left-{0}".format(i + 1)) for i in range(nRight): - cv.create_polygon(pRight[i], tags="Right-{0}".format(i + 1)) + cv.create_polygon(self.cvXY(pRight[i]), tags="Right-{0}".format(i + 1)) for id in cv.find_all(): - cv.itemconfigure(id, outline="#808080", width=3) - cv.tag_bind(id, "<Button-1>", self.cbSelectArea) + if id != self.weightImgId: + cv.itemconfigure(id, fill="", outline="#808080", width=3) + cv.tag_bind(id, "<Button-1>", self.cbSelectArea) + + def calcEdgeWeighting(self, edgeWeighting): + w = float(edgeWeighting) / 10.0 + fHeight = float(self.aHeight - 1) + fWidth = float(self.aWidth - 1) + centerY = self.aHeight / 2 + centerX = self.aWidth / 2 + for y in range(self.aHeight): + yNorm = float(y) / fHeight + if self.sTop: + wTop = pow(1.0 - yNorm, w) + if self.sBottom: + wBottom = pow(yNorm, w) + for x in range(self.aWidth): + xNorm = float(x) / fWidth + weight = 0.0 + if self.sLeft and x < centerX: + weight = pow(1.0 - xNorm, w) + if self.sRight and x >= centerX: + weight = max(weight, pow(xNorm, w)) + if self.sTop and y < centerY: + weight = max(weight, wTop) + if self.sBottom and y >= centerY: + weight = max(weight, wBottom) + bright = int(255.0 * weight) + px = self.cvX(x) + px2 = self.cvX(x + 1) + py = self.cvY(y) + py2 = self.cvY(y + 1) + if bright > 32: + bBright = bright - 32 + else: + bBright = 0 + self.weightDraw.polygon([(px, py), (px2, py), (px2, py2), (px, py2)], fill=bright, outline=bBright) + self.root.weightImg.paste(self.weightImg) + self.edgeWeighting = edgeWeighting + + def showEdgeWeighting(self, edgeWeighting, topWin): + if self.edgeWeighting != edgeWeighting: + cursor = topWin["cursor"] + topWin["cursor"] = "watch" + self.root.update_idletasks() + self.calcEdgeWeighting(edgeWeighting) + topWin["cursor"] = cursor + if self.edgeWeighting == edgeWeighting: + self.root.itemconfigure(self.weightImgId, state=NORMAL) + def hideEdgeWeighting(self): + self.root.itemconfigure(self.weightImgId, state=HIDDEN) + + def resetAreas(self): + self.parent["background"] = "cyan" + self.root["background"] = "black" + for id in self.root.find_all(): + if id != self.weightImgId: + self.root.itemconfigure(id, fill="", outline="#808080") + self.selectedArea = None + def initAreas(self, color): - self.root.configure(background=color) + self.parent["background"] = color + self.root["background"] = color for id in self.root.find_all(): - self.root.itemconfigure(id, fill=color, outline="#808080") + if id != self.weightImgId: + self.root.itemconfigure(id, fill=color, outline="#808080") self.selectedArea = None def setAreaColor(self, area, color): @@ -225,11 +366,12 @@ class AreasDialog: idList = cv.find_closest(cv.canvasx(event.x), cv.canvasx(event.y)) if len(idList): id = idList[0] - if self.selectedArea: - cv.itemconfigure(self.selectedArea, outline="#808080") - self.selectedArea = cv.gettags(id)[0] - cv.tag_raise(id) - cv.itemconfigure(id, outline="yellow") + if id != self.weightImgId: + if self.selectedArea: + cv.itemconfigure(self.selectedArea, outline="#808080") + self.selectedArea = cv.gettags(id)[0] + cv.tag_raise(id) + cv.itemconfigure(id, outline="yellow") for cb in self.selectCallbacks: cb.cbAreaSelected() diff --git a/df10ch_setup_pkg/bright_dlg.py b/df10ch_setup_pkg/bright_dlg.py index 0bf8bf4..294c40a 100644 --- a/df10ch_setup_pkg/bright_dlg.py +++ b/df10ch_setup_pkg/bright_dlg.py @@ -70,6 +70,7 @@ class BrightDialog: tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__()) return + self.areasDlg.hideEdgeWeighting() self.areasDlg.initAreas("black") self.setBright() diff --git a/df10ch_setup_pkg/device_dlg.py b/df10ch_setup_pkg/device_dlg.py index 0d48f2e..d400b33 100644 --- a/df10ch_setup_pkg/device_dlg.py +++ b/df10ch_setup_pkg/device_dlg.py @@ -37,6 +37,7 @@ class DeviceDialog: self.layoutDlg = layoutDlg self.selectedConfig = None self.selectedDeviceIdx = -1 + self.echo_test_running = False root = Frame(master, **args) self.root = root @@ -74,29 +75,46 @@ class DeviceDialog: self.btScanDevices = Button(root, text="Scan Devices", command=self.cbScanDevices) self.btScanDevices.grid(row=5, column=0, padx=5, pady=5, ipadx=5) - self.btResetSetup = Button(root, text="Firmware update", command=self.cbFirmwareUpdate) - self.btResetSetup.grid(row=5, column=1, padx=5, pady=5, ipadx=5) + self.btShowStatus = Button(root, text="Show Status", command=self.cbShowStatus) + self.btShowStatus.grid(row=6, column=0, padx=5, pady=5, ipadx=5) self.btStoreSetup = Button(root, text="Backup", command=self.cbBackupSetup) - self.btStoreSetup.grid(row=5, column=2, padx=5, pady=5, ipadx=5, sticky=E) + self.btStoreSetup.grid(row=5, column=1, padx=5, pady=5, ipadx=5) self.btStoreSetup = Button(root, text="Restore", command=self.cbRestoreSetup) - self.btStoreSetup.grid(row=5, column=3, padx=5, pady=5, ipadx=5, sticky=W) + self.btStoreSetup.grid(row=6, column=1, padx=5, pady=5, ipadx=5) + + self.btResetSetup = Button(root, text="Firmware update", command=self.cbFirmwareUpdate) + self.btResetSetup.grid(row=5, column=2, columnspan=4, padx=5, pady=5, ipadx=5) + + self.btEchoTest = Button(root, text="Start echo test", command=self.cbEchoTest) + self.btEchoTest.grid(row=6, column=2, columnspan=4, padx=5, pady=5, ipadx=5) self.btResetSetup = Button(root, text="Reset Setup", command=self.cbResetSetup) - self.btResetSetup.grid(row=5, column=4, padx=5, pady=5, ipadx=5, sticky=E) + self.btResetSetup.grid(row=5, column=6, padx=5, pady=5, ipadx=5) self.btStoreSetup = Button(root, text="Store Setup", command=self.cbStoreSetup) - self.btStoreSetup.grid(row=5, column=5, padx=5, pady=5, ipadx=5, sticky=W) + self.btStoreSetup.grid(row=6, column=6, padx=5, pady=5, ipadx=5) self.varStatus = StringVar() self.lbStatus = Label(root, textvariable=self.varStatus, anchor=W, relief=RIDGE) - self.lbStatus.grid(row=6, column=0, columnspan=6, padx=0, pady=0, sticky=W+E) + self.lbStatus.grid(row=7, column=0, columnspan=7, padx=0, pady=0, sticky=W+E) def cbSheetSelected(self, event): if self.selectedConfig: self.loadDeviceValues() + + def cbShowStatus(self): + if len(device_drv.DeviceList): + self.showStatus() + + def cbEchoTest(self): + if self.echo_test_running: + self.echo_test_running = False + else: + if self.selectedDeviceIdx != -1: + self.echoTest() def cbFirmwareUpdate(self): if len(device_drv.DeviceList): @@ -146,24 +164,27 @@ class DeviceDialog: self.scanDevices() def scanDevices(self): - deviceList = None self.selectedConfig = None self.selectedDeviceIdx = -1 - while not deviceList: + retry = True + while retry: try: device_drv.LoadConfigs() - if len(device_drv.DeviceList): - deviceList = device_drv.DeviceList except (device_drv.AtmoControllerError, usb.USBError) as err: if not tkMessageBox.askretrycancel(self.root.winfo_toplevel().title(), "Scanning for controllers fails:" + err.__str__(), icon=tkMessageBox.ERROR): - return False + if len(device_drv.DeviceList): + retry = False + else: + return False else: - if not deviceList: + if len(device_drv.DeviceList): + retry = False + else: if not tkMessageBox.askretrycancel(self.root.winfo_toplevel().title(), "No Controllers found!", icon=tkMessageBox.ERROR): return False idList = "" - for dev in deviceList: + for dev in device_drv.DeviceList: if len(idList) > 0: idList = idList + " " idList = idList + dev.id @@ -426,3 +447,43 @@ class DeviceDialog: def displayStatus(self, msg): self.varStatus.set(msg) self.root.update_idletasks() + + def showStatus(self): + msg = "" + for dev in device_drv.DeviceList: + request_stat = "N/A" + reply_stat = "N/A" + try: + rc = dev.get_reply_error_status() + except device_drv.AtmoControllerError as err: + pass + else: + reply_stat = device_drv.GetCommErrMsg(rc) + + try: + rc = dev.get_request_error_status() + except device_drv.AtmoControllerError as err: + pass + else: + request_stat = device_drv.GetCommErrMsg(rc) + + msg = msg + "{0}: ERR:{1} USB:{2} PWM:{3}\n".format(dev.id, dev.error_count, reply_stat, request_stat) + tkMessageBox.showinfo(self.root.winfo_toplevel().title() + " Communication status", msg) + + def echoTest(self): + self.echo_test_running = True + self.btEchoTest['text'] = "Stop echo test" + dev = device_drv.DeviceList[self.selectedDeviceIdx] + testValue = 0 + while testValue < 0x7FFFFFFF: + self.varStatus.set("Testing {0}: {1}".format(dev.id, testValue)) + self.root.update() + if not self.echo_test_running: + break + try: + dev.pwm_echo_test(testValue) + except device_drv.AtmoControllerError as err: + tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__()) + testValue = testValue + 1 + self.varStatus.set("") + self.btEchoTest['text'] = "Start echo test" diff --git a/df10ch_setup_pkg/device_drv.py b/df10ch_setup_pkg/device_drv.py index cf00272..8941df7 100644 --- a/df10ch_setup_pkg/device_drv.py +++ b/df10ch_setup_pkg/device_drv.py @@ -233,13 +233,25 @@ def GetCommErrMsg(stat): CONFIG_VALID_ID = 0xA0A1 -CONFIG_VERSION = 0x0001 -CONFIG_CLASS_VERSION = 0x0001 +CONFIG_VERSION = 0x0002 +CONFIG_CLASS_VERSION = 0x0002 DEFAULT_GAMMA_VAL = 22 MIN_GAMMA_VAL = 10 MAX_GAMMA_VAL = 50 +DEFAULT_OVERSCAN = 30 +MIN_OVERSCAN = 0 +MAX_OVERSCAN = 200 + +DEFAULT_EDGE_WEIGHTING = 80 +MIN_EDGE_WEIGHTING = 10 +MAX_EDGE_WEIGHTING = 200 + +DEFAULT_ANALYZE_SIZE = 1 +MIN_ANALYZE_SIZE = 0 +MAX_ANALYZE_SIZE = 5 + AREA_NAMES = "Top", "Bottom", "Left", "Right", "Center", "TopLeft", "TopRight", "BottomLeft", "BottomRight" MAX_AREAS = 30, 30, 30, 30, 1, 1, 1, 1, 1 @@ -297,7 +309,8 @@ class DF10CHController: self.version = version self.serial = serial self.id = 'DF10CH[{0},{1}]'.format(self.busnum, self.devnum) - + self.error_count = 0 + def release(self): self.usbdev.releaseInterface() @@ -310,11 +323,14 @@ class DF10CHController: retry = retry - 1 written = self.usbdev.controlMsg(usb.ENDPOINT_OUT|usb.RECIP_DEVICE|usb.TYPE_VENDOR, req, data, value, index, timeout) except usb.USBError as err: + self.error_count = self.error_count + 1 + print 'write req={0}, retry={1}: {2}'.format(req, retry, err.__str__()) if retry == 0: - raise AtmoControllerError(self, err.__str__()) + raise AtmoControllerError(self, 'write req={0}: {1}'.format(req, err.__str__())) else: if written != len(data): - raise AtmoControllerError(self, 'could not write all payload data to device') + self.error_count = self.error_count + 1 + raise AtmoControllerError(self, 'write req={0}: could not write all payload data'.format(req)) break def ctrl_read(self, req, value = 0, index = 0, size = 0, timeout = DEF_USB_TIMEOUT, retry = DEF_RETRY): @@ -323,27 +339,33 @@ class DF10CHController: retry = retry - 1 data = self.usbdev.controlMsg(usb.ENDPOINT_IN|usb.RECIP_DEVICE|usb.TYPE_VENDOR, req, size, value, index, timeout) except usb.USBError as err: + print 'read req={0}, retry={1}: {2}'.format(req, retry, err.__str__()) if retry == 0: - raise AtmoControllerError(self, err.__str__()) + self.error_count = self.error_count + 1 + raise AtmoControllerError(self, 'read req={0}: {1}'.format(req, err.__str__())) else: if len(data) != size: - raise AtmoControllerError(self, 'could not read all payload data') + self.error_count = self.error_count + 1 + raise AtmoControllerError(self, 'read req={0}: could not read all payload data'.format(req)) break return data def pwm_ctrl_write(self, req, value, index, data, timeout = DEF_USB_TIMEOUT, retry = DEF_RETRY): if len(data) > MAX_PWM_REQ_PAYLOAD_SIZE: + self.error_count = self.error_count + 1 raise AtmoControllerError(self, 'to many bytes in payload request data') self.ctrl_write(req, value, index, data, timeout, retry) def pwm_ctrl_read(self, req, value = 0, index = 0, size = 0, timeout = DEF_USB_TIMEOUT, retry = DEF_RETRY): if size > MAX_PWM_REPLY_PAYLOAD_SIZE: + self.error_count = self.error_count + 1 raise AtmoControllerError(self, 'to many bytes for reply payload data') return self.ctrl_read(req, value, index, size, timeout, retry) def verify_reply_data(self, start, data, rdata, msg): for i in range(len(data)): if data[i] != rdata[i]: + self.error_count = self.error_count + 1 raise AtmoControllerError(self, '{4}: verify of written {3} data fails {0:04X}: write {1:02X} read {2:02X}'.format(start + i, data[i], rdata[i], msg, self.id)) def read_ee_data(self, start, size): @@ -461,6 +483,13 @@ class DF10CHController: data = self.pwm_ctrl_read(PWM_REQ_GET_VERSION, 0, 0, 2) return data[1] + def pwm_echo_test(self, testValue): + v = testValue & 0x0FFFF + i = testValue >> 16 + data = self.pwm_ctrl_read(PWM_REQ_ECHO_TEST, v, i, 8) + if (data[2] + data[3] * 256) != v or (data[4] + data[5] * 256) != i: + raise AtmoControllerError(self, 'echo test fails for value {0}'.format(testValue)) + def get_pwm_flash_page_size(self): data = self.pwm_ctrl_read(BL_PWM_REQ_GET_PAGE_SIZE, 0, 0, 2) return data[0] + data[1] * 256 @@ -493,6 +522,7 @@ class dummyController: self.flash = dict() self.pwm_vers = PWM_VERS_APPL self.pwm_flash = dict() + self.error_count = 0 def _reset_setup(self): self.common_bright = NCOMMONBRIGHTS - 1 @@ -618,6 +648,9 @@ class dummyController: def get_pwm_version(self): return 1 + def pwm_echo_test(self, testValue): + pass + def get_bootloader_request_error_status(self): return 0 @@ -668,23 +701,36 @@ class ControllerConfig: self.commonPWMRes = self.ctrl.get_common_max_pwm_value() self.pwmFreq = self.ctrl.get_pwm_freq() self.commonBright = self.ctrl.get_common_brightness() + self.configVersion = 0 self.numAreas = [ 0 ] * NumBaseAreas() - - eedata = self.ctrl.read_ee_data(1, 5 + len(self.numAreas) + NCHANNELS * 6) + self.numReqChannels = 0 + self.analyzeSize = DEFAULT_ANALYZE_SIZE + self.edgeWeighting = DEFAULT_EDGE_WEIGHTING + self.overscan = DEFAULT_OVERSCAN + + eedata = self.ctrl.read_ee_data(1, 8 + len(self.numAreas) + NCHANNELS * 6) #print "read eedata:", eedata configValidId = eedata[0] + eedata[1] * 256 if configValidId == CONFIG_VALID_ID: - configVersion = "{0:04X}".format(eedata[2] + eedata[3] * 256) - for p in range(len(self.numAreas)): - self.numAreas[p] = eedata[4 + p] - if self.numAreas[p] > MAX_AREAS[p]: self.numAreas = MAX_AREAS[p] + self.configVersion = eedata[2] + eedata[3] * 256 + configVersionStr = "{0:04X}".format(self.configVersion) + p = 4 + for i in range(len(self.numAreas)): + self.numAreas[i] = min(eedata[p], MAX_AREAS[i]) + p = p + 1 + self.numReqChannels = min(eedata[p], NCHANNELS) + p = p + 1 + if self.configVersion > 1: + p = p + self.numReqChannels * 6 + self.overscan = max(min(eedata[p], MAX_OVERSCAN), MIN_OVERSCAN) + self.analyzeSize = max(min(eedata[p + 1], MAX_ANALYZE_SIZE), MIN_ANALYZE_SIZE) + self.edgeWeighting = max(min(eedata[p + 2], MAX_EDGE_WEIGHTING), MIN_EDGE_WEIGHTING) else: - configVersion = "" - self.version = "USB:{0} PWM:{1:04X} CONFIG:{2}".format(self.ctrl.version, self.ctrl.get_pwm_version(), configVersion) + configVersionStr = "" + self.version = "USB:{0} PWM:{1:04X} CONFIG:{2}".format(self.ctrl.version, self.ctrl.get_pwm_version(), configVersionStr) pwmChannelMap = self.ctrl.get_channel_map(0, NCHANNELS) #print "read pwmChannelMap", pwmChannelMap self.channelMap = dict() - self.numReqChannels = 0 for portName in PORT_NAME_MAP.keys(): foundArea = None port, pin = PORT_NAME_MAP[portName] @@ -694,21 +740,15 @@ class ControllerConfig: outPins = channelRec['pins'] if outPort == port and (outPins & pin): if configValidId == CONFIG_VALID_ID: - p = 4 + len(self.numAreas) - self.numReqChannels = eedata[p] - if self.numReqChannels > NCHANNELS: self.numReqChannels = 0 - p = p + 1 + p = 5 + len(self.numAreas) for i in range(self.numReqChannels): if eedata[p] == reqChannel: area = AreaName(eedata[p + 1], eedata[p + 2]) if area: foundArea = area color = eedata[p + 1] & 0x03 - gamma = eedata[p + 3] - if gamma < MIN_GAMMA_VAL: gamma = MIN_GAMMA_VAL - if gamma > MAX_GAMMA_VAL: gamma = MAX_GAMMA_VAL - whiteCal = eedata[p + 4] + eedata[p + 5] * 256 - if whiteCal > self.pwmRes: whiteCal = self.pwmRes + gamma = max(min(eedata[p + 3], MAX_GAMMA_VAL), MIN_GAMMA_VAL) + whiteCal = min((eedata[p + 4] + eedata[p + 5] * 256), self.pwmRes) break p = p + 6 break @@ -757,6 +797,9 @@ class ControllerConfig: pwmChannelMap.append(dict(channel=reqChannel, port=port, pins=pin)) eedata[4 + len(self.numAreas)] = n + eedata.append(self.overscan) + eedata.append(self.analyzeSize) + eedata.append(self.edgeWeighting) self.numReqChannels = 0 while len(pwmChannelMap) < NCHANNELS: diff --git a/df10ch_setup_pkg/layout_dlg.py b/df10ch_setup_pkg/layout_dlg.py index 500c029..7fc9ed7 100644 --- a/df10ch_setup_pkg/layout_dlg.py +++ b/df10ch_setup_pkg/layout_dlg.py @@ -29,36 +29,37 @@ import device_drv class LayoutDialog: def __init__(self, areasDlg, master=None, **args): self.areasDlg = areasDlg + self.edgeWeighting = 0 + self.analyzeSize = 0 + self.overscan = 0 self.numAreas = [ 0 ] * device_drv.NumBaseAreas() - self.varNumAreas = list() - for i in range(device_drv.NumBaseAreas()): - self.varNumAreas.append(StringVar()) root = Frame(master, **args) self.root = root + root.bind("<Map>", self.cbSheetSelected) - Label(root, text="Configure RGB-Areas", font=tkFont.Font(weight="bold")).grid(row=0, column=0, columnspan=5, padx=5, pady=5) - Label(root, text="Top").grid(row=1, column=2) - Label(root, text="TopLeft").grid(row=1, column=0, sticky=E) - Label(root, text="Left").grid(row=3, column=0, sticky=E) - Label(root, text="BottomLeft").grid(row=5, column=0, sticky=E) - Label(root, text="TopRight").grid(row=1, column=4, sticky=W) - Label(root, text="Right").grid(row=3, column=4, sticky=W) - Label(root, text="BottomRight").grid(row=5, column=4, sticky=W) - Label(root, text="Bottom").grid(row=5, column=2) + Label(root, text="Configure RGB-Areas", font=tkFont.Font(weight="bold")).grid(row=0, column=0, columnspan=8, padx=5, pady=5) + self.varNumAreas = list() + for i in range(device_drv.NumBaseAreas()): + self.varNumAreas.append(StringVar()) + + Label(root, text="TopLeft").grid(row=1, column=0, sticky=E) i = device_drv.AreaIndex("TopLeft") self.sbTopLeft = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], width=2) self.sbTopLeft.grid(row=2, column=1, padx=5, pady=5) + Label(root, text="TopRight").grid(row=1, column=4, sticky=W) i = device_drv.AreaIndex("TopRight") self.sbTopRight = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], width=2) self.sbTopRight.grid(row=2, column=3, padx=5, pady=5) + Label(root, text="BottomLeft").grid(row=5, column=0, sticky=E) i = device_drv.AreaIndex("BottomLeft") self.sbBottomLeft = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], width=2) self.sbBottomLeft.grid(row=4, column=1, padx=5, pady=5) + Label(root, text="BottomRight").grid(row=5, column=4, sticky=W) i = device_drv.AreaIndex("BottomRight") self.sbBottomRight = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], width=2) self.sbBottomRight.grid(row=4, column=3, padx=5, pady=5) @@ -67,45 +68,91 @@ class LayoutDialog: self.sbCenter = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], width=2) self.sbCenter.grid(row=3, column=2, padx=20, pady=20) + Label(root, text="Top").grid(row=1, column=2) i = device_drv.AreaIndex("Top") self.sbTop = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], increment=1, width=3) self.sbTop.grid(row=2, column=2, padx=5, pady=5) + Label(root, text="Bottom").grid(row=5, column=2) i = device_drv.AreaIndex("Bottom") self.sbBottom = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], increment=1, width=3) self.sbBottom.grid(row=4, column=2, padx=5, pady=5) + Label(root, text="Left").grid(row=3, column=0, sticky=E) i = device_drv.AreaIndex("Left") self.sbLeft = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], increment=1, width=3) self.sbLeft.grid(row=3, column=1, padx=5, pady=5) + Label(root, text="Right").grid(row=3, column=4, sticky=W) i = device_drv.AreaIndex("Right") self.sbRight = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], increment=1, width=3) self.sbRight.grid(row=3, column=3, padx=5, pady=5) + Label(root, text="Overscan [%1000]:").grid(row=2, column=6, sticky=E) + self.varOverscan = StringVar() + self.sbOverscan = Spinbox(root, textvariable=self.varOverscan, from_=device_drv.MIN_OVERSCAN, to=device_drv.MAX_OVERSCAN, increment=1, width=4) + self.sbOverscan.grid(row=2, column=7, padx=5, pady=5, sticky=W) + + Label(root, text="Analyze window size:").grid(row=3, column=6, sticky=E) + self.varAnalyzeSize = StringVar() + self.sbAnalyzeSize = Spinbox(root, textvariable=self.varAnalyzeSize, from_=device_drv.MIN_ANALYZE_SIZE, to=device_drv.MAX_ANALYZE_SIZE, increment=1, width=4) + self.sbAnalyzeSize.grid(row=3, column=7, padx=5, pady=5, sticky=W) + + Label(root, text="Edge weighting:").grid(row=4, column=6, sticky=E) + self.varWeight = StringVar() + self.sbWeight = Spinbox(root, textvariable=self.varWeight, from_=device_drv.MIN_EDGE_WEIGHTING, to=device_drv.MAX_EDGE_WEIGHTING, increment=1, width=4) + self.sbWeight.grid(row=4, column=7, padx=5, pady=5, sticky=W) + + self.btShowEdgeWeighting = Button(root, text="Show edge weighting", command=self.cbShowEdgeWeighting) + self.btShowEdgeWeighting.grid(row=6, column=0, columnspan=7, padx=20, pady=20, ipadx=5, sticky=E) + self.btApply = Button(root, text="Apply", command=self.cbApply) - self.btApply.grid(row=6, column=4, padx=20, pady=20, ipadx=5) + self.btApply.grid(row=6, column=7, columnspan=1, padx=20, pady=20, ipadx=5, sticky=E) + def cbSheetSelected(self, event): + self.areasDlg.resetAreas() + + def cbShowEdgeWeighting(self): + self.applyValues() + self.areasDlg.showEdgeWeighting(self.edgeWeighting, self.root.winfo_toplevel()) + def cbApply(self): + self.applyValues() + + def applyValues(self): for i in range(device_drv.NumBaseAreas()): self.numAreas[i] = int(self.varNumAreas[i].get()) - self.areasDlg.configAreas(self.numAreas) - + self.overscan = int(self.varOverscan.get()) + self.analyzeSize = int(self.varAnalyzeSize.get()) + self.edgeWeighting = int(self.varWeight.get()) + self.areasDlg.configAreas(self.numAreas, self.overscan, self.analyzeSize) + def setLayoutFromConfig(self): - for i in range(device_drv.NumBaseAreas()): - self.numAreas[i] = 0 + self.analyzeSize = 0 + self.edgeWeighting = 0 + self.overscan = 0 + self.numAreas = [ 0 ] * device_drv.NumBaseAreas() for ctrlId in device_drv.ConfigMap.keys(): config = device_drv.ConfigMap[ctrlId] + self.overscan = config.overscan + self.analyzeSize = config.analyzeSize + self.edgeWeighting = config.edgeWeighting for i in range(device_drv.NumBaseAreas()): if config.numAreas[i] > self.numAreas[i]: self.numAreas[i] = config.numAreas[i] for i in range(device_drv.NumBaseAreas()): self.varNumAreas[i].set(self.numAreas[i]) - self.areasDlg.configAreas(self.numAreas) - + self.varOverscan.set(self.overscan) + self.varAnalyzeSize.set(self.analyzeSize) + self.varWeight.set(self.edgeWeighting) + self.areasDlg.configAreas(self.numAreas, self.overscan, self.analyzeSize) + def setConfigFromLayout(self): for ctrlId in device_drv.ConfigMap.keys(): config = device_drv.ConfigMap[ctrlId] + config.overscan = self.overscan + config.analyzeSize = self.analyzeSize + config.edgeWeighting = self.edgeWeighting for i in range(device_drv.NumBaseAreas()): config.numAreas[i] = self.numAreas[i] - + diff --git a/df10ch_setup_pkg/map_dlg.py b/df10ch_setup_pkg/map_dlg.py index b8cd575..c91564b 100644 --- a/df10ch_setup_pkg/map_dlg.py +++ b/df10ch_setup_pkg/map_dlg.py @@ -206,6 +206,7 @@ class ChannelMapDialog: tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__()) return + self.areasDlg.hideEdgeWeighting() self.areasDlg.initAreas("black") self.actualCtrlId = None self.actualPortName = None diff --git a/df10ch_setup_pkg/white_cal_dlg.py b/df10ch_setup_pkg/white_cal_dlg.py index 3843e78..5f1f8b7 100644 --- a/df10ch_setup_pkg/white_cal_dlg.py +++ b/df10ch_setup_pkg/white_cal_dlg.py @@ -123,6 +123,7 @@ class WhiteCalDialog: tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__()) return + self.areasDlg.hideEdgeWeighting() if area: self.selectArea(area) self.setBright() |