Commit 5471678e authored by Mike Lyons's avatar Mike Lyons

Merge branch 'fastclock' of github.com:mjlyons/vSPI into fastclock

parents 4eb0c859 a31012bc
from cheetah_py import *
import time
class SpiComm:
"""Controls a Cheetah USB/SPI adapter to talk over SPI to the spiifc
module"""
_port = 0 # Change if using multiple Cheetahs
_mode = 3 # spiifc SPI mode
_bitrate = 28000 # kbps
handle = None # handle to Cheetah SPI
class SpiCommError(Exception):
"""There was some error interacting with the Cheetah SPI adapter"""
def __init__(self, msg):
self.msg = msg
def __init__(self):
self.handle = ch_open(self._port)
if (self.handle <= 0):
raise SpiCommError("Unable to open Cheetah device on port %d.\nError code = %d (%s)" % (self._port, self.handle, ch_status_string(self.handle)))
ch_host_ifce_speed(self.handle)
ch_spi_configure(self.handle, (self._mode >> 1), self._mode & 1,
CH_SPI_BITORDER_MSB, 0x0)
ch_spi_bitrate(self.handle, self._bitrate)
#ch_spi_queue_clear(self.handle)
#ch_spi_queue_oe(self.handle, 1)
def __del__(self):
ch_close(self.handle)
def SendToSlave(self, byteArray):
byteCount = len(byteArray) + 1
data_in = array('B', [0 for i in range(byteCount)])
actualByteCount = 0
ch_spi_queue_clear(self.handle)
ch_spi_queue_oe(self.handle, 1)
#ch_spi_queue_ss(self.handle, 0x2)
#ch_spi_queue_byte(self.handle, 1, 0xCC)
ch_spi_queue_ss(self.handle, 0x1)
ch_spi_queue_byte(self.handle, 1, 1) # Sending data to slave
for byte in byteArray:
ch_spi_queue_byte(self.handle, 1, byte)
#ch_spi_queue_ss(self.handle, 0x2)
#ch_spi_queue_byte(self.handle, 1, 0xCC)
ch_spi_queue_ss(self.handle, 0)
ch_spi_queue_oe(self.handle, 0)
(actualByteCount, data_in) = ch_spi_batch_shift(self.handle, byteCount)
def RecvFromSlave(self, byteCount):
totalByteCount = byteCount + 1 # Extra byte for cmd
data_in = array('B', [0 for i in range(totalByteCount)])
actualByteCount = 0
ch_spi_queue_clear(self.handle)
ch_spi_queue_oe(self.handle, 1)
#ch_spi_queue_ss(self.handle, 0x2)
#ch_spi_queue_byte(self.handle, 1, 0xCC)
ch_spi_queue_ss(self.handle, 0x1)
ch_spi_queue_byte(self.handle, 1, 3) # Receive data from slave
ch_spi_queue_byte(self.handle, byteCount, 0x56)
#ch_spi_queue_ss(self.handle, 0x2)
#ch_spi_queue_byte(self.handle, 1, 0xCC)
ch_spi_queue_ss(self.handle, 0x0)
ch_spi_queue_oe(self.handle, 0)
(actualByteCount, data_in) = ch_spi_batch_shift(self.handle,
totalByteCount)
return data_in[1:]
from cheetah_py import *
from time import *
import sys
import spilib
import time
import datetime
import random
def print_usage():
print \
"""
usage: spitest.py PORT
"""
#
# SingleBytePacketTest:
#
# Sends a predefined pattern of single-byte SPI transmissions (master-out)
#
def SingleBytePacketsSendTest():
packetsToSend = [[0x55],[0xAA],[0x33],[0x66],[0xCC],[0x99],[0xF0],\
[0x0F],[0xFF],[0x00]]
packetIndex = 0
while True:
dataToSend = packetsToSend[packetIndex]
sys.stdout.write("Sending: [")
for sendByte in dataToSend:
sys.stdout.write(" 0x%02x" % (sendByte))
sys.stdout.write(" ]\n")
spi.SendToSlave(dataToSend)
packetIndex = (packetIndex + 1) % len(packetsToSend)
time.sleep(1)
packetIndex + 1
if (len(sys.argv) < 2):
print_usage()
sys.exit(1)
#
# MultiBytePacketSendTest:
#
# Sends a predefined single multi-byte packet over SPI (master-out)
#
def MultiBytePacketSendTest():
dataToSend = [0x01, 0x55, 0xAA, 0x33, 0x66, 0xCC, 0x99, 0xF0, 0xFF, 0x0F]
sys.stdout.write("Sending: [")
for sendByte in dataToSend:
sys.stdout.write(" 0x%02x" % (sendByte))
sys.stdout.write(" ]\n")
spi.SendToSlave(dataToSend)
port = int(sys.argv[1])
mode = 3
bitrate = 30000 # kbps
byteCount = 4096 # bytes
#
# LoopbackTest:
#
# Sends randomly generated blocks of data over SPI, then reads back
# data. Assumes that slave is using a common read and write buffer
# and reads the block of data back. The test verifies that the block of
# data is identical to the one sent. The test will run continuously
# until a received packet does not match the sent packet.
#
def LoopbackTest():
passCount = 0
loopbackErrors = 0
packetByteSize = 4096
while loopbackErrors == 0:
print("PassCount: %d" % (passCount))
dataToSend = []
for randIndex in range(packetByteSize):
dataToSend.append(random.randint(0, 255))
print("Sending [0x%x 0x%x 0x%x 0x%x 0x%x ...]" % (
dataToSend[0], dataToSend[1], dataToSend[2],
dataToSend[3], dataToSend[4]))
# Send some data to the slave
sys.stdout.write("Sending data to slave...");
spi.SendToSlave(dataToSend)
sys.stdout.write("done!\n")
# Receive some data from the slave
recvData = spi.RecvFromSlave(packetByteSize)
# Make sure bytes sent match bytes received
if len(recvData) != packetByteSize:
sys.stdout.write("[FAIL] Did not receive 4096 bytes from spiifc\n")
sys.exit(0)
for byteIndex in range(packetByteSize):
if recvData[byteIndex] != dataToSend[byteIndex]:
sys.stdout.write("[FAIL] mismatch at index %d: sent=0x%x, recv=0x%x\n" \
% (byteIndex, dataToSend[byteIndex], recvData[byteIndex]))
loopbackErrors = loopbackErrors + 1
if loopbackErrors >= 5:
break
if 0 == loopbackErrors:
sys.stdout.write("[PASS] All loopback SPI bytes match.\n");
passCount = passCount + 1
# Open the device
handle = ch_open(port)
if (handle <= 0):
print "Unable to open Cheetah device on port %d" % port
print "Error code = %d (%s)" % (handle, ch_status_string(handle))
sys.exit(1)
# Print number of passed tests before failure
print("PassCount: %d" % (passCount))
print "Opened Cheetah device on port %d" % port
ch_host_ifce_speed_string = ""
if (ch_host_ifce_speed(handle)):
ch_host_ifce_speed_string = "high speed"
else:
ch_host_ifce_speed_string = "full speed"
print "Host interface is %s" % ch_host_ifce_speed_string
#
# PrintCliSyntax:
#
# Displays the syntax for the command line interface (CLI)
def PrintCliSyntax():
print """
Syntax:
spitest.py test [random-seed]
Valid tests (case sensitive):
- SingleBytePacketsSend
- MultiBytePacketSend
- Loopback
"""
# Ensure that SPI subsystem is configured
ch_spi_configure(handle, (mode >> 1), mode & 1, CH_SPI_BITORDER_MSB, 0x0)
print "SPI configuration set to mode %d, MSB shift, SS[2:0] active low" % mode
sys.stdout.flush()
#
# Main
#
# Set the bitrate
bitrate = ch_spi_bitrate(handle, bitrate)
print "Bitrate set to %d kHz" % bitrate
sys.stdout.flush()
# Parse CLI
if len(sys.argv) < 2 or len(sys.argv) > 3:
PrintCliSyntax()
sys.exit(1)
# Create 4KB of fake data so we can exchange it for real data
data_in = array('B', [0 for i in range(byteCount)])
# Retreive specified test function(s)
cliTest = sys.argv[1]
testMapping = {'SingleBytePacketsSend' : [SingleBytePacketsSendTest],
'MultiBytePacketSend' : [MultiBytePacketSendTest],
'Loopback' : [LoopbackTest]}
if cliTest not in testMapping:
sys.stderr.write('%s is not a valid test.\n' % (cliTest,))
PrintCliSyntax()
sys.exit(1)
testsToRun = testMapping[cliTest]
# Seed random number generator
if len(sys.argv) == 3:
seed = int(sys.argv[2])
else:
seed = datetime.datetime.utcnow().microsecond
ch_spi_queue_clear(handle)
ch_spi_queue_oe(handle, 1)
ch_spi_queue_ss(handle, 0x1)
ch_spi_queue_byte(handle, 1, 1) # Sending data to FPGA
ch_spi_queue_byte(handle, 1, 0xFF) # Sending bytes
ch_spi_queue_byte(handle, 1, 0xF0) # Sending bytes
ch_spi_queue_byte(handle, 1, 0x33) # Sending bytes
ch_spi_queue_byte(handle, 1, 0x55) # Sending bytes
ch_spi_queue_byte(handle, 1, 0x12) # Sending bytes
ch_spi_queue_byte(handle, 1, 0x34) # Sending bytes
ch_spi_queue_byte(handle, 1, 0x56) # Sending bytes
ch_spi_queue_byte(handle, 1, 0x78) # Sending bytes
ch_spi_queue_byte(handle, 1, 0x9A) # Sending bytes
ch_spi_queue_ss(handle, 0)
(actualByteCount, data_in) = ch_spi_batch_shift(handle, byteCount)
for i in range(actualByteCount):
sys.stdout.write("%x " % data_in[i])
sys.stdout.write("\n")
# Initialize Cheetah SPI/USB adapter
spi = spilib.SpiComm()
ch_spi_queue_clear(handle)
ch_spi_queue_oe(handle, 1)
ch_spi_queue_ss(handle, 0x1)
ch_spi_queue_byte(handle, 1, 3) # Receiving data from FPGA
for i in range(1024):
ch_spi_queue_byte(handle, 1, 0x00) # Sending bytes (1024 bytes of gibberish)
ch_spi_queue_ss(handle, 0)
(actualByteCount, data_in) = ch_spi_batch_shift(handle, byteCount)
for i in range(actualByteCount):
sys.stdout.write("%x " % data_in[i])
sys.stdout.write("\n")
# Seed random
print("Random seed: %d" % seed)
random.seed(seed)
# Run specified test
for testToRun in testsToRun:
testToRun()
# Close and exit
ch_close(handle)
sys.stdout.write("Exiting...\n")
sys.exit(0)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment