def test_i2c_decode(self): self.test_name = 'I2C transfer' self.trial_count = 20 for i in xrange(self.trial_count): self.update_progress(i+1) clock_freq = 100.0e3 transfers = [] transfers.append(i2c.I2CTransfer(i2c.I2C.Write, 0x23, [1,2,3, 4])) transfers.append(i2c.I2CTransfer(i2c.I2C.Write, 0x183, [5, 6, 240])) transfers = [] for _ in xrange(random.randint(1, 6)): addr = random.randint(1, 2**10-1) data = [] for __ in xrange(random.randint(1, 10)): data.append(random.randint(0, 255)) r_wn = random.choice((i2c.I2C.Write, i2c.I2C.Read)) # reads with 10-bit addressing are special if r_wn == i2c.I2C.Read and addr > 0x77: transfers.append(i2c.I2CTransfer(i2c.I2C.Write, addr, data)) transfers.append(i2c.I2CTransfer(r_wn, addr, data)) else: transfers.append(i2c.I2CTransfer(r_wn, addr, data)) use_edges = random.choice((True, False)) scl, sda = i2c.i2c_synth(transfers, clock_freq, idle_start=3.0e-5, idle_end=3.0e-5) if use_edges: records_it = i2c.i2c_decode(scl, sda, stream_type=streaming.StreamType.Edges) else: sample_period = 1.0 / (20.0 * clock_freq) scl_s = sigp.edges_to_sample_stream(scl, sample_period) sda_s = sigp.edges_to_sample_stream(sda, sample_period) records_it = i2c.i2c_decode(scl_s, sda_s, stream_type=streaming.StreamType.Samples) records = list(records_it) d_txfers = list(i2c.reconstruct_i2c_transfers(iter(records))) # validate the decoded transfers match = True for i, t in enumerate(d_txfers): if t != transfers[i]: print('\nMismatch:') print(' ', t) print(' ', transfers[i]) match = False break self.assertTrue(match, msg='Transfers not decoded successfully') self.assertEqual(len(d_txfers), len(transfers), 'Missing or extra decoded transfers')
def lm73_decode(i2c_stream, addresses=LM73Addresses): '''Decode an LM73 data stream i2c_stream (sequence of StreamRecord or I2CTransfer) An iterable representing either a stream of I2C StreamRecord objects or I2CTransfer objects produced by i2c_decode() or reconstruct_i2c_transfers() respectively. addresses (set of ints) A collection identifying the valid LM73 addresses to decode. All others are ignored. Yields a series of LM73Transfer objects and any unrelated I2CTransfer objects. ''' cur_reg = LM73Register.Temperature # check type of stream stream_it, check_it = itertools.tee(i2c_stream) try: rec0 = next(check_it) except StopIteration: # Stream is empty rec0 = None if rec0 is not None: if not isinstance(rec0, i2c.I2CTransfer): # Convert the stream to a set of I2C transfers stream_it = i2c.reconstruct_i2c_transfers(stream_it) del check_it for tfer in stream_it: if tfer.address not in addresses: yield tfer continue if tfer.r_wn == i2c.I2C.Write: if len(tfer.data) == 0: # Error condition # This should only happen if the data portion of a write is missing tfer.status = LM73StreamStatus.MissingDataError yield tfer continue elif len(tfer.data) == 1: # Set pointer op cur_reg = tfer.data[0] lm_tfer = LM73Transfer(tfer.address, LM73Operation.SetPointer, cur_reg, None) lm_tfer.annotate('frame', {}, stream.AnnotationFormat.Hidden) lm_tfer.subrecords = tfer.subrecords lm_tfer.subrecords[0].data_format = stream.AnnotationFormat.Small address = lm_tfer.subrecords[0].data >> 1 lm_tfer.subrecords[0].fields['value'] = 'set ptr\n{}'.format(hex(address)) lm_tfer.subrecords[2].annotate('ctrl', None, stream.AnnotationFormat.Enum) lm_tfer.subrecords[2].fields['value'] = LM73Register(lm_tfer.subrecords[2].data) else: # Write data cur_reg = tfer.data[0] lm_tfer = LM73Transfer(tfer.address, LM73Operation.WriteData, \ cur_reg, tfer.data[1:]) lm_tfer.annotate('frame', {}, stream.AnnotationFormat.Hidden) lm_tfer.subrecords = tfer.subrecords else: # Read data lm_tfer = LM73Transfer(tfer.address, LM73Operation.ReadData, cur_reg, tfer.data) lm_tfer.annotate('frame', {}, stream.AnnotationFormat.Hidden) lm_tfer.subrecords = tfer.subrecords lm_tfer.subrecords[0].data_format = stream.AnnotationFormat.Small address = lm_tfer.subrecords[0].data >> 1 lm_tfer.subrecords[0].fields['value'] = 'read\n{}'.format(hex(address)) for sr in lm_tfer.subrecords[2::2]: sr.data_format = stream.AnnotationFormat.Hex if cur_reg == LM73Register.Temperature and len(tfer.data) == 2: temp_data = lm_tfer.subrecords[2:] temp_sr = stream.StreamSegment((temp_data[0].start_time, temp_data[-1].end_time), kind='LM73 Temperature') value = 'Temp. = {} C\n0x{:04X}'.format(lm_tfer.temperature, (tfer.data[0] << 8) + tfer.data[1]) temp_sr.annotate('data', {'value':value}, stream.AnnotationFormat.Small) temp_sr.subrecords = temp_data for sr in temp_sr.subrecords: sr.data_format = stream.AnnotationFormat.Hidden lm_tfer.subrecords = lm_tfer.subrecords[0:2] + [temp_sr] lm_tfer.i2c_tfer = tfer yield lm_tfer
def lm73_decode(i2c_stream, addresses=LM73Addresses): '''Decode an LM73 data stream i2c_stream (sequence of StreamRecord or I2CTransfer) An iterable representing either a stream of I2C StreamRecord objects or I2CTransfer objects produced by i2c_decode() or reconstruct_i2c_transfers() respectively. addresses (set of ints) A collection identifying the valid LM73 addresses to decode. All others are ignored. Yields a series of LM73Transfer objects and any unrelated I2CTransfer objects. ''' cur_reg = LM73Register.Temperature # check type of stream stream_it, check_it = itertools.tee(i2c_stream) try: rec0 = next(check_it) except StopIteration: # Stream is empty rec0 = None if rec0 is not None: if not isinstance(rec0, i2c.I2CTransfer): # Convert the stream to a set of I2C transfers stream_it = i2c.reconstruct_i2c_transfers(stream_it) del check_it for tfer in stream_it: if tfer.address not in addresses: yield tfer continue if tfer.r_wn == i2c.I2C.Write: if len(tfer.data) == 0: # Error condition # This should only happen if the data portion of a write is missing tfer.status = LM73StreamStatus.MissingDataError yield tfer continue elif len(tfer.data) == 1: # Set pointer op cur_reg = tfer.data[0] lm_tfer = LM73Transfer(tfer.address, LM73Operation.SetPointer, cur_reg, None) lm_tfer.annotate('frame', {}, stream.AnnotationFormat.Hidden) lm_tfer.subrecords = tfer.subrecords lm_tfer.subrecords[ 0].data_format = stream.AnnotationFormat.Small address = lm_tfer.subrecords[0].data >> 1 lm_tfer.subrecords[0].fields['value'] = 'set ptr\n{}'.format( hex(address)) lm_tfer.subrecords[2].annotate('ctrl', None, stream.AnnotationFormat.Enum) lm_tfer.subrecords[2].fields['value'] = LM73Register( lm_tfer.subrecords[2].data) else: # Write data cur_reg = tfer.data[0] lm_tfer = LM73Transfer(tfer.address, LM73Operation.WriteData, \ cur_reg, tfer.data[1:]) lm_tfer.annotate('frame', {}, stream.AnnotationFormat.Hidden) lm_tfer.subrecords = tfer.subrecords else: # Read data lm_tfer = LM73Transfer(tfer.address, LM73Operation.ReadData, cur_reg, tfer.data) lm_tfer.annotate('frame', {}, stream.AnnotationFormat.Hidden) lm_tfer.subrecords = tfer.subrecords lm_tfer.subrecords[0].data_format = stream.AnnotationFormat.Small address = lm_tfer.subrecords[0].data >> 1 lm_tfer.subrecords[0].fields['value'] = 'read\n{}'.format( hex(address)) for sr in lm_tfer.subrecords[2::2]: sr.data_format = stream.AnnotationFormat.Hex if cur_reg == LM73Register.Temperature and len(tfer.data) == 2: temp_data = lm_tfer.subrecords[2:] temp_sr = stream.StreamSegment( (temp_data[0].start_time, temp_data[-1].end_time), kind='LM73 Temperature') value = 'Temp. = {} C\n0x{:04X}'.format( lm_tfer.temperature, (tfer.data[0] << 8) + tfer.data[1]) temp_sr.annotate('data', {'value': value}, stream.AnnotationFormat.Small) temp_sr.subrecords = temp_data for sr in temp_sr.subrecords: sr.data_format = stream.AnnotationFormat.Hidden lm_tfer.subrecords = lm_tfer.subrecords[0:2] + [temp_sr] lm_tfer.i2c_tfer = tfer yield lm_tfer