/***************************************************************
Copyright 2024-2029. All rights reserved.
文件名 : 01_usr_serial.c
作者 : tangmingfei2013@126.com
版本 : V1.0
描述 : linux 串口应用程序接口
其他 : 无
日志 : 初版V1.0 2024/03/01
***************************************************************/
#include "usr_serial.h"
/* Private define ------------------------------------------------------------*/
#define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+2)
#define TIMEOUT_USEC 0
/* Private variables ---------------------------------------------------------*/
static unsigned int fd;
static struct termios termios_old;
static struct termios termios_new;
static struct timeval tv_timeout;
static fd_set fs_read;
static fd_set fs_write;
/* Private function prototypes -----------------------------------------------*/
static speed_t baudrate_to_Bxx (unsigned int baudrate);
static void set_data_bit (unsigned int databit);
static unsigned int get_baudrate( void );
static unsigned int set_portattr ( unsigned int baudrate,unsigned int databit, const char *stopbit,char parity);
int usr_serial_open( char *port, unsigned int baudrate,
unsigned int databit, const char *stopbit, char parity)
{
int err;
fd = open (port, O_RDWR | O_NOCTTY | O_NDELAY);
if (-1 == fd) {
fprintf(stderr, "cannot open port %s\n", port);
return (-1);
}
tcgetattr (fd, &termios_old); /* save the form termios value */
err = set_portattr (baudrate, databit, stopbit, parity);
if ( err ) {
fprintf ( stderr, "\nport %s cannot set baudrate at %d\n",
port, baudrate);
}
return fd;
}
void usr_serial_close( void )
{
/* flush output data before close and restore old attribute */
tcsetattr(fd, TCSADRAIN, &termios_old);
close(fd);
}
unsigned int usr_serial_sendbytes (char * data, unsigned int datalength)
{
unsigned int total_len = 0;
return (total_len);
}
int usr_serial_readbytes (void *data, unsigned int datalength)
{
unsigned int retval = 0;
return (retval);
}
static void set_data_bit (unsigned int databit)
{
termios_new.c_cflag &= ~CSIZE;
switch (databit) {
default:
case 8:
termios_new.c_cflag |= CS8;
break;
case 7:
termios_new.c_cflag |= CS7;
break;
case 6:
termios_new.c_cflag |= CS6;
break;
case 5:
termios_new.c_cflag |= CS5;
break;
}
}
static void set_stopbit (const char *stopbit)
{
if (0 == strcmp (stopbit, "1")) {
termios_new.c_cflag &= ~CSTOPB; /* 1 stop bit */
}
else if (0 == strcmp (stopbit, "1.5")) {
termios_new.c_cflag &= ~CSTOPB; /* 1.5 stop bits */
}
else if (0 == strcmp (stopbit, "2")) {
termios_new.c_cflag |= CSTOPB; /* 2 stop bits */
}
else {
termios_new.c_cflag &= ~CSTOPB; /* 1 stop bit */
}
}
static void set_parity (char parity)
{
switch (parity) {
case 'N': /* no parity check */
termios_new.c_cflag &= ~PARENB;
break;
case 'E': /* even */
termios_new.c_cflag |= PARENB;
termios_new.c_cflag &= ~PARODD;
break;
case 'O': /* odd */
termios_new.c_cflag |= PARENB;
termios_new.c_cflag |= ~PARODD;
break;
default: /* no parity check */
termios_new.c_cflag &= ~PARENB;
break;
}
}
static speed_t baudrate_to_Bxx (unsigned int baudrate)
{
switch (baudrate) {
case 0:
return (B0);
case 50:
return (B50);
case 75:
return (B75);
case 110:
return (B110);
case 134:
return (B134);
case 150:
return (B150);
case 200:
return (B200);
case 300:
return (B300);
case 600:
return (B600);
case 1200:
return (B1200);
case 2400:
return (B2400);
case 9600:
return (B9600);
case 19200:
return (B19200);
case 38400:
return (B38400);
case 57600:
return (B57600);
case 115200:
return (B115200);
default:
return (B9600);
}
}
static void set_baudrate (unsigned int baudrate)
{
speed_t speed;
speed = baudrate_to_Bxx (baudrate); /* set baudrate */
cfsetispeed(&termios_new, speed); // set input speed
cfsetospeed(&termios_new, speed); // set output speed
}
static unsigned int set_portattr ( unsigned int baudrate, // 1200 2400 4800 9600 .. 115200
unsigned int databit, // 5, 6, 7, 8
const char *stopbit, // "1", "1.5", "2"
char parity) // N(o), O(dd), E(ven)
{
bzero(&termios_new, sizeof (termios_new));
cfmakeraw (&termios_new);
set_baudrate (baudrate);
termios_new.c_cflag |= CLOCAL | CREAD; /* | CRTSCTS */
set_data_bit (databit);
set_parity (parity);
set_stopbit (stopbit);
termios_new.c_cc[VTIME] = 1; /* unit: 1/10 second. */
termios_new.c_cc[VMIN] = 255; /* minimal characters for reading */
return (tcsetattr (fd, TCSANOW, &termios_new));
}
/* End of this file */