LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 06-02-2012, 07:59 AM   #1
embeduser
LQ Newbie
 
Registered: Aug 2011
Posts: 7

Rep: Reputation: Disabled
Serial Port Input and out buffer


Hi
I am trying to communicate to a GSM modem Wavecom 2403 over a serial cable through my laptop. As the laptop has no serial interface, I am using a Prolific USB to serial converter. I have written a serial communication program following the tutorial -
http://http://www.easysw.com/~mike/serial/serial.html

Based on that my code is as follows -
Code:
  int open_port(void)
    {
      int fd; /* File descriptor for the port */
        struct termios options;
      fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
      if (fd == -1)
      {
     
        perror("open_port: Unable to open /dev/ttyUSB0 - ");
      }
      else
        {

                tcgetattr(fd,&options);
                /*Sets the read flag in blocking mode*/
                fcntl(fd, F_SETFL, 0);
         
 
                /*
                * Enable the receiver and set local mode...
                */
                options.c_cflag |= (CLOCAL | CREAD);
               options.c_lflag &= ~(ECHO | ECHOE | ICANON | ISIG);
                options.c_lflag |= ICANON;
                options.c_oflag &= ~OPOST;
                tcsetattr(fd,TCSANOW,&options);
        }

      return (fd);
    }


int port_write(int fd)
{
        int ret = 0;
        ret = write(fd,"AT\r",3);
        if (ret != 3)
        {
                perror("Serial port write failed\n");
        }
        else
        {
                printf("Write to port successful\n");
        }

}

void *port_read(void *fileDesc)
{
        int n=0;
        char buf[10]={0};;
        int fd = (int)fileDesc;
        while(1)
        {
                n= read(fd,&buf,10);
                if(n>0)
                {
                        buf[n]='\0';
                        printf("Result returned bytes read %d ,%s\n",n,buf);
                }
        }

}
The read code is working in a differnt thread. The problem I am facing is that whatever command I write to the serial port is read by my program also. for eg if I give a command as shown above -"AT\r" the same is read by the port_read function and it also reads back the desired output. So my quetsion is that are the input and output buffers same or is there some kind of echo from input to output buffer hapenning?
 
Old 06-02-2012, 10:20 AM   #2
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
It is possible that the GSM modem is echoing everything that is sent to it. I've never heard of outgoing data being echoed back to the receiver, however I've never put sending and receiving code in separate threads. Does each thread try to and succeed in opening the serial port?
--- rod.
 
Old 06-03-2012, 03:13 AM   #3
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942
If the USB-serial converter uses an FTDI chip, make sure the driver does not have the local echo debug mode enabled. (If I read the specs correctly, FTDI converters have a mode where the converter itself does the local echo. Pretty useful for debugging, but would match what you are seeing right now.)

The RXD and TXD pins in the cable or the device could be shorted (in electrical connection which each other), which could also explain the local echo. One way to test would be to turn off the modem, but try communicating with it. A better way would be to use an RS232 device known to work, maybe a small microcontroller with RS232.

(You might find the Pololu Wixel interesting. It has a short-range 2.4GHz radio, but it is not 802.11 compatible. A Wixel]Wixel[/URL], the RS-232 connector, and an USB cable would cost about $35. You can program the Wixel to look like any kind of device to the computer, and handle all the communication with the modem on the Wixel instead of on the computer. If you use another Wixel, you can even access the modem wirelessly.)

On a different aspect, you should be more careful in handling the low-level read and write routines. read() and write() are always allowed to return a short count, and regularly do, with serial communications. I recommend you use simple wrapper functions to handle that. I prefer a write function which returns zero for success, and errno error code otherwise:
Code:
static inline int wr(const int descriptor, const void *const data, const size_t length)
{
    const char       *head = (const char *)data;
    const char *const tail = length + (const char *)data;
    ssize_t           bytes;

    while (head < tail) {

        bytes = write(descriptor, head, (size_t)(tail - head));
        if (bytes > (ssize_t)0)
            head += bytes;

        else
        if (bytes != (ssize_t)-1)
            return errno = EIO;

        else
        if (errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN)
            return errno;
    }

    return 0;
}
There are lots of options how to handle the reading part, but you should use at least
Code:
    do {
        bytes = read(fd, buffer, size_of_buffer);
    } while (bytes == (ssize_t)-1 && (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN));
It is quite possible a serial port driver returns EWOULDBLOCK or EAGAIN even if the descriptor is not [/I]nonblocking[/I], so checking for those is prudent. Do not take handling them as any sort of implication that the descriptor should be nonblocking: quite contrary, blocking I/O is very likely the best option here.
 
Old 06-04-2012, 12:55 PM   #4
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
Nom: I use the FTDI USB-Serial dongles all the time, and I've never seen the effect you describe, although I'm certainly not saying it cannot happen. I seem to be using ftdi_sio as the driver. As the standard termios interface doesn't seem to support the mode you mention, how would one detect and/or disable it?

--- rod.
 
Old 06-04-2012, 01:57 PM   #5
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942
Quote:
Originally Posted by theNbomr View Post
I seem to be using ftdi_sio as the driver. As the standard termios interface doesn't seem to support the mode you mention, how would one detect and/or disable it?
Via the debug switch for that driver under /sys -- I thought. Looking at the FT232R specs, the RS-232 FTDI chip does not seem to have that feature, only the RS-485 one does (but I don't know if the kernel driver supports that; I doubt it). Should have checked before opening my mouth! Sorry for the confusion.

Having the TXD and RXD pins be in contact in hardware is not that difficult, since they're next to each other in hardware. In the male connector, you could have a slightly twisted one pin in transit, and bent when first inserted. If so, it is immediately visible when you just look at the male connector. (When prototyping, it is too easy to drop a cut strand of multi-strand signal wire on top of an angled DB9 connector, and have it short the two legs. So it really could be a faulty adapter cable too; I don't think they test the cables too carefully at the factory.)

I much prefer working with native USB interfaces instead. I guess my background shows, but I find it easier to handle datagrams as opposed to individual bytes. I especially like the USB HID interface for a lot of stuff. I don't even know where my USB-to-whatever adapter cables are right now..
 
  


Reply

Tags
communication, linux, serial port, ttyusb


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Serial port output buffer lag morpheusss Linux - Software 1 03-24-2011 01:11 PM
expecting Serial port output to a buffer nathan Programming 5 09-22-2009 04:29 PM
serial port not filling buffer entirely windell Programming 1 08-05-2008 11:12 AM
Serial Port Buffer Overrun damiendusha Linux - Hardware 1 06-22-2006 03:56 AM
Buffer serial input -- create new device? prell Programming 4 04-30-2005 04:52 PM


All times are GMT -5. The time now is 10:31 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration