"Alexander Solianic" <solia...@null.ru> wrote:
>man termio, termios
That will not be much help for any termios man page I've ever
read.
>"Camiel Rouweler" <camiel.rouwe...@asml.nl> wrote:
>> I have to do the following task: determine the state of a
>> certain switch, which is connected to a serial port. It is
>> specified that if I set a high signal to the RTS pin, that I
>> can read the state of the switch (on or off) on the CTS pin.
>> How do I do this? I have no clue how to control the serial
>> port and all the documentation I have found so far seems to
>> deal only with communication of entire characters through the
>> serial port and not with controlling single pins.
>> If anyone could give me some hints or point me to a useful
>> FAQ, I would be very happy.
It might vary considerably depending on the specific UNIX being
used. The best bet is to fetch the source code to two or three
modem programs that are known to work on that platform, and look
to see how it those programs managed to handle RTS and CTS.
(minicom, seyon, pcomm, pppd etc are all helpful.)
Here is an example, which works on Linux. I am assuming that
there might also be a need to know how to check status of the
DCD (Carrier Detect) line, because if said device is cabled
correctly the DCD line will only be set when the device is
actually connected. Otherwise it is impossible to differentiate
between CTS off and loose cable connectors breaking the
connection.
This demo only checks the status, of a variety of things though,
most of which are probably not important in this specific
application but are included just in case they are interesting.
At the end of the code are a couple functions which can be used
to set or clear modem control lines. Hints are included about
some of the possible variations that might be encountered on
different platforms.
Floyd
/*
* Serial.c -- demonstrates how to diddle with modem control lines.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <linux/serial.h>
#include <sys/ioctl.h>
void show_serial(char *);
/*
* list of serial ports this program checks
*/
#define MAXDEVICES 4
char devices[MAXDEVICES][30] = {
"/dev/ttyS0",
"/dev/ttyS1",
"/dev/ttyS2",
"/dev/ttyS3"
};
int
main(void)
{
int i;
for (i = 0; i < MAXDEVICES; ++i) {
show_serial(devices[i]);
}
return EXIT_SUCCESS;
}
#if 0
/*
* These lists are from /usr/include/asm/termios.h on a Linux box.
* They might be different on other platforms, and are included here
* for instructional purposes only.
*/
/* line disciplines */
#define N_TTY 0
#define N_SLIP 1
#define N_MOUSE 2
#define N_PPP 3
#define N_STRIP 4
#define N_AX25 5
#define N_X25 6 /* X.25 async */
#define N_6PACK 7
#define N_MASC 8 /* Reserved for Mob ... [snipped] */
#define N_R3964 9 /* Reserved for Sim ... [snipped] */
#define N_PROFIBUS_FDL 10 /* Reserved for Pro ... [snipped] */
#define N_IRDA 11 /* Linux IR - http: ... [snipped] */
#define N_SMSBLOCK 12 /* SMS block mode - ... [snipped] */
#define N_HDLC 13 /* synchronous HDLC */
/* modem lines */
#define TIOCM_LE 0x001
#define TIOCM_DTR 0x002
#define TIOCM_RTS 0x004
#define TIOCM_ST 0x008
#define TIOCM_SR 0x010
#define TIOCM_CTS 0x020
#define TIOCM_CAR 0x040
#define TIOCM_RNG 0x080
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
#endif
void show_serial(char *device) {
int valid;
int rts;
int openflag;
int cntrlreg;
int fd;
int results;
struct termios term;
struct serial_struct serinfo; /* defined in /usr/include/asm/serial.h */
valid = 1;
openflag = 0;
if ((fd = open(device, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
valid = 0;
printf("Device: %s <Cannot be opened>", device);
} else {
openflag = 1;
}
serinfo.reserved_char[0] = 0;
if (valid && ioctl(fd, TIOCGSERIAL, &serinfo) < 0) {
valid = 0; /* can't get serial info */
printf("Device: %s <cannot get serial info struct>", device);
}
if (valid && ioctl(fd, TIOCMGET, &cntrlreg) < 0) {
valid = 0; /* can't get control register */
printf("Device: %s <cannot get control register>", device);
}
if (serinfo.line >= MAXDEVICES) {
valid = 0; /* out of interesting range */
printf("Device: %s <Device is out of range>", device);
}
if (valid) {
printf("device: %s: DCD = %s",
device,
cntrlreg & TIOCM_CAR ? "ON" : "OFF");
}
#if 0
if (! (cntrlreg & TIOCM_CAR)) {
valid = 0; /* no carrier detect */
}
#endif
if (valid && tcgetattr(fd, &term) < 0) {
valid = 0; /* can't get termios info */
printf(" <Cannot get termios struct> ", device);
}
if (valid && B0 == cfgetospeed(&term)) {
valid = 0; /* disabled if speed is 0 */
printf(" [Speed is set to 0 (DTR cleared)] ", device);
}
if( valid && ioctl (fd, TIOCSERGETLSR, &results) < 0) {
valid = 0; /* can't check line status */
printf(" <Cannot get line status register> ", device);
}
if (valid &&
results &&
term.c_line != N_SLIP &&
term.c_line != N_PPP &&
term.c_line != N_TTY) {
valid = 0; /* not a tty, ppp orb slip line */
printf(" [Not set for tty, slip or ppp line discipline] ", device);
}
rts = !(cntrlreg & TIOCM_RTS);
if (valid) {
printf(" rcs status: %s", rts ? "ON" : "OFF");
}
if (openflag) {
close(fd);
}
putchar('\n');
return;
}
#if 0
/*
* Two different ways to set/clear modem control lines.
*/
/*
* Set or Clear DTR modem control line
*
* Note: TIOCMBIS: CoMmandd bIt Set
* TIOCMBIC: CoMmandd bIt Clear
*
*/
void
setdtr (int fd, int on)
{
int controlbits = TIOCM_DTR;
ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &controlbits);
}
/*
* Set or Clear RTS modem control line
*
* Note: TIOCMSET and TIOCMGET are POSIX
*
* the same things:
*
* TIOCMODS and TIOCMODG are BSD (4.3 ??)
* MCSETA and MCGETA are HPUX
*/
void
setrts(int fd, int on)
{
int controlbits;
ioctl(fd, TIOCMGET, &controlbits);
if (on) {
controlbits |= TIOCM_RTS;
} else {
controlbits &= ~TIOCM_RTS;
}
ioctl(fd, TIOCMSET, &controlbits);
}
#endif