/** | |
* ±¾³ÌÐò·ûºÏ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; | |
} | |