LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   USB-RS232 serial driver (https://www.linuxquestions.org/questions/programming-9/usb-rs232-serial-driver-790810/)

ddlawrence 02-22-2010 11:29 AM

USB-RS232 serial driver
 
I am writing a simple driver to talk to an electronic chess board.
Actually I hacked a serial com emulator called com.c which uses
interrupt control.

I can receive data no problem.
I can write data into the tx buffer but it does not send!
I noticed if I close the program, the tx buffer is written
out and the chess board responds.

I think I need to flag an interrupt to transmit. Which I do not
know how to do in linux.
Or maybe it is because I am using a usb-rs232 cable adapter.

help..........don

devnull10 02-22-2010 04:29 PM

Do you need to flush the buffer after writing perhaps?

theNbomr 02-22-2010 06:27 PM

There are at least two possible things going wrong, here. Your program may be failing to send the data, the data may be incorrect and so does not elicit a response from the chess board. Have you tried a loopback cable, to see whether the data you think should be getting sent, actually is? It is possible that the chess board does not consider your message until it sees a line terminator (most commonly CF, LF or the two in combination). It is also possible that the serial port driver is not sending the data until it sees a line terminator, or has received a fflush().
--- rod.

ddlawrence 02-24-2010 09:11 AM

flushing
 
Quote:

Originally Posted by devnull10 (Post 3873137)
Do you need to flush the buffer after writing perhaps?

Yeah, flush clears the tx buffer without transmitting it.

thanks........don

ddlawrence 02-24-2010 09:36 AM

loopback
 
Quote:

Originally Posted by theNbomr (Post 3873244)
There are at least two possible things going wrong, here. Your program may be failing to send the data, the data may be incorrect and so does not elicit a response from the chess board. Have you tried a loopback cable, to see whether the data you think should be getting sent, actually is? It is possible that the chess board does not consider your message until it sees a line terminator (most commonly CF, LF or the two in combination). It is also possible that the serial port driver is not sending the data until it sees a line terminator, or has received a fflush().
--- rod.

Hi. Thanks for the tips. I will make a loopback cable, fflush() and I will check the CR LF options. I do believe the data is being sent (the chess board is 25 yrs old and does not echo). When I run my program with gtkterm on the same port, and I send a command with CR, nothing happens. When I close my program normally, there is the normal response from the chess board that is received and displayed by gtkterm. This happens repeatedly dozens of times. The chess board expects a CR before it responds.

I downloaded the gtkterm source, the danged serial function is 500 lines long! gtkterm works well, I think I will have to dissect it and find out what I am doing differently.

I think it might be the USB-rs232 adapter cable. Do you know where I can find the definitions for the data structure sent to open() & tcsetattr() functions?

Where do they document the programmers nuts & bolts stuff of linux?

thanks............don

theNbomr 02-24-2010 11:12 AM

A few indispensable online references for serial comm's:
Serial HOWTO
Serial Programming HOWTO
Serial Programmming Guide for POSIX Operating Systems
Terminal Concepts in GNU/Linux

The first two references specifically will answer your questions about open() and tcsetatr().

--- rod.

ddlawrence 02-24-2010 04:39 PM

update
 
Quote:

Originally Posted by theNbomr (Post 3875218)
A few indispensable online references for serial comm's:
Serial HOWTO
Serial Programming HOWTO
Serial Programmming Guide for POSIX Operating Systems
Terminal Concepts in GNU/Linux

The first two references specifically will answer your questions about open() and tcsetatr().

--- rod.

thanks Rod, I will check these refs.
About your previous suggestions:

* I made a loopback cable and tested it with gtkterm successfully.
When using the loopback cable the serial program is definitely NOT sending anything.

*fflush() man page says it will send whatever is in the tx buff, great.
However the fflush arg is type FILE *stream and my serial port file descriptor is type int. [btw I use open().]
Do you know of another way to open the serial port with a compatible file descriptor?
Man page says fflush(NULL) should flush all open streams, but when tested, the serial program still did not transmit the tx buffer.

*CR & LF I tested these options with gtkterm in hex mode. The chess board expects to see a CR (0x0d) at the end of the string.

*tcflush() man page says it flushes the txbuffer but does not send. I tried it anyway without success.

*tcflow() man page says this disables/enables output. It has no effect in my problem.

*tcdrain() This is interesting. Man page says this function waits until the tx buffer is empty. When I call tcdrain() after I call write(), my serial program hangs. This confirms the tx buffer is not being emptied/sent.

I need a way to tell the UART to send the contents of the tx buffer. I know this is done by flagging an interrupt. Any ideas on how to do this in Linux?

thanks...........don

theNbomr 02-24-2010 06:10 PM

Oops, you're right. Sorry about that. To flush, you call ioctl() on the filehandle with request = TCFLSH.

You may need to set some attributes to cause your serial port to ignore hardware handshaking/flow control.
Code:

    c_cflag &= ~CNEW_RTSCTS;
Read about the attributes (and ioctl()) you can set in the links I posted.

I don't think the use of interrupts is part of the problem you're trying to solve.

--- rod.

ddlawrence 02-25-2010 11:30 AM

Hi Rod. Thanks for the help. I hate to bother you with details, but I can't fine the definition of TCFLSH. It is not in termios.h (as documented) or the raft of header files I have included.

later.........don

theNbomr 02-25-2010 12:00 PM

Simplest answer:

man ioctl

ioctl() is a generic way of talking to various drivers. It is used to modify the behavior of the driver itself, and the various requests depend on the specific driver. In this case, it is a request to flush the transmit queue.

Also, see http://www.easysw.com/~mike/serial/serial.html#5_1

--- rod.

ddlawrence 02-26-2010 12:27 PM

OK found the byte representation for TCFLSH. I will need to study this problem more. That easysw guy is good but his article is not definitive. Actually none of what I have found is. I will crack this problem when I get home next week and try it on another linux box.

thank you kindly........don


All times are GMT -5. The time now is 01:26 PM.