rendered paste body/* name:Comm.c
* desc:proc for serial port debug,loop back only
* author:Linxb
* history:
* 050723 first
*/
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <sys/types.h>
//#include <linux/types.h>
#include <string.h>
#include <limits.h>
#include <sys/time.h>
#include <errno.h>
/*desc:timeout 20 means 10 bits for data to send,and timeout for select()*/
#define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+2)
#define TIMEOUT_USEC 0
#define BUFFER_LEN 1024
#define u8 unsigned char
static int fd;
//static struct termios termios_old,termios_new;
static struct termios tm;
static fd_set fs_read,fs_write;
static struct timeval tv_timeout;
//static struct sigaction sigaction_io;
int open_com_port(char * str_com_port/*,int baudrate,int databit,const char *stopbit,char parity*/)
{
int retval = 0;
// printf("comm:open_com_port:start.\n");
fd = open(str_com_port,O_RDWR | O_NOCTTY | O_NONBLOCK);
if(fd == -1)
{
printf("comm:open_com_port:Err:could not open device file.\n");
return -1;
}
// printf("comm:open_com_port:[1]open file device ok!!fd = %d\n",fd);
// tcgetattr(fd,&termios_old);
// printf("comm:open_com_port:[2]save old termios attribute\n");
// we did not need to change the attribute here,but maybe someday we shuold
// implement it
/*set baud to 115200*/
/* tcgetattr(fd,&tm);
tm.c_iflag &= ~(INLCR|ICRNL|BRKINT|IXON);
tm.c_lflag &= ~(ECHONL|ECHO|IEXTEN|ISIG|ICANON);
tm.c_oflag &= ~(OPOST);
// tm.c_cc[VMIN] = TTY_MIN_READ_SIZE;
// tm.c_cc[VTIME] = TTY_RETURN_TIME;
cfsetispeed(&tm,B115200);
cfsetospeed(&tm,B115200);
tm.c_cflag &= ~(CSIZE);
tm.c_cflag |= CS8;
tm.c_cflag &= ~(PARENB);
// cfsetispeed(&tm,B9600);
// cfsetospeed(&tm,B9600);
// tm.c_cflag |= (CLOCAL | CREAD);
tcsetattr(fd,TCSANOW,&tm);
*/
//programming guide::
tcgetattr(fd,&tm);
tm.c_cflag |= (CLOCAL|CREAD);
tm.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG);
tm.c_oflag &= ~(OPOST);
tm.c_cc[VMIN] = 0;
tm.c_cc[VTIME] = 10;
cfsetispeed(&tm,B115200);
cfsetospeed(&tm,B115200);
tcsetattr(fd,TCSANOW,&tm);
//programming guide::
// printf("comm:open_com_port:[2]set baud to 115200.\n");
// printf("comm:open_com_port:quit.\n");
return retval;
}
void close_com_port()
{
/*maybe you can do some termios attribute here*/
close(fd);
// printf("comm:close_com_port:start and quit.\n");
}
int read_com_port(void * data,int data_len)
{
int retval = 0;
// printf("comm:read_com_port:start.\n");
FD_ZERO (&fs_read);
FD_SET (fd,&fs_read);
tv_timeout.tv_sec = TIMEOUT_SEC(data_len,115200);
tv_timeout.tv_usec = TIMEOUT_USEC;
// printf("comm:read_com_port:[1]initial fs ok and then call select.\n");
//Linxb::
// retval = select(fd+1,&fs_read,NULL,NULL,&tv_timeout);
// tv_timeout.tv_sec = 0;
// tv_timeout.tv_usec = 0;
retval = select(fd+1,&fs_read,NULL,NULL,&tv_timeout);
if(retval > 0) /*retval not 0 means some data in*/
{
// printf("comm:read_com_port:[2]read data from serial port.\n");
return(read(fd,data,data_len));
}else if(retval < 0)
{
printf("comm:read_com_port:Err:error while select read/\n");
return -1;
}else
{
// printf("comm:read_con_port:select return 0,means no data in.\n");
return 0;
}
}
int write_com_port(u8 * data,int data_len)
{
int retval=0,len=0,total_len=0;
// printf("comm:write_com_port:start\n");
FD_ZERO(&fs_write);
FD_SET(fd,&fs_write);
tv_timeout.tv_sec = TIMEOUT_SEC(data_len,115200);
tv_timeout.tv_usec = TIMEOUT_USEC;
// printf("comm:write_com_port:[1]initial fs_write ok!!\n");
for(total_len = 0 , len = 0 ; total_len < data_len;)
{
retval = select(fd+1,NULL,&fs_write,NULL,&tv_timeout);
printf("comm:write_com_port:[2]return from select and retval = %d\n",retval);
if(retval)
{
len = write(fd,&data[total_len],data_len-total_len);
if(len > 0)
{
printf("comm:write_com_port:[3]write to serial port ok,and len = %d\n",len);
total_len += len;
}
}else
{
tcflush(fd,TCOFLUSH); /*clean out buffer*/
break;
}
}
// printf("comm:write_com_port:write end total_len = %d\n",total_len);
return total_len;
}
int zwave_check(char *buf, int len)
{
int i;
char ret = (char) 0xff;
for (i = 0; buf && (i < len); i++)
ret ^= buf[i];
return ret;
}
int main(void)
{
int retval;
u8 buf_write[BUFFER_LEN],buf_read[BUFFER_LEN];
int proc_cnt = 0;
char *device = "/dev/ttyUSB0";
retval = open_com_port(device);
if (retval)
{
printf("failed to open %s\n", device);
return -1;
}
printf("please input data you want to send:\n");
while(1)
{
int i, len;
proc_cnt++;
printf("comm:proc_cnt = %d\n",proc_cnt);
Linxb:
buf_write[BUFFER_LEN-1] = 0;
len = 0;
buf_write[0] = 0x1; // Start code
buf_write[1] = 0; // lenght
for (i = 0; i < BUFFER_LEN - 2; i++)
{
unsigned int tmp;
scanf("%x", &tmp);
buf_write[i+2] = (char) (tmp & 0xff);
if (buf_write[i+2]==0xff)
{
len = i+3;
break;
}
}
if (len <= 3)
continue;
buf_write[1] = len - 2;
buf_write[len-1] = zwave_check(buf_write+1, buf_write[1]);
printf("comm:main:data in:");
for (i = 0; i < len; i++)
printf(" 0x%x", buf_write[i]);
printf("\n");
write_com_port(buf_write,len);
retval = read_com_port(buf_read,BUFFER_LEN);
if (retval <= 0)
continue;
printf("buf_read@%d: ", retval);
for (i = 0; i < len; i++)
printf(" 0x%x", buf_read[i]);
printf("\n");
buf_read[retval] = 0x00;
while(retval)
{
if (retval < 0)
{
printf("%s : %s : retval = %d\n" , __FILE__ , __FUNCTION__ , retval);
break;
}
else
{
printf("buf_read@%d: ", retval);
for (i = 0; i < len; i++)
printf(" 0x%x", buf_read[i]);
printf("\n");
tcflush(fd,TCIOFLUSH);
retval = read_com_port(buf_read,BUFFER_LEN);
}
}
sleep(1);
printf("please input data you want to send:\n");
}
}