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

Commit 63df8b9

Browse files
author
mpratt14
authored
Fix mistakes in SPI method from previous pull request
Fix mistakes from #98 This time, extensively tested Also added support for read requests of odd length, read requests of length 1 working Also applied same ideas to write requests
1 parent 377c684 commit 63df8b9

File tree

1 file changed

+69
-44
lines changed

1 file changed

+69
-44
lines changed

Adafruit_GPIO/FT232H.py

+69-44
Original file line numberDiff line numberDiff line change
@@ -481,16 +481,23 @@ def write(self, data):
481481
# Compute length low and high bytes.
482482
# NOTE: Must actually send length minus one because the MPSSE engine
483483
# considers 0 a length of 1 and FFFF a length of 65536
484-
length = len(data)-1
485-
len_low = length & 0xFF
486-
len_high = (length >> 8) & 0xFF
484+
# splitting into two lists for two commands to prevent buffer errors
485+
data1 = data[:len(data)/2]
486+
data2 = data[len(data)/2:]
487+
len_low1 = (len(data1) - 1) & 0xFF
488+
len_high1 = ((len(data1) - 1) >> 8) & 0xFF
489+
len_low2 = (len(data2) - 1) & 0xFF
490+
len_high2 = ((len(data2) - 1) >> 8) & 0xFF
487491
self._assert_cs()
488-
# Send command and length.
489-
self._ft232h._write(str(bytearray((command, len_low, len_high))))
490-
# Send data.
491-
self._ft232h._write(str(bytearray(data)))
492+
# Send command and length, then data, split into two commands, handle for length 1
493+
if len(data1) > 0:
494+
self._ft232h._write(str(bytearray((command, len_low1, len_high1))))
495+
self._ft232h._write(str(bytearray(data1)))
496+
if len(data2) > 0:
497+
self._ft232h._write(str(bytearray((command, len_low2, len_high2))))
498+
self._ft232h._write(str(bytearray(data2)))
492499
self._deassert_cs()
493-
500+
494501
def read(self, length):
495502
"""Half-duplex SPI read. The specified length of bytes will be clocked
496503
in the MISO line and returned as a bytearray object.
@@ -506,18 +513,24 @@ def read(self, length):
506513
# Compute length low and high bytes.
507514
# NOTE: Must actually send length minus one because the MPSSE engine
508515
# considers 0 a length of 1 and FFFF a length of 65536
509-
length = length/2
510-
len_low = (length-1) & 0xFF
511-
len_high = ((length-1) >> 8) & 0xFF
516+
#force odd numbers to round up instead of down
517+
lengthR = length
518+
if length % 2 == 1:
519+
lengthR += 1
520+
lengthR = lengthR/2
521+
#when odd length requested, get the remainder instead of the same number
522+
lenremain = length - lengthR
523+
len_low = (lengthR - 1) & 0xFF
524+
len_high = ((lengthR - 1) >> 8) & 0xFF
512525
self._assert_cs()
513526
# Send command and length.
514527
# Perform twice to prevent error from hardware defect/limits
515528
self._ft232h._write(str(bytearray((command, len_low, len_high))))
516-
payload1 = self._ft232h._poll_read(length)
529+
payload1 = self._ft232h._poll_read(lengthR)
517530
self._ft232h._write(str(bytearray((command, len_low, len_high))))
518-
payload2 = self._ft232h._poll_read(length)
531+
payload2 = self._ft232h._poll_read(lenremain)
519532
self._deassert_cs()
520-
# Read response bytes.
533+
# Read response bytes
521534
return bytearray(payload1 + payload2)
522535

523536
def bulkread(self, data = [], lengthR = 'None', readmode = 1):
@@ -540,30 +553,36 @@ def bulkread(self, data = [], lengthR = 'None', readmode = 1):
540553
lengthR = len(data)
541554
#command parameters definition and math
542555
#MPSSE engine sees length 0 as 1 byte, so - 1 lengths
543-
commandW = 0x10 | (spi.lsbfirst << 3) | spi.write_clock_ve
556+
commandW = 0x10 | (self.lsbfirst << 3) | self.write_clock_ve
544557
lengthW = len(data) - 1
545558
len_lowW = (lengthW) & 0xFF
546559
len_highW = ((lengthW) >> 8) & 0xFF
547-
commandR = 0x20 | (spi.lsbfirst << 3) | (spi.read_clock_ve << 2)
548-
lengthR = lengthR/2
549-
len_lowR = (lengthR-1) & 0xFF
550-
len_highR = ((lengthR-1) >> 8) & 0xFF
560+
commandR = 0x20 | (self.lsbfirst << 3) | (self.read_clock_ve << 2)
561+
#force odd numbers to round up instead of down
562+
length = lengthR
563+
if lengthR % 2 == 1:
564+
length += 1
565+
length = length/2
566+
#when odd length requested, get the remainder instead of the same number
567+
lenremain = lengthR - length
568+
len_lowR = (length - 1) & 0xFF
569+
len_highR = ((length - 1) >> 8) & 0xFF
551570
#logger debug info
552-
#logger.debug('SPI bulkread with write command {0:2X}.'.format(commandW))
553-
#logger.debug('and read command {0:2X}.'.format(commandR))
571+
logger.debug('SPI bulkread with write command {0:2X}.'.format(commandW))
572+
logger.debug('and read command {0:2X}.'.format(commandR))
554573
#begin command set
555-
spi._assert_cs()
574+
self._assert_cs()
556575
#write command, these have to be separated due to TypeError
557-
spi._ft232h._write(str(bytearray((commandW, len_lowW, len_highW))))
558-
spi._ft232h._write(str(bytearray(data)))
559-
#read command, which is now divided into two commands
560-
spi._ft232h._write(str(bytearray((commandR, len_lowR, len_highR))))
561-
payload1 = spi._ft232h._poll_read(lengthR)
562-
spi._ft232h._write(str(bytearray((commandR, len_lowR, len_highR))))
563-
payload2 = spi._ft232h._poll_read(lengthR)
576+
self._ft232h._write(str(bytearray((commandW, len_lowW, len_highW))))
577+
self._ft232h._write(str(bytearray(data)))
578+
#read command, which is divided into two commands
579+
self._ft232h._write(str(bytearray((commandR, len_lowR, len_highR))))
580+
payload1 = self._ft232h._poll_read(length)
581+
self._ft232h._write(str(bytearray((commandR, len_lowR, len_highR))))
582+
payload2 = self._ft232h._poll_read(lenremain)
583+
self._deassert_cs()
564584
#end command set
565-
spi._deassert_cs()
566-
# Read response bytes.
585+
# Read response bytes
567586
return bytearray(payload1 + payload2)
568587

569588
def transfer(self, data):
@@ -582,25 +601,31 @@ def transfer(self, data):
582601
# Compute length low and high bytes.
583602
# NOTE: Must actually send length minus one because the MPSSE engine
584603
# considers 0 a length of 1 and FFFF a length of 65536
585-
length = len(data)
586-
length = length/2
587-
len_low = (length-1) & 0xFF
588-
len_high = ((length-1) >> 8) & 0xFF
589-
# Send command and length.
590-
# Perform twice to prevent error from hardware defect/limits
604+
data1 = data[:len(data)/2]
605+
data2 = data[len(data)/2:]
606+
len_low1 = (len(data1) - 1) & 0xFF
607+
len_high1 = ((len(data1) - 1) >> 8) & 0xFF
608+
len_low2 = (len(data2) - 1) & 0xFF
609+
len_high2 = ((len(data2) - 1) >> 8) & 0xFF
610+
payload1 = ''
611+
payload2 = ''
612+
#start command set
591613
self._assert_cs()
592-
self._ft232h._write(str(bytearray((command, len_low, len_high))))
593-
self._ft232h._write(str(bytearray(data)))
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)
614+
# Perform twice to prevent error from hardware defect/limits
615+
# Send command and length, then data, split into two commands, handle for length 1
616+
if len(data1) > 0:
617+
self._ft232h._write(str(bytearray((command, len_low1, len_high1))))
618+
self._ft232h._write(str(bytearray(data1)))
619+
payload1 = self._ft232h._poll_read(len(data1))
620+
if len(data2) > 0:
621+
self._ft232h._write(str(bytearray((command, len_low2, len_high2))))
622+
self._ft232h._write(str(bytearray(data2)))
623+
payload2 = self._ft232h._poll_read(len(data2))
598624
#self._ft232h._write('\x87')
599625
self._deassert_cs()
600626
# Read response bytes.
601627
return bytearray(payload1 + payload2)
602628

603-
604629
class I2CDevice(object):
605630
"""Class for communicating with an I2C device using the smbus library.
606631
Allows reading and writing 8-bit, 16-bit, and byte array values to registers

0 commit comments

Comments
 (0)