Replay I2C

The following script can be used to repeat I2C transactions captured and exported from Saleae Logic. After the capture is completed, export the I2C analyzer results as a csv file. You can follow this guide to export the file. The exported data should be in HEX-- Note that the base/radix of the exported data will match the current setting for display in the software.

Simply modify the parameters in lines 9-15 in the script below and then everything is ready to play back the file from the Binho Nova Multi-Protocol USB Host Adapter.

For easy testing, here's an example export file from Saleae Logic that works with this script:

from binhoHostAdapter import binhoHostAdapter
from binhoHostAdapter import binhoUtilities

from datetime import datetime, timedelta, time
import math
import csv


i2cIndex = 0
i2cClockFreq = 400000
i2cPullEn = 'EN'

captureExportFile = 'C:\\Users\\Batman\\Desktop\\LogicExports\\i2c_eeprom.csv'

binhoCommPort = 'COM27'


# ---- No Need to Change Anything Below Here ----

print("Opening " + binhoCommPort + "...")
print()

# create the binhoHostAdapter object
binho = binhoHostAdapter.binhoHostAdapter(binhoCommPort)

print("Connecting to binho host adapter...")
print()

print("Connected!")
print()
binho.setLEDColor('YELLOW')

print("Setting I2C bus parameters:")
print()
binho.setOperationMode(0, 'I2C')

print('Clock Frequency: ' + str(i2cClockFreq))
binho.setClockI2C(i2cIndex, i2cClockFreq)

print('PullUps: ' + str(i2cPullEn))
binho.setPullUpStateI2C(i2cIndex, i2cPullEn)

print()
print("Computing USB Transit time...")
t0 = datetime.now()
binho.ping()
binho.ping()
binho.ping()
binho.ping()
binho.ping()
t1 = datetime.now()

avgUSBTxTime = (t1 - t0)/5
print('Average USB Tx Time = ' + str(avgUSBTxTime) + 's')
print()


print("Beginning Replay...")
print()

with open(captureExportFile) as captureExport:
	capture_reader = csv.reader(captureExport, delimiter=',')
	rowCount = 0

	startTime = datetime.now()
	prevTimestamp = startTime
	prevRowTime = 0

	currentPacketID = 0
	deviceAddress = 0
	payload = []
	isReadPacket = True
	
	for row in capture_reader:

		if rowCount == 0:

			# These are the column headers, just advance to the next row
			rowCount += 1
			print('PacketID#\tTimestamp\t\t\tAddress\tType\tLen(Bytes)')

		else:
			rowPacketID = row[1]

			#check if packetID is empty
			if rowPacketID == "":
				#this is a single write command with no data to follow it, skip it
				rowCount +=1

			elif int(row[1]) == currentPacketID:
				currRowTime = float(row[0])
				deviceAddress = int(row[2],16)
				payload.append(int(row[3], 16))

				if row[4] == 'Write':
					isReadPacket = False
				else:
					isReadPacket = True

				rowCount += 1

			else:
				# starts a new packet, so do the transaction we loaded

				deltaTimems = (currRowTime - prevRowTime) * 1000
				#deltaTimems = 0.125 * 1000
				#print('DeltaT: ' + str(deltaTimems))
				print('Waiting ' + str(timedelta(0,0,0,math.floor(deltaTimems))) + ' until next packet transmission', end='\r')

				while (datetime.now() - prevTimestamp) < timedelta(0,0,0,math.floor(deltaTimems)):
					#nothing, sleep does not have high enough resolution
					#print('WAITING ' + str(datetime.now() - prevTimestamp))
					pass

				if isReadPacket:

					print(str(currentPacketID) + '\t\t' + str(datetime.now()) + '\t' +  format(deviceAddress, '#02x') + '\tREAD\t' + str(len(payload)))

					binho.readBytesI2C(i2cIndex, deviceAddress, len(payload))

				else:

					print(str(currentPacketID) + '\t\t' + str(datetime.now()) + '\t' + format(deviceAddress, '#02x') + '\tWRITE\t' + str(len(payload)))
					binho.startI2C(i2cIndex, deviceAddress)

					for dataByte in payload:
						binho.writeByteI2C(i2cIndex, dataByte)

					binho.endI2C(i2cIndex)

				payload = []
				prevTimestamp = datetime.now()
				prevRowTime = currRowTime

				currentPacketID = int(row[1])
				currRowTime = float(row[0])

				deviceAddress = int(row[2],16)
				payload.append(int(row[3], 16))

				if row[4] == 'Write':
					isReadPacket = False
				else:
					isReadPacket = True

				rowCount += 1

print('Finished Replaying...')
print()
binho.setLEDColor('BLUE')
binho.close()
print('Goodbye!')

Last updated

Was this helpful?