| 1 |
14 |
mjlyons |
from cheetah_py import *
|
| 2 |
|
|
|
| 3 |
|
|
class SpiComm:
|
| 4 |
|
|
"""Controls a Cheetah USB/SPI adapter to talk over SPI to the spiifc
|
| 5 |
|
|
module"""
|
| 6 |
|
|
|
| 7 |
|
|
_port = 0 # Change if using multiple Cheetahs
|
| 8 |
|
|
_mode = 3 # spiifc SPI mode
|
| 9 |
|
|
|
| 10 |
|
|
handle = None # handle to Cheetah SPI
|
| 11 |
|
|
|
| 12 |
|
|
class SpiCommError(Exception):
|
| 13 |
|
|
"""There was some error interacting with the Cheetah SPI adapter"""
|
| 14 |
|
|
def __init__(self, msg):
|
| 15 |
|
|
self.msg = msg
|
| 16 |
|
|
|
| 17 |
|
|
def __init__(self, kbpsBitrate=9000):
|
| 18 |
|
|
self.handle = ch_open(self._port)
|
| 19 |
|
|
if (self.handle <= 0):
|
| 20 |
|
|
raise SpiCommError("Unable to open Cheetah device on port %d.\nError code = %d (%s)" % (self._port, self.handle, ch_status_string(self.handle)))
|
| 21 |
|
|
ch_host_ifce_speed(self.handle)
|
| 22 |
|
|
ch_spi_configure(self.handle, (self._mode >> 1), self._mode & 1,
|
| 23 |
|
|
CH_SPI_BITORDER_MSB, 0x0)
|
| 24 |
|
|
ch_spi_bitrate(self.handle, kbpsBitrate)
|
| 25 |
|
|
|
| 26 |
|
|
def __del__(self):
|
| 27 |
|
|
ch_close(self.handle)
|
| 28 |
|
|
|
| 29 |
|
|
def SendToSlave(self, byteArray):
|
| 30 |
|
|
byteCount = len(byteArray) + 1
|
| 31 |
|
|
data_in = array('B', [0 for i in range(byteCount)])
|
| 32 |
|
|
actualByteCount = 0
|
| 33 |
|
|
ch_spi_queue_clear(self.handle)
|
| 34 |
|
|
ch_spi_queue_oe(self.handle, 1)
|
| 35 |
|
|
ch_spi_queue_ss(self.handle, 0x1)
|
| 36 |
|
|
for byte in byteArray:
|
| 37 |
|
|
ch_spi_queue_byte(self.handle, 1, byte)
|
| 38 |
|
|
ch_spi_queue_ss(self.handle, 0)
|
| 39 |
|
|
ch_spi_queue_oe(self.handle, 0)
|
| 40 |
|
|
(actualByteCount, data_in) = ch_spi_batch_shift(self.handle, byteCount)
|
| 41 |
|
|
|
| 42 |
|
|
def RecvFromSlave(self, command, byteCount):
|
| 43 |
|
|
totalByteCount = byteCount + 1 # Extra byte for cmd
|
| 44 |
|
|
data_in = array('B', [0 for i in range(totalByteCount)])
|
| 45 |
|
|
actualByteCount = 0
|
| 46 |
|
|
ch_spi_queue_clear(self.handle)
|
| 47 |
|
|
ch_spi_queue_oe(self.handle, 1)
|
| 48 |
|
|
ch_spi_queue_ss(self.handle, 1)
|
| 49 |
|
|
ch_spi_queue_byte(self.handle, 1, command) # Receive data from slave
|
| 50 |
|
|
ch_spi_queue_byte(self.handle, byteCount, 0xFF)
|
| 51 |
|
|
ch_spi_queue_ss(self.handle, 0x0)
|
| 52 |
|
|
ch_spi_queue_oe(self.handle, 0)
|
| 53 |
|
|
(actualByteCount, data_in) = ch_spi_batch_shift(self.handle,
|
| 54 |
|
|
totalByteCount)
|
| 55 |
|
|
return data_in[1:]
|
| 56 |
|
|
|
| 57 |
|
|
def ReadMemory(self, byteCount):
|
| 58 |
|
|
return self.RecvFromSlave(0x3, byteCount)
|
| 59 |
|
|
|
| 60 |
|
|
def WriteMemory(self, bytesToWrite):
|
| 61 |
|
|
bytePacket = [0x01]
|
| 62 |
|
|
bytePacket.extend(bytesToWrite)
|
| 63 |
|
|
return self.SendToSlave(bytePacket)
|
| 64 |
|
|
|
| 65 |
|
|
def ReadReg(self, regId):
|
| 66 |
|
|
commandCode = 0x80 + regId
|
| 67 |
|
|
regValBytes = self.RecvFromSlave(commandCode, 4)
|
| 68 |
|
|
regValWord = 0
|
| 69 |
|
|
for regValByte in regValBytes:
|
| 70 |
|
|
regValWord = (regValWord * 256) + regValByte
|
| 71 |
|
|
return regValWord
|
| 72 |
|
|
|
| 73 |
|
|
def WriteReg(self, regId, value):
|
| 74 |
|
|
commandCode = 0xC0 + regId
|
| 75 |
|
|
bytesToSend = [commandCode, 0, 0, 0, 0]
|
| 76 |
|
|
for sendByteId in range(4,0,-1):
|
| 77 |
|
|
bytesToSend[sendByteId] = value % 256
|
| 78 |
|
|
value = value / 256
|
| 79 |
|
|
self.SendToSlave(bytesToSend)
|
| 80 |
|
|
|