Search code examples
cusblibusbspi

How do I flash an LED, using libftdi v0.18?


It's a FT2232D chip, and the LED is connected to BDBUS6.

The library is less documented than I might like (better than FTDI's own library though, which doesn't even work on modern kernels), the only example code I can find that does this uses a deprecated function (I tried, it doesn't seem to work), and I'm absolutely stumped.

The harder I try with this thing, the more difficult it seems. I'm not looking for someone to do my homework for me so much as I just need a nudge in the right direction. Any help appreciated (even speculative).

Update: I've been trying this, though ftdi_enable_bitbang() is deprecated. The following code compiles, it runs without barfing, but no blinkenlighten. Schematics of the device in question are available at http://www.semtech.com/images/datasheet/sx1211ska_v1_std.pdf , page 23. BDBUS6 and BDBUS7 are hooked up to the LEDs.

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <ftdi.h>

#define FTDI_VID                0x0403
#define FTDI_PID                0x6010


static struct ftdi_context ftdic_context;

int main(void) {
        int ret;
        unsigned int i;
        unsigned char c = 0;

        // Initialize bitbang.
//      ret = ft2232_bb_init();

        ftdi_usb_open(&ftdic_context, FTDI_VID, FTDI_PID);
        ftdi_set_interface(&ftdic_context, INTERFACE_B);
        ftdi_enable_bitbang(&ftdic_context, 0xb0);

        // Trying to blink some lights.
        printf("\nNow let's try to blinkenlights...\n");
        for (i = 0; i < 20; i++) {
                c ^= 0x80;
                ftdi_write_data(&ftdic_context, &c, 1);
                sleep(1);
        }

        return EXIT_SUCCESS;
}

Solution

  • You need to initialize the ftdi context before you can open a device with it.

    ftdi_init(&ftdic_context);

    Also you need to set the interface channel before you open the device.

    Heres the function I use to set up a ftdi context

    int initFTDI(struct ftdi_context * ftdic)
    {
        unsigned char Mask = 0x1F;
        int ret=0;
    
        fprintf(stderr,"start init\n");
    
        ftdi_init(ftdic);
    
        //for multi-channel ftdi chips eg(ft2232)
        if(ftdi_set_interface(ftdic,INTERFACE_B))
            fprintf(stderr,"%s\n",ftdi_get_error_string(ftdic));
    
        if((ret = ftdi_usb_open(ftdic, VID, PID)) < 0){
            fprintf(stderr, "unable to open ftdi device: %d (%s)\n", ret,   ftdi_get_error_string(ftdic));
            return EXIT_FAILURE;
        }
        if(ftdi_usb_reset(ftdic))
            fprintf(stderr,"%s\n",ftdi_get_error_string(ftdic));
    
        if(ftdi_usb_purge_buffers(ftdic)) //clean buffers
            fprintf(stderr,"%s\n",ftdi_get_error_string(ftdic));
    
        if(ftdi_write_data_set_chunksize(ftdic,65536)) //64k transfer size
            fprintf(stderr,"%s\n",ftdi_get_error_string(ftdic));
    
        if(ftdi_read_data_set_chunksize(ftdic,4096)) //64k transfer size
            fprintf(stderr,"%s\n",ftdi_get_error_string(ftdic));
    
        if(ftdi_set_event_char(ftdic,false,0)) //disable event chars
            fprintf(stderr,"%s\n",ftdi_get_error_string(ftdic));
    
        if(ftdi_set_error_char(ftdic,false,0)) //disable error chars
            fprintf(stderr,"%s\n",ftdi_get_error_string(ftdic));
    
        if(ftdi_set_latency_timer(ftdic,2)) //Set the latency timer to 1mS (default is 16mS)
            fprintf(stderr,"%s\n",ftdi_get_error_string(ftdic));
    
        if(ftdi_set_baudrate(ftdic,921600)) 
            fprintf(stderr,"%s\n",ftdi_get_error_string(ftdic));
    
        if(ftdi_setflowctrl(ftdic,SIO_RTS_CTS_HS)) //set flow control
            fprintf(stderr,"%s\n",ftdi_get_error_string(ftdic));
    
        if ((ret = ftdi_set_bitmode( ftdic, 0x00, BITMODE_RESET )) < 0 )
        {
            fprintf(stderr, "can't set bitmode to %x: %d (%s)\n", BITMODE_RESET, ret, ftdi_get_error_string(ftdic));
            fprintf( stderr, "RESET\n" );
            return EXIT_FAILURE;
        }
        if ((ret = ftdi_set_bitmode( ftdic, Mask, BITMODE_BITBANG )) < 0 )
    
            fprintf(stderr, "can't set bitmode to %x: %d (%s)\n", BITMODE_BITBANG, ret, ftdi_get_error_string(ftdic));
            fprintf( stderr, "RESET\n" );
            return EXIT_FAILURE;
        }
    
        //fprintf(stderr,"end init\n");
    
        return ret;
    }