diff --git a/libsigrokdecode4DSL/decoders/avr_pdi/pd.py b/libsigrokdecode4DSL/decoders/avr_pdi/pd.py index f55d856d..3b958c02 100644 --- a/libsigrokdecode4DSL/decoders/avr_pdi/pd.py +++ b/libsigrokdecode4DSL/decoders/avr_pdi/pd.py @@ -86,6 +86,7 @@ class Ann: BIN_BYTES, ) = range(1) +#元组 Bit = namedtuple('Bit', 'val ss es') class PDI: @@ -175,10 +176,14 @@ class Decoder(srd.Decoder): self.break_es = None self.clear_insn() + + + def clear_insn(self): # Collect instructions and their arguments, # properties of the current instructions. self.insn_rep_count = 0 + self.insn_opcode = None self.insn_wr_counts = [] self.insn_rd_counts = [] @@ -191,6 +196,17 @@ class Decoder(srd.Decoder): self.cmd_insn_parts_nice = [] self.cmd_insn_parts_terse = [] + #new + self.insn_write_counts = 0 + self.insn_read_counts = 0 + self.width_addr = 0 + self.width_data = 0 + self.ptr_txt = None + self.ptr_txt_terse = None + self.reg_num = None + self.reg_txt = None + self.reg_txt_terse = None + def metadata(self, key, value): if key == srd.SRD_CONF_SAMPLERATE: self.samplerate = value @@ -218,6 +234,7 @@ class Decoder(srd.Decoder): # Handle BREAK conditions, which will abort any # potentially currently executing instruction. + is_break = byteval is None if is_break: self.cmd_insn_parts_nice.append('BREAK') @@ -227,6 +244,7 @@ class Decoder(srd.Decoder): # Decode instruction opcodes and argument sizes # from the first byte of a transaction. + if self.insn_opcode is None and not is_break: opcode = (byteval & 0xe0) >> 5 arg30 = byteval & 0x0f @@ -238,112 +256,137 @@ class Decoder(srd.Decoder): if opcode == PDI.OP_LDS: # LDS: load data, direct addressing. # Writes an address, reads a data item. - width_addr = arg32 + 1 - width_data = arg10 + 1 - self.insn_wr_counts = [width_addr] - self.insn_rd_counts = [width_data] + + self.width_addr = arg32 + 1 + self.width_data = arg10 + 1 + + self.insn_write_counts = 1 + self.insn_read_counts = 1 + mnemonics = [ - 'Insn: LDS a{:d}, m{:d}'.format(width_addr, width_data), - 'LDS a{:d}, m{:d}'.format(width_addr, width_data), 'LDS', + 'Insn: LDS a{:d}, m{:d}'.format(self.width_addr, self.width_data), + 'LDS a{:d}, m{:d}'.format(self.width_addr, self.width_data), 'LDS', ] self.cmd_insn_parts_nice = ['LDS'] self.cmd_insn_parts_terse = ['LDS'] elif opcode == PDI.OP_LD: # LD: load data, indirect addressing. # Reads a data item, with optional repeat. - ptr_txt = PDI.pointer_format_nice[arg32] - ptr_txt_terse = PDI.pointer_format_terse[arg32] - width_data = arg10 + 1 - self.insn_wr_counts = [] - self.insn_rd_counts = [width_data] + + self.ptr_txt = PDI.pointer_format_nice[arg32] + self.ptr_txt_terse = PDI.pointer_format_terse[arg32] + + self.width_data = arg10 + 1 + + self.insn_write_counts = 0 + self.insn_read_counts = 1 + if self.insn_rep_count: - self.insn_rd_counts.extend(self.insn_rep_count * [width_data]) + self.insn_read_counts = self.insn_rep_count * self.insn_read_counts self.insn_rep_count = 0 mnemonics = [ - 'Insn: LD {:s} m{:d}'.format(ptr_txt, width_data), - 'LD {:s} m{:d}'.format(ptr_txt, width_data), 'LD', + 'Insn: LD {:s} m{:d}'.format(self.ptr_txt, self.width_data), + 'LD {:s} m{:d}'.format(self.ptr_txt, self.width_data), 'LD', ] - self.cmd_insn_parts_nice = ['LD', ptr_txt] - self.cmd_insn_parts_terse = ['LD', ptr_txt_terse] + self.cmd_insn_parts_nice = ['LD', self.ptr_txt] + self.cmd_insn_parts_terse = ['LD', self.ptr_txt_terse] elif opcode == PDI.OP_STS: # STS: store data, direct addressing. # Writes an address, writes a data item. - width_addr = arg32 + 1 - width_data = arg10 + 1 - self.insn_wr_counts = [width_addr, width_data] - self.insn_rd_counts = [] + self.width_addr = arg32 + 1 + self.width_data = arg10 + 1 + + self.insn_write_counts = 2 + self.insn_read_counts = 0 + mnemonics = [ - 'Insn: STS a{:d}, i{:d}'.format(width_addr, width_data), - 'STS a{:d}, i{:d}'.format(width_addr, width_data), 'STS', + 'Insn: STS a{:d}, i{:d}'.format(self.width_addr, self.width_data), + 'STS a{:d}, i{:d}'.format(self.width_addr, self.width_data), 'STS', ] self.cmd_insn_parts_nice = ['STS'] self.cmd_insn_parts_terse = ['STS'] elif opcode == PDI.OP_ST: # ST: store data, indirect addressing. # Writes a data item, with optional repeat. - ptr_txt = PDI.pointer_format_nice[arg32] - ptr_txt_terse = PDI.pointer_format_terse[arg32] - width_data = arg10 + 1 - self.insn_wr_counts = [width_data] - self.insn_rd_counts = [] + self.ptr_txt = PDI.pointer_format_nice[arg32] + self.ptr_txt_terse = PDI.pointer_format_terse[arg32] + + self.width_data = arg10 + 1 + + self.insn_write_counts = 1 + self.insn_read_counts = 0 + if self.insn_rep_count: - self.insn_wr_counts.extend(self.insn_rep_count * [width_data]) + self.insn_write_counts = self.insn_rep_count * self.insn_write_counts self.insn_rep_count = 0 mnemonics = [ - 'Insn: ST {:s} i{:d}'.format(ptr_txt, width_data), - 'ST {:s} i{:d}'.format(ptr_txt, width_data), 'ST', + 'Insn: ST {:s} i{:d}'.format(self.ptr_txt, self.width_data), + 'ST {:s} i{:d}'.format(self.ptr_txt, self.width_data), 'ST', ] - self.cmd_insn_parts_nice = ['ST', ptr_txt] - self.cmd_insn_parts_terse = ['ST', ptr_txt_terse] + self.cmd_insn_parts_nice = ['ST', self.ptr_txt] + self.cmd_insn_parts_terse = ['ST', self.ptr_txt_terse] elif opcode == PDI.OP_LDCS: # LDCS: load control/status. # Loads exactly one byte. - reg_num = arg30 - reg_txt = PDI.ctrl_reg_name.get(reg_num, 'r{:d}'.format(reg_num)) - reg_txt_terse = '{:d}'.format(reg_num) - self.insn_wr_counts = [] - self.insn_rd_counts = [1] + + self.reg_num = arg30 + self.reg_txt = PDI.ctrl_reg_name.get(self.reg_num, 'r{:d}'.format(self.reg_num)) + self.reg_txt_terse = '{:d}'.format(self.reg_num) + + self.insn_write_counts = 0 + self.insn_read_counts = 1 + + self.width_data = 1 + mnemonics = [ - 'Insn: LDCS {:s}, m1'.format(reg_txt), - 'LDCS {:s}, m1'.format(reg_txt), 'LDCS', + 'Insn: LDCS {:s}, m1'.format(self.reg_txt), + 'LDCS {:s}, m1'.format(self.reg_txt), 'LDCS', ] - self.cmd_insn_parts_nice = ['LDCS', reg_txt] - self.cmd_insn_parts_terse = ['LDCS', reg_txt_terse] + self.cmd_insn_parts_nice = ['LDCS', self.reg_txt] + self.cmd_insn_parts_terse = ['LDCS', self.reg_txt_terse] elif opcode == PDI.OP_STCS: # STCS: store control/status. # Writes exactly one byte. - reg_num = arg30 - reg_txt = PDI.ctrl_reg_name.get(reg_num, 'r{:d}'.format(reg_num)) - reg_txt_terse = '{:d}'.format(reg_num) - self.insn_wr_counts = [1] - self.insn_rd_counts = [] + + self.reg_num = arg30 + self.reg_txt = PDI.ctrl_reg_name.get(self.reg_num, 'r{:d}'.format(self.reg_num)) + self.reg_txt_terse = '{:d}'.format(self.reg_num) + + self.width_data = 1 + + self.insn_write_counts = 1 + self.insn_read_counts = 0 + mnemonics = [ - 'Insn: STCS {:s}, i1'.format(reg_txt), - 'STCS {:s}, i1'.format(reg_txt), 'STCS', + 'Insn: STCS {:s}, i1'.format(self.reg_txt), + 'STCS {:s}, i1'.format(self.reg_txt), 'STCS', ] - self.cmd_insn_parts_nice = ['STCS', reg_txt] - self.cmd_insn_parts_terse = ['STCS', reg_txt_terse] + self.cmd_insn_parts_nice = ['STCS', self.reg_txt] + self.cmd_insn_parts_terse = ['STCS', self.reg_txt_terse] elif opcode == PDI.OP_REPEAT: # REPEAT: sets repeat count for the next instruction. # Reads repeat count from following bytes. - width_data = arg10 + 1 - self.insn_wr_counts = [width_data] - self.insn_rd_counts = [] + self.width_data = arg10 + 1 + + self.insn_write_counts = 1 + self.insn_read_counts = 0 + mnemonics = [ - 'Insn: REPEAT i{:d}'.format(width_data), - 'REPEAT i{:d}'.format(width_data), 'REP', + 'Insn: REPEAT i{:d}'.format(self.width_data), + 'REPEAT i{:d}'.format(self.width_data), 'REP', ] self.cmd_insn_parts_nice = ['REPEAT'] self.cmd_insn_parts_terse = ['REP'] + elif opcode == PDI.OP_KEY: # KEY: set activation key (enables PDIBUS mmap access). # Writes a sequence of 8 bytes, fixed length. - width_data = 8 - self.insn_wr_counts = [width_data] - self.insn_rd_counts = [] + + self.width_data = 8 + mnemonics = [ - 'Insn: KEY i{:d}'.format(width_data), - 'KEY i{:d}'.format(width_data), 'KEY', + 'Insn: KEY i{:d}'.format(self.width_data), + 'KEY i{:d}'.format(self.width_data), 'KEY', ] self.cmd_insn_parts_nice = ['KEY'] self.cmd_insn_parts_terse = ['KEY'] @@ -353,12 +396,33 @@ class Decoder(srd.Decoder): # Prepare to write/read operands/data bytes. self.insn_dat_bytes = [] - if self.insn_wr_counts: - self.insn_dat_count = self.insn_wr_counts[0] + + if self.insn_write_counts != 0: + if self.insn_opcode == PDI.OP_LDS: + self.insn_dat_count = self.width_addr + elif self.insn_opcode == PDI.OP_STS: + if self.insn_write_counts == 2: + self.insn_dat_count = self.width_addr + elif self.insn_write_counts == 1: + self.insn_dat_count = self.width_data + elif self.insn_opcode == PDI.OP_ST: + self.insn_dat_count = self.width_data + elif opcode == PDI.OP_STCS: + self.insn_dat_count = self.width_data + elif opcode == PDI.OP_REPEAT: + self.insn_dat_count = self.width_data + elif opcode == PDI.OP_KEY: + self.insn_dat_count = self.width_data return - if self.insn_rd_counts: - self.insn_dat_count = self.insn_rd_counts[0] + if self.insn_read_counts != 0: + if self.insn_opcode == PDI.OP_LDS: + self.insn_dat_count = self.width_data + elif self.insn_opcode == PDI.OP_LD: + self.insn_dat_count = self.width_data + elif self.insn_opcode == PDI.OP_LDCS: + self.insn_dat_count = self.width_data return + # FALLTHROUGH. # When there are no operands or data bytes to read, # then fall through to the end of the instruction @@ -366,6 +430,7 @@ class Decoder(srd.Decoder): # Read bytes which carry operands (addresses, immediates) # or data values for memory access. + if self.insn_dat_count and not is_break: # Accumulate received bytes until another multi byte @@ -373,6 +438,7 @@ class Decoder(srd.Decoder): if not self.insn_dat_bytes: self.insn_ss_data = ss self.insn_dat_bytes.append(byteval) + self.insn_dat_count -= 1 if self.insn_dat_count: return @@ -381,16 +447,17 @@ class Decoder(srd.Decoder): # "consume" its length spec (to simplify later steps). data_ss = self.insn_ss_data data_es = es - if self.insn_wr_counts: + if self.insn_write_counts != 0: data_ann = Ann.DATA_PROG - data_width = self.insn_wr_counts.pop(0) - elif self.insn_rd_counts: + self.insn_write_counts = self.insn_write_counts - 1 + elif self.insn_read_counts != 0: data_ann = Ann.DATA_DEV - data_width = self.insn_rd_counts.pop(0) + self.insn_read_counts = self.insn_read_counts - 1 # PDI communicates multi-byte data items in little endian # order. Get a nice textual representation of the number, # wide and narrow for several zoom levels. + self.insn_dat_bytes.reverse() data_txt_digits = ''.join(['{:02x}'.format(b) for b in self.insn_dat_bytes]) data_txt_hex = '0x' + data_txt_digits @@ -407,19 +474,40 @@ class Decoder(srd.Decoder): self.cmd_insn_parts_nice.append(data_txt_hex) self.cmd_insn_parts_terse.append(data_txt_digits) - # Send out write data first until exhausted, - # then drain expected read data. - if self.insn_wr_counts: - self.insn_dat_count = self.insn_wr_counts[0] + if self.insn_write_counts != 0: + if self.insn_opcode == PDI.OP_LDS: + self.insn_dat_count = self.width_addr + elif self.insn_opcode == PDI.OP_STS: + if self.insn_write_counts == 2: + self.insn_dat_count = self.width_addr + elif self.insn_write_counts == 1: + self.insn_dat_count = self.width_data + elif self.insn_opcode == PDI.OP_ST: + self.insn_dat_count = self.width_data + elif opcode == PDI.OP_STCS: + self.insn_dat_count = self.width_data + elif opcode == PDI.OP_REPEAT: + self.insn_dat_count = self.width_data + elif opcode == PDI.OP_KEY: + self.insn_dat_count = self.width_data return - if self.insn_rd_counts: - self.insn_dat_count = self.insn_rd_counts[0] + if self.insn_read_counts != 0: + if self.insn_opcode == PDI.OP_LDS: + self.insn_dat_count = self.width_data + elif self.insn_opcode == PDI.OP_LD: + self.insn_dat_count = self.width_data + elif self.insn_opcode == PDI.OP_LDCS: + self.insn_dat_count = self.width_data return # FALLTHROUGH. # When all operands and data bytes were seen, # terminate the inspection of the instruction. + if self.cmd_ss == None: + self.printlog("self.cmd_ss is null") + return + # Postprocess the instruction after its operands were seen. cmd_es = es cmd_txt_nice = ' '.join(self.cmd_insn_parts_nice) @@ -481,10 +569,16 @@ class Decoder(srd.Decoder): # after the line went idle (high) again. Pass BREAK to the upper layer # as well. When the line is low, BREAK still is pending. When the line # is high, the current bit cannot be START, thus return from here. + if self.break_ss is not None: - if bitval == '0': + if bitval == 0: self.break_es = es return + + if self.break_es == None: + self.printlog("self.break_es is null.") + return + self.put(self.break_ss, self.break_es, self.out_ann, [Ann.BREAK, ann_class_text[Ann.BREAK]]) self.handle_byte(self.break_ss, self.break_es, None) @@ -573,4 +667,4 @@ class Decoder(srd.Decoder): def decode(self): while True: (clock_pin, data_pin) = self.wait({0: 'e'}) - self.handle_clk_edge(clock_pin, data_pin) + self.handle_clk_edge(clock_pin, data_pin) \ No newline at end of file