]> sigrok.org Git - libsigrokdecode.git/blobdiff - decoders/nunchuk.py
srd: nunchuk.py: Add some more URLs.
[libsigrokdecode.git] / decoders / nunchuk.py
index 068c170f9a32458683f8ff29d7dd1b6043e1e967..128b10e56294c44ade696de01a61440a229eae1b 100644 (file)
 # 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 = [
@@ -47,121 +53,133 @@ example_packets = [
     {'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':
-            pass # FIXME
-
-        elif p['type'] == 'AR':
-            # TODO: Error/Warning, not supported, I think.
-            pass
-
-        elif p['type'] == 'AW':
-            # The Wii Nunchuk always has slave address 0x54.
-            # TODO: Handle this stuff more correctly.
-            if p['data'] == 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
-            else:
-                pass # TODO
-
-            if 0 <= databytecount <= 5:
-                databytecount += 1
-
-            # TODO: If 6 bytes read -> save and reset
-
-        # TODO
-        elif p['type'] == 'DR' and 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]
+class Sample():
+    def __init__(self, data):
+        self.data = data
+    def probe(self, probe):
+        s = ord(self.data[probe / 8]) & (1 << (probe % 8))
+        return True if s else False
+
+def sampleiter(data, unitsize):
+    for i in range(0, len(data), unitsize):
+        yield(Sample(data[i:i+unitsize]))
+
+class Decoder():
+    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 = {}
+    options = {}
+
+    def __init__(self, **kwargs):
+        self.probes = Decoder.probes.copy()
+
+        # TODO: Don't hardcode the number of channels.
+        self.channels = 8
+
+        self.IDLE, self.START, self.NUNCHUK_SLAVE, self.INIT, \
+        self.INITIALIZED = range(5)
+
+        self.state = self.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.unitsize = metadata['unitsize']
+
+    def report(self):
+        pass
+
+    def decode(self, data):
+        """Nintendo Wii Nunchuk decoder"""
+
+        out = []
+        o = {}
+
+        # We should accept a list of samples and iterate...
+        # for sample in sampleiter(data['data'], self.unitsize):
+        for p in example_packets:
+
+            # TODO: Eliminate the need for ord().
+            # s = ord(sample.data)
+
+            if p['type'] == 'S': # TODO: Handle 'Sr' here, too?
+                self.state = self.START
+
+            elif p['type'] == 'Sr':
+                pass # FIXME
+
+            elif p['type'] == 'AR':
+                # TODO: Error/Warning, not supported, I think.
+                pass
+
+            elif p['type'] == 'AW':
+                # The Wii Nunchuk always has slave address 0x54.
+                # TODO: Handle this stuff more correctly.
+                if p['data'] == 0x54:
+                    pass # TODO
+                else:
+                    pass # TODO: What to do here? Ignore? Error?
+
+            elif p['type'] == 'DR' and self.state == self.INITIALIZED:
+                if self.databytecount == 0:
+                    self.sx = p['data']
+                elif self.databytecount == 1:
+                    self.sy = p['data']
+                elif self.databytecount == 2:
+                    self.ax = p['data'] << 2
+                elif self.databytecount == 3:
+                    self.ay = p['data'] << 2
+                elif self.databytecount == 4:
+                    self.az = p['data'] << 2
+                elif self.databytecount == 5:
+                    self.bz =  (p['data'] & (1 << 0)) >> 0
+                    self.bc =  (p['data'] & (1 << 1)) >> 1
+                    self.ax |= (p['data'] & (3 << 2)) >> 2
+                    self.ay |= (p['data'] & (3 << 4)) >> 4
+                    self.az |= (p['data'] & (3 << 6)) >> 6
+                    # del o
+                    o = {'type': 'D', 'range': (0, 0), 'data': []}
+                    o['data'] = [self.sx, self.sy, self.ax, self.ay, \
+                                 self.az, self.bz, self.bc]
+                    # sx = sy = ax = ay = az = bz = bc = 0
+                else:
+                    pass # TODO
+
+                if 0 <= self.databytecount <= 5:
+                    self.databytecount += 1
+
+                # TODO: If 6 bytes read -> save and reset
+
+            # TODO
+            elif p['type'] == 'DR' and self.state != self.INITIALIZED:
+                pass
+
+            elif p['type'] == 'DW':
+                if p['data'] == 0x40 and self.state == self.START:
+                    self.state = self.INIT
+                elif p['data'] == 0x00 and self.state == self.INIT:
+                    o = {'type': 'I', 'range': (0, 0), 'data': []}
+                    o['data'] = [0x40, 0x00]
+                    out.append(o)
+                    self.state = self.INITIALIZED
+                else:
+                    pass # TODO
+
+            elif p['type'] == 'P':
                 out.append(o)
-                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,
-}
+                self.state = self.INITIALIZED
+                self.databytecount = 0
+
+        sigrok.put(out)
+
+import sigrok