hi3516 uart1 485
原文链接: hi3516 uart1 485
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <stdlib.h>
#define RS485_DEV "/dev/ttyAMA1"
CRS485::CRS485()
{
hasRs485Inited = false;
mFd = -1;
}
CRS485::~CRS485()
{
DEBUG_INFO(DEV_MNG, "RS485 exit");
if( mFd != -1 )
{
close( mFd );
}
hasRs485Inited = false;
}
int CRS485::setRS485(int band, int stopBit, int parity, int dataBit)
{
int status = -1;
struct termios options;
tcgetattr( mFd, &options );
tcflush( mFd, TCIOFLUSH ); // discard data written to RS485 that hasn't not been transmitted
// set band rate
switch( band )
{
case 1200:
cfsetispeed( &options, B1200 );
cfsetospeed( &options, B1200 );
break;
case 2400:
cfsetispeed( &options, B2400 );
cfsetospeed( &options, B2400 );
break;
case 4800:
cfsetispeed( &options, B4800 );
cfsetospeed( &options, B4800 );
break;
case 9600:
cfsetispeed( &options, B9600 );
cfsetospeed( &options, B9600 );
break;
case 19200:
cfsetispeed( &options, B19200 );
cfsetospeed( &options, B19200 );
break;
case 38400:
cfsetispeed( &options, B38400 );
cfsetospeed( &options, B38400 );
break;
case 57600:
cfsetispeed( &options, B57600 );
cfsetospeed( &options, B57600 );
break;
default:
DEBUG_ERROR(DEV_MNG, "Band rate:%d is not supported, now use 9600", band);
cfsetispeed( &options, B9600 );
cfsetospeed( &options, B9600 );
break;
}
status = tcsetattr( mFd, TCSANOW, &options );
if( status != 0 )
{
DEBUG_API_ERROR( DEV_MNG, "tcsetattr(TCSANOW)");
return -1;
}
tcflush( mFd, TCIOFLUSH );
status = tcgetattr( mFd, &options );
if( status < 0 )
{
DEBUG_API_ERROR( DEV_MNG, "tcgetattr()");
return -1;
}
// set data bits
options.c_cflag &= (~CSIZE);
switch( dataBit )
{
case 5:
options.c_cflag |= CS5;
break;
case 6:
options.c_cflag |= CS6;
break;
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
DEBUG_ERROR(DEV_MNG, "Unsupported data bits(%d)", dataBit);
return -1;
break;
}
// set parity
switch( parity )
{
case 0: // None
options.c_cflag &= (~PARENB);
options.c_iflag &= (~INPCK);
break;
case 1: // ODD
options.c_cflag |= (PARODD | PARENB);
options.c_iflag |= INPCK;
break;
case 2: // Even
options.c_cflag |= PARENB;
options.c_cflag &= (~PARODD);
options.c_iflag |= INPCK;
break;
default:
DEBUG_ERROR(DEV_MNG, "Unsupported parity type:%d", parity);
return -1;
break;
}
// set stop bits
switch( stopBit )
{
case 1:
options.c_cflag &= (~CSTOPB);
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
DEBUG_ERROR(DEV_MNG, "Unsupported stop bits:%d", stopBit);
return -1;
break;
}
/* Set input parity option */
if (parity != 0)
options.c_iflag |= INPCK;
/* Set Raw Mode */
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
options.c_oflag &= ~OPOST; /*Output*/
tcflush( mFd, TCIFLUSH );
options.c_cc[VTIME] = 150;
options.c_cc[VMIN] = 7;
status = tcsetattr( mFd, TCSANOW, &options );
if( status != 0 )
{
DEBUG_API_ERROR(DEV_MNG, "tcsetattr()");
return -1;
}
return 0;
}
int CRS485::init(int band, int stopBit, int parity, int dataBit)
{
if( hasRs485Inited )
{
DEBUG_ERROR(DEV_MNG, "RS485 has been inited");
return -1;
}
int ret = -1;
// open device
mFd = open( RS485_DEV, O_RDWR );
if( mFd < 0 )
{
DEBUG_API_ERROR(DEV_MNG, "open()");
return -1;
}
ret = setRS485(band, stopBit, parity, dataBit);
if(ret == -1)
goto ERROR;
// success
hasRs485Inited = 1;
DEBUG_INFO(DEV_MNG, "RS485 init success");
return 0;
ERROR:
close( mFd );
return -1;
}
int CRS485::sendData(char *data, int dataLen)
{
if( data == NULL )
return -1;
if( dataLen <= 0 )
return -1;
if( hasRs485Inited != 1 )
{
DEBUG_ERROR(DEV_MNG, "Can't send 485 data before inited");
return -1;
}
return write( mFd, data, dataLen );
}
int CRS485::recvData(char *data, int dataLen, int maxWaitTime)
{
if( data == NULL )
return -1;
if( dataLen <= 0 )
return -1;
if( hasRs485Inited != 1 )
{
DEBUG_ERROR(DEV_MNG, "Can't recv 485 data before inited");
return -1;
}
int index = 0;
int rc = 0;
int rcnum = dataLen;
struct timeval tv;
fd_set readfd;
tv.tv_sec = maxWaitTime / 1000;
tv.tv_usec = maxWaitTime % 1000 * 1000;
FD_ZERO(&readfd);
FD_SET(mFd, &readfd);
rc = select(mFd + 1, &readfd, NULL, NULL, &tv);
if(rc > 0)
{
while(dataLen)
{
rc = read(mFd, &data[index], 1);
if(rc > 0)
index = index + 1;
dataLen = dataLen - 1;
}
if(index != rcnum)
return -1;
return rcnum;
}
else
{
return -1;
}
return -1;
//return read( mFd, data, dataLen );
}