/* name:Comm.c * desc:proc for serial port debug,loop back only * author:Linxb * history: * 050723 first */ #include #include #include #include #include #include //#include #include #include #include #include /*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"); } }