⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sio.c

📁 moxa串口服务器串口cts_rts_dsr_dtr应用程序源码
💻 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 + -