blob: dfdd8694f0a6b2010ee9cc06db1116ec770945ca [file] [log] [blame]
/**
* ±¾³ÌÐò·ûºÏGPLÌõÔ¼
* Beneboy 2003-5-16
*/
#include <stdio.h> // printf
#include <fcntl.h> // open
#include <string.h> // bzero
#include <stdlib.h> // exit
#include <termios.h> //termios, tcgetattr(), tcsetattr()
#include <unistd.h>
#include "port_com.h"
// ½ÓÊÕ³¬Ê±
#define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+1)
#define TIMEOUT_USEC 0
// serial port information
portinfo_t g_sPortInfo =
{
'0', // print prompt after receiving
115200, // baudrate: 115200
'8', // databit: 8
'0', // debug: off
'0', // echo: off
'0', // flow control: software
'0', // default tty: COM1
'0', // parity: none
'1', // stopbit: 1
0 // reserved
};
/**
* ²¨ÌØÂÊת»¯×ª»»º¯Êý
*/
int convbaud(unsigned long int baudrate)
{
switch (baudrate)
{
case 2400:
return B2400;
case 4800:
return B4800;
case 9600:
return B9600;
case 19200:
return B19200;
case 38400:
return B38400;
case 57600:
return B57600;
case 115200:
return B115200;
default:
return B9600;
}
}
/**
* Setup comm attr
* fd: ´®¿ÚÎļþÃèÊö·û, pportinfo: ´ýÉèÖõĶ˿ÚÐÅÏ¢s
*
*/
int PortSet(int fd)
{
struct termios termios_old, termios_new;
int baudrate, tmp;
char databit, stopbit, parity, fctl;
bzero(&termios_old, sizeof(termios_old));
bzero(&termios_new, sizeof(termios_new));
cfmakeraw(&termios_new);
tcgetattr(fd, &termios_old); //get the serial port attributions
/*------------ÉèÖö˿ÚÊôÐÔ----------------*/
//baudrates
baudrate = convbaud(g_sPortInfo.baudrate);
cfsetispeed(&termios_new, baudrate); // ÌîÈë´®¿ÚÊäÈë¶Ë²¨ÌØÂÊ
cfsetospeed(&termios_new, baudrate); // ÌîÈë´®¿ÚÊä³ö¶Ë²¨ÌØÂÊ
termios_new.c_cflag |= CLOCAL; // ¿ØÖÆÄ£Ê½, ±£Ö¤³ÌÐò²»»á³ÉΪ¶Ë¿ÚµÄÕ¼ÓÐÕß
termios_new.c_cflag |= CREAD; // ¿ØÖÆÄ£Ê½, ʹÄܶ˿ڶÁÈ¡ÊäÈëµÄÊý¾Ý
// ¿ØÖÆÄ£Ê½, flow control
fctl = g_sPortInfo.fctl;
switch (fctl)
{
case '0':
{
termios_new.c_cflag &= ~CRTSCTS; //no flow control
}
break;
case '1':
{
termios_new.c_cflag |= CRTSCTS; //hardware flow control
}
break;
case '2':
{
termios_new.c_iflag |= IXON | IXOFF | IXANY; //software flow control
}
break;
default:
{
printf("Unknown fctl %c\n", fctl);
break;
}
}
// ¿ØÖÆÄ£Ê½, data bits
termios_new.c_cflag &= ~CSIZE; // ¿ØÖÆÄ£Ê½, ÆÁ±Î×Ö·û´óСλ
databit = g_sPortInfo.databit;
switch (databit)
{
case '5':
termios_new.c_cflag |= CS5;
//lint -fallthrough
case '6':
termios_new.c_cflag |= CS6;
//lint -fallthrough
case '7':
termios_new.c_cflag |= CS7;
//lint -fallthrough
default:
termios_new.c_cflag |= CS8;
}
// ¿ØÖÆÄ£Ê½ parity check
parity = g_sPortInfo.parity;
switch (parity)
{
case '0':
{
termios_new.c_cflag &= ~PARENB; // no parity check
}
break;
case '1':
{
termios_new.c_cflag |= PARENB; // odd check
termios_new.c_cflag &= ~PARODD;
}
break;
case '2':
{
termios_new.c_cflag |= PARENB; // even check
termios_new.c_cflag |= PARODD;
}
break;
default:
{
printf("Unknown parity %c\n", parity);
break;
}
}
// ¿ØÖÆÄ£Ê½, stop bits
stopbit = g_sPortInfo.stopbit;
if (stopbit == '2')
{
termios_new.c_cflag |= CSTOPB; // 2 stop bits
}
else
{
termios_new.c_cflag &= ~CSTOPB; // 1 stop bits
}
//other attributions default
termios_new.c_oflag &= ~OPOST; // Êä³öģʽ, ԭʼÊý¾ÝÊä³ö
termios_new.c_cc[VMIN] = 1; // ¿ØÖÆ×Ö·û, ËùÒª¶ÁÈ¡×Ö·ûµÄ×îСÊýÁ¿
termios_new.c_cc[VTIME] = 1; // ¿ØÖÆ×Ö·û, ¶ÁÈ¡µÚÒ»¸ö×Ö·ûµÄµÈ´ýʱ¼ä, unit: (1/10)second
tcflush(fd, TCIFLUSH); // Òç³öµÄÊý¾Ý¿ÉÒÔ½ÓÊÕ,µ«²»¶Á
tmp = tcsetattr(fd, TCSANOW, &termios_new); // ÉèÖÃÐÂÊôÐÔ, TCSANOW: ËùÓɸıäÁ¢¼´ÉúЧ
tcgetattr(fd, &termios_old);
return(tmp);
}
/**
* Open serial port
* tty: ¶Ë¿ÚºÅ ttyS0, ttyS1, ....
* ·µ»ØÖµÎª´®¿ÚÎļþÃèÊö·û
*/
int PortOpen(pportinfo_t pportinfo, int mode)
{
return 0;
}
/**
* Close serial port
*/
void PortClose(int fd)
{
close(fd);
}
/**
* PortSend
* fd: ´®¿ÚÃèÊö·û,
* data: ´ý·¢ËÍÊý¾ÝÖ¸Õë
* datalen: Êý¾Ý³¤¶È
* flag: ·¢ËÍ·½Ê½±êʶ
* ·µ»ØÊµ¼Ê·¢Ëͳ¤¶È
*/
int PortSend(int fd, unsigned char* data, int datalen)
{
int len = 0;
len = write(fd, data, datalen); //ʵ¼ÊдÈëµÄ³¤¶È
if (len == datalen)
{
return (len);
}
else
{
tcflush(fd, TCOFLUSH);
return -1;
}
}
/**
* PortRecv
* ²ÎÊý£º
* fd: ´®¿ÚÃèÊö·û,
* data: ´ý½ÓÊÕÊý¾ÝÖ¸Õë
* datalen: Êý¾Ý³¤¶È
* flag: ½ÓÊÕ·½Ê½±êʶ
* ·µ»ØÊµ¼Ê¶ÁÈëµÄ×Ö½ÚÊý
*/
int PortRecv(int fd, unsigned char* data, int datalen)
{
#if 0
int readlen, fs_sel;
fd_set fs_read;
struct timeval tv_timeout;
FD_ZERO(&fs_read);
FD_SET(fd, &fs_read);
/*RAT ¸ÃÖµÓ¦¸Ã¼õСÒÔÌá¸ßÏìÓ¦ËÙ¶È*/
tv_timeout.tv_sec = 0;/*TIMEOUT_SEC(datalen, baudrate);*/
tv_timeout.tv_usec = 200;/*TIMEOUT_USEC;*/
fs_sel = select(fd + 1, &fs_read, NULL, NULL, &tv_timeout);
if (fs_sel)
{
printf("rpmsg: portrecv fd =%d\n",fd);
readlen = read(fd, data, datalen);
return(readlen);
}
else
{
return(0);
}
#else
int readlen = read(fd, data, datalen);
return(readlen);
#endif
}
int tty_set_log_port(int fd)
{
if (fd < 0)
{
printf("tty_set_port failed. %d\n", fd);
return 0;
}
printf("tty_set_port ok.\n");
//ioctl(g_AtProxy_RpProxyFd, (('R'<<8)|6|(0x4004<<16)), 0x400);
//printf("rpmsg: ap port open fd = %d\n",fd);//add shideyou
//ioctl(fd, (('R'<<8)|1|(0x4004<<16)), 0x400);
//ioctl(fd, (('R'<<8)|4|(0x4004<<16)), 0);
PortSet(fd);
//ZTE_LOG(LOG_DEBUG, "port is open!");
return 1;
}