# HOWTO: FTDI bitbang mode on FreeBSD



## draco003 (Jul 13, 2012)

Hello =)

I'd like to give a simple introduction on using FTDI chips in bitbang mode based on this post on Hack a Day.

For the hardware we will be using the "Breakout Board for FT232RL USB to Serial" from Sparkfun, of course you can use any flavor of FTDI ICs.

Also we will need to get the libftdi devel/libftdi if you don't have it already.

```
#cd /usr/ports/devel/libftdi
#make install clean
```

The documentation is very helpful when working with libftdi API in C++: libftdi docs

When you connect the FT232R breakout board via USB, you should be able to see your device as a virtual serial port in my case: /dev/cuaU0 and it was identified as a ugen1.2 device.

```
$dmesg | tail
ugen1.2: <FTDI> at usbus1
uftdi0: < FT232R USB UART > on usbus1
```

Next let's try the LED blinker example by Phil at Hack a Day.
I made some changes to the C++ code to be compatible with the latest *libftdi* 0.20

We will need an LED and a 330 Ohm resistor. Connect the Anode of LED (long lead +ve) to CTS pin on FTDI breakout, and the Cathode (short lead -ve) to the resistor, and the other lead of the resistor will be connected to GND.

Put the following code in a file named *hello_ftdi.c*

```
/* hello_ftdi.c: flash LED connected between CTS and GND.
   This example uses the libftdi API.
   Minimal error checking; written for brevity, not durability. */

#include <stdio.h>
#include <ftdi.h>

#define LED 0x08  /* CTS */

int main()
{
    unsigned char c = 0;
    struct ftdi_context ftdic;

    /* Initialize context for subsequent function calls */
    ftdi_init(&ftdic);

    /* Open FTDI device based on FT232R vendor & product IDs */
    if(ftdi_usb_open(&ftdic, 0x0403, 0x6001) < 0) {
        puts("Can't open device");
        return 1;
    }

    /* Enable bitbang mode with a single output line */
     ftdi_set_bitmode(&ftdic, LED, BITMODE_BITBANG); 

    /* Endless loop: invert LED state, write output, pause 1 second */
    for(;;) {
        c ^= LED;
        ftdi_write_data(&ftdic, &c, 1);
        sleep(1);
    }
}
```

To compile the above code we use the following command:
`# gcc -I/usr/local/include/ -L/usr/local/lib/ -o blink hello_ftdi.c -lftdi`

This will generate an executable named hello, run it 
`# ./hello`

You should see the LED blinking on and off with a period of 1 second.

We might need this pin mapping for the FTDI pins in future programming:


```
/*
 * bitbang I/O pin mappings 
 * 
 * #define PIN_TXD  0x01
 * #define PIN_RXD  0x02
 * #define PIN_RTS 0x04
 * #define PIN_CTS 0x08
 * #define PIN_DTR 0x10
 * #define PIN_DSR 0x20
 * #define PIN_DCD 0x40
 * #define PIN_RI  0x80
 */
```

For now you can have a look on Phil's post on Hack a Day he explains the code pretty well, the code above is modified and works well with libftdi 0.20, also I'll post here the PWM LED chaser code in that other article it's written using  D2XX API instead. So I'll post below a modified version to work with libftdi API.

The hardware setup includes 4 LEDs and 4 330 Ohm resistors, I happened to use an LED bar that I had laying around.


```
/* pwmchase.c: 8-bit PWM on 4 LEDs using FTDI cable or breakout.
   This example uses the libftdi API.
   Minimal error checking; written for brevity, not durability. */

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ftdi.h>

#define LED1 0x08  /* CTS */
#define LED2 0x01  /* TXD  */
#define LED3 0x02  /* RXD */
#define LED4 0x14  /* RTS + DTR */

int main()
{
    int i,n;
    unsigned char data[255 * 256];
    struct ftdi_context ftdic;
    
    /* Generate data for a single PWM 'throb' cycle */
    memset(data, 0, sizeof(data));
    for(i=1; i<128; i++) {
        /* Apply gamma correction to PWM brightness */
        n = (int)(pow((double)i / 127.0, 2.5) * 255.0);
        memset(&data[i * 255], LED1, n);         /* Ramp up */
        memset(&data[(256 - i) * 255], LED1, n); /* Ramp down */
    }   

    /* Copy data from first LED to others, offset as appropriate */
    n = sizeof(data) / 4;
    for(i=0; i<sizeof(data); i++)
    {
        if(data[i] & LED1) {
            data[(i + n    ) % sizeof(data)] |= LED2;
            data[(i + n * 2) % sizeof(data)] |= LED3;
            data[(i + n * 3) % sizeof(data)] |= LED4;
        }
    }   

    /* Initialize context for subsequent function calls */
    ftdi_init(&ftdic);

    /* Open FTDI device based on FT232R vendor & product IDs */
    if(ftdi_usb_open(&ftdic, 0x0403, 0x6001) < 0) {
        puts("Can't open device");
        return 1;
    }

    /* Initialize, open device, set bitbang mode w/5 outputs */
    
    ftdi_set_bitmode(&ftdic, LED1 | LED2 | LED3 | LED4, BITMODE_BITBANG); 
    ftdi_set_baudrate(&ftdic, 9600);  /* Actually 9600 * 16 */

    /* Endless loop: dump precomputed PWM data to the device */
    for(;;) ftdi_write_data(&ftdic, data, sizeof(data));
}
```

To compile run:
`# gcc -I/usr/local/include/ -L/usr/local/lib/ -o pwm pwmchase.c -lftdi -lm`

then to run:
`# ./pwm`

You should now see the 4 LEDs chasing each other with the PWM (Pulse Width Modulation) effect.

I'm currently working on connecting a 20x4 LCD display, and will have it show some info.Will keep you posted.

I hope this would be of any help to you and have fun. :i

Draco ^^


----------



## wblock@ (Jul 13, 2012)

An FTDI board can be used as an IR receiver with nox's port of comms/lirc.


----------



## draco003 (Jul 13, 2012)

wblock@ said:
			
		

> An FTDI board can be used as an IR receiver with nox's port of comms/lirc.



This is interesting, I'm sure I'll play around with it =) 

I'm also working on flashing some ATmega328 chips using devel/avrdude and the FTDI chip, still having some problems with avrdude.conf, but thanks to Joerg Wunsch he gave me some instructions in reply to my email yesterday, so I'll get working and update this Howto with the results.


----------



## wblock@ (Jul 13, 2012)

The IR receiver: http://www.huitsing.nl/irftdi/

I have some scripts for burning the Arduino boot loader using avrdude, if that would help.  They are set up for an avrisp programmer, but everything except the programmer ID should be the same.


----------



## draco003 (Jul 13, 2012)

Yes that would be great, I'd  be very grateful if you could share it with me.

So the problem on my end when using the FT232R chip with avrdude I get this error:

```
Unknown type 3 (0x3)
```

Thanks to Joerg Wunsch he pointed out the following:


> According to <ftdi.h>, type 3 is TYPE_R, i.e. you are using an FT232R.
> I don't think this device offers the MPSSE feature which is required for
> the SPI implementation.



Which is true. So I'm looking into this patch by David Brownell : http://lists.gnu.org/archive/html/avrdude-dev/2006-10/msg00011.html 

David's patch is based on *libftdi*, which is unlike  Johnathan Corgan's patch based on *FTD2XX* which is proprietary source.

I'll dig more into this, but I'm not sure if I can apply these changes to devel/avrdude or even if someone already ported them.

I also came across this article on AVR Freaks: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=103730&start=0 
Some guy created a code to flash AVRs using FT232R (You need to be logged in to view the files, I'll upload it later somewhere).

A helpful link: http://doswa.com/2010/08/24/avrdude-5-10-with-ftdi-bitbang.html


----------



## wblock@ (Jul 13, 2012)

burn_bootloader_328


```
#!/bin/sh

# based on http://www.arduino.cc/playground/uploads/Bootloader/Burn_Bootloader_168

avrdude="/usr/local/bin/avrdude"
options="-P /dev/cuaU0 -p atmega328p [color="Red"]-c avrisp[/color] -b 19200"
bootldr="/usr/local/arduino/hardware/arduino/bootloaders/atmega/ATmegaBOOT_168_atmega328.hex"

# erase chip write lock and fuses
${avrdude} ${options} -e -Ulock:w:0x3f:m -U lfuse:w:0xff:m -U hfuse:w:0xda:m -U efuse:w:0x05:m

# upload the bootloader
${avrdude} ${options} -D -V -U flash:w:${bootldr}:i

# lock the boot section
${avrdude} ${options} -V -U lock:w:0x0f:m
```


----------

