Thursday, May 27, 2010

I tired using the FTDI's FT232R USB to Serial chip for the Bit bang type of application using the D2XX mode driver in Python.
The Bit-Bang mode of the FT232R chip is detailed in the FTDI Application note AN232R-01.
It was amazingly easy. I did it on my Windows XP laptop. This reminds me of the Parallel port days when we used to make stuff interfaced using the PC's Parallel Port. In fact due to some wrong connection I burnt the input pins of my PC's Parallel Port. But with FT232R's Bit-Bang mode I can happily say a good bye to the Parallel Port.
I would try to explain this in as lucid way as I can, so that it becomes a good document even for me to use at a later point.

[1] So the first we would being with setup needed for this Bit-Bang Experiment:
Listed below are the Pre-requisites:
  • Python V2.6 anything higher than this will also work however I don't know on the compatibility of Python V3.0 & higher ups
  • PyWin32 use the Latest version available for the Python V2.6
  • PyUSB package V1.6 for Windows I have tested this to be working, you can try for higher version if available
    UPDATE 06-NOV-2010: The PyUSB is only available till Python Version 2.6
    Still checking if we can get the newer Version available.

  • FT232R Chip of course in the form of some module or your custom PCB. I plan to make one for myself too would post once ready. There are a verity of Modules available from various vendors depending on the Flexibility and I/Os provided for use. Some of them only provide a few serial lines and the rest are hidden. I like the FTDI's conventional UM232R module for which I found an alternative at Sunrom (However now its non-stock). There are other modules too : SparkFun's BOB-00718 , Foca and Modren Devices USB - BUB.
[2] Details about the Modes available in FT232 for Bit Banging:
  • Asynchronous Bit Bang Mode: This mode helps to emulate the Parallel port kind of interface. Whatever is written to the 8bit port(D0-D7) is written out. The rate at which its written out is controlled by the Baud rate set in the chip. The CBUS pins are not accessible and also the Serial Interface Pins are now acting as the data pins(Given in the Below Section). Since this mode the write to the Bus and the Read from the bus can be without any strobe, that's why its called Asynchronous. below table shows the Pins available in this mode.
FT232RL/
FT245RL
Pin
Number
FT232RQ/
FT245RQ
Pin
Number
Signal Serial
Pins
FT232
Type Description
1 30 D0 TXD Input/Output Bit Bang Data Bus Bit 0
5 2 D1 RXD Input/Output Bit Bang Data Bus Bit 1
3 32 D2 RTS# Input/Output Bit Bang Data Bus Bit 2
11 8 D3 CTS# Input/Output Bit Bang Data Bus Bit 3
2 31 D4 DTR# Input/Output Bit Bang Data Bus Bit 4
9 6 D5 DSR# Input/Output Bit Bang Data Bus Bit 5
10 7 D6 DCD# Input/Output Bit Bang Data Bus Bit 6
6 3 D7 RI# Input/Output Bit Bang Data Bus Bit 7
  • Synchronous Bit Bang Mode: In this mode the communication of data is controlled by the #RD and #WR strobe signal from the CBUS port(Pre config required in the FT232 EEPROM). This mode is good to interface with microcontroller for parallel transfer of data but I would not details about this mode since its not useful in the present context.
  • CBUS Bit Bang Mode: This mode is a Handy mode for interfacing some small control logic along with a Serial Interface. In this mode the Serial Interface work as it is and the CBUS can be handled in parallel. Its an interesting mode for implementing control on the microcontroller such as an additional connection needed to reset the micro(not like Arduino since its uses the DTR pin) or put the micro in boot loader mode. Note that CBUS4 cant be used for this bit bang mode.

    FT232RL Pin Number FT232RQ Pin Number Signal Type Description
    23 22 C0 Input/Output Configurable function
    22 21 C1 Input/Output Configurable function
    13 10 C2 Input/Output Configurable function
    14 11 C3 Input/Output Configurable function
[3] Commands for Asynchronous Bit Bang Mode and CBUS Bit Bang Mode '{}' - contains the Python Command Equivalent:

  1. FT_SetBitMode {[handle].setBitMode([mask],[mode])}:
    Asynchronous Bit Bang mode is enabled using the FT_SetBitMode command.
    A value of 0x01 will enable it and a value of 0x00 will reset the device mode.
    [mode] = 0x00:Reset , 0x01:Asynchronous Bit Bang Mode , 0x20:CBUS Bit Bang Mode
    [mask] = 8bit Mask for configuring the I/O pins

    • Asynchronous Bit Bang Mode:[mode]=0x01
      This configures the direction 8 pins of the Bus(D0-D7)
      Bit = 0:Input , 1:Output
      Eg. For setting D0=Input and All the Other pins as Output  this Value would be 0xFE (0b11111110)
    • CBUS Bit Bang Mode: [mode]=0x20
      The first 4bits is the Mask for C0-C3 and the Lower bits are used to Set the Data to the Pins.
      Eg1. Set all pins to output with bit 0 high: 0xF1(0b1111[mask] 0001[data])
      Eg2. Set bits 0 and 1 to input, bits 2 and 3 to output and make bits 2 and 3 high: 0xCC(0b1100[mask] 1100[data])

  2. FT_GetBitMode {[handle].getBitMode()}:
    This reads the current Bus(D0-D7) data in Asynchronous mode & CBUS BitBang Setup of the FT232 chip. It has the same bit pattern as that of current mode.

    • Asynchronous Bit Bang Mode
      This gives the status at the Pins on the Bus(D0-D7). Even if its configured as output the current status would be reported back.
    • CBUS Bit Bang Mode
      In this mode it would give the status of the C0-C3 pins with first 4bits are the Mask for C0-C3 and the Lower bits are the Data available. This last nibble would show up complete nibble even if the pin is configured as an output.

  3. FT_SetBaudRate {[handle].setBaudRate([baud])}: (only for the Asynchronous Bit Bang mode)
    The rate of data transfer can be controlled by using the FT_SetBaudRate command. The maximum Baud rate is 3MBaud.The clock for the Asynchronous Bit Bang mode is actually 16 times the Baud rate. A value of 9600 Baud would transfer the data at (9600x16) = 153600 bytes per second, or 1 every 6.5 mS.

  4. FT_Write {[handle].write([string])}: (only for the Asynchronous Bit Bang mode)
    Data can be written to the device in Asynchronous Bit Bang mode using the FT_Write command. If multiple bytes are written to the device the values on the pins will change at the rate set by FT_SetBaudRate. The string would be standard "" as for Python with escape sequences to send bytes.
    Eg1: Wrting a full data pattern to the port [handle].write("Hello world!\r\n")
    Eg2: Wrting a byte of data to the port [handle].write("\x01")
  5. FT_ListDevices {[handle].listDevices([string])}:
    This is used to check the number of devices(FT232's) connected to the PC. Depending on that the required device can be opened for communication. There are three different ways in which the devices connected can be listed.

[4] Example:
Listed below is an example that was executed in the Python Window:

Step 1: Include the Driver from the installed Location
Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import d2xx
>>>

Step2: Find if there are any devices

Type (I): Check by Name:
>>> d = d2xx.listDevices(d2xx.OPEN_BY_DESCRIPTION)
>>> print d
('FT232R USB UART',)

Type (II): Check by Serial Number
>>> print d2xx.listDevices()
('A2004GKu',)

Step3: Open the Device. Since we can see that only one device is available, we can directly open using the Zero location. As the FT232 devices are enumerated starting from Zero.
>>> h = d2xx.open(0)
>>> print h

>>>

(Here 'h' is the handle to the device no created)


Step4: Configure the Parallel Port Asynchronous Bit Bang Mode for I/O
>>> h.setBitMode(0xF0,1)
>>>

The device is configured for Asynchronous Bit Bang Mode  and D0-D3 are 4bit Input port & D4-D7 are 4bit Output Port.

Step 5: Set the outputs to some value
>>> print h.write("\x80")
1
>>>

The "1" printed indicates that the byte was written. At this point the D7=1 and D6-D4 are all 0.

Step 6: Read the Pins
>>> print "0x%X" % h.getBitMode()
0x1
This shows that D0 is pulled to High and D1-D3 are Zero.

Step7: Close the Port. This is important if you wish to keep accessing the device on the same computer. Else you might need to reconnect the device to make it work again after you have opened an handle to the device.
>>> h.close()

This is a basic operations example. Need to detail it further to include the Serial Mode bit banging and the CBUS mode also. Let us know your suggestions.

UPDATE 09-JAN-2011: New driver for Python 2.7.1 has been compiled successfully. Need to tweak the DLL interface so waiting till the PyUSB creator comes back. Would be adding a full blown tutorial for this soon with the update for the pyUSB driver.

{ 14 Discuss... read them below or Comment }

  1. So does this mean that the FT232RL can emulate a FT245RL in BitBang mode? Mode specifically, can the TF232RL be a 'USB to parallel' device?

    ReplyDelete
  2. Yes, Mostly. This tutorial still needs to be completed. I would add more info.

    Warm Regards,
    Boseji

    ReplyDelete
  3. Great tutorial!! have you some examples for read inputs?
    with 4 inputs i'm veeery happy!

    thanks

    Daniel

    ReplyDelete
  4. Thank you for simplifying. I am trying to write & read by following the above steps however I get no response from the FTDI controller. Please see the code & output below. Any insights much appreciated.

    -------code---------
    import d2xx

    d = d2xx.listDevices(d2xx.OPEN_BY_DESCRIPTION)
    print "Device Description:",d

    handle = d2xx.open(0)

    handle.setBaudRate(9600)

    print handle.getBitMode()

    handle.setBitMode(0xf0, 0x01)

    print handle.write('INVENTORY')
    print handle.read(64)
    -------------output----------
    C:\Python26>python.exe FTDISimple.py
    Device Description: ('FT232R USB UART',)
    15
    9
    ☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼

    ReplyDelete
  5. Using this to write to registers inside a cpld, of course I scratched my head for a while to figure out a way to send byte wide ints instead of string literals.

    Her's the code I came up with:

    import d2xx

    #return the hexadecimal string representation of integer n

    def dec2hex(n):
    return "%X" % n

    #return the integer value of a hexadecimal string s

    def hex2dec(s):
    return int(s, 16)

    d = d2xx.listDevices(d2xx.OPEN_BY_DESCRIPTION)

    h = d2xx.open(0)

    h.setBitMode(0xFF,0x1)

    a = 0x55

    b = dec2hex(a)

    print h.write(('\\x' + b).decode('string_escape'))

    ReplyDelete
  6. Sridev,

    Step1: Check version of the Python(upto 2.6 is supported) & D2xx(1.6 supports the above tutorial) package was installed.
    Step2: If FT232 Hardware is connected to the USB port of the PC.
    (Verify this in the Hardware Manager in WinXP else on the 'udev' command in linux).
    Step3: Check if the UART in FT232 device is working by opening the comm port in a Terminal.

    If all the above steps are fine then you have the FT232device to PC connection ok.

    Next to check the d2xx driver is working in python. Just open python shell and give the command:

    >>> import d2xx
    >>> print d2xx.listDevices(d2xx.OPEN_BY_DESCRIPTION)

    This should first show up the devices such as this output:
    ('FT232R USB UART',)

    This means that the Device is identifiable by the d2xx driver and you can possibly go ahead with your functional implementation.
    Post your results or let us know if you need further assistance.
    Warm Regards,
    Boseji

    ReplyDelete
  7. Gar F,
    Your implementation looks like quite detailed one.
    I would like to indicate that in case you go more than on device then you might need to change the h = d2xx.open(0) part.
    Also for writing the Hex directly it might be easy is you wrote: h.write('\x55') as this still does the same job. Also you can use an return variable to check if the command has succeed.
    If you are interested please drop us a line when you have implemented you CPLD project using Python+D2xx.
    Thanks for your comments,
    Warm Regards,
    Boseji

    ReplyDelete
  8. Boseji,

    As suggested, followed the steps above and checked. The device is connected to PC and Python shell is responding with ('FT232R USB UART',). When I "write" I am also getting the right number of bytes as given in the command. However, the read command is returning either all '_' (underscores) or all '*'(stars). Could it be related to some settings in the firmware(eeprom)?

    ReplyDelete
  9. Hello Sridev,

    I would suggest you a simpler trick to get things validated for operation.

    Step1: Make a loop back connection by shorting the TX and RX pins on the FT232 device. If you use a Dongle/Sparkfun then just take a jumper wire and short the pins. Be careful not to short some unknown pins else it might damage the board.
    Step2: Now open the FT232 device in the way as stated earlier.
    Step3: Set the Baud Rate for the Serial Port and Receive Timeout.
    >>> h.setBaudRate(9600)
    >>> h.setTimeouts(5000,1000)

    The First Line Sets Baud Rate of 9600 and the seconds line sets the Receive(5Sec) and Transmit(1Sec) Timeouts. This makes sure that your read function has some data.
    Step4: Send some data using
    >>> h.write("Hello")
    Step5: Now since there was a loop back so you must receive the data back. You can read it by sending:
    >>> h.read(h.getQueueStatus())
    This would read back whatever you sent such as a "Hello"

    If this works then the Interface is working fine. Possibly you can check with the Target that you are connecting to. Let us know your results. Possibly it might help us to make this tutorial better.

    Warm Regards,
    Boseji

    ReplyDelete
  10. Boseji, I have FT232R connected via USB to my laptop with Win XP Pro. Do not know where to find the TX & RX pins to short. Is there any other alternate way to check?

    ReplyDelete
  11. Hello Sridev,
    if possible drop us a link cointaining picture of your FT232R board or posibly the link to the vendor from whome you have procured the board. We can guide you further on making the loop back test.

    In general if you set the Tx Rx time outs and baudrate for the device there are no problems.
    In case if you need some help on your FT232R to Target side feel free to send in your query also by email. Just in case you do not wish to discuss in this place.
    You can find a recaptch protected direct email page and email link in the top banner of this blog.
    Warm Regards,
    Boseji

    ReplyDelete
  12. Boseji, I am able to set Tx & Rx timeouts as well as baudrate. Looks like FT232R to Target side issue. Not sure though. Anyways, I have sent you the mail with device image, manufacturer product link & eeprom settings. Thank you for your help.

    ReplyDelete
  13. Boseji, D2XX Programmer's Guide(FT_000071) says, in EEPROM for FT232R, RIsD2XX should be non-zero if using D2XX driver. Please see under Appendix A - Type Definitions in page 95 (Rev 6 (FT232R) extensions.

    The FTDI device I am working with has it as zero, could this be a problem? Should I get the manufacturer to enable it? or Can I do it myself?

    ReplyDelete
  14. Great post!

    Thanks very much!

    Regards
    Bronek

    ReplyDelete

Welcome to Boseji's Blog

Popular Post

Blogger templates

Welcome

Creation by Electronics Hobbyists from Bharat(India) to encourage & help people. This blog hosts the numerous innovations, discoveries and projects we provide.
Our Research Wing Adhar Labs
Contact Form | Email Address
We Support Open Source Hardware Definition v1.0
Creative Commons License
All works on this blog are licensed under a
Creative Commons Attribution-ShareAlike 3.0 Unported License.
Based on a work at forbharat.wordpress.com and m8051.blogspot.com.

Permissions beyond the scope of this license may be available at http://forbharat.wordpress.com/permissions/.
Thank you for all your support.

© A.D.H.A.R Labs Research 2008-2013 . Powered by Blogger.

Follow by Email

Followers

PCB Unit Converter

mils
mm

- Copyright © Electronics for Bharat -Robotic Notes- Powered by Blogger - Designed by Johanes Djogan -