libftdi Archives

Subject: Re: ftdi_read_data return 0xff

From: Rodrigo Rosa <rodrigorosa.lg@xxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Wed, 9 Feb 2011 20:54:45 -0800
one of my coworkers got openocd to communicate with our chip, we're
going to try that out. the irscan and drscan work, so things will be
much easier there.

> >>             for(i=0;i<numBytesRead;i++)
> >>             {
> >>                 input_buff[i]=0x00;
> >>             }
>
> numBytesRead appears unitialized here.  What compiler are you using and
> which warning options do you have enabled?  Are you ignoring any warnings?
>

i'm using gcc in codeblocks, ignoring basically everything.

> >>    Flushing buffer: 0x3C 0x01 0x8C
>
> Hrm.  Maybe you could show how the initial settings are setup?  Like
> ftdi_set_bitmode, any loopback commands (or none), etc?  It's odd that you
> seem to be getting exactly what you sent out, since the 0x3C and 0x01 should
> be stripped by the MPSSE engine.  I also don't know if 0x3C works for JTAG
> or not (it might!).
>

i had loopback enabled, and that was what i was reading. when i
disabled it I got 0xFF ...
this is my latest initial config. i got it to work, but i didn't get a
response from my device.

    struct ftdi_context ftdic;
    if (ftdi_init(&ftdic) < 0)
    {
        fprintf(stderr, "ftdi_init failed\n");
        return EXIT_FAILURE;
    }

    if ((ret = ftdi_usb_open(&ftdic, VENDOR, DEVICE)) < 0)
    {
        fprintf(stderr, "unable to open ftdi device: %d (%s)\n", ret,
ftdi_get_error_string(&ftdic));
        return EXIT_FAILURE;
    }

    // Read out FTDIChip-ID of 2232H type chips
    if (ftdic.type == TYPE_2232H)
    {
        unsigned int chipid;
        printf("ftdi_read_chipid: %d\n", ftdi_read_chipid(&ftdic, &chipid));
        printf("ftdi.type: %s\n","TYPE_2232H");
        printf("FTDI chipid: %X\n", chipid);
    }

    // Set interface
    if((ret = ftdi_set_interface(&ftdic, INTERFACE_A)) < 0)
    {
        fprintf(stderr, "ftdi_set_interface: %d (%s)\n", ret,
ftdi_get_error_string(&ftdic));
        return EXIT_FAILURE;
    }

    //Set the lacentcy time to a low value
    if((ret = ftdi_set_latency_timer(&ftdic, 3)) <0)
    {
        fprintf(stderr, "ftdi_set_latency_timer: %d (%s)\n", ret,
ftdi_get_error_string(&ftdic));
        return EXIT_FAILURE;
    }

    // Set mode to MPSSE
    if((ret = ftdi_set_bitmode(&ftdic, 0xff, BITMODE_MPSSE)) < 0)
    {
        fprintf(stderr, "ftdi_set_de: %d (%s)\n", ret,
ftdi_get_error_string(&ftdic));
        return EXIT_FAILURE;
    }

    if ((ret = ftdi_usb_purge_buffers(&ftdic)) < 0)
    {
        fprintf(stderr,"Purging USB buffers failed: %d (%s)\n", ret,
ftdi_get_error_string(&ftdic));
        return EXIT_FAILURE;
    }

    sleep(5); // Wait for all the USB stuff to complete and work
(should be 50, but it's boring)

    /*
    -----------------------------------------------------------
    At this point, the MPSSE is ready for commands
    -----------------------------------------------------------
    */
    // ------------------------------------------------------------------
    // Configure the MPSSE settings for JTAG
    //
    // Multple commands can be sent to the MPSSE with one ftdi_write_data
    // ------------------------------------------------------------------
    // "Translated" from WINDOW$ version
    numBytesToSend = 0; // fresh start
    // Set up the Hi-Speed specific commands for the FTx232H
    output_buff[numBytesToSend++] = 0x8A;
    // Use 60MHz master clock (disable divide by 5)
    output_buff[numBytesToSend++] = 0x97;
    // Turn off adaptive clocking (may be needed for ARM)
    output_buff[numBytesToSend++] = 0x8D;
    // Disable three-phase clocking
    if ((ret = ftdi_write_data(&ftdic, output_buff, numBytesToSend)) < 0)
    {
        fprintf(stderr,"JTAG config failed: %d (%s)\n", ret,
ftdi_get_error_string(&ftdic));
        // Send off the HS-specific commands
        return EXIT_FAILURE;
    }
    else
    {
        numBytesToSend -= ret;
    }

    numBytesToRead = 20;//ftdic.readbuffer_remaining;
    if ((ret = ftdi_read_data(&ftdic, input_buff, numBytesToRead)) < 0)
    {
        fprintf(stderr,"Enabling JTAG mode failed: %d (%s)\n", ret,
ftdi_get_error_string(&ftdic));
        return EXIT_FAILURE;
    }

// let's try another config, one from AN135
//  pin_name    signal  direction   config  init_state  config
//  ADBUS0       TCK/SK  output      1       high        1
//  ADBUS1       TDI/DO  output      1       low         0
//  ADBUS2       TDO/DI  input       0                   0
//  ADBUS3       TMS/CS  output      1       high        1
//  ADBUS4       GPIOL0  output      1       low         0
//  ADBUS5       GPIOL1  output      1       low         0
//  ADBUS6       GPIOL2  output      1       high        1
//  ADBUS7       GPIOL3  output      1       high        1
    numBytesToSend=0;
    output_buff[numBytesToSend++] = 0x80;// Configure data bits
low-byte of MPSSE port
    output_buff[numBytesToSend++] = 0xC1;// Initial pin states
    output_buff[numBytesToSend++] = 0xFB;// Set pins to I/O

    if ((ret = ftdi_write_data(&ftdic, output_buff, numBytesToSend)) < 0)
    {
        fprintf(stderr,"Write failed: %d (%s)\n", ret,
ftdi_get_error_string(&ftdic));
        return EXIT_FAILURE;
    }
    else
    {
        numBytesToSend -= ret;
    }
    // Send off the low GPIO config commands


    numBytesToSend = 0;
    // Reset output buffer pointer
    // Set initial states of the MPSSE interface - high byte, both pin
directions and output values
    output_buff[numBytesToSend++] = 0x82;// Set data bits low-byte of MPSSE port
    output_buff[numBytesToSend++] = 0x00;// Initial state config above
    output_buff[numBytesToSend++] = 0x00;// Direction config above
    if ((ret = ftdi_write_data(&ftdic, output_buff, numBytesToSend)) < 0)
    {
        fprintf(stderr,"Setting initial state of MPSSE interface
failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
        return EXIT_FAILURE;
    }
    else
    {
        numBytesToSend -= ret;
    }



////////    numBytesToSend=0;
////////    output_buff[numBytesToSend++] = 0x80;
////////    // Set data bits low-byte of MPSSE port
////////    output_buff[numBytesToSend++] = 0x08;
////////    // Initial state config above
////////    output_buff[numBytesToSend++] = 0x0B;
////////    // Direction config above
////////
////////    if ((ret = ftdi_write_data(&ftdic, output_buff,
numBytesToSend)) < 0)
////////    {
////////        fprintf(stderr,"Write failed: %d (%s)\n", ret,
ftdi_get_error_string(&ftdic));
////////        return EXIT_FAILURE;
////////    }
////////    else
////////    {
////////        numBytesToSend -= ret;
////////    }
////////    // Send off the low GPIO config commands
////////
////////
////////    numBytesToSend = 0;
////////    // Reset output buffer pointer
////////    // Set initial states of the MPSSE interface - high byte,
both pin directions and output values
////////    output_buff[numBytesToSend++] = 0x82;
////////    // Set data bits low-byte of MPSSE port
////////    output_buff[numBytesToSend++] = 0x00;
////////    // Initial state config above
////////    output_buff[numBytesToSend++] = 0x00;
////////    // Direction config above
////////    if ((ret = ftdi_write_data(&ftdic, output_buff,
numBytesToSend)) < 0)
////////    {
////////        fprintf(stderr,"Setting initial state of MPSSE
interface failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
////////        return EXIT_FAILURE;
////////    }
////////    else
////////    {
////////        numBytesToSend -= ret;
////////    }
    // Send off the high GPIO config commands
    numBytesToSend = 0;
    // Reset output buffer pointer

    // Set TCK frequency
    // TCK = 60MHz /((1 + [(1 +0xValueH*256) OR 0xValueL])*2)
    output_buff[numBytesToSend++] = '\x86';
    //Command to set clock divisor
    output_buff[numBytesToSend++] = clockDivisor & 0xFF;
    //Set 0xValueL of clock divisor
    output_buff[numBytesToSend++] = (clockDivisor >> 8) & 0xFF;
    //Set 0xValueH of clock divisor
    if ((ret = ftdi_write_data(&ftdic, output_buff, numBytesToSend)) < 0)
    {
        fprintf(stderr,"Setting TCK frequency failed: %d (%s)\n", ret,
ftdi_get_error_string(&ftdic));
        return EXIT_FAILURE;
    }
    else
    {
        numBytesToSend -= ret;
    }
    // Send off the clock divisor commands

    numBytesToSend = 0;
    // Reset output buffer pointer
    // Enable (0x84) or disable (0x85) internal loop-back
    output_buff[numBytesToSend++] = 0x85;
    if ((ret = ftdi_write_data(&ftdic, output_buff, numBytesToSend)) < 0)
    {
        fprintf(stderr,"Loopback disabling failed: %d (%s)\n", ret,
ftdi_get_error_string(&ftdic));
        return EXIT_FAILURE;
    }
    else
    {
        numBytesToSend -= ret;
    }
    // Send off the loopback command
    numBytesToSend = 0;
    // Reset output buffer pointer




>
> >> i'm having trouble with the sync. i'm doing this:
>
> I'll try looking over your sync, but I might miss something.  So I'll first
> tell you how I did it and you can go from there.  I did the following until
> it succeeded, or failed after 4 time-outs (anything other than timeout or
> success aborted immediately, kicking it up to a higher protocol layer):
>
> 1. read until empty
> 2. write 0xAA, then write 0xAB, then (optionally) write send-immediate
> 3. Init:  have not found 0xFA, 0xAA, or 0xAB.
> 4. While not timed out, and not found both bad commands echoed, do:
>    4a. clear out my local buffer.
>    4b. read until ftdi_read_data returns 0 or until my local buffer is full
>    4c. while my local buffer is not empty:
>        4c(i). search for and delete 0xFA 0xAA, with any number of
>               intervening bytes, then 0xFA 0xAB, allowing for the
>               possibility that these may span calls to ftdi_read_data,
>               thus the flags initialized in step 3.
> 5. Return status (timeout, success, etc) after maybe printing diagnostics.
>
> The code I wrote is not exactly simple, and relies on other functions which
> I can't easily post.  It is a little simpler if you only send 0xAA, not
> both.  Anyway, let me take a look at what you've done.
>

i'll save this pseudocode for later, i bet i'll be back to this in a
couple of days. thanks!


> I would rewrite this as
>
> for(i=0; i<ret && !read_bogus; i++) {
>  if(input_buff[i] == acq_code)
>    read_acq = 1;
>  else if(input_buff[i] == bogus_code && read_acq)
>    read_bogus = 1;
>  else
>    read_acq = 0; // either 0xFA followed by != 0xAA, else harmless.
> }
>
> Note that read_acq can be nonzero while read_bogus might be zero after this
> loop if input_buf[ret-1]==0xFA.  But only break on read_bogus, as the code
> should be written such that that implies read_acq.
>

got it.

> >> when sync do you use ftdi_usb_purge_buffers ?
>
> Only the first time (during init).  I have noticed errors with this if the
> device had JUST been plugged in, and IF it's on Windows.  I don't recall
> seeing such an error on Linux, but the device was *usually* plugged before
> power-up and only unplugged after power-down on Linux, so I'm not sure if it
> also causes errors on Linux.  I am not confident of that particular code
> section, but it worked so I didn't mess with it.  I had it set up to retry
> (in conjunction with a few other APIs) 4 times.  I never saw it fail more
> than once.  Again, this was only in init (i.e., once per
> device-open-operation).
>

got it.

> >> running instruction 0x3C, which is supposed to write TDI and read TDO
> >> there's a little change in TDO when TDI is being driven, looks pretty
> >> week.
>
> This can happen if both devices try to drive the same line and one is
> driving more strongly than the other.  It could indicate a wire swap.  I've
> seen this on someone else's (real-)RS232 setup, and I've kept an eye out for
> it ever since, since it's so easy to overlook during review.  In connection
> with you not seeing one of the two lines change ever, the hardware might be
> worth looking at.  But hard to be certain without seeing it.  Do you have
> any series resistors (even 0-ohm jumpers) on those JTAG lines?
>

i had a very bad connection set up. i built some decent connectors and
interconnected the gnd of the ft2232h and my device XD now things look
much better, everything was floating so i had tons of noise.

ok, i didn't get it working, but i think i learned a lot. i'll keep
this email and use it to retake this in a couple of days, except if
the openocd solves everything.

thanks for all your time and advice!
i truly appreciate your support :)

regards,
--
Rodrigo.

--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx

Current Thread