2
0
forked from Ivasoft/DSView

update: Some protocols support multiple display formats

This commit is contained in:
dreamsourcelabTAI
2022-03-30 18:24:13 +08:00
parent e6a496755f
commit 63e01f2d3b
13 changed files with 115 additions and 82 deletions

View File

@@ -153,6 +153,7 @@ const std::vector<QString>& Annotation::annotations() const
for (QString &rd_src : resItem.src_lines)
{
QString src = rd_src.replace("{$}", "%s");
const char *num_str = _status->m_resTable.format_numberic(resItem.str_number_hex, resItem.cur_display_format);
const char *src_str = src.toUtf8().data();

View File

@@ -22,6 +22,8 @@
#include "annotationrestable.h"
#include <assert.h>
#include <stdlib.h>
#include <QDebug>
#include "../../dsvdef.h"
const char g_bin_cvt_table[] = "0000000100100011010001010110011110001001101010111100110111101111";
@@ -154,7 +156,21 @@ const char* AnnotationResTable::format_to_string(const char *hex_str, int fmt)
while (rd >= data)
{
c = *rd;
dex = (int)(c <= '9' ? (c - '0') : (c - 'A' + 10));
if (c >= '0' && c <= '9'){
dex = (int)(c - '0');
}
else if (c >= 'A' && c <= 'F'){
dex = (int)(c - 'A') + 10;
}
else if (c >= 'a' && c <= 'f'){
dex = (int)(c - 'a') + 10;
}
else{
qDebug()<<"is not a hex string!";
assert(false);
}
char *ptable = (char*)g_bin_cvt_table + dex * 4;
buf -= 4; //move to left for 4 bytes
@@ -225,14 +241,11 @@ const char* AnnotationResTable::format_numberic(const char *hex_str, int fmt)
c = *rd;
rd++;
if (c >= '0' && c <= '9')
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))
{
continue;
}
if (c >= 'A' && c <= 'F')
{
continue;
continue;
}
bMutil = true;
break;
}
@@ -255,7 +268,7 @@ const char* AnnotationResTable::format_numberic(const char *hex_str, int fmt)
c = *rd;
rd++;
if (c >= '0' && c <= '9'){
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')){
if (sub_wr == sub_end){
printf("conver error,sub string length is too long!\n");
return hex_str;
@@ -265,17 +278,6 @@ const char* AnnotationResTable::format_numberic(const char *hex_str, int fmt)
sub_wr++;
continue;
}
if (c >= 'A' && c <= 'F'){
if (sub_wr == sub_end){
printf("convert error,sub string length is too long!\n");
return hex_str;
}
*sub_wr = c;
sub_wr++;
continue;
}
//convert sub string
if (sub_wr != sub_buf){

View File

@@ -130,14 +130,10 @@ class Decoder(srd.Decoder):
if reg_name is None:
# We don't know the bank we're in yet.
self.putr([ANN_REG_ADDR, [
'Reg Bank ? Addr 0x{0:02X}'.format(reg_addr),
'?:{0:02X}'.format(reg_addr)]])
self.putr([ANN_WARNING, ['Warning: Register bank not known yet.',
'Warning']])
self.putr([ANN_REG_ADDR, ['Reg Bank ? Addr {$}', '?:{$}', '@%02X' % reg_addr]])
self.putr([ANN_WARNING, ['Warning: Register bank not known yet.', 'Warning']])
else:
self.putr([ANN_REG_ADDR, ['Reg {0}'.format(reg_name),
'{0}'.format(reg_name)]])
self.putr([ANN_REG_ADDR, ['Reg {0}'.format(reg_name), '{0}'.format(reg_name)]])
if (reg_name == '-') or (reg_name == 'Reserved'):
self.putr([ANN_WARNING, ['Warning: Invalid register accessed.',
@@ -151,11 +147,9 @@ class Decoder(srd.Decoder):
self.range_es = self.ranges[byte_index + 1][0]
if binary:
self.putr([ANN_DATA, ['Data 0b{0:08b}'.format(data),
'{0:08b}'.format(data)]])
self.putr([ANN_DATA, ['Data 0b{0:08b}'.format(data), '{0:08b}'.format(data)]])
else:
self.putr([ANN_DATA, ['Data 0x{0:02X}'.format(data),
'{0:02X}'.format(data)]])
self.putr([ANN_DATA, ['Data {$}','{S}', '@%02X' % data]])
def _put_command_warning(self, reason):
self.putc([ANN_WARNING, ['Warning: {0}'.format(reason), 'Warning']])

View File

@@ -75,11 +75,14 @@ class Decoder(srd.Decoder):
self.put(ss, es, self.out_ann, [ann_reg, ['%s: %s' % (reg, value)]])
def putdigit(self, ss, es, digit, value):
self.put(ss, es, self.out_ann, [ann_digit, ['Digit %d: %02X' % (digit, value)]])
self.put(ss, es, self.out_ann, [ann_digit, ['Digit %d: {$}' % digit, '@%02X' % value]])
def putwarn(self, ss, es, message):
self.put(ss, es, self.out_ann, [ann_warning, [message]])
def putwarn_ann(self, ss, es, message):
self.put(ss, es, self.out_ann, [ann_warning, message])
def decode(self, ss, es, data):
ptype, mosi, _ = data
@@ -97,8 +100,7 @@ class Decoder(srd.Decoder):
name, decoder = registers[self.addr]
self.putreg(self.addr_start, es, name, decoder(mosi))
else:
self.putwarn(self.addr_start, es,
'Unknown register %02X' % (self.addr))
self.putwarn_ann(self.addr_start, es,['Unknown register {$}', '@%02X' % self.addr])
self.pos += 1
elif ptype == 'CS-CHANGE':

View File

@@ -69,9 +69,9 @@ class Decoder(srd.Decoder):
reg = (self.mosi_bytes[0] >> 1) & 0x3f
reg_desc = sregs.get(reg, 'illegal')
if write:
self.putx([1, ['%s: %#x' % (reg_desc, self.mosi_bytes[1])]])
self.putx([1, ['%s: {$}' % reg_desc, '@%02X' % self.mosi_bytes[1]]])
else:
self.putx([0, ['%s: %#x' % (reg_desc, self.miso_bytes[1])]])
self.putx([0, ['%s: {$}' % reg_desc, '@%02X' % self.miso_bytes[1]]])
def handle_long(self):
dword = self.mosi_bytes[0] << 8 | self.mosi_bytes[1]
@@ -95,9 +95,9 @@ class Decoder(srd.Decoder):
reg_desc = 'RX:%#x' % reg
if write:
self.putx([3, ['%s: %#x' % (reg_desc, self.mosi_bytes[2])]])
self.putx([3, ['%s: {$}' % reg_desc, '@%02X' % self.mosi_bytes[2]]])
else:
self.putx([2, ['%s: %#x' % (reg_desc, self.miso_bytes[2])]])
self.putx([2, ['%s: {$}' % reg_desc, '@%02X' % self.miso_bytes[2]]])
def decode(self, ss, es, data):
ptype = data[0]

View File

@@ -74,8 +74,6 @@ class Decoder(srd.Decoder):
options = (
{'id': 'chip', 'desc': 'Chip type',
'default': 'nrf24l01', 'values': ('nrf24l01', 'xn297')},
{'id': 'hex_display', 'desc': 'Display payload in Hex', 'default': 'yes',
'values': ('yes', 'no')},
)
annotations = (
# Sent from the host to the chip.
@@ -120,6 +118,10 @@ class Decoder(srd.Decoder):
'''Put an annotation message 'msg' at 'pos'.'''
self.put(pos[0], pos[1], self.out_ann, [ann, [msg]])
def putp_ann(self, pos, ann, msg):
#msg is a list
self.put(pos[0], pos[1], self.out_ann, [ann, msg])
def next(self):
'''Resets the decoder after a complete command was decoded.'''
# 'True' for the first byte after CS went low.
@@ -264,13 +266,14 @@ class Decoder(srd.Decoder):
return c
data = ''.join([escape(b) for b in data])
text = '{} = "{}"'.format(label, data.strip())
self.putp(pos, ann, text)
self.putp_ann(pos, ann, [label + ' = "{$}"', '@' + data.strip()])
def finish_command(self, pos):
'''Decodes the remaining data bytes at position 'pos'.'''
always_hex = True
always_hex = self.options['hex_display'] == 'yes'
if self.cmd == 'R_REGISTER':
self.decode_register(pos, self.ann_reg,
self.dat, self.miso_bytes())

View File

@@ -175,7 +175,7 @@ class Decoder(srd.Decoder):
for byte in cmd_bytes[1:]:
data += format(byte[0], '02X') + ' '
es = byte[2]
self.put(ss, es, self.out_ann, [ann, [prefix + data]])
self.put(ss, es, self.out_ann, [ann, [prefix + '{$}', '@' + data]])
def handle_WC(self):
start_addr = self.mosi_bytes[0][0] & 0x0F
@@ -206,12 +206,13 @@ class Decoder(srd.Decoder):
def handle_CC(self):
cmd, dta = self.mosi_bytes[0], self.mosi_bytes[1]
channel = ((cmd[0] & 0x01) << 8) + dta
channel = ((cmd[0] & 0x01) << 8) + dta[0]
data = self.extract_vars(CHN_CFG, cmd[0])
data += '| CHN = ' + str(channel)
self.put(self.mosi_bytes[0][1], self.mosi_bytes[1][2],
self.out_ann, [Ann.REG_WR, [data]])
def handle_STAT(self):
status = 'STAT = ' + self.extract_vars(STAT_REG, self.miso_bytes[0][0])
self.put(self.miso_bytes[0][1], self.miso_bytes[0][2],

View File

@@ -251,11 +251,11 @@ class Decoder(srd.Decoder):
if self.last_fifo_and_reset & 0x08:
self.putx(0, 8, ['Pattern: 0x2D%02X' % pattern])
else:
self.putx(0, 8, ['Pattern: %02X' % pattern])
self.putx(0, 8, ['Pattern: {$}', '@%02X' % pattern])
def handle_fifo_read_cmd(self, cmd, ret):
self.putx(0, 8, ['FIFO read command', 'FIFO read'])
self.putx(3, 8, ['Data: %02X' % ret[1]])
self.putx(3, 8, ['Data: {$}', '@%02X' % ret[1]])
def handle_afc_cmd(self, cmd, ret):
self.putx(0, 8, ['AFC command'])

View File

@@ -30,6 +30,8 @@ class Decoder(srd.Decoder):
inputs = ['spi']
outputs = []
tags = ['Memory']
# annotations length: 135 + 1
annotations = \
tuple(('cmd%d' % i, 'CMD%d' % i) for i in range(64)) + \
tuple(('acmd%d' % i, 'ACMD%d' % i) for i in range(64)) + ( \
@@ -38,12 +40,13 @@ class Decoder(srd.Decoder):
('r2', 'R2 reply'),
('r3', 'R3 reply'),
('r7', 'R7 reply'),
('bits:', 'Bits'),
('bits', 'Bits'),
('bit-warnings', 'Bit warnings'),
)
annotation_rows = (
('bits', 'Bits', (133, 134)),
('cmd-reply', 'Commands/replies', tuple(range(133))),
('bits', 'Bits', (134, 135)),
('cmd-reply', 'Commands/replies', tuple(range(133))), #0-132
)
def __init__(self):
@@ -71,6 +74,9 @@ class Decoder(srd.Decoder):
def putc(self, cmd, desc):
self.putx([cmd, ['%s: %s' % (self.cmd_str, desc)]])
def putc_4(self, cmd, desc, v):
self.putx([cmd, ['%s: %s' % (self.cmd_str, desc), '@%04X' % v]])
def putb(self, data):
self.put(self.ss_bit, self.es_bit, self.out_ann, data)
@@ -137,13 +143,13 @@ class Decoder(srd.Decoder):
# Bits[39:8]: Argument
self.arg = (t[1] << 24) | (t[2] << 16) | (t[3] << 8) | t[4]
self.ss_bit, self.es_bit = tb(4, 7)[1], tb(1, 0)[2]
self.putb([134, ['Argument: 0x%04x' % self.arg]])
self.putb([134, ['Argument: {$}', '@%04X' % self.arg]])
# Bits[7:1]: CRC7
# TODO: Check CRC7.
crc = t[5] >> 1
self.ss_bit, self.es_bit = tb(0, 7)[1], tb(0, 1)[2]
self.putb([134, ['CRC7: 0x%01x' % crc]])
self.putb([134, ['CRC7: {$}', '@%01X' % crc]])
# Bits[0:0]: End bit (always 1)
bit, self.ss_bit, self.es_bit = tb(0, 0)[0], tb(0, 0)[1], tb(0, 0)[2]
@@ -158,8 +164,8 @@ class Decoder(srd.Decoder):
self.cmd_str = '%s%d (%s)' % (s, cmd, self.cmd_name(cmd))
else:
self.state = 'HANDLE CMD999'
a = '%s%d: %02x %02x %02x %02x %02x %02x' % ((s, cmd) + tuple(t))
self.putx([cmd, [a]])
a = '%s%d: {$}' % (s, cmd)
self.putx([cmd, [a, '@' + '%02x %02x %02x %02x %02x %02x' % (tuple(t))]])
def handle_cmd0(self):
# CMD0: GO_IDLE_STATE
@@ -213,7 +219,7 @@ class Decoder(srd.Decoder):
def handle_cmd17(self):
# CMD17: READ_SINGLE_BLOCK
self.putc(17, 'Read a block from address 0x%04x' % self.arg)
self.putc_4(17, 'Read a block from address {$}', self.arg)
if len(self.read_buf) == 0:
self.ss_cmd = self.ss
self.read_buf.append(self.miso)
@@ -227,7 +233,7 @@ class Decoder(srd.Decoder):
def handle_cmd24(self):
# CMD24: WRITE_BLOCK
self.putc(24, 'Write a block to address 0x%04x' % self.arg)
self.putc_4(24, 'Write a block to address {$}', self.arg)
self.is_cmd24 = True
self.state = 'GET RESPONSE R1'
@@ -297,7 +303,7 @@ class Decoder(srd.Decoder):
# Sent by the card after every command except for SEND_STATUS.
self.ss_cmd, self.es_cmd = self.miso_bits[7][1], self.miso_bits[0][2]
self.putx([65, ['R1: 0x%02x' % res]])
self.putx([65, ['R1: {$}', '@%02x' % res]])
def putbit(bit, data):
b = self.miso_bits[bit]

View File

@@ -164,15 +164,17 @@ class Decoder(srd.Decoder):
self.addr |= (mosi << ((4 - self.cmdstate) * 8))
b = ((3 - (self.cmdstate - 2)) * 8) - 1
self.putx([Ann.BIT,
['Address bits %d..%d: 0x%02x' % (b, b - 7, mosi),
'Addr bits %d..%d: 0x%02x' % (b, b - 7, mosi),
'Addr bits %d..%d' % (b, b - 7), 'A%d..A%d' % (b, b - 7)]])
['Address bits %d..%d: {$}' % (b, b - 7),
'Addr bits %d..%d: {$}' % (b, b - 7),
'Addr bits %d..%d' % (b, b - 7),
'A%d..A%d' % (b, b - 7),
'@%02X' % mosi
]])
if self.cmdstate == 2:
self.ss_field = self.ss
if self.cmdstate == 4:
self.es_field = self.es
self.putf([Ann.FIELD, ['Address: 0x%06x' % self.addr,
'Addr: 0x%06x' % self.addr, '0x%06x' % self.addr]])
self.putf([Ann.FIELD, ['Address: {$}', 'Addr: {$}', '{$}', '@%06x' % self.addr]])
def handle_wren(self, mosi, miso):
self.putx([Ann.WREN, self.cmd_ann_list()])
@@ -188,14 +190,14 @@ class Decoder(srd.Decoder):
self.emit_cmd_byte()
elif self.cmdstate == 2:
# Byte 2: Slave sends the JEDEC manufacturer ID.
self.putx([Ann.FIELD, ['Manufacturer ID: 0x%02x' % miso]])
self.putx([Ann.FIELD, ['Manufacturer ID: {$}', '@%02x' % miso]])
elif self.cmdstate == 3:
# Byte 3: Slave sends the memory type.
self.putx([Ann.FIELD, ['Memory type: 0x%02x' % miso]])
self.putx([Ann.FIELD, ['Memory type: {$}', '@%02x' % miso]])
elif self.cmdstate == 4:
# Byte 4: Slave sends the device ID.
self.device_id = miso
self.putx([Ann.FIELD, ['Device ID: 0x%02x' % miso]])
self.putx([Ann.FIELD, ['Device ID: {$}', '@%02x' % miso]])
if self.cmdstate == 4:
self.es_cmd = self.es
@@ -316,7 +318,7 @@ class Decoder(srd.Decoder):
# Bytes 2/3/4: Master sends read address (24bits, MSB-first).
self.emit_addr_bytes(mosi)
elif self.cmdstate == 5:
self.putx([Ann.BIT, ['Dummy byte: 0x%02x' % mosi]])
self.putx([Ann.BIT, ['Dummy byte: {$}', '@%02x' % mosi]])
elif self.cmdstate >= 6:
# Bytes 6-x: Master reads data bytes (until CS# de-asserted).
self.es_field = self.es # Will be overwritten for each byte.
@@ -346,7 +348,7 @@ class Decoder(srd.Decoder):
# Byte 5: Dummy byte. Also handle byte 4 (address LSB) here.
self.emit_addr_bytes(b1)
self.cmdstate = 5
self.putx([Ann.BIT, ['Dummy byte: 0x%02x' % b2]])
self.putx([Ann.BIT, ['Dummy byte: {$}', '@%02x' % b2]])
elif self.cmdstate >= 6:
# Bytes 6-x: Master reads data bytes (until CS# de-asserted).
self.es_field = self.es # Will be overwritten for each byte.
@@ -368,7 +370,7 @@ class Decoder(srd.Decoder):
self.es_field = self.es
if self.cmdstate == 2:
self.ss_field = self.ss
self.putx([Ann.BIT, ['Status register byte %d: 0x%02x' % ((self.cmdstate % 2) + 1, miso)]])
self.putx([Ann.BIT, ['Status register byte %d: {$}' % ((self.cmdstate % 2) + 1, '@%02x' % miso)]])
self.cmdstate += 1
# TODO: Warn/abort if we don't see the necessary amount of bytes.
@@ -384,8 +386,8 @@ class Decoder(srd.Decoder):
if self.cmdstate == 4:
self.es_cmd = self.es
d = 'Erase sector %d (0x%06x)' % (self.addr, self.addr)
self.putc([Ann.SE, [d]])
d = ['Erase sector %d ({$})' % self.addr, '@%06x' % self.addr]
self.putc([Ann.SE, d])
# TODO: Max. size depends on chip, check that too if possible.
if self.addr % 4096 != 0:
# Sector addresses must be 4K-aligned (same for all 3 chips).
@@ -437,7 +439,7 @@ class Decoder(srd.Decoder):
self.emit_cmd_byte()
elif self.cmdstate in (2, 3, 4):
# Bytes 2/3/4: Master sends three dummy bytes.
self.putx([Ann.FIELD, ['Dummy byte: %02x' % mosi]])
self.putx([Ann.FIELD, ['Dummy byte: {$}', '@%02x' % mosi]])
elif self.cmdstate == 5:
# Byte 5: Slave sends device ID.
self.es_cmd = self.es
@@ -454,7 +456,7 @@ class Decoder(srd.Decoder):
self.emit_cmd_byte()
elif self.cmdstate in (2, 3):
# Bytes 2/3: Master sends two dummy bytes.
self.putx([Ann.FIELD, ['Dummy byte: 0x%02x' % mosi]])
self.putx([Ann.FIELD, ['Dummy byte: {$}', '@%02X' % mosi]])
elif self.cmdstate == 4:
# Byte 4: Master sends 0x00 or 0x01.
# 0x00: Master wants manufacturer ID as first reply byte.
@@ -466,12 +468,12 @@ class Decoder(srd.Decoder):
# Byte 5: Slave sends manufacturer ID (or device ID).
self.ids = [miso]
d = 'Manufacturer' if self.manufacturer_id_first else 'Device'
self.putx([Ann.FIELD, ['%s ID: 0x%02x' % (d, miso)]])
self.putx([Ann.FIELD, ['%s ID: {$}' % d, '@%02X' % miso]])
elif self.cmdstate == 6:
# Byte 6: Slave sends device ID (or manufacturer ID).
self.ids.append(miso)
d = 'Device' if self.manufacturer_id_first else 'Manufacturer'
self.putx([Ann.FIELD, ['%s ID: 0x%02x' % (d, miso)]])
self.putx([Ann.FIELD, ['%s ID: {$}' % d, '@%02X' % miso]])
if self.cmdstate == 6:
id_ = self.ids[1] if self.manufacturer_id_first else self.ids[0]
@@ -512,8 +514,7 @@ class Decoder(srd.Decoder):
else:
s = ''.join(map(chr, self.data))
self.putf([Ann.FIELD, ['%s (%d bytes)' % (label, len(self.data))]])
self.putc([idx, ['%s (addr 0x%06x, %d bytes): %s' % \
(cmds[self.state][1], self.addr, len(self.data), s)]])
self.putc([idx, ['%s (addr {$}, %d bytes): %s' % (cmds[self.state][1], len(self.data), s), '@%06x' % self.addr]])
def decode(self, ss, es, data):
ptype, mosi, miso = data
@@ -535,5 +536,5 @@ class Decoder(srd.Decoder):
try:
self.cmd_handlers[self.state](mosi, miso)
except KeyError:
self.putx([Ann.BIT, ['Unknown command: 0x%02x' % mosi]])
self.putx([Ann.BIT, ['Unknown command: {$}', '@%02x' % mosi]])
self.state = None

View File

@@ -82,6 +82,9 @@ class Decoder(srd.Decoder):
def putp2(self, pos, ann, msg1, msg2):
'''Put an annotation message 'msg' at 'pos'.'''
self.put(pos.ss, pos.es, self.out_ann, [ann, [msg1, msg2]])
def put_ann(self, pos, ann, data):
self.put(pos.ss, pos.es, self.out_ann, [ann, data])
def next(self):
'''Resets the decoder after a complete command was decoded.'''
@@ -111,7 +114,7 @@ class Decoder(srd.Decoder):
def decode_command(self, pos, b):
'''Decodes the command byte 'b' at position 'pos' and prepares
the decoding of the following data bytes.'''
c = self.parse_command(b)
c = self.parse_command(pos, b)
if c is None:
self.warn(pos, 'Unknown command')
return
@@ -135,7 +138,7 @@ class Decoder(srd.Decoder):
else:
return 'TODO Cmd {}'.format(self.cmd)
def parse_command(self, b):
def parse_command(self, pos, b):
'''Parses the command byte.
Returns a tuple consisting of:
- the name of the command
@@ -254,10 +257,11 @@ class Decoder(srd.Decoder):
data = ' '.join([escape(b) for b in data])
if (ann == Ann.FIFO_WRITE) or (ann == Ann.FIFO_READ):
text = '{}{}'.format(label, data)
text = label + '{$}'
else:
text = '{} = {}'.format(label, data)
self.putp(pos, ann, text)
text = label + ' = {$}'
self.put_ann(pos, ann, [text, '@' + data])
def finish_command(self, pos):
'''Decodes the remaining data bytes at position 'pos'.'''

View File

@@ -65,8 +65,10 @@ class Decoder(srd.Decoder):
def putreadwrite(self, ss, es, reg, idx, addr, value):
self.put(ss, es, self.out_ann,
[idx, ['%s: %s => 0x%4.4x' % (reg, addr, value),
'%s: %s => 0x%4.4x' % (reg[0], addr, value), reg[0]]])
[idx, ['%s: %s => {$}' % (reg, addr),
'%s: %s => {$}' % (reg[0], addr),
reg[0],
'@%04x' % value]])
def putcmd(self, ss, es, reg, idx):
self.put(ss, es, self.out_ann, [idx, [reg, reg[0]]])

View File

@@ -68,6 +68,8 @@ static int py_parse_ann_data(PyObject *list_obj, char ***out_strv, int list_size
int i;
long long lv;
int nstr;
char *up_ptr;
char c;
gstate = PyGILState_Ensure();
@@ -132,6 +134,21 @@ static int py_parse_ann_data(PyObject *list_obj, char ***out_strv, int list_size
str[0] = '\n'; //set ignore flag
str[1] = 0;
}
//convert to upper
up_ptr = hex_str_buf;
while (*up_ptr)
{
c = *up_ptr;
if (c >= 'a' && c <= 'f'){
*up_ptr = c - 32;
}
up_ptr++;
}
}
strv[i] = str;