247 lines
4.1 KiB
C
247 lines
4.1 KiB
C
#include "lpctool_serial.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/ioctl.h>
|
|
#include <fcntl.h>
|
|
#include <termios.h>
|
|
#include <errno.h>
|
|
|
|
#include "infohelper.h"
|
|
|
|
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
|
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
|
|
|
static int serialDev = -1;
|
|
static struct termios term;
|
|
|
|
void setBaud(unsigned int baud)
|
|
{
|
|
// change baudrate
|
|
switch(baud)
|
|
{
|
|
case 2400:
|
|
cfsetispeed(&term,B2400);
|
|
cfsetospeed(&term,B2400);
|
|
break;
|
|
case 4800:
|
|
cfsetispeed(&term,B4800);
|
|
cfsetospeed(&term,B4800);
|
|
break;
|
|
case 9600:
|
|
cfsetispeed(&term,B9600);
|
|
cfsetospeed(&term,B9600);
|
|
break;
|
|
case 19200:
|
|
cfsetispeed(&term,B19200);
|
|
cfsetospeed(&term,B19200);
|
|
break;
|
|
case 38400:
|
|
cfsetispeed(&term,B38400);
|
|
cfsetospeed(&term,B38400);
|
|
break;
|
|
case 57600:
|
|
cfsetispeed(&term,B57600);
|
|
cfsetospeed(&term,B57600);
|
|
break;
|
|
case 115200:
|
|
cfsetispeed(&term,B115200);
|
|
cfsetospeed(&term,B115200);
|
|
break;
|
|
case 230400:
|
|
cfsetispeed(&term,B230400);
|
|
cfsetospeed(&term,B230400);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void setFlow(unsigned char flow)
|
|
{
|
|
if(flow == 0)
|
|
{
|
|
term.c_iflag&=~(IXON|IXOFF|IXANY|INLCR|ICRNL);
|
|
}
|
|
else
|
|
{
|
|
term.c_iflag&=~(INLCR|ICRNL|IXANY);
|
|
term.c_iflag|=(IXON|IXOFF);
|
|
}
|
|
}
|
|
|
|
void setTimeout(unsigned int tout)
|
|
{
|
|
term.c_cc[VMIN]=0;
|
|
term.c_cc[VTIME]=tout; // 10 seconds timeout
|
|
}
|
|
|
|
int openSerial(char *dev)
|
|
{
|
|
|
|
serialDev=open(dev,O_RDWR);
|
|
if(serialDev<0) {
|
|
printf("cannot acces %s\n",dev);
|
|
return serialDev;
|
|
}
|
|
|
|
setDTR(0);
|
|
setRTS(0);
|
|
|
|
tcgetattr(serialDev,&term);
|
|
|
|
setBaud(19200);
|
|
|
|
term.c_cflag = (term.c_cflag & ~CSIZE) | CS8;
|
|
term.c_cflag |= CLOCAL | CREAD;
|
|
|
|
term.c_cflag &= ~(PARENB | PARODD);
|
|
term.c_cflag &= ~CSTOPB;
|
|
term.c_iflag=IGNBRK;
|
|
|
|
term.c_iflag |= IXON | IXOFF;
|
|
|
|
term.c_lflag=0;
|
|
|
|
term.c_oflag=0;
|
|
|
|
|
|
setTimeout(30);
|
|
|
|
if (tcsetattr(serialDev, TCSANOW, &term)!=0)
|
|
return printError("setattr stage 1 failed");
|
|
|
|
|
|
if (tcgetattr(serialDev, &term)!=0)
|
|
return printError("getattr failed");
|
|
|
|
|
|
term.c_cflag &= ~CRTSCTS;
|
|
|
|
if (tcsetattr(serialDev, TCSANOW, &term)!=0)
|
|
return printError("setattr stage 2 failed");
|
|
|
|
return serialDev;
|
|
}
|
|
|
|
int closeSerial(void)
|
|
{
|
|
if(serialDev)
|
|
{
|
|
tcflush(serialDev, TCIOFLUSH);
|
|
close(serialDev);
|
|
return 0;
|
|
}
|
|
else
|
|
return serialDev;
|
|
}
|
|
|
|
int reconfSerial(unsigned int baud, unsigned char flow, unsigned char tout)
|
|
{
|
|
if(serialDev > 0)
|
|
{
|
|
|
|
setBaud(baud);
|
|
setFlow(flow);
|
|
setTimeout(tout);
|
|
return tcsetattr(serialDev,TCSANOW,&term);
|
|
}
|
|
else
|
|
return serialDev;
|
|
}
|
|
|
|
#define XFERSIZE 16
|
|
|
|
int sendBuf(unsigned int len, char *buf)
|
|
{
|
|
unsigned int boff;
|
|
int ret;
|
|
|
|
if(serialDev > 0)
|
|
{
|
|
boff = 0;
|
|
while (boff < len)
|
|
{
|
|
ret = write (serialDev, buf+boff, MIN (len - boff, XFERSIZE));
|
|
if (ret < 0 && errno != EAGAIN)
|
|
{
|
|
perror ("error writing to serial port");
|
|
return 0;
|
|
}
|
|
boff += ret;
|
|
}
|
|
return boff;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int sendBufE(unsigned int len, char *buf)
|
|
{
|
|
return(getBuf(sendBuf(len,buf), buf));
|
|
}
|
|
|
|
int getBuf(unsigned int len, char *buf)
|
|
{
|
|
unsigned int boff;
|
|
int ret;
|
|
|
|
if(serialDev > 0)
|
|
{
|
|
boff = 0;
|
|
while (boff < len)
|
|
{
|
|
ret = read (serialDev, buf+boff, MIN (len - boff, XFERSIZE));
|
|
if (ret < 0 && errno != EAGAIN)
|
|
{
|
|
perror ("error reading from serial port");
|
|
return 0;
|
|
}
|
|
boff += ret;
|
|
}
|
|
return boff;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void setDTR(unsigned char val)
|
|
{
|
|
int mcs;
|
|
if(serialDev)
|
|
{
|
|
ioctl (serialDev, TIOCMGET, &mcs);
|
|
if(val)
|
|
{
|
|
mcs |= TIOCM_DTR;
|
|
ioctl (serialDev, TIOCMSET, &mcs);
|
|
}
|
|
else
|
|
{
|
|
mcs &= ~TIOCM_DTR;
|
|
ioctl (serialDev, TIOCMSET, &mcs);
|
|
}
|
|
}
|
|
}
|
|
|
|
void setRTS(unsigned char val)
|
|
{
|
|
int mcs;
|
|
if(serialDev)
|
|
{
|
|
ioctl (serialDev, TIOCMGET, &mcs);
|
|
if(val)
|
|
{
|
|
mcs |= TIOCM_RTS;
|
|
ioctl (serialDev, TIOCMSET, &mcs);
|
|
}
|
|
else
|
|
{
|
|
mcs &= ~TIOCM_RTS;
|
|
ioctl (serialDev, TIOCMSET, &mcs);
|
|
}
|
|
}
|
|
}
|
|
|