mirror of
https://github.com/DreamSourceLab/DSView.git
synced 2025-02-02 13:52:55 +08:00
fix: avr pdi decoding is error
This commit is contained in:
parent
735a8b5933
commit
12cec54159
@ -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)
|
Loading…
x
Reference in New Issue
Block a user