import sigrokdecode as srd
-class MissingDataError(Exception):
+class ChannelError(Exception):
pass
regs = {
0x1d: ('FEATURE', 1),
}
+xn297_regs = {
+ 0x19: ('DEMOD_CAL', 5),
+ 0x1e: ('RF_CAL', 7),
+ 0x1f: ('BB_CAL', 5),
+}
+
class Decoder(srd.Decoder):
api_version = 2
id = 'nrf24l01'
license = 'gplv2+'
inputs = ['spi']
outputs = ['nrf24l01']
+ options = (
+ {'id': 'chip', 'desc': 'Chip type',
+ 'default': 'nrf24l01', 'values': ('nrf24l01', 'xn297')},
+ )
annotations = (
# Sent from the host to the chip.
('cmd', 'Commands sent to the device'),
def __init__(self, **kwargs):
self.next()
+ self.requirements_met = True
+ self.cs_was_released = False
def start(self):
self.out_ann = self.register(srd.OUTPUT_ANN)
+ if self.options['chip'] == 'xn297':
+ regs.update(xn297_regs)
def warn(self, pos, msg):
'''Put a warning message 'msg' at 'pos'.'''
'''Returns the label for the current command.'''
if self.cmd == 'R_REGISTER':
reg = regs[self.dat][0] if self.dat in regs else 'unknown register'
- return 'Cmd. R_REGISTER "{}"'.format(reg)
+ return 'Cmd R_REGISTER "{}"'.format(reg)
else:
- return 'Cmd. {}'.format(self.cmd)
+ return 'Cmd {}'.format(self.cmd)
def parse_command(self, b):
'''Parses the command byte.
# The 'W_REGISTER' command is merged with the following byte(s).
label = '{}: {}'.format(self.format_command(), name)
else:
- label = 'Reg. {}'.format(name)
+ label = 'Reg {}'.format(name)
- self.decode_mb_data(pos, ann, data, label)
+ self.decode_mb_data(pos, ann, data, label, True)
- def decode_mb_data(self, pos, ann, data, label, escape_all=True):
+ def decode_mb_data(self, pos, ann, data, label, always_hex):
'''Decodes the data bytes 'data' of a multibyte command at position
- 'pos'. The decoded data is prefixed with 'label'. If 'excape_all' is
- True, all data bytes are escaped as hex codes.'''
+ 'pos'. The decoded data is prefixed with 'label'. If 'always_hex' is
+ True, all bytes are decoded as hex codes, otherwise only non
+ printable characters are escaped.'''
- def escape(b):
- c = chr(b)
- if escape_all or not str.isprintable(c):
- return '\\x{:02X}'.format(b)
- return c
+ if always_hex:
+ def escape(b):
+ return '{:02X}'.format(b)
+ else:
+ def escape(b):
+ c = chr(b)
+ if not str.isprintable(c):
+ return '\\x{:02X}'.format(b)
+ return c
data = ''.join([escape(b) for b in data])
text = '{} = "{}"'.format(label, data)
self.warn(pos, 'wrong data for "ACTIVATE" command')
def decode(self, ss, es, data):
+ if not self.requirements_met:
+ return
+
ptype, data1, data2 = data
if ptype == 'CS-CHANGE':
+ if data1 is None:
+ if data2 is None:
+ self.requirements_met = False
+ raise ChannelError('CS# pin required.')
+ elif data2 == 1:
+ self.cs_was_released = True
+
if data1 == 0 and data2 == 1:
# Rising edge, the complete command is transmitted, process
# the bytes that were send after the command byte.
self.finish_command((self.mb_s, self.mb_e))
self.next()
- elif ptype == 'DATA':
+ self.cs_was_released = True
+ elif ptype == 'DATA' and self.cs_was_released:
mosi, miso = data1, data2
pos = (ss, es)
if miso is None or mosi is None:
- raise MissingDataError('Both MISO and MOSI pins required.')
+ self.requirements_met = False
+ raise ChannelError('Both MISO and MOSI pins required.')
if self.first:
self.first = False