libftdi Archives

Subject: FT2232D bitbang mode.

From: John Oyler <john.oyler@xxxxxxxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Tue, 7 Sep 2010 15:45:54 -0500
I'm initializing bitbang on interface B with the following code:

int ft2232_bb_init(void) {
        int f;
        struct ftdi_context *ftdic = &ftdic_context_B;
        unsigned char buf[512];

        if (ftdi_init(ftdic) < 0) {
                printf("ftdi_init failed\n");
                return EXIT_FAILURE; // TODO

        if (ftdi_set_interface(ftdic, INTERFACE_B) < 0) {
                printf("Unable to select interface: %s\n", ftdic->error_str);

        f = ftdi_usb_open(ftdic, FTDI_VID, FTDI_PID);
        if (f < 0 && f != -5) {
                printf("Unable to open FTDI device: %d (%s)\n", f, ftdi_get_error_string(ftdic));
                exit(-1); // TODO

        if (ftdi_set_bitmode(ftdic, 0xc0, BITMODE_BITBANG_NORMAL) < 0) {
                printf("Unable to set bitmode to bitbangin'\n");

        return 0;

This seems to work, even if I've initialized SPI mode on interface A.

I can do whatever I like to the LEDs on BDBUS6 & 7 with the following code...

#define SX1211_LED_RX           0x01
#define SX1211_LED_TX           0x02
#define SX1211_LED_BOTH         0x03
#define SX1211_LED_OFF          0
#define SX1211_LED_ON           255

void sx1211_led(int tx_or_rx, int on_or_off) {
        struct ftdi_context *ftdic = &ftdic_context_B;
        static unsigned char led_state = 0xff;
        unsigned char c = tx_or_rx;

        if (on_or_off) c = c << 6 | led_state;
        else c = ~(c << 6) & led_state;
        led_state = c;
        ftdi_write_data(ftdic, &c, 1);

This works as well, even if not as elegant as I might like.

And, to check the IRQs on BDBUS0 & 1 I have the following code...

int sx1211_irq() {
        struct ftdi_context *ftdic = &ftdic_context_B;
        unsigned char c = 0x00;
        int d;
        ftdi_read_data(ftdic, &c, 1);
        d = c & 0x03;
        return d;

Now, whenever a full packet is available in the fifo, I can read it one byte at a time with something like ft2232_spi_send_command(0, 1, NULL, &fifo_byte, 1); and I do get back valid data much of the time. My understanding of the SX1211 data sheet is that when both interrupts go high (0x03) I have a packet ready for me. And that they'll only go low once I've read the entire packet.

This doesn't seem to be the case. I'm a little concerned that perhaps sx1211_irq() takes so long to execute or is blocking or something like that, that by the time it goes low, it immediately goes high once more and I'm never detecting it. Will an ftdi_read_data() in bitbang mode return a value immediately? I can't exactly send it a "send immediate" or anything like that. The D2xx programmer's guide hints at that API differing from libftdi in some relatively subtle ways. Is there something here I should be doing differently? I can hook those IRQ lines up to a scope, but I know I'll see them go low briefly... I just don't know why I'm not able to see it from within my code. If I'm lucky, I'll see indications that it went low, but maybe only about every 50 times that I should have.

John O.

libftdi - see for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx

Current Thread
  • FT2232D bitbang mode., John Oyler <=