📄 sio.c
字号:
/* Company : MOXA Technologies Co., Ltd. */
/* Filename : sio.c */
/* Description : */
/* Product : Serial Sample Code for UC7420 */
/* Programmer : Jared Wu */
/* Date : 2005-06-20 */
/*****************************************************************************/
#ifndef _SIO_C_
#define _SIO_C_
#endif
//#define SIO_DEBUG
#include <termio.h> /* POSIX terminal control definitions */
#include <moxadevice.h>
#include <unistd.h>
#include <fcntl.h>
#include "sio.h"
#define CMSPAR 010000000000 /* mark or space (stick) parity */
/* ================================================================== */
int sio_open(int port)
{
struct termios options;
char fname[256];
int fd;
sprintf(fname,"/dev/ttyM%d",port) ;
if( (fd = open( fname, O_RDWR | O_NOCTTY )) < 0 )
{
return SIO_OPENFAIL;
}
fcntl(fd, F_SETFL, FNDELAY); /* Set nonblocking mode */
/*
* Get the current options for the port...
*/
tcgetattr(fd, &options);
options.c_lflag = 0;
options.c_iflag = 0;
options.c_oflag = 0;
/*jimmy_chen@moxa.com.tw said: this flags is set to turn on the private break,parity,frame error notify
* on TIOCMIWAIT, check it on NotifyLineStatus Function.
*/
options.c_iflag |= IGNBRK ;
/*
* Choosing Noncanonical Input
*/
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/*
* Enable the receiver and set local mode...
*/
options.c_cflag |= (CLOCAL | CREAD);
options.c_cc[VMIN] = 1;
options.c_cc[VTIME] = 0;
/*
* Set the new options for the port...
*/
tcsetattr(fd, TCSANOW, &options);
sio_ioctl(fd, BAUD_38400, (BIT_8 | STOP_1 | P_NONE) );
sio_flowctrl(port, 0); //disable flow control
return fd;
}
int sio_close(int fd)
{
if( fd < 0 )
return SIO_BADPORT;
if( close(fd) == -1 )
return SIO_BADPORT;
return SIO_OK;
}
int sio_ioctl(int fd, int baud, int mode)
{
struct termios options;
speed_t speed;
if( baud < BAUD_50 || baud > BAUD_921600 )
return SIO_BADPARM;
if( mode < 0 || mode > (BIT_8 | STOP_2 | P_SPC) )
return SIO_BADPARM;
/*
* Get the current options for the port...
*/
tcgetattr(fd, &options);
/*
* Set the baud rates
*/
switch( baud )
{
case BAUD_50: speed = B50; break;
case BAUD_75: speed = B75; break;
case BAUD_110: speed = B110; break;
case BAUD_134: speed = B134; break;
case BAUD_150: speed = B150; break;
case BAUD_300: speed = B300; break;
case BAUD_600: speed = B600; break;
case BAUD_1200: speed = B1200; break;
case BAUD_1800: speed = B1800; break;
case BAUD_2400: speed = B2400; break;
case BAUD_4800: speed = B4800; break;
case BAUD_7200: speed = B0; break; /* Not Support */
case BAUD_9600: speed = B9600; break;
case BAUD_19200: speed = B19200; break;
case BAUD_38400: speed = B38400; break;
case BAUD_57600: speed = B57600; break;
case BAUD_115200: speed = B115200; break;
case BAUD_230400: speed = B230400; break;
case BAUD_460800: speed = B460800; break;
case BAUD_921600: speed = B921600; break;
default: speed = B0; break; /* 0 baud (drop DTR) */
}
cfsetispeed(&options, speed);
cfsetospeed(&options, speed);
/*
* Set the data bits
*/
options.c_cflag &= ~CSIZE;
switch( mode & 0x03 )
{
case BIT_5: options.c_cflag |= CS5; break;
case BIT_6: options.c_cflag |= CS6; break;
case BIT_7: options.c_cflag |= CS7; break;
case BIT_8: options.c_cflag |= CS8; break;
default: options.c_cflag |= CS8; break;
}
/*
* Set the stop bits
*/
switch( mode & 0x04 )
{
case STOP_1: options.c_cflag &= ~CSTOPB; break;
case STOP_2: options.c_cflag |= CSTOPB; break;
default: options.c_cflag |= CSTOPB; break;
}
/*
* Set the parity
*/
options.c_cflag &= ~(PARENB | PARODD | CMSPAR);
switch( mode & 0x38 )
{
case P_EVEN:
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
break;
case P_ODD:
options.c_cflag |= PARENB;
options.c_cflag |= PARODD;
break;
case P_SPC:
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_cflag |= CMSPAR;
break;
case P_MRK:
options.c_cflag |= PARENB;
options.c_cflag |= PARODD;
options.c_cflag |= CMSPAR;
break;
case P_NONE:
default:
options.c_cflag &= ~PARENB;
break;
}
/*
* Set the new options for the port...
*/
tcsetattr(fd, TCSANOW, &options);
return SIO_OK;
}
/* Turn on/off RTS
int fd: the serial port file description number
int mode: 1:DTR on
0:DTR off
*/
int sio_DTR(int fd, int mode)
{
int status;
if( fd < 0 )
return SIO_BADPORT;
if( mode < 0 || mode > (C_DTR | C_RTS) )
return SIO_BADPARM;
ioctl(fd, TIOCMGET, &status);
status &= ~TIOCM_DTR;
if( mode )
status |= TIOCM_DTR;
else
status &= ~(TIOCM_DTR);
ioctl(fd, TIOCMSET, &status);
return SIO_OK;
}
/* Turn on/off RTS
int fd: the serial port file description number
int mode: 1:RTS on
0:RTS off
*/
int sio_RTS(int fd, int mode)
{
int status;
if( fd < 0 )
return SIO_BADPORT;
if( mode < 0 || mode > (C_DTR | C_RTS) )
return SIO_BADPARM;
ioctl(fd, TIOCMGET, &status);
status &= ~TIOCM_RTS;
if( mode )
status |= TIOCM_RTS;
else
status &= ~(TIOCM_RTS);
ioctl(fd, TIOCMSET, &status);
return SIO_OK;
}
int sio_lctrl(int fd, int mode)
{
int status;
if( fd < 0 )
return SIO_BADPORT;
if( mode < 0 || mode > (C_DTR | C_RTS) )
return SIO_BADPARM;
ioctl(fd, TIOCMGET, &status);
status &= ~TIOCM_DTR;
status &= ~TIOCM_RTS;
if( mode & C_DTR )
status |= TIOCM_DTR;
if( mode & C_RTS )
status |= TIOCM_RTS;
ioctl(fd, TIOCMSET, &status);
return SIO_OK;
}
int sio_baud(int fd, long speed)
{
if( fd < 0 )
return SIO_BADPORT;
ioctl(fd, MOXA_SET_SPECIAL_BAUD_RATE, &speed);
return SIO_OK;
}
int sio_read(int fd, char *buf, int len)
{
int n;
if( fd < 0 )
return SIO_BADPORT;
if( buf == NULL || len < 0 )
return SIO_BADPARM;
n = read(fd, buf, len);
if( n < 0 )
{
return SIO_WRITETIMEOUT;
}
return n;
}
int sio_write(int fd, char *buf, int len)
{
int n ,nOutQueueFreeBytes;
if( fd < 0 )
return SIO_BADPORT;
if( buf == NULL || len < 0 )
return SIO_BADPARM;
n = write(fd, buf, len);
if( n < 0 )
{
return SIO_WRITETIMEOUT;
}
return n;
}
int sio_lstatus(int fd)
{
int status;
int result;
if( fd < 0 )
return SIO_BADPORT;
ioctl(fd, TIOCMGET, &status);
result = 0;
if( status & TIOCM_DSR ) /* DSR */
result |= S_DSR;
if( status & TIOCM_CTS ) /* CTS */
result |= S_CTS;
if( status & TIOCM_RNG ) /* RI */
result |= S_RI;
if( status & TIOCM_CD ) /* DCD */
result |= S_CD;
return result;
}
long sio_getbaud(int fd)
{
long result;
struct termios options;
speed_t speed;
if( fd < 0 )
return SIO_BADPORT;
/*
* Get the current options for the port...
*/
tcgetattr(fd, &options);
/*
* Get the baud rates
*/
speed = cfgetispeed(&options);
speed = cfgetospeed(&options);
switch( speed )
{
case B0: result = 0; break;
case B50: result = 50; break;
case B75: result = 75; break;
case B110: result = 110; break;
case B134: result = 134; break;
case B150: result = 150; break;
case B300: result = 300; break;
case B600: result = 600; break;
case B1200: result = 1200; break;
case B1800: result = 1800; break;
case B2400: result = 2400; break;
case B4800: result = 4800; break;
case B9600: result = 9600; break;
case B19200: result = 19200; break;
case B38400: result = 38400; break;
case B57600: result = 57600; break;
case B115200: result = 115200; break;
case B230400: result = 230400; break;
case B460800: result = 460800; break;
case B921600: result = 921600; break;
default: result = 0; break;
}
return result;
}
int sio_flowctrl(int fd, int mode)
{
char *buf ;
struct termios options;
struct termios oldoptions;
if( fd < 0 )
return SIO_BADPORT;
if( mode < 0 || mode > 0x0F )
return SIO_BADPARM;
/*
* Get the current options for the port...
*/
tcgetattr(fd, &options);
oldoptions = options;
/*
* Disable hardware/software flow control
*/
options.c_cflag &= ~CRTSCTS;
options.c_iflag &= ~(IXON | IXOFF | IXANY);
if( mode & F_HW )
options.c_cflag |= CRTSCTS;
if( mode & F_SW )
{
options.c_iflag |= (IXON | IXOFF);
}
/*
* Set the new options for the port...
*/
tcsetattr(fd, TCSANOW, &options);
return SIO_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -