libftdi Archives

Subject: Fwd: opening device given its serial and hardware flow control

From: Thomas Jarosch <thomas.jarosch@xxxxxxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Wed, 11 Feb 2009 09:36:27 +0100
----------  Forwarded Message  ----------

Subject: opening device given its serial and hardware flow control
Date: Tuesday, 10. February 2009
From: "frrrt_" <frrrt_@xxxxxxxxxxxxx>
To: opensource@xxxxxxxxxxxxx

Dear libftdi developers,

I wrote (based on a couple of examples seen online) a little test/demo 
program which features two threads: read (continually reads FTDI device) 
and write (continually writes random numbers to FTDI device).

I run this program with a FTDI USB cable 
http://www.ftdichip.com/Documents/DataSheets/Modules/DS_TTL-232R_CABLES_V201.pdf
 

with TX connected to RX and ideally RTS connected to CTS doing a 
hardware flow control communication between the two aforementioned threads.

However I am stepping into a couple of errors detailed below, which I 
hope somebody could help me with please?
See attached readwrite.c

Cheers,
Luca



   1. Cant open specific FTDI device with serial D44F6D5        
      tried with        ftdi_usb_open_desc(&ctx, vendor, device, NULL, 
"D44F6D5");
      and also with     ftdi_usb_open_desc(&ctx, vendor, device, 
"TTL232R-3V3", "D44F6D5");

     If I am logged in as root
      init: OK
      open: rv=-3, error=device not found, errno=Inappropriate ioctl for 
device (25)

     If I am logged in as a user
      init: OK
     open: rv=-3, error=device not found, errno=Operation not permitted (1)



   2. Can't get to use handshaking signals RTS and CTS (hardware flow)
       Either I connect RTS and CTS together or leave them floating, it 
reads 0 for about 5 seconds
       then I get following error: (basically it times out after so many 
write attempts)

      write: rv=-110, error=usb bulk write failed, errno=Resource 
temporarily unavailable (11)
      close: rv=0, error=usb bulk write failed, errno=Resource 
temporarily unavailable (11)

      If I manually connect CTS to GND then everything works and I 
receive the random numbers. Sounds like FTDI device never
     sets RTS(ready to send) to GND. I don't understand this because, 
from what I have gathered
     googling hardware flow control, CTS line should be high (+3.3V) for 
source device to begin transmission

     The same happens regardless I set bitbang ON or OFF






-------------------------------------------------------



--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx   
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// Example of pthread read and pthread write inspired by 
//
//   sertest.c     Copyright (c) 2006 Dave Hylands     <dhylands@xxxxxxxxx>
//   testusb.c     Copyright (c) 06/2004 by Wolfgang Wieser
//
// This program is meant to be run on a FTDI device with RX connected to TX and 
// CTS connected to RTS (hardware flow control)
//
//    ________
//            |
//        TX  |---> 
//            |     | 
//        RX  |<---
//            |
//            |
//       RTS  |--->
//            |     |
//       CTS  |<---
//            |
//    ________|
//
//  From my understanding of RS232 gathered from internet and books the 
following should happen:
//
//    RTS goes high whenever the device is ready to receive
//  
//    CTS high allows device to begin transmission
//
//---------------------------------------------------------------------------------
//
// USAGE
// go to directory 
// /home/duffyduck/new_ftdi_driver/my_example2
//
// compile with the following
// gcc -O readwrite.c -o readwrite /usr/local/lib/libftdi.a -W -Wall -Wformat 
/usr/lib/libusb.a -pthread
//
//---------------------------------------------------------------------------------
//
//   PROBLEMS SEEN SO FAR
//
//
//
//   1. Cant open specific FTDI device with serial D44F6D5         
//       tried with        ftdi_usb_open_desc(&ctx, vendor, device, NULL, 
"D44F6D5");
//       and also with     ftdi_usb_open_desc(&ctx, vendor, device, 
"TTL232R-3V3", "D44F6D5");
//
//      If I am logged in as root
//      init: OK
//      open: rv=-3, error=device not found, errno=Inappropriate ioctl for 
device (25)
//
//      If I am logged in as a user
//      init: OK
//      open: rv=-3, error=device not found, errno=Operation not permitted (1)
//
//
//
//   2. Can't get to use handshaking signals RTS and CTS (hardware flow)
// Either I connect RTS and CTS together or leave them floating, it reads 0 for 
about 5 seconds 
// then I get following error
// write: rv=-110, error=usb bulk write failed, errno=Resource temporarily 
unavailable (11)
// close: rv=0, error=usb bulk write failed, errno=Resource temporarily 
unavailable (11)
//
// If I manually connect CTS to GND then everything works and I receive the 
random numbers. Sounds like FTDI device never
// sets RTS(ready to send) to GND. I don't understand this because, from what I 
have gathered 
// googling hardware flow control, CTS line should be high (+3.3V) for source 
device to begin trasmission
//
// The same happens regardles I set bitbang ON or OFF







#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/unistd.h>
#include <pthread.h>
#include <getopt.h>
//#include <termios.h>


//testusb
#include "ftdi.h"
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
//#include <sys/time.h>
//#include <time.h>


struct ftdi_context ctx;


static void Error(const char *where,int rv,struct ftdi_context *ctx,int doclose)
{
        if(rv)
        {
                fprintf(stderr,"%s: rv=%d, error=%s, errno=%s (%d)\n",
                        where,rv,ctx->error_str,strerror(errno),errno);
                if(doclose)
                {
                        rv=ftdi_usb_close(ctx);
                        fprintf(stderr,"close: rv=%d, error=%s, errno=%s 
(%d)\n",
                                rv,ctx->error_str,strerror(errno),errno);
                }
                ftdi_deinit(ctx);
                exit(1);
        }
        else
                fprintf(stderr,"%s: OK\n",where);
}







////////////////////////////////////////////////////////////
//
//   Thread which processes the incoming serial data.
//

void *ReaderThread(  )
{


   int rv;

   int i;
   const int bufsize = 32;
   unsigned char buf[bufsize];

   printf("\nEntered ReaderThread  \n");

   while ( 1 ) 
   {
      rv=ftdi_read_data(&ctx,buf,bufsize);
      if(rv<0) Error("read",rv,&ctx,1);
      else
      {
         printf("%3d: ",rv);
         for(i=0; i<rv; i++)
            printf("%02x%s",buf[i],i%8==7 ? i%16==15 ? "\n     " : "  " : " ");
      }
      printf("\n"); fflush(stdout);
   }

   return 0;

} // ReaderThread




////////////////////////////////////////////////////////////
//
//   Thread which writes serial data.
//

void *WriterThread(  )
{


   int rv;

   int i;
   const int bufsize = 16;
   unsigned char buf[bufsize];

   printf("\nEntered WriterThread  \n");



   //Fill TX buffer with some stuff
   for (i=0; i<bufsize; i++) {
      //buf[i] = 'c';
      // buf[i] = i;
      buf[i] = random();
   }



   while ( 1 ) 
   {

      //Fill TX buffer with some stuff
      for (i=0; i<bufsize; i++) {
         // buf[i] = 'c';
         // buf[i] = i;
         buf[i] = random();
      }



      rv=ftdi_write_data(&ctx,buf,bufsize);
      if(rv<0) Error("write",rv,&ctx,1);
   }

   return 0;

} // WriterThread





////////////////////////////////////////////////////////////
//
//   Main
//

int main() {


   
   int rv;
   int vendor=0x0403;
   int device=0x6001;

   int rc;


   pthread_t   readerThreadId;


   


   // Initialize
   rv=ftdi_init(&ctx);
   Error("init",rv,&ctx,0);


   // Open FTDI device with serial D44F6D5
   //rv=ftdi_usb_open_desc(&ctx, vendor, device, NULL , "D44F6D5");
   //rv=ftdi_usb_open_desc(&ctx, vendor, device, NULL , NULL);
   //rv=ftdi_usb_open_desc(&ctx, vendor, device, "TTL232R-3V3", "NULL");
   rv=ftdi_usb_open(&ctx,vendor,device);
   Error("open",rv,&ctx,0);


   // Reset
   rv=ftdi_usb_reset(&ctx);
   Error("reset",rv,&ctx,1);


   // Disable bitbang: will need the handshake lines connected or nothing will 
happen (short RTS and CTS)
   // Comment read in testusb.c 
   //...With bitbang mode disabled, hence you need to use the handshake 
signals. Otherwise, sending 
   // will stop with timeout and receiving will continuously read chunks of 
length 0

   rv=ftdi_disable_bitbang(&ctx);
   Error("bitbang(off)",rv,&ctx,1);


   // Set baudrate to 115200
   rv=ftdi_set_baudrate(&ctx,115200);
   Error("baudrate",rv,&ctx,1);


   // Set hardware flow control
   rv=ftdi_setflowctrl(&ctx,SIO_RTS_CTS_HS);
   //rv=ftdi_setflowctrl(&ctx,SIO_XON_XOFF_HS);
   Error("hardware_flow_control",rv,&ctx,1);



    // Read out FTDIChip-ID of R type chips
    if (ctx.type == TYPE_R) {
        unsigned int chipid;
        printf("ftdi_read_chipid: %d\n", ftdi_read_chipid(&ctx, &chipid));
        printf("FTDI chipid: %X\n", chipid);
    }



   //Kick off read thread
   rc = pthread_create( &readerThreadId, NULL, ReaderThread, NULL );
   if ( rc != 0 ) {
      fprintf( stderr, "Error creating ReaderThread: %s\n", strerror( rc ));
      exit( 7 );
   }

   printf("\nInside main function after kicking off ReaderThread \n");



   //Kick off write thread
   rc = pthread_create( &readerThreadId, NULL, WriterThread, NULL );
   if ( rc != 0 ) {
      fprintf( stderr, "Error creating WriterThread: %s\n", strerror( rc ));
      exit( 7 );
   }

   printf("\nInside main function after kicking off WriterThread \n");







   //for(i=0; i<10; i++) {
      //sleep(1);
   //}


   //keep main alive
   while ( 1 ) {
   }

}








Current Thread