diff options
-rw-r--r-- | decoders/i2c.py | 232 | ||||
-rw-r--r-- | decoders/nunchuk.py | 264 | ||||
-rw-r--r-- | decoders/spi.py | 8 | ||||
-rw-r--r-- | decoders/transitioncounter.py | 122 |
4 files changed, 312 insertions, 314 deletions
diff --git a/decoders/i2c.py b/decoders/i2c.py index f2b0c2d..874e735 100644 --- a/decoders/i2c.py +++ b/decoders/i2c.py @@ -99,9 +99,9 @@ # Possible other events: # - Error event in case protocol looks broken: # [{'type': 'ERROR', 'range': (min, max), -# 'data': TODO, 'ann': 'This is not a Microchip 24XX64 EEPROM'}, +# 'data': TODO, 'ann': 'This is not a Microchip 24XX64 EEPROM'}, # [{'type': 'ERROR', 'range': (min, max), -# 'data': TODO, 'ann': 'TODO'}, +# 'data': TODO, 'ann': 'TODO'}, # - TODO: Make list of possible errors accessible as metadata? # # TODO: I2C address of slaves. @@ -126,145 +126,143 @@ # def decode(l): - print(l) - sigrok.put(l) - - + print(l) + sigrok.put(l) def decode2(inbuf): - """I2C protocol decoder""" + """I2C protocol decoder""" - # FIXME: Get the data in the correct format in the first place. - inbuf = [ord(x) for x in inbuf] + # FIXME: Get the data in the correct format in the first place. + inbuf = [ord(x) for x in inbuf] - # FIXME: This should be passed in as metadata, not hardcoded here. - metadata = { - 'numchannels': 8, - 'signals': { - 'scl': {'ch': 5, 'name': 'SCL', 'desc': 'Serial clock line'}, - 'sda': {'ch': 7, 'name': 'SDA', 'desc': 'Serial data line'}, - }, - } + # FIXME: This should be passed in as metadata, not hardcoded here. + metadata = { + 'numchannels': 8, + 'signals': { + 'scl': {'ch': 5, 'name': 'SCL', 'desc': 'Serial clock line'}, + 'sda': {'ch': 7, 'name': 'SDA', 'desc': 'Serial data line'}, + }, + } - out = [] - o = ack = d = '' - bitcount = data = 0 - wr = startsample = -1 - IDLE, START, ADDRESS, DATA = range(4) - state = IDLE + out = [] + o = ack = d = '' + bitcount = data = 0 + wr = startsample = -1 + IDLE, START, ADDRESS, DATA = range(4) + state = IDLE - # Get the channel/probe number of the SCL/SDA signals. - scl_bit = metadata['signals']['scl']['ch'] - sda_bit = metadata['signals']['sda']['ch'] + # Get the channel/probe number of the SCL/SDA signals. + scl_bit = metadata['signals']['scl']['ch'] + sda_bit = metadata['signals']['sda']['ch'] - # Get SCL/SDA bit values (0/1 for low/high) of the first sample. - s = inbuf[0] - oldscl = (s & (1 << scl_bit)) >> scl_bit - oldsda = (s & (1 << sda_bit)) >> sda_bit + # Get SCL/SDA bit values (0/1 for low/high) of the first sample. + s = inbuf[0] + oldscl = (s & (1 << scl_bit)) >> scl_bit + oldsda = (s & (1 << sda_bit)) >> sda_bit - # Loop over all samples. - # TODO: Handle LAs with more/less than 8 channels. - for samplenum, s in enumerate(inbuf[1:]): # We skip the first byte... - # Get SCL/SDA bit values (0/1 for low/high). - scl = (s & (1 << scl_bit)) >> scl_bit - sda = (s & (1 << sda_bit)) >> sda_bit + # Loop over all samples. + # TODO: Handle LAs with more/less than 8 channels. + for samplenum, s in enumerate(inbuf[1:]): # We skip the first byte... + # Get SCL/SDA bit values (0/1 for low/high). + scl = (s & (1 << scl_bit)) >> scl_bit + sda = (s & (1 << sda_bit)) >> sda_bit - # TODO: Wait until the bus is idle (SDA = SCL = 1) first? + # TODO: Wait until the bus is idle (SDA = SCL = 1) first? - # START condition (S): SDA = falling, SCL = high - if (oldsda == 1 and sda == 0) and scl == 1: - o = {'type': 'S', 'range': (samplenum, samplenum), - 'data': None, 'ann': None}, - out.append(o) - state = ADDRESS - bitcount = data = 0 + # START condition (S): SDA = falling, SCL = high + if (oldsda == 1 and sda == 0) and scl == 1: + o = {'type': 'S', 'range': (samplenum, samplenum), + 'data': None, 'ann': None}, + out.append(o) + state = ADDRESS + bitcount = data = 0 - # Data latching by transmitter: SCL = low - elif (scl == 0): - pass # TODO + # Data latching by transmitter: SCL = low + elif (scl == 0): + pass # TODO - # Data sampling of receiver: SCL = rising - elif (oldscl == 0 and scl == 1): - if startsample == -1: - startsample = samplenum - bitcount += 1 + # Data sampling of receiver: SCL = rising + elif (oldscl == 0 and scl == 1): + if startsample == -1: + startsample = samplenum + bitcount += 1 - # out.append("%d\t\tRECEIVED BIT %d: %d\n" % \ - # (samplenum, 8 - bitcount, sda)) + # out.append("%d\t\tRECEIVED BIT %d: %d\n" % \ + # (samplenum, 8 - bitcount, sda)) - # Address and data are transmitted MSB-first. - data <<= 1 - data |= sda + # Address and data are transmitted MSB-first. + data <<= 1 + data |= sda - if bitcount != 9: - continue + if bitcount != 9: + continue - # We received 8 address/data bits and the ACK/NACK bit. - data >>= 1 # Shift out unwanted ACK/NACK bit here. - ack = (sda == 1) and 'N' or 'A' - d = (state == ADDRESS) and (data & 0xfe) or data - if state == ADDRESS: - wr = (data & 1) and 1 or 0 - state = DATA - o = {'type': state, - 'range': (startsample, samplenum - 1), - 'data': d, 'ann': None} - if state == ADDRESS and wr == 1: - o['type'] = 'AW' - elif state == ADDRESS and wr == 0: - o['type'] = 'AR' - elif state == DATA and wr == 1: - o['type'] = 'DW' - elif state == DATA and wr == 0: - o['type'] = 'DR' - out.append(o) - o = {'type': ack, 'range': (samplenum, samplenum), - 'data': None, 'ann': None} - out.append(o) - bitcount = data = startsample = 0 - startsample = -1 + # We received 8 address/data bits and the ACK/NACK bit. + data >>= 1 # Shift out unwanted ACK/NACK bit here. + ack = (sda == 1) and 'N' or 'A' + d = (state == ADDRESS) and (data & 0xfe) or data + if state == ADDRESS: + wr = (data & 1) and 1 or 0 + state = DATA + o = {'type': state, + 'range': (startsample, samplenum - 1), + 'data': d, 'ann': None} + if state == ADDRESS and wr == 1: + o['type'] = 'AW' + elif state == ADDRESS and wr == 0: + o['type'] = 'AR' + elif state == DATA and wr == 1: + o['type'] = 'DW' + elif state == DATA and wr == 0: + o['type'] = 'DR' + out.append(o) + o = {'type': ack, 'range': (samplenum, samplenum), + 'data': None, 'ann': None} + out.append(o) + bitcount = data = startsample = 0 + startsample = -1 - # STOP condition (P): SDA = rising, SCL = high - elif (oldsda == 0 and sda == 1) and scl == 1: - o = {'type': 'P', 'range': (samplenum, samplenum), - 'data': None, 'ann': None}, - out.append(o) - state = IDLE - wr = -1 + # STOP condition (P): SDA = rising, SCL = high + elif (oldsda == 0 and sda == 1) and scl == 1: + o = {'type': 'P', 'range': (samplenum, samplenum), + 'data': None, 'ann': None}, + out.append(o) + state = IDLE + wr = -1 - # Save current SDA/SCL values for the next round. - oldscl = scl - oldsda = sda + # Save current SDA/SCL values for the next round. + oldscl = scl + oldsda = sda - # FIXME: Just for testing... - return str(out) + # FIXME: Just for testing... + return str(out) register = { - 'id': 'i2c', - 'name': 'I2C', - 'longname': 'Inter-Integrated Circuit (I2C) bus', - 'desc': 'I2C is a two-wire, multi-master, serial bus.', - 'longdesc': '...', - 'author': 'Uwe Hermann', - 'email': 'uwe@hermann-uwe.de', - 'license': 'gplv2+', - 'in': ['logic'], - 'out': ['i2c'], - 'probes': [ - ['scl', 'Serial clock line'], - ['sda', 'Serial data line'], - ], - 'options': { - 'address-space': ['Address space (in bits)', 7], - }, - # 'start': start, - # 'report': report, + 'id': 'i2c', + 'name': 'I2C', + 'longname': 'Inter-Integrated Circuit (I2C) bus', + 'desc': 'I2C is a two-wire, multi-master, serial bus.', + 'longdesc': '...', + 'author': 'Uwe Hermann', + 'email': 'uwe@hermann-uwe.de', + 'license': 'gplv2+', + 'in': ['logic'], + 'out': ['i2c'], + 'probes': [ + ['scl', 'Serial clock line'], + ['sda', 'Serial data line'], + ], + 'options': { + 'address-space': ['Address space (in bits)', 7], + }, + # 'start': start, + # 'report': report, } # Use psyco (if available) as it results in huge performance improvements. try: - import psyco - psyco.bind(decode) + import psyco + psyco.bind(decode) except ImportError: - pass + pass diff --git a/decoders/nunchuk.py b/decoders/nunchuk.py index 57be1d7..4ac1c83 100644 --- a/decoders/nunchuk.py +++ b/decoders/nunchuk.py @@ -26,149 +26,149 @@ # 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': ''}, + # 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) + 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] - out.append(o) - state = INITIALIZED - else: - pass # TODO - - elif p['type'] == 'P': - out.append(o) - state = INITIALIZED - databytecount = 0 - - print out - - # FIXME - return '' + """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] + 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, + '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) + import psyco + psyco.bind(decode) except ImportError: - pass + pass diff --git a/decoders/spi.py b/decoders/spi.py index 0ac8b56..7b3d8ab 100644 --- a/decoders/spi.py +++ b/decoders/spi.py @@ -17,6 +17,7 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ## + class Sample(): def __init__(self, data): self.data = data @@ -65,8 +66,8 @@ class Decoder(): if sck == self.oldsck: continue self.oldsck = sck - if not sck: - continue + if not sck: + continue # If this is first bit, save timestamp if self.rxcount == 0: @@ -92,7 +93,7 @@ class Decoder(): self.rxcount = 0 # Keep stats for summary self.bytesreceived += 1 - + if __name__ == "__main__": data = open("spi_dump.bin").read() @@ -112,4 +113,3 @@ else: #Tested with: # sigrok-cli -d 0:samplerate=1000000:rle=on --time=1s -p 1,2 -a spidec - diff --git a/decoders/transitioncounter.py b/decoders/transitioncounter.py index 996cf2e..d3fa732 100644 --- a/decoders/transitioncounter.py +++ b/decoders/transitioncounter.py @@ -17,6 +17,7 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ## + import sigrok lastsample = None @@ -25,79 +26,78 @@ transitions = None rising = None falling = None - def decode(sampledata): - """Counts the low->high and high->low transitions in the specified - channel(s) of the signal.""" - global lastsample - global oldbit, transitions, rising, falling + """Counts the low->high and high->low transitions in the specified + channel(s) of the signal.""" + global lastsample + global oldbit, transitions, rising, falling + + # TODO: Don't hardcode the number of channels. + channels = 8 + + # FIXME: Get the data in the correct format in the first place. + inbuf = [ord(x) for x in sampledata['data']] - # TODO: Don't hardcode the number of channels. - channels = 8 + if lastsample == None: + oldbit = [0] * channels + transitions = [0] * channels + rising = [0] * channels + falling = [0] * channels - # FIXME: Get the data in the correct format in the first place. - inbuf = [ord(x) for x in sampledata['data']] + # Initial values. + lastsample = inbuf[0] + for i in range(channels): + oldbit[i] = (lastsample & (1 << i)) >> i - if lastsample == None: - oldbit = [0] * channels - transitions = [0] * channels - rising = [0] * channels - falling = [0] * channels + # TODO: Handle LAs with more/less than 8 channels. + for s in inbuf: + # Optimization: Skip identical bytes (no transitions). + if lastsample != s: + for i in range(channels): + curbit = (s & (1 << i)) >> i + # Optimization: Skip identical bits (no transitions). + if oldbit[i] == curbit: + continue + elif (oldbit[i] == 0 and curbit == 1): + rising[i] += 1 + elif (oldbit[i] == 1 and curbit == 0): + falling[i] += 1 + oldbit[i] = curbit - # Initial values. - lastsample = inbuf[0] - for i in range(channels): - oldbit[i] = (lastsample & (1 << i)) >> i - - # TODO: Handle LAs with more/less than 8 channels. - for s in inbuf: - # Optimization: Skip identical bytes (no transitions). - if lastsample != s: - for i in range(channels): - curbit = (s & (1 << i)) >> i - # Optimization: Skip identical bits (no transitions). - if oldbit[i] == curbit: - continue - elif (oldbit[i] == 0 and curbit == 1): - rising[i] += 1 - elif (oldbit[i] == 1 and curbit == 0): - falling[i] += 1 - oldbit[i] = curbit + # Total number of transitions is the sum of rising and falling edges. + for i in range(channels): + transitions[i] = rising[i] + falling[i] - # Total number of transitions is the sum of rising and falling edges. - for i in range(channels): - transitions[i] = rising[i] + falling[i] - - lastsample = s - print(transitions) + lastsample = s + print(transitions) - sigrok.put(sampledata) + sigrok.put(sampledata) register = { - 'id': 'transitioncounter', - 'name': 'Transition counter', - 'longname': '...', - 'desc': 'Counts rising/falling edges in the signal.', - 'longdesc': '...', - 'author': 'Uwe Hermann', - 'email': 'uwe@hermann-uwe.de', - 'license': 'gplv2+', - 'in': ['logic'], - 'out': ['transitioncounts'], - 'probes': [ - # All probes. - ], - 'options': { - # No options so far. - }, - # 'start': start, - # 'report': report, + 'id': 'transitioncounter', + 'name': 'Transition counter', + 'longname': '...', + 'desc': 'Counts rising/falling edges in the signal.', + 'longdesc': '...', + 'author': 'Uwe Hermann', + 'email': 'uwe@hermann-uwe.de', + 'license': 'gplv2+', + 'in': ['logic'], + 'out': ['transitioncounts'], + 'probes': [ + # All probes. + ], + 'options': { + # No options so far. + }, + # 'start': start, + # 'report': report, } # Use psyco (if available) as it results in huge performance improvements. try: - import psyco - psyco.bind(decode) + import psyco + psyco.bind(decode) except ImportError: - pass + pass |