예제 #1
0
 def __init__(self, parent=None, app=None):
     QtGui.QMainWindow.__init__(self, parent)
     self.app = app
     self.ui = Ui_MainWindow()
     self.ui.setupUi(self)
     self.ui.textEditCode = LNTextEdit(self.set_breakpoint, self.ui.splitterHorizontal)
     font = QtGui.QFont()
     font.setFamily("Andale Mono")
     font.setPointSize(10)
     edit = self.ui.textEditCode.edit
     edit.setFont(font)
     edit.setLineWrapMode(QtGui.QPlainTextEdit.NoWrap)
     edit.setReadOnly(True)
     edit.setObjectName("textEditCode")                                                        
     self.ui.textEditCode.number_bar.setFont(font)
     self.avr = AVR(memblocks, None) # self.mem_block_changed
     # debug modes
     self.DM_TERMINATED = 0
     self.DM_RUNNING = 1
     self.DM_PAUSED = 2
     self.debug_mode = self.DM_TERMINATED
     self.pause_asap = False
     self.reset()
     if pyside:
         # signal new style
         self.ui.actionStart.triggered.connect(self.on_actionStart_triggered)
         self.ui.actionMemoryManager.triggered.connect(self.on_actionMemoryManager_triggered)
         self.ui.actionChangeRegisterValue.triggered.connect(self.on_actionChangeRegisterValue_triggered)
         self.ui.actionSetStartAddress.triggered.connect(self.on_actionSetStartAddress_triggered)
         self.ui.actionTerminate.triggered.connect(self.on_actionTerminate_triggered)
         self.ui.actionPause.triggered.connect(self.on_actionPause_triggered)
         self.ui.actionStepInto.triggered.connect(self.on_actionStepInto_triggered)
def command(cmd, ok):
    result = AVR().send(cmd)
    if result == 'OK':
        card = alexa.create_card(title="Marantz", subtitle=None, content=ok)
        response = alexa.create_response(ok, end_session=True, card_obj=card)
    else:
        card = alexa.create_card(title="Marantz",
                                 subtitle="Error",
                                 content=result)
        response = alexa.create_response(
            "Sorry, the receiver doesn't seem to be cooperating.",
            end_session=True,
            card_obj=card)
    return response
예제 #3
0
 def connect(self, port=0, baudrate=38400):
     AVR.connect(self, port, baudrate)
     Arduino.init(self)
예제 #4
0
 def __init__(self, port=None):
     AVR.__init__(self)
     self._frozen = False
     LeonardoBoard.__init__(self, self)
     Arduino.__init__(self, self)
     self._frozen = True
예제 #5
0
 def connect(self, port=0, baudrate=38400):
     AVR.connect(self, port, baudrate)
     Arduino.init(self)
예제 #6
0
 def __init__(self, port=None):
     AVR.__init__(self)
     self._frozen = False
     LeonardoBoard.__init__(self, self)
     Arduino.__init__(self, self)
     self._frozen = True
예제 #7
0
class MainForm(QtGui.QMainWindow):

    def __init__(self, parent=None, app=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.app = app
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.textEditCode = LNTextEdit(self.set_breakpoint, self.ui.splitterHorizontal)
        font = QtGui.QFont()
        font.setFamily("Andale Mono")
        font.setPointSize(10)
        edit = self.ui.textEditCode.edit
        edit.setFont(font)
        edit.setLineWrapMode(QtGui.QPlainTextEdit.NoWrap)
        edit.setReadOnly(True)
        edit.setObjectName("textEditCode")                                                        
        self.ui.textEditCode.number_bar.setFont(font)
        self.avr = AVR(memblocks, None) # self.mem_block_changed
        # debug modes
        self.DM_TERMINATED = 0
        self.DM_RUNNING = 1
        self.DM_PAUSED = 2
        self.debug_mode = self.DM_TERMINATED
        self.pause_asap = False
        self.reset()
        if pyside:
            # signal new style
            self.ui.actionStart.triggered.connect(self.on_actionStart_triggered)
            self.ui.actionMemoryManager.triggered.connect(self.on_actionMemoryManager_triggered)
            self.ui.actionChangeRegisterValue.triggered.connect(self.on_actionChangeRegisterValue_triggered)
            self.ui.actionSetStartAddress.triggered.connect(self.on_actionSetStartAddress_triggered)
            self.ui.actionTerminate.triggered.connect(self.on_actionTerminate_triggered)
            self.ui.actionPause.triggered.connect(self.on_actionPause_triggered)
            self.ui.actionStepInto.triggered.connect(self.on_actionStepInto_triggered)

    def set_breakpoint(self, lineno, state):
        """
        Add or remove breakpoint for given line
        @param  lineno  line number for the breakpoint
        @param  state   0: remove breakpoint, 1: add breakpoint
        @return: True if the breakpoint to Add is in a valid line
        """
        found = False
        for line in self.avr.list:
            if line['line'] == lineno:
                found = True
                break
            if line['line'] > lineno:
                break
        if found:
            if state == 0:
                brkpt.remove(lineno)
            elif state == 1:
                brkpt.append(lineno)
        return found

    def enable_debug_buttons(self):
        if self.debug_mode is self.DM_RUNNING:
            enable = play = False
            pause = True
        elif self.debug_mode is self.DM_PAUSED:
            enable = play = True
            pause = False
        else:
            # default terminated
            enable = pause = False
            play = True
        self.ui.actionStart.setEnabled(play)
        self.ui.actionPause.setEnabled(pause)
        self.ui.actionTerminate.setEnabled(enable)
        self.ui.actionStepInto.setEnabled(enable)
        self.ui.actionStepOver.setEnabled(enable)
        self.ui.actionStepReturn.setEnabled(enable)
        self.ui.actionChangeRegisterValue.setEnabled(enable)

    def set_current_line(self, line):
        """Sets the cursor and 'current instruction' arrow icon to the given line in the text editor"""
        # move the cursor to the beginning of the specified line
        edit = self.ui.textEditCode.edit
        cursor = edit.textCursor()
        cursor.setPosition(edit.document().findBlockByLineNumber(line).position() - 1)
        cursor.movePosition(QTextCursor.StartOfLine)
        edit.setTextCursor(cursor)
        # set the icon
        self.ui.textEditCode.setCurrentInstruction(line)

    def set_next_addr(self, next_addr, animate=False):
        global current_inst
        # move to following instruction
        if next_addr == -1:
            # have to move to the next instruction
            if current_inst + 1 >= len(self.avr.list):
                QtGui.QMessageBox.critical(self, 'Error', "Cannot move to next instruction. Program end.")
                return False
            current_inst += 1
        else:
            current_inst = next_addr
        if animate:
            self.set_current_line(self.avr.list[current_inst]['line'])
        return True

    def reset(self):
        self.avr.reset()

    def on_actionMemoryManager_triggered(self, checked=None):
        if not pyside and checked is None: return
        mman = MemoryManager()
        mman.exec_()

    def on_actionChangeRegisterValue_triggered(self, checked=None):
        if not pyside and checked is None: return
        dlg = QtGui.QDialog()
        chval = Ui_ChangeValueDialog()
        chval.setupUi(dlg)
        for key in sorted(self.avr.r.keys()):
            chval.comboBoxRegister.addItem(key)
        if dlg.exec_() == 1:
            try:
                value = "%s"%chval.lineEditValue.text().trimmed()
                valint = int(value, 0)
                if value == "" or value is None or valint > 0xffffffff:
                    QtGui.QMessageBox.critical(self, 'Error', "Invalid value (must be an integer between -2,147,483,648 and +2,147,483,647)")
                    return
                self.avr.r["%s"%chval.comboBoxRegister.currentText()] = valint
                self.update_reg_view()
            except:
                QtGui.QMessageBox.critical(self, 'Error', "Invalid value (must be an integer between -2,147,483,648 and +2,147,483,647)")
                return

    def on_actionSetStartAddress_triggered(self, checked=None):
        if not pyside and checked is None: return
        dlg = QtGui.QDialog()
        input = Ui_InputDialog()
        input.setupUi(dlg)
        input.labelField.setText("Start Address")
        input.labelInfo.setText("Select the start address for the program")
        input.lineEditField.setText("0x%.8x"%options['start'])
        if dlg.exec_() == 1:
            try:
                value = str(input.lineEditField.text().trimmed())
                valint = int(value, 0)
                if value == "" or value is None or valint > 0xffffffff:
                    QtGui.QMessageBox.critical(self, 'Error', "Invalid start address (must be an integer between 0x0 and 0xFFFFFFFF)")
                    return
                options['start'] = valint
            except:
                QtGui.QMessageBox.critical(self, 'Error', "Invalid start address (must be an integer between 0x0 and 0xFFFFFFFF)")
                return

    def on_actionTerminate_triggered(self, checked=None):
        if not pyside and checked is None: return
        self.debug_mode = self.DM_TERMINATED
        self.enable_debug_buttons()
        self.ui.textEditCode.setCurrentInstruction(None)
        global current_inst
        current_inst = -1
        self.reset()
        self.update_reg_view()

    def start_program(self, checked=None, animate=False):
        if not pyside and checked is None: return
        global current_inst
        list = self.avr.list
        if self.debug_mode == self.DM_TERMINATED:
            self.reg_prev = self.avr.r.copy()
            self.f_prev = self.avr.f.copy()
            self.cycles_prev = 0
            current_inst = 0
            start = options['start']
            ot_brkpt.append(list[0]['line'])
        # run/resume the program
        self.debug_mode = self.DM_RUNNING
        self.enable_debug_buttons()
        self.pause_asap = False
        self.ui.textEditCode.setCurrentInstruction(None)
        first = True
        print "Start: %s"%datetime.datetime.now()
        i = 0
        # TODO: scoreboard debug only
        testcase = { 'bp': [299, 210], 'exp': 19 } # front porch
        testcase = { 'bp': [324, 299], 'exp': 74 } # hsync pulse
        testcase = { 'bp': [353, 324], 'exp': 38 } # back porch
        testcase = { 'bp': [210, 353], 'exp': 503 } # line painting
        testcase = { 'bp': [], 'exp': 0 } # nothing
        dbg_brkpt = testcase['bp']
        dbg_first = True
        while not self.pause_asap:
            # backup registers and flags
#            self.reg_prev = self.avr.r.copy()
#            self.f_prev = self.avr.f.copy()
            # check one-time breakpoints
            line = list[current_inst]['line']
            if line in ot_brkpt:
                ot_brkpt.remove(line)
                break
            # check regular breakpoints
            if not first and line in brkpt:
                print "Breakpoint: %s"%datetime.datetime.now()
                break
            if line in dbg_brkpt:
                d = self.avr.cycles - self.cycles_prev
                if not dbg_first and dbg_brkpt[0] == line:
                    print "Diff Cycles: %d [ @20MHz = %.2fus ] Line: %d<br>"%(d, d * 0.05, line)
                    if d != testcase['exp']:
                        break
                dbg_first = False
                self.cycles_prev = self.avr.cycles
            first = False
            # execute assembly line
            err, next_addr = self.avr.execute_asm_line(current_inst)
            if err is not None:
                # show message and break on error
                QtGui.QMessageBox.critical(self, 'Error', err)
                break
            if not self.set_next_addr(next_addr, animate):
                break
            if animate:
                self.update_reg_view()
            if i > 100:
                # process GUI events
                self.app.processEvents()
                i = 0
            i += 1
        # program paused
        self.update_reg_view()
        self.set_current_line(list[current_inst]['line'])
        self.debug_mode = self.DM_PAUSED
        self.enable_debug_buttons()

    def on_actionStart_triggered(self, checked=None):
        #global GLOBAL
        #GLOBAL = self
        #import cProfile
        #cProfile.run("GLOBAL.start_program(%r,%r)"%(checked, animate))
        self.start_program(checked, False)

    def on_actionPause_triggered(self, checked=None):
        if not pyside and checked is None: return
        if self.debug_mode == self.DM_RUNNING:
            self.pause_asap = True

    def update_reg_view(self):
        edit = self.ui.plainTextEditRegisters
        # list of registers in the order they should appear on screen
        regs = ('r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10', 'r11', 'r12',
                'r13', 'r14', 'r15', 'r16', 'r17', 'r18', 'r19', 'r20', 'r21', 'r22', 'r23', 'r24', 'r25',
                'r26', 'r27', 'r28', 'r29', 'r30', 'r31')
        lines = len(regs) / 2
        html = ""
        strs = ""
        for i in range(lines):
            reg1 = regs[i]
            reg2 = regs[i+lines] if i+lines < len(regs) else None
            for reg in (reg1, reg2):
                if reg == None: continue
                end = 5*"&nbsp;" if reg == reg1 else "<br>"
                color = "red" if self.reg_prev[reg] != self.avr.r[reg] else "black"
                spaces = (9-len(reg))*"&nbsp;"
                html += "<font color='%s'>%s:%s0x%.8x</color>%s"%(color, reg, spaces, self.avr.r[reg] or 0, end)
        # strings
        for reg in regs:
            # find the memory block
            addr = self.avr.r[reg]
            value = ""
            for i, memblock in enumerate(memblocks):
                if addr >= memblock['addr'] and addr <= memblock['addr'] + len(memblock['mem']):
                    addr -= memblock['addr']
                    endaddr = addr
                    while endaddr < len(memblock['mem']):
                        if memblock['mem'][endaddr] == 0:
                            break
                        endaddr += 1
                    value = "%s"%str(memblock['mem'][addr:endaddr])
            if value == "" and addr < 256:
                value = "'%c'"%(addr & 0xFF, ) if addr else "NULL"
            #value = strings.get("%.8x"%self.avr.r[key]) or ""
            strs += "%s: %s<br>"%(reg, value, )

        html += "<br><br>"
        strs += "<br><br>"
        flags = ('Z', 'N', 'C', 'V')
        for flag in flags:
            color = "red" if self.f_prev[flag] != self.avr.f[flag] else "black"
            html += "<font color='%s'>%s: %s</color>&nbsp;&nbsp;"%(color, flag, self.avr.f[flag])
        html += "<br>"
        html += "Cycles: %d<br>"%(self.avr.cycles)
        d = self.avr.cycles - self.cycles_prev
        html += "Diff Cycles: %d [ @20MHz = %.2fus ]"%(d, d * 0.05)
        html += "<br>"
        edit.clear()
        edit.appendHtml(html)
        self.cycles_prev = self.avr.cycles
        self.ui.plainTextEditStrings.clear()
        self.ui.plainTextEditStrings.appendHtml(strs)

    def mem_block_changed(self, index, pos, size):
        if index != 3: return
        edit = self.ui.plainTextEditMemory
        cursor = edit.textCursor()
        cursor.beginEditBlock()
        for i in range(size):
            offset = pos + i
            lines = math.trunc(offset / 32)
            line_offset = offset % 32
            # each line has 10 + (3 * 32) + 32 + 1 = 139
            cursor.setPosition((lines * 139) + 10 + (line_offset * 3))
            cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, 2)
            cursor.removeSelectedText()
            cursor.insertText("%.2x"%(memblocks[index]['mem'][offset] & 0xFF))
            # now replace the 'readable' part
            cursor.setPosition((lines * 139) + 106 + line_offset)
            cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, 1)
            cursor.removeSelectedText()
            cursor.insertText("%s"%(memblocks[index]['mem'][offset:offset + 1].translate(printable)))
        cursor.endEditBlock()

    def on_actionStepInto_triggered(self, checked=None):
        if not pyside and checked is None: return
        global current_inst
        if current_inst < 0 or current_inst >= len(self.avr.list):
            return
        self.reg_prev = self.avr.r.copy()
        self.f_prev = self.avr.f.copy()
        err, next_addr = self.avr.execute_asm_line(current_inst)
        if err is not None:
            QtGui.QMessageBox.critical(self, 'Error', err)
            return
        # update registers view
        self.update_reg_view()
        if next_addr is None:
            return
        self.set_next_addr(next_addr, True)