annotations = [
['Text (verbose)', 'Human-readable text (verbose)'],
['Text', 'Human-readable text'],
+ ['Warnings', 'Human-readable warnings'],
]
def __init__(self, **kwargs):
self.state = 'IDLE'
- self.sx = self.sy = self.ax = self.ay = self.az = self.bz = self.bc = 0
+ self.sx = self.sy = self.ax = self.ay = self.az = self.bz = self.bc = -1
self.databytecount = 0
self.reg = 0x00
+ self.init_seq = []
def start(self, metadata):
# self.out_proto = self.add(srd.OUTPUT_PROTO, 'nunchuk')
# Helper for annotations which span exactly one I2C packet.
self.put(self.ss, self.es, self.out_ann, data)
+ def putb(self, data):
+ # Helper for annotations which span a block of I2C packets.
+ self.put(self.block_start_sample, self.block_end_sample,
+ self.out_ann, data)
+
def handle_reg_0x00(self, databyte):
self.sx = databyte
self.putx([0, ['Analog stick X position: 0x%02x' % self.sx]])
self.putx([0, ['Accelerometer Z value bits[1:0]: 0x%x' % az_rest]])
self.putx([1, ['AZ[1:0]: 0x%x' % az_rest]])
+ def output_full_block_if_possible(self):
+ # For now, only output summary annotation if all values are available.
+ t = (self.sx, self.sy, self.ax, self.ay, self.az, self.bz, self.bc)
+ if -1 in t:
+ return
+
+ s = 'Analog stick X position: 0x%02x\n' % self.sx
+ s += 'Analog stick Y position: 0x%02x\n' % self.sy
+ s += 'Z button: %spressed\n' % ('' if (self.bz == 0) else 'not ')
+ s += 'C button: %spressed\n' % ('' if (self.bc == 0) else 'not ')
+ s += 'Accelerometer X value: 0x%03x\n' % self.ax
+ s += 'Accelerometer Y value: 0x%03x\n' % self.ay
+ s += 'Accelerometer Z value: 0x%03x\n' % self.az
+ self.put(self.block_start_sample, self.block_end_sample,
+ self.out_ann, [0, [s]])
+
+ s = 'SX = 0x%02x, SY = 0x%02x, AX = 0x%02x, AY = 0x%02x, ' \
+ 'AZ = 0x%02x, BZ = 0x%02x, BC = 0x%02x' % (self.sx, \
+ self.sy, self.ax, self.ay, self.az, self.bz, self.bc)
+ self.put(self.block_start_sample, self.block_end_sample,
+ self.out_ann, [1, [s]])
+
+ def handle_reg_write(self, databyte):
+ self.putx([0, ['Nunchuk write: 0x%02x' % databyte]])
+ if len(self.init_seq) < 2:
+ self.init_seq.append(databyte)
+
+ def output_init_seq(self):
+ if len(self.init_seq) != 2:
+ self.putb([2, ['Init sequence was %d bytes long (2 expected)' % \
+ len(self.init_seq)]])
+
+ if self.init_seq != (0x40, 0x00):
+ self.putb([2, ['Unknown init sequence (expected: 0x40 0x00)']])
+
+ # TODO: Detect Nunchuk clones (they have different init sequences).
+ s = 'Initialized Nintendo Wii Nunchuk'
+
+ self.putb([0, [s]])
+ self.putb([1, ['INIT']])
+
def decode(self, ss, es, data):
cmd, databyte = data
self.state = 'GET SLAVE ADDR'
self.block_start_sample = ss
elif self.state == 'GET SLAVE ADDR':
- # Wait for an address read operation.
- if cmd != 'ADDRESS READ':
- return
- self.state = 'READ REGS'
+ # Wait for an address read/write operation.
+ if cmd == 'ADDRESS READ':
+ self.state = 'READ REGS'
+ elif cmd == 'ADDRESS WRITE':
+ self.state = 'WRITE REGS'
elif self.state == 'READ REGS':
if cmd == 'DATA READ':
handle_reg = getattr(self, 'handle_reg_0x%02x' % self.reg)
self.reg += 1
elif cmd == 'STOP':
self.block_end_sample = es
-
- # TODO: Only works if host reads _all_ regs (0x00 - 0x05).
- d = 'SX = 0x%02x, SY = 0x%02x, AX = 0x%02x, AY = 0x%02x, ' \
- 'AZ = 0x%02x, BZ = 0x%02x, BC = 0x%02x' % (self.sx, \
- self.sy, self.ax, self.ay, self.az, self.bz, self.bc)
- self.put(self.block_start_sample, self.block_end_sample,
- self.out_ann, [0, [d]])
-
- self.sx = self.sy = self.ax = self.ay = self.az = 0
- self.bz = self.bc = 0
-
+ self.output_full_block_if_possible()
+ self.sx = self.sy = self.ax = self.ay = self.az = -1
+ self.bz = self.bc = -1
+ self.state = 'IDLE'
+ else:
+ # self.putx([0, ['Ignoring: %s (data=%s)' % (cmd, databyte)]])
+ pass
+ elif self.state == 'WRITE REGS':
+ if cmd == 'DATA WRITE':
+ self.handle_reg_write(databyte)
+ elif cmd == 'STOP':
+ self.block_end_sample = es
+ self.output_init_seq()
+ self.init_seq = []
self.state = 'IDLE'
else:
# self.putx([0, ['Ignoring: %s (data=%s)' % (cmd, databyte)]])