]> sigrok.org Git - libsigrokdecode.git/blobdiff - decoders/nunchuk.py
srd: nunchuk: Partial update to new stacking API.
[libsigrokdecode.git] / decoders / nunchuk.py
index 31de4ffa20c1ba3c8c47a99844c315dc4f598259..0a1a24c04e84bdf040f9dbc9578c607aaf86c89c 100644 (file)
@@ -1,7 +1,7 @@
 ##
 ## This file is part of the sigrok project.
 ##
-## Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
+## Copyright (C) 2010-2012 Uwe Hermann <uwe@hermann-uwe.de>
 ##
 ## This program is free software; you can redistribute it and/or modify
 ## it under the terms of the GNU General Public License as published by
 # Nintendo Wii Nunchuk decoder
 #
 
+#
 # TODO: Description
+#
+# http://wiibrew.org/wiki/Wiimote/Extension_Controllers/Nunchuck
+# http://todbot.com/blog/2008/02/18/wiichuck-wii-nunchuck-adapter-available/
+# https://www.sparkfun.com/products/9281
+#
 
-# FIXME: This is just some example input for testing purposes...
-example_packets = [
-    # START condition.
-    {'type': 'S',  'range': (10, 11), 'data': None, 'ann': ''},
-
-    # Nunchuk init: Write 0x40,0x00 to slave address 0x54.
-    {'type': 'AW', 'range': (12, 13), 'data': 0x54, 'ann': ''},
-    {'type': 'DW', 'range': (14, 15), 'data': 0x40, 'ann': ''},
-    {'type': 'AW', 'range': (16, 17), 'data': 0x54, 'ann': ''},
-    {'type': 'DW', 'range': (18, 19), 'data': 0x00, 'ann': ''},
-
-    # Get data: Read 6 bytes of data.
-    {'type': 'DR', 'range': (20, 21), 'data': 0x11, 'ann': ''},
-    {'type': 'DR', 'range': (22, 23), 'data': 0x22, 'ann': ''},
-    {'type': 'DR', 'range': (24, 25), 'data': 0x33, 'ann': ''},
-    {'type': 'DR', 'range': (26, 27), 'data': 0x44, 'ann': ''},
-    {'type': 'DR', 'range': (28, 29), 'data': 0x55, 'ann': ''},
-    {'type': 'DR', 'range': (30, 31), 'data': 0x66, 'ann': ''},
-
-    # STOP condition.
-    {'type': 'P',  'range': (32, 33), 'data': None, 'ann': ''},
-]
-
-def decode(l):
-    print(l)
-    sigrok.put(l)
-
-
-def decode2(inbuf):
-    """Nintendo Wii Nunchuk decoder"""
-
-    # FIXME: Get the data in the correct format in the first place.
-    inbuf = [ord(x) for x in inbuf]
-    out = []
-    o = {}
-
-    # TODO: Pass in metadata.
-
-    # States
-    IDLE, START, NUNCHUK_SLAVE, INIT, INITIALIZED = range(5)
-    state = IDLE # TODO: Can we assume a certain initial state?
-
-    sx = sy = ax = ay = az = bz = bc = 0
-
-    databytecount = 0
-
-    # Loop over all I2C packets.
-    for p in example_packets:
-        if p['type'] == 'S': # TODO: Handle 'Sr' here, too?
-            state = START
-
-        elif p['type'] == 'Sr':
+import sigrokdecode as srd
+
+# States
+IDLE = 0
+START = 1
+NUNCHUK_SLAVE = 2
+INIT = 3
+INITIALIZED = 4
+
+class Decoder(srd.Decoder):
+    id = 'nunchuk'
+    name = 'Nunchuk'
+    longname = 'Nintendo Wii Nunchuk decoder'
+    desc = 'Decodes the Nintendo Wii Nunchuk I2C-based protocol.'
+    longdesc = '...'
+    author = 'Uwe Hermann'
+    email = 'uwe@hermann-uwe.de'
+    license = 'gplv2+'
+    inputs = ['i2c']
+    outputs = ['nunchuck']
+    probes = [] # TODO
+    options = {}
+    annotations = [
+        ['TODO', 'TODO'], 
+    ]
+
+    def __init__(self, **kwargs):
+        self.state = IDLE # TODO: Can we assume a certain initial state?
+        self.sx = self.sy = self.ax = self.ay = self.az = self.bz = self.bc = 0
+        self.databytecount = 0
+
+    def start(self, metadata):
+        # self.out_proto = self.add(srd.OUTPUT_PROTO, 'nunchuk')
+        self.out_ann = self.add(srd.OUTPUT_ANN, 'nunchuk')
+
+    def report(self):
+        pass
+
+    def decode(self, ss, es, data):
+
+        cmd, databyte, ack_bit = data
+
+        if cmd == 'START': # TODO: Handle 'Sr' here, too?
+            self.state = START
+
+        elif cmd == 'START_REPEAT':
             pass # FIXME
 
-        elif p['type'] == 'AR':
+        elif cmd == 'ADDRESS_READ':
             # TODO: Error/Warning, not supported, I think.
             pass
 
-        elif p['type'] == 'AW':
+        elif cmd == 'ADDRESS_WRITE':
             # The Wii Nunchuk always has slave address 0x54.
             # TODO: Handle this stuff more correctly.
-            if p['data'] == 0x54:
+            if databyte == 0x54:
                 pass # TODO
             else:
                 pass # TODO: What to do here? Ignore? Error?
 
-        elif p['type'] == 'DR' and state == INITIALIZED:
-            if databytecount == 0:
-                sx = p['data']
-            elif databytecount == 1:
-                sy = p['data']
-            elif databytecount == 2:
-                ax = p['data'] << 2
-            elif databytecount == 3:
-                ay = p['data'] << 2
-            elif databytecount == 4:
-                az = p['data'] << 2
-            elif databytecount == 5:
-                bz =  (p['data'] & (1 << 0)) >> 0
-                bc =  (p['data'] & (1 << 1)) >> 1
-                ax |= (p['data'] & (3 << 2)) >> 2
-                ay |= (p['data'] & (3 << 4)) >> 4
-                az |= (p['data'] & (3 << 6)) >> 6
-                # del o
-                o = {'type': 'D', 'range': (0, 0), 'data': []}
-                o['data'] = [sx, sy, ax, ay, az, bz, bc]
-                # sx = sy = ax = ay = az = bz = bc = 0
+        elif cmd == 'DATA_READ' and self.state == INITIALIZED:
+            if self.databytecount == 0:
+                self.sx = databyte
+            elif self.databytecount == 1:
+                self.sy = databyte
+            elif self.databytecount == 2:
+                self.ax = databyte << 2
+            elif self.databytecount == 3:
+                self.ay = databyte << 2
+            elif self.databytecount == 4:
+                self.az = databyte << 2
+            elif self.databytecount == 5:
+                self.bz =  (databyte & (1 << 0)) >> 0
+                self.bc =  (databyte & (1 << 1)) >> 1
+                self.ax |= (databyte & (3 << 2)) >> 2
+                self.ay |= (databyte & (3 << 4)) >> 4
+                self.az |= (databyte & (3 << 6)) >> 6
+
+                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(ss, es, self.out_ann, [0, [d]])
+
+                self.sx = self.sy = self.ax = self.ay = self.az = 0
+                self.bz = self.bc = 0
             else:
                 pass # TODO
 
-            if 0 <= databytecount <= 5:
-                databytecount += 1
+            if 0 <= self.databytecount <= 5:
+                self.databytecount += 1
 
             # TODO: If 6 bytes read -> save and reset
 
         # TODO
-        elif p['type'] == 'DR' and state != INITIALIZED:
+        elif cmd == 'DATA_READ' and self.state != INITIALIZED:
             pass
 
-        elif p['type'] == 'DW':
-            if p['data'] == 0x40 and state == START:
-                state = INIT
-            elif p['data'] == 0x00 and state == INIT:
-                o = {'type': 'I', 'range': (0, 0), 'data': []}
-                o['data'] = [0x40, 0x00]
-                out.append(o)
-                state = INITIALIZED
+        elif cmd == 'DATA_WRITE':
+            if self.state == IDLE:
+                self.state = INITIALIZED
+            return
+    
+            if databyte == 0x40 and self.state == START:
+                self.state = INIT
+            elif databyte == 0x00 and self.state == INIT:
+                self.put(ss, es, self.out_ann, [0, ['Initialize nunchuk']])
+                self.state = INITIALIZED
             else:
                 pass # TODO
 
-        elif p['type'] == 'P':
-            out.append(o)
-            state = INITIALIZED
-            databytecount = 0
-
-    print out
-
-    # FIXME
-    return ''
-
-register = {
-    'id': 'nunchuk',
-    'name': 'Nunchuk',
-    'longname': 'Nintendo Wii Nunchuk decoder',
-    'desc': 'Decodes the Nintendo Wii Nunchuk I2C-based protocol.',
-    'longdesc': '...',
-    'author': 'Uwe Hermann',
-    'email': 'uwe@hermann-uwe.de',
-    'license': 'gplv2+',
-    'in': ['i2c'],
-    'out': ['nunchuck'],
-    'probes': [
-        # TODO
-    ],
-    'options': {
-        # TODO
-    },
-    # 'start': start,
-    # 'report': report,
-}
-
-# Use psyco (if available) as it results in huge performance improvements.
-try:
-    import psyco
-    psyco.bind(decode)
-except ImportError:
-    pass
+        elif cmd == 'STOP':
+            self.state = INITIALIZED
+            self.databytecount = 0