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

Commit 8a10df5

Browse files
author
mpratt14
authored
Applying Hardware limit and data error prevention fixes
Applying fixes described here: #94 #95 In order to: Prevent a data stream larger than 64 KB from passing per command and warn the user Fix the weird data corruption error that may or may not occur from full hardware limit length reads
1 parent ede3d7d commit 8a10df5

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

Adafruit_GPIO/FT232H.py

+30-4
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,43 +495,64 @@ 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))
521+
return bytearray(payload1 + payload2)
507522

508523
def transfer(self, data):
509524
"""Full-duplex SPI read and write. The specified array of bytes will be
510525
clocked out the MOSI line, while simultaneously bytes will be read from
511526
the MISO line. Read bytes will be returned as a bytearray object.
512527
"""
528+
#check for hardware limit of FT232H and similar MPSSE chips
529+
if (len(data) > 65536):
530+
print 'the FTDI chip is limited to 65536 bytes (64 KB) of input/output per command!'
531+
print 'use for loops for larger reads'
532+
exit(1)
513533
# Build command to read and write SPI data.
514534
command = 0x30 | (self.lsbfirst << 3) | (self.read_clock_ve << 2) | self.write_clock_ve
515535
logger.debug('SPI transfer with command {0:2X}.'.format(command))
516536
# Compute length low and high bytes.
517537
# NOTE: Must actually send length minus one because the MPSSE engine
518538
# considers 0 a length of 1 and FFFF a length of 65536
519539
length = len(data)
540+
length = length/2
520541
len_low = (length-1) & 0xFF
521542
len_high = ((length-1) >> 8) & 0xFF
522543
# Send command and length.
544+
# Perform twice to prevent error from hardware defect/limits
523545
self._assert_cs()
524546
self._ft232h._write(str(bytearray((command, len_low, len_high))))
525547
self._ft232h._write(str(bytearray(data)))
526-
self._ft232h._write('\x87')
548+
payload1 = self._ft232h._poll_read(length)
549+
self._ft232h._write(str(bytearray((command, len_low, len_high))))
550+
self._ft232h._write(str(bytearray(data)))
551+
payload2 = self._ft232h._poll_read(length)
552+
#self._ft232h._write('\x87')
527553
self._deassert_cs()
528554
# Read response bytes.
529-
return bytearray(self._ft232h._poll_read(length))
555+
return bytearray(payload1 + payload2)
530556

531557

532558
class I2CDevice(object):

0 commit comments

Comments
 (0)