@@ -504,6 +504,51 @@ def read(self, length):
504504 self ._deassert_cs ()
505505 # Read response bytes.
506506 return bytearray (self ._ft232h ._poll_read (length ))
507+
508+ def bulkread (self , data = [], lengthR = 'None' , readmode = 1 ):
509+ """Half-duplex SPI write then read. Send command and payload to slave as bytearray
510+ then consequently read out response from the slave for length in bytes.
511+ Designed for use with NOR or NAND flash chips, and possibly SD cards...etc...
512+ Read command is cut in half and performed twice in series to prevent single byte errors.
513+ Hardware limits per command are enforced before doing anything.
514+ Read length is an optional argument, so that it can function similar to transfer
515+ but still half-duplex.
516+ For reading without writing, one can send a blank array or skip that argument.
517+ """
518+ #check for hardware limit of FT232H and similar MPSSE chips
519+ if (1 > lengthR > 65536 )| (len (data ) > 65536 ):
520+ print 'the FTDI chip is limited to 65536 bytes (64 KB) of input/output per command!'
521+ print 'use for loops for larger reads'
522+ exit (1 )
523+ #default mode is to act like `transfer` but half-duplex
524+ if (lengthR == 'None' )& (readmode == 1 ):
525+ lengthR = len (data )
526+ #command parameters definition and math
527+ #MPSSE engine sees length 0 as 1 byte, so - 1 lengths
528+ commandW = 0x10 | (spi .lsbfirst << 3 ) | spi .write_clock_ve
529+ lengthW = len (data ) - 1
530+ len_lowW = (lengthW ) & 0xFF
531+ len_highW = ((lengthW ) >> 8 ) & 0xFF
532+ commandR = 0x20 | (spi .lsbfirst << 3 ) | (spi .read_clock_ve << 2 )
533+ lengthR = lengthR / 2
534+ len_lowR = (lengthR - 1 ) & 0xFF
535+ len_highR = ((lengthR - 1 ) >> 8 ) & 0xFF
536+ #logger debug info
537+ #logger.debug('SPI bulkread with write command {0:2X}.'.format(commandW))
538+ #logger.debug('and read command {0:2X}.'.format(commandR))
539+ #begin command set
540+ spi ._assert_cs ()
541+ #write command, these have to be separated due to TypeError
542+ spi ._ft232h ._write (str (bytearray ((commandW , len_lowW , len_highW ))))
543+ spi ._ft232h ._write (str (bytearray (data )))
544+ #read command, which is now divided into two commands
545+ spi ._ft232h ._write (str (bytearray ((commandR , len_lowR , len_highR ))))
546+ payload1 = spi ._ft232h ._poll_read (lengthR )
547+ spi ._ft232h ._write (str (bytearray ((commandR , len_lowR , len_highR ))))
548+ payload2 = spi ._ft232h ._poll_read (lengthR )
549+ #end command set
550+ spi ._deassert_cs ()
551+ return bytearray (payload1 + payload2 )
507552
508553 def transfer (self , data ):
509554 """Full-duplex SPI read and write. The specified array of bytes will be
0 commit comments