rs.c (3218B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <errno.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <termios.h> 6 #include <unistd.h> 7 #include <signal.h> 8 #include <ftdi.h> 9 #include "util.h" 10 11 static struct ftdi_context ftdictx; 12 static struct termios tio, savedtio; 13 14 static int bflag = 0; 15 static int vflag = 0; 16 static int pflag = 0; 17 18 static sig_atomic_t done = 0; 19 20 static void 21 interrupt(int sig) 22 { 23 done = 1; 24 } 25 26 static int 27 ttyinit(void) 28 { 29 long vdisable; 30 31 errno = 0; 32 vdisable = fpathconf(STDIN_FILENO, _PC_VDISABLE); 33 if (vdisable < 0) { 34 if (errno) 35 eprintf("fpathconf: _PC_VDISABLE:"); 36 vdisable = 0; 37 } 38 39 tcgetattr(STDIN_FILENO, &tio); 40 savedtio = tio; 41 cfmakeraw(&tio); 42 tio.c_cc[VMIN] = 0; 43 tio.c_cc[VTIME] = 0; 44 tio.c_lflag |= ISIG; 45 tio.c_cc[VQUIT] = CTRL('\\'); 46 tio.c_cc[VINTR] = vdisable; 47 tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio); 48 return 0; 49 } 50 51 static void 52 ttyrestore(void) 53 { 54 tcsetattr(STDIN_FILENO, TCSAFLUSH, &savedtio); 55 } 56 57 static int 58 txrxloop(void) 59 { 60 unsigned char buf[1]; 61 ssize_t n = 0; 62 63 while (!done) { 64 n = read(STDIN_FILENO, buf, sizeof(buf)); 65 if (n < 0 && errno == EINTR) 66 continue; 67 if (n > 0) { 68 n = ftdi_write_data(&ftdictx, buf, n); 69 if (n < 0) { 70 ttyrestore(); 71 enprintf(EXIT_FAILURE, "ftdi_write_data: write error: %s\n", 72 ftdi_get_error_string(&ftdictx)); 73 } 74 } 75 n = ftdi_read_data(&ftdictx, buf, sizeof(buf)); 76 if (n < 0) { 77 ttyrestore(); 78 enprintf(EXIT_FAILURE, "ftdi_read_data: read error: %s\n", 79 ftdi_get_error_string(&ftdictx)); 80 } 81 write(STDOUT_FILENO, buf, n); 82 } 83 return n; 84 } 85 86 static void 87 usage(void) 88 { 89 fprintf(stderr, "usage: %s [ -b baudrate ] [ -v vendorid ] [ -p productid ]\n", argv0); 90 fprintf(stderr, "\t-b\tSet baudrate\n"); 91 fprintf(stderr, "\t-v\tSpecify vendor, defaults to 0x0403\n"); 92 fprintf(stderr, "\t-p\tSpecify product, defaults to 0x6001\n"); 93 exit(EXIT_FAILURE); 94 } 95 96 int 97 main(int argc, char *argv[]) 98 { 99 struct sigaction sa; 100 int baudrate = 115200; 101 int ret; 102 int vendor = 0x0403; 103 int product = 0x6001; 104 105 ARGBEGIN { 106 case 'b': 107 bflag = 1; 108 baudrate = estrtol(EARGF(usage()), 10); 109 break; 110 case 'v': 111 vflag = 1; 112 vendor = estrtol(EARGF(usage()), 0); 113 break; 114 case 'p': 115 pflag = 1; 116 product = estrtol(EARGF(usage()), 0); 117 break; 118 default: 119 usage(); 120 } ARGEND; 121 122 if (!isatty(STDIN_FILENO)) 123 eprintf("isatty: stdin:"); 124 125 ret = ftdi_init(&ftdictx); 126 if (ret < 0) 127 enprintf(EXIT_FAILURE, "failed to initialize ftdi context\n"); 128 129 ret = ftdi_set_interface(&ftdictx, INTERFACE_ANY); 130 if (ret < 0) 131 enprintf(EXIT_FAILURE, "ftdi_set_interface: %s\n", 132 ftdi_get_error_string(&ftdictx)); 133 134 ret = ftdi_usb_open(&ftdictx, vendor, product); 135 if (ret < 0) 136 enprintf(EXIT_FAILURE, "ftdi_usb_open: %04x:%04x: %s\n", 137 vendor, product, ftdi_get_error_string(&ftdictx)); 138 139 ret = ftdi_set_baudrate(&ftdictx, baudrate); 140 if (ret < 0) 141 enprintf(EXIT_FAILURE, "ftdi_set_baudrate: %d: %s\n", 142 baudrate, ftdi_get_error_string(&ftdictx)); 143 144 printf("Break key is set to ^\\\n"); 145 146 sa.sa_handler = interrupt; 147 sigemptyset(&sa.sa_mask); 148 sa.sa_flags = SA_RESTART; 149 sigaction(SIGQUIT, &sa, NULL); 150 151 ttyinit(); 152 txrxloop(); 153 ttyrestore(); 154 putchar('\n'); 155 ftdi_usb_close(&ftdictx); 156 exit(EXIT_SUCCESS); 157 }