Skip to content
This repository was archived by the owner on Sep 30, 2019. It is now read-only.

Commit 377c684

Browse files
authored
Merge pull request #98 from mpratt14/patch-4
SPI Methods: Prevention of hardware limit errors and data corruption
2 parents 96651c9 + 57adb1e commit 377c684

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

Adafruit_GPIO/FT232H.py

+32-5
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,11 @@ def write(self, data):
470470
"""Half-duplex SPI write. The specified array of bytes will be clocked
471471
out the MOSI line.
472472
"""
473+
#check for hardware limit of FT232H and similar MPSSE chips
474+
if (len(data) > 65536):
475+
print 'the FTDI chip is limited to 65536 bytes (64 KB) of input/output per command!'
476+
print 'use for loops for larger reads'
477+
exit(1)
473478
# Build command to write SPI data.
474479
command = 0x10 | (self.lsbfirst << 3) | self.write_clock_ve
475480
logger.debug('SPI write with command {0:2X}.'.format(command))
@@ -490,21 +495,31 @@ def read(self, length):
490495
"""Half-duplex SPI read. The specified length of bytes will be clocked
491496
in the MISO line and returned as a bytearray object.
492497
"""
498+
#check for hardware limit of FT232H and similar MPSSE chips
499+
if (1 > length > 65536):
500+
print 'the FTDI chip is limited to 65536 bytes (64 KB) of input/output per command!'
501+
print 'use for loops for larger reads'
502+
exit(1)
493503
# Build command to read SPI data.
494504
command = 0x20 | (self.lsbfirst << 3) | (self.read_clock_ve << 2)
495505
logger.debug('SPI read with command {0:2X}.'.format(command))
496506
# Compute length low and high bytes.
497507
# NOTE: Must actually send length minus one because the MPSSE engine
498508
# considers 0 a length of 1 and FFFF a length of 65536
509+
length = length/2
499510
len_low = (length-1) & 0xFF
500511
len_high = ((length-1) >> 8) & 0xFF
501512
self._assert_cs()
502513
# Send command and length.
503-
self._ft232h._write(str(bytearray((command, len_low, len_high, 0x87))))
514+
# Perform twice to prevent error from hardware defect/limits
515+
self._ft232h._write(str(bytearray((command, len_low, len_high))))
516+
payload1 = self._ft232h._poll_read(length)
517+
self._ft232h._write(str(bytearray((command, len_low, len_high))))
518+
payload2 = self._ft232h._poll_read(length)
504519
self._deassert_cs()
505520
# Read response bytes.
506-
return bytearray(self._ft232h._poll_read(length))
507-
521+
return bytearray(payload1 + payload2)
522+
508523
def bulkread(self, data = [], lengthR = 'None', readmode = 1):
509524
"""Half-duplex SPI write then read. Send command and payload to slave as bytearray
510525
then consequently read out response from the slave for length in bytes.
@@ -548,30 +563,42 @@ def bulkread(self, data = [], lengthR = 'None', readmode = 1):
548563
payload2 = spi._ft232h._poll_read(lengthR)
549564
#end command set
550565
spi._deassert_cs()
566+
# Read response bytes.
551567
return bytearray(payload1 + payload2)
552568

553569
def transfer(self, data):
554570
"""Full-duplex SPI read and write. The specified array of bytes will be
555571
clocked out the MOSI line, while simultaneously bytes will be read from
556572
the MISO line. Read bytes will be returned as a bytearray object.
557573
"""
574+
#check for hardware limit of FT232H and similar MPSSE chips
575+
if (len(data) > 65536):
576+
print 'the FTDI chip is limited to 65536 bytes (64 KB) of input/output per command!'
577+
print 'use for loops for larger reads'
578+
exit(1)
558579
# Build command to read and write SPI data.
559580
command = 0x30 | (self.lsbfirst << 3) | (self.read_clock_ve << 2) | self.write_clock_ve
560581
logger.debug('SPI transfer with command {0:2X}.'.format(command))
561582
# Compute length low and high bytes.
562583
# NOTE: Must actually send length minus one because the MPSSE engine
563584
# considers 0 a length of 1 and FFFF a length of 65536
564585
length = len(data)
586+
length = length/2
565587
len_low = (length-1) & 0xFF
566588
len_high = ((length-1) >> 8) & 0xFF
567589
# Send command and length.
590+
# Perform twice to prevent error from hardware defect/limits
568591
self._assert_cs()
569592
self._ft232h._write(str(bytearray((command, len_low, len_high))))
570593
self._ft232h._write(str(bytearray(data)))
571-
self._ft232h._write('\x87')
594+
payload1 = self._ft232h._poll_read(length)
595+
self._ft232h._write(str(bytearray((command, len_low, len_high))))
596+
self._ft232h._write(str(bytearray(data)))
597+
payload2 = self._ft232h._poll_read(length)
598+
#self._ft232h._write('\x87')
572599
self._deassert_cs()
573600
# Read response bytes.
574-
return bytearray(self._ft232h._poll_read(length))
601+
return bytearray(payload1 + payload2)
575602

576603

577604
class I2CDevice(object):

0 commit comments

Comments
 (0)