libftdi Archives

Subject: Re: ftdi_read_data return 0xff

From: Rodrigo Rosa <rodrigorosa.lg@xxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Tue, 8 Feb 2011 23:20:24 -0800
On Tue, Feb 8, 2011 at 3:40 PM, Michael Plante <michael.plante@xxxxxxxxx> wrote:
>
> Please use plain text.
>
>
> Rodrigo Rosa wrote:
> >> i enabled loopback (tied TDI to TDO) i tried debugging this code:
>
> While the debugger may be fine for you, the results are not easily conveyed
> to the mailing list.  If you use printf()'s to debug, you can post the
> output to the list and everyone will be on the same page.
>
running this code:

    while(1)
    {
        // sync
        sync_mpsse(&ftdic);
        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;
        }

        // write
        numBytesToSend = 0;
        output_buff[numBytesToSend++] = 0x3C;// write TDI and read TDO
        output_buff[numBytesToSend++] = 0x01;// One byte (or 1 bit?...)
        output_buff[numBytesToSend++] = 0x8C;// One byte (or 1 bit?...)
        numBytesSent = ftdi_write_data(&ftdic, output_buff, numBytesToSend);
        // read
        numBytesToRead=5;
        do
        {
            int i;
            for(i=0;i<numBytesRead;i++)
            {
                input_buff[i]=0x00;
            }
            numBytesRead = 0;
            numBytesRead = ftdi_read_data(&ftdic, input_buff, numBytesToRead);
            if(numBytesRead < 0)
                printf("Read error!");
            if(numBytesRead > 0)
                {
                    printf("Flushing buffer: ");
                    for(counter=0;counter<numBytesRead;counter++)
                        printf("0x%02X ",input_buff[counter]);
                    printf("\n");
                }

        }
        while(numBytesRead>0);
        fflush (stdout);
    }

got this output:

    Flushing buffer: 0x3C 0x01 0x8C
    Flushing buffer: 0x3C 0x01 0x8C
    Flushing buffer: 0x3C 0x01 0x8C
    Flushing buffer: 0x3C 0x01 0x8C
    Flushing buffer: 0x3C 0x01 0x8C
    Flushing buffer: 0x3C 0x01 0x8C
    ...

occasionally i got

    Flushing buffer: 0x3C 0x01 0x8C
    Flushing buffer: 0x3C 0x01 0x8C
    Flushing buffer: 0x3C
    Flushing buffer: 0x01 0x8C
    Flushing buffer: 0x3C 0x01 0x8C

but 99% of the time it worked ok.
i'm having trouble with the sync. i'm doing this:

    int sync_mpsse(struct ftdi_context *ftdi)
    {
        /*
        -----------------------------------------------------------
        Synchronize the MPSSE by sending a bogus opcode (0xAA),
        The MPSSE will respond with "Bad Command" (0xFA) followed by
        the bogus opcode itself.
        -----------------------------------------------------------
        */
        int read_acq = 1;
        int read_bogus = 0;
        int max_retries = 10000;
        int ret = 0;
        uint bogus_code = 0xAA;
        uint acq_code = 0xFA;
        int numBytesToSend = 0;
        unsigned char output_buff[TX_BUF];
        unsigned char input_buff[TX_BUF];
        output_buff[numBytesToSend++] = bogus_code;// Write bogus op
code to test interaction. Code:'\xAA'

        int retries = 0;
        int numBytesToRead = 20;
        while (retries < max_retries)
        {
            while((ftdi_read_data(ftdi, input_buff, numBytesToRead)) != 0);
            if ((ret = ftdi_write_data(ftdi, output_buff, numBytesToSend)) < 0)
            {
                fprintf(stderr,"Enabling MPSSE mode failed when
writing bogus code: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
                return EXIT_FAILURE;
            }

            if ((ret = ftdi_read_data(ftdi, input_buff, numBytesToRead)) < 0)
            {
                fprintf(stderr,"Enabling MPSSE mode failed when
reading: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
                return EXIT_FAILURE;
            }

            // Check if MPSSE sync ok ()
            int i =0;
            while(i<ret)
            {
                if(input_buff[i]==acq_code)
                    read_acq = 1;
                if(input_buff[i]==bogus_code)
                    read_bogus = 1;
                i++;
            }
            if(read_acq && read_bogus)
                break;
            else
                retries++;
        }
        if (retries == max_retries)
        {
            fprintf(stderr,"MPSSE sync failed. Retries: %d\n", retries);
            fflush (stderr);
            return EXIT_FAILURE;
        }
        else
            //fprintf(stderr,"MPSSE sync ok!. Retries: %d\n", retries);
            //fflush (stderr);
            return 0;
    }

when i unplug/plug the usb port connecting to the ft2232 minimodule
i'm working the sync works ok, i get the 0xFA and the bogus code when
i read. that happens only the first time i sync. afterwards, the
device only return the bogus code. is this expected or am i doing
something wrong with the sync?

> Note that under normal conditions, none of those syncs or purges should
> discard any good data.  Only when there's an error will it discard anything
> possibly useful.  A higher level of my protocol will then re-send under
> those failure conditions.
>

when sync do you use ftdi_usb_purge_buffers ?

>
> At one point you said that:
>
> >> the scope shows that TDI goes 0 1 0
>
> How wide is that '1' pulse on TDI?  Does TCK rise or fall in the middle of
> the 1 on TDI?
>

i've got clocks rise and fall during TDI pulse, tomorrow i'll bring a
camera and get a snapshot of the scope if.
i'm going home, i've been on this for 13 hours!
tomorrow i'll check this part.
i'm getting decent stuff, so i'll be able to check timing, verify that
i have as many clocks as i need/want.

> Hrm.  Has that been the entire time, or just recently?  AN108 seems to say
> that TDO is what your target device writes out on and what the FT2232 reads
> in on, so maybe that's why you're getting 0xFF's?  Could you check if it's
> being driven weakly (i.e., staying close to a rail but changing a little),
> as opposed to not being driven at all?
>

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.
i'll dig in a bit more tomorrow.

thanks!!
--
Rodrigo.

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

Current Thread