RS232_unix.c
538 lines
| 11.2 KiB
| text/x-c
|
CLexer
/ src / RS232_unix.c
|
r5 | #include <stdio.h> | ||
#include <unistd.h> | ||||
#include <fcntl.h> | ||||
#include <string.h> | ||||
#include <errno.h> | ||||
|
r33 | #include <malloc.h> | ||
|
r34 | #include <dirent.h> | ||
#include <limits.h> | ||||
#include <stdlib.h> | ||||
#include <sys/stat.h> | ||||
|
r44 | #include <termios.h> | ||
#include <termio.h> | ||||
|
r5 | #include "RS232.h" | ||
rs232speed_t rs232cfspeed(unsigned int BaudeRate); | ||||
rs232port_t rs232open(char* psPortName) | ||||
{ | ||||
|
r44 | rs232port_t fd; | ||
int flags; | ||||
fd = (rs232port_t)open(psPortName, O_RDWR | O_NOCTTY );//| O_NDELAY); | ||||
//fcntl((int)fd, F_SETFL, FNDELAY); | ||||
//fd = open(psPortName, O_RDWR | O_NOCTTY); | ||||
#ifdef RS232_debug | ||||
if(fd==-1)printf("can't open Port\n"); | ||||
#else | ||||
if(fd!=-1) | ||||
{ | ||||
//flags = fcntl(fd, F_GETFL); | ||||
//flags |= O_NONBLOCK; | ||||
//flags|=FNDELAY; | ||||
//fcntl(fd, F_SETFL, flags); | ||||
//fcntl((int)fd, F_SETFL, FNDELAY); | ||||
} | ||||
|
r37 | |||
|
r44 | #endif | ||
return fd; | ||||
|
r5 | } | ||
int rs232close(rs232port_t fd) | ||||
{ | ||||
|
r44 | if ((int)fd == -1) | ||
{ | ||||
return -1; | ||||
} | ||||
else | ||||
{ | ||||
close(fd); | ||||
return 0; | ||||
} | ||||
|
r5 | } | ||
|
r33 | rs232portslist_t* rs232getportlist() | ||
{ | ||||
|
r44 | struct dirent *dp; | ||
char* path="/dev/serial/by-id"; | ||||
DIR *dir = opendir(path); | ||||
rs232portslist_t* firstitem=NULL; | ||||
rs232portslist_t* previtem=NULL; | ||||
|
r45 | char* linkname; | ||
char* devName; | ||||
|
r44 | int i=0; | ||
if(dir!=NULL) | ||||
{ | ||||
while ((dp=readdir(dir)) != NULL) | ||||
{ | ||||
|
r45 | int len = strlen(path)+strlen(dp->d_name)+8;//+8 => let's put some margin | ||
linkname = (char*)malloc(len); | ||||
memset(linkname,'\0',len); | ||||
|
r44 | struct stat statbuf; | ||
strcpy(linkname,path); | ||||
strcat(linkname,"/"); | ||||
strcat(linkname,dp->d_name); | ||||
lstat(linkname, &statbuf); | ||||
if(S_ISLNK(statbuf.st_mode)) | ||||
{ | ||||
|
r45 | devName=realpath(linkname, NULL); | ||
if(devName!=NULL) | ||||
|
r44 | { | ||
|
r45 | rs232portslist_t* item = (rs232portslist_t*)malloc(sizeof(rs232portslist_t)); | ||
item->name = devName; | ||||
item->next = NULL; | ||||
if(NULL!=previtem)previtem->next = item; | ||||
previtem = item; | ||||
if(NULL==firstitem)firstitem = item; | ||||
|
r44 | } | ||
} | ||||
|
r45 | free(linkname); | ||
|
r44 | } | ||
} | ||||
return firstitem; | ||||
|
r33 | } | ||
void rs232deleteportlist(rs232portslist_t* list) | ||||
{ | ||||
|
r44 | if(list!=NULL) | ||
{ | ||||
if(list->next != NULL) | ||||
rs232deleteportlist(list->next); | ||||
free(list); | ||||
} | ||||
|
r33 | } | ||
|
r5 | |||
|
r8 | int rs232setup(rs232port_t fd, int ChSize, int BaudeRate, rs232parity Parity, rs232stop NbStop) | ||
|
r5 | { | ||
|
r44 | if ((int)fd == -1) | ||
{ | ||||
return -1; | ||||
} | ||||
else | ||||
{ | ||||
struct termios terminos; | ||||
tcgetattr(fd, &terminos); | ||||
terminos.c_iflag=0; | ||||
terminos.c_oflag=0; | ||||
terminos.c_cflag=0; | ||||
terminos.c_lflag=0; | ||||
cfsetispeed(&terminos, rs232cfspeed(BaudeRate)); | ||||
cfsetospeed(&terminos, rs232cfspeed(BaudeRate)); | ||||
terminos.c_cflag |= (CLOCAL | CREAD); | ||||
rs232cfparity((int)fd, &terminos, Parity); | ||||
rs232cfnbstop((int)fd, &terminos, NbStop); | ||||
rs232cfcsize((int)fd, &terminos, ChSize); | ||||
terminos.c_cc[VMIN]=0; | ||||
terminos.c_cc[VTIME]=1; | ||||
tcflush(fd, TCIFLUSH); | ||||
#ifdef RS232_debug | ||||
if(tcsetattr(fd, TCSANOW, &terminos)!=0)printf("bad setup\n"); | ||||
#else | ||||
tcsetattr(fd, TCSANOW, &terminos); | ||||
#endif | ||||
return 0; | ||||
} | ||||
|
r5 | } | ||
int rs232setbaudrate(rs232port_t fd, int baudrate) | ||||
{ | ||||
|
r44 | if ((int)fd == -1) | ||
{ | ||||
return fd; | ||||
} | ||||
else | ||||
{ | ||||
struct termios terminos; | ||||
tcgetattr((int)fd, &terminos); | ||||
cfsetispeed(&terminos, rs232cfspeed(baudrate)); | ||||
cfsetospeed(&terminos, rs232cfspeed(baudrate)); | ||||
tcsetattr((int)fd, TCSANOW, &terminos); | ||||
return 0; | ||||
} | ||||
|
r5 | } | ||
int rs232setparity(rs232port_t fd, rs232parity Parity) | ||||
{ | ||||
|
r44 | if ((int)fd == -1) | ||
{ | ||||
return fd; | ||||
} | ||||
else | ||||
{ | ||||
struct termios terminos; | ||||
tcgetattr((int)fd, &terminos); | ||||
terminos.c_cflag &= ~PARENB; | ||||
terminos.c_cflag &= ~PARODD; | ||||
switch(Parity) | ||||
{ | ||||
case rs232parityNo: | ||||
terminos.c_cflag &= ~PARENB; | ||||
break; | ||||
case rs232parityOdd: | ||||
terminos.c_cflag |= PARENB; | ||||
terminos.c_cflag |= PARODD; | ||||
break; | ||||
case rs232parityEven: | ||||
terminos.c_cflag |= PARENB; | ||||
terminos.c_cflag &= ~PARODD; | ||||
break; | ||||
default: | ||||
terminos.c_cflag &= ~PARENB; | ||||
break; | ||||
} | ||||
tcsetattr((int)fd, TCSANOW, &terminos); | ||||
return 0; | ||||
} | ||||
|
r5 | } | ||
|
r9 | int rs232setnbstop(rs232port_t fd, rs232stop NbStop) | ||
|
r5 | { | ||
|
r44 | if ((int)fd == -1) | ||
{ | ||||
return fd; | ||||
} | ||||
else | ||||
{ | ||||
struct termios terminos; | ||||
tcgetattr((int)fd, &terminos); | ||||
switch(NbStop) | ||||
{ | ||||
case rs232OneStop: | ||||
terminos.c_cflag &= ~CSTOPB; | ||||
break; | ||||
case rs232One5Stop: | ||||
terminos.c_cflag |= CSTOPB; | ||||
break; | ||||
case rs232TwoStop: | ||||
terminos.c_cflag |= CSTOPB; | ||||
break; | ||||
default: | ||||
terminos.c_cflag &= ~CSTOPB; | ||||
break; | ||||
} | ||||
tcsetattr((int)fd, TCSANOW, &terminos); | ||||
return 0; | ||||
} | ||||
|
r5 | } | ||
int rs232setcsize(rs232port_t fd, int ChSize) | ||||
{ | ||||
|
r44 | if ((int)fd == -1) | ||
{ | ||||
return fd; | ||||
} | ||||
else | ||||
{ | ||||
struct termios terminos; | ||||
tcgetattr((int)fd, &terminos); | ||||
terminos.c_cflag &= ~CSIZE; | ||||
switch(ChSize) | ||||
{ | ||||
case 5: | ||||
terminos.c_cflag |= CS5; | ||||
break; | ||||
case 6: | ||||
terminos.c_cflag |= CS6; | ||||
break; | ||||
case 7: | ||||
terminos.c_cflag |= CS7; | ||||
break; | ||||
default: | ||||
terminos.c_cflag |= CS8; | ||||
break; | ||||
} | ||||
tcsetattr((int)fd, TCSANOW, &terminos); | ||||
return 0; | ||||
} | ||||
|
r5 | } | ||
rs232speed_t rs232cfspeed(unsigned int BaudeRate) | ||||
{ | ||||
|
r44 | if(BaudeRate<25) | ||
return B0; | ||||
if(BaudeRate<67) | ||||
return B50; | ||||
if(BaudeRate<93) | ||||
return B75; | ||||
if(BaudeRate<123) | ||||
return B110; | ||||
if(BaudeRate<142) | ||||
return B134; | ||||
if(BaudeRate<175) | ||||
return B150; | ||||
if(BaudeRate<250) | ||||
return B200; | ||||
if(BaudeRate<450) | ||||
return B300; | ||||
if(BaudeRate<900) | ||||
return B600; | ||||
if(BaudeRate<1500) | ||||
return B1200; | ||||
if(BaudeRate<2100) | ||||
return B1800; | ||||
if(BaudeRate<3600) | ||||
return B2400; | ||||
|
r5 | |||
|
r44 | if(BaudeRate<7200) | ||
return B4800; | ||||
if(BaudeRate<1400) | ||||
return B9600; | ||||
if(BaudeRate<28800) | ||||
return B19200; | ||||
if(BaudeRate<48000) | ||||
return B38400; | ||||
if(BaudeRate<86400) | ||||
return B57600; | ||||
if(BaudeRate<172800) | ||||
return B115200; | ||||
|
r41 | |||
|
r44 | if(BaudeRate<345600) | ||
return B230400; | ||||
|
r41 | |||
|
r44 | if(BaudeRate<345600) | ||
return B460800; | ||||
if(BaudeRate<748800) | ||||
return B576000; | ||||
|
r41 | |||
|
r44 | if(BaudeRate<1210800) | ||
return B921600; | ||||
if(BaudeRate<1750000) | ||||
return B1500000; | ||||
|
r41 | |||
|
r44 | if(BaudeRate<2250000) | ||
return B2000000; | ||||
|
r41 | |||
|
r44 | if(BaudeRate<2750000) | ||
return B2500000; | ||||
else | ||||
return B3000000; | ||||
|
r41 | |||
|
r5 | } | ||
int rs232cfparity(int fd, struct termios *terminos, rs232parity Parity) | ||||
{ | ||||
|
r44 | if ((int)fd == -1) | ||
{ | ||||
return fd; | ||||
} | ||||
else | ||||
{ | ||||
terminos->c_cflag &= ~PARENB; | ||||
terminos->c_cflag &= ~PARODD; | ||||
switch(Parity) | ||||
{ | ||||
case rs232parityNo: | ||||
terminos->c_cflag &= ~PARENB; | ||||
terminos->c_cflag &= ~PARODD; | ||||
break; | ||||
case rs232parityOdd: | ||||
terminos->c_cflag |= PARENB; | ||||
terminos->c_cflag |= PARODD; | ||||
break; | ||||
case rs232parityEven: | ||||
terminos->c_cflag |= PARENB; | ||||
terminos->c_cflag &= ~PARODD; | ||||
break; | ||||
default: | ||||
terminos->c_cflag &= ~PARENB; | ||||
terminos->c_cflag &= ~PARODD; | ||||
break; | ||||
} | ||||
return 0; | ||||
} | ||||
|
r5 | } | ||
|
r8 | int rs232cfnbstop(int fd, struct termios *terminos, rs232stop NbStop) | ||
|
r5 | { | ||
|
r44 | if ((int)fd == -1) | ||
{ | ||||
return fd; | ||||
} | ||||
else | ||||
{ | ||||
switch(NbStop) | ||||
{ | ||||
case 2: | ||||
terminos->c_cflag |= CSTOPB; | ||||
break; | ||||
default: | ||||
terminos->c_cflag &= ~CSTOPB; | ||||
break; | ||||
} | ||||
return 0; | ||||
} | ||||
|
r5 | } | ||
int rs232cfcsize(int fd, struct termios *terminos, int ChSize) | ||||
{ | ||||
|
r44 | if ((int)fd == -1) | ||
{ | ||||
return fd; | ||||
} | ||||
else | ||||
{ | ||||
terminos->c_cflag &= ~CSIZE; | ||||
switch(ChSize) | ||||
{ | ||||
case 5: | ||||
terminos->c_cflag |= CS5; | ||||
break; | ||||
case 6: | ||||
terminos->c_cflag |= CS6; | ||||
break; | ||||
case 7: | ||||
terminos->c_cflag |= CS7; | ||||
break; | ||||
default: | ||||
terminos->c_cflag |= CS8; | ||||
break; | ||||
} | ||||
return 0; | ||||
} | ||||
|
r5 | } | ||
int rs232write(rs232port_t fd,char *psWrite, int WriteBufferSize) | ||||
{ | ||||
|
r44 | if ((int)fd == -1) | ||
{ | ||||
return -1; | ||||
} | ||||
else | ||||
{ | ||||
return write((int)fd, psWrite, WriteBufferSize); | ||||
} | ||||
|
r5 | } | ||
r49 | int rs232availablebytes(rs232port_t fd) | |||
{ | ||||
int bytes; | ||||
ioctl(fd, FIONREAD, &bytes); | ||||
return bytes; | ||||
} | ||||
|
r5 | |||
int rs232read(rs232port_t fd,char *psReadHex, int ReadBufferSize) | ||||
{ | ||||
|
r44 | if ((int)fd == -1) | ||
{ | ||||
return -1; | ||||
} | ||||
else | ||||
{ | ||||
return read((int)fd, psReadHex, ReadBufferSize); | ||||
} | ||||
|
r5 | |||
} | ||||
|
r26 | |||
int rs232setRTS(rs232port_t fd) | ||||
{ | ||||
|
r44 | int status; | ||
ioctl((int)fd, TIOCMGET, &status); | ||||
status &= ~TIOCM_RTS; | ||||
if (ioctl((int)fd, TIOCMSET, &status)) | ||||
{ | ||||
return -1; | ||||
} | ||||
return 0; | ||||
|
r26 | } | ||
int rs232clearRTS(rs232port_t fd) | ||||
{ | ||||
|
r44 | int status; | ||
ioctl((int)fd, TIOCMGET, &status); | ||||
status |= TIOCM_RTS; | ||||
if (ioctl((int)fd, TIOCMSET, &status)) | ||||
{ | ||||
return -1; | ||||
} | ||||
return 0; | ||||
|
r26 | } | ||
int rs232setDTR(rs232port_t fd) | ||||
{ | ||||
|
r44 | int status; | ||
ioctl((int)fd, TIOCMGET, &status); | ||||
status &= ~TIOCM_DTR; | ||||
if (ioctl((int)fd, TIOCMSET, &status)) | ||||
{ | ||||
return -1; | ||||
} | ||||
return 0; | ||||
|
r26 | } | ||
int rs232clearDTR(rs232port_t fd) | ||||
{ | ||||
|
r44 | int status; | ||
ioctl((int)fd, TIOCMGET, &status); | ||||
status |= TIOCM_DTR; | ||||
if (ioctl((int)fd, TIOCMSET, &status)) | ||||
{ | ||||
return -1; | ||||
} | ||||
return 0; | ||||
|
r26 | } | ||
int rs232saferead(rs232port_t fd,char* data,int count ) | ||||
{ | ||||
|
r44 | int read=0; | ||
int i=0; | ||||
for(i=0;i<1000;i++) | ||||
{ | ||||
read = rs232read((int)fd,data,count); | ||||
//printf("read %d bytes\n",read); | ||||
if(read==-1)read=0; | ||||
count-=read; | ||||
data+=read; | ||||
if(count==0) | ||||
return 0; | ||||
usleep(10); | ||||
} | ||||
return -1; | ||||
|
r26 | } | ||
int rs232safewrite(rs232port_t fd,char* data,int count) | ||||
{ | ||||
|
r44 | int written=0; | ||
int i=0; | ||||
for(i=0;i<1000;i++) | ||||
{ | ||||
written = rs232write((int)fd,data+written,count); | ||||
//printf("%d bytes written\n",written); | ||||
if(written==-1)written=0; | ||||
count-=written; | ||||
data+=written; | ||||
if(count==0) | ||||
return 0; | ||||
} | ||||
return -1; | ||||
|
r26 | } | ||
|
r5 | |||