fix: avr pdi decoding is error

This commit is contained in:
dreamsourcelabTAI 2023-12-27 10:37:19 +08:00
parent 735a8b5933
commit 12cec54159

View File

@ -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)