X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=decoders%2Fnunchuk%2Fnunchuk.py;h=0dae39c504114ec3013d1bece3e4141e216e760a;hb=19dd61efcc1fe07c6a66f48f74b7926607f3a541;hp=b274f4ad00578ab08fc9eb616ae23b9471df4869;hpb=739f1b7310b5b6926dfd8e9991bcb2fe057eca5d;p=libsigrokdecode.git diff --git a/decoders/nunchuk/nunchuk.py b/decoders/nunchuk/nunchuk.py index b274f4a..0dae39c 100644 --- a/decoders/nunchuk/nunchuk.py +++ b/decoders/nunchuk/nunchuk.py @@ -37,13 +37,15 @@ class Decoder(srd.Decoder): 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') @@ -56,6 +58,11 @@ class Decoder(srd.Decoder): # 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]]) @@ -109,6 +116,47 @@ class Decoder(srd.Decoder): 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 @@ -123,10 +171,11 @@ class Decoder(srd.Decoder): 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) @@ -134,17 +183,20 @@ class Decoder(srd.Decoder): 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)]])