Commit | Line | Data |
---|---|---|
9c66c9ff JM |
1 | #include <stdio.h> |
2 | #include <stdlib.h> | |
3 | #include <termios.h> | |
4 | #include <unistd.h> | |
5 | #include <sys/types.h> | |
6 | #include <sys/stat.h> | |
7 | #include <sys/ioctl.h> | |
8 | #include <fcntl.h> | |
9 | #include <string.h> | |
10 | #include <errno.h> | |
11 | ||
12 | #include "log.h" | |
13 | #include "serial.h" | |
14 | ||
15 | struct serial_port { | |
16 | int fd; | |
17 | }; | |
18 | ||
19 | static speed_t baud(int speed) | |
20 | { | |
21 | if (speed == 230400) return B230400; else | |
22 | if (speed == 115200) return B115200; else | |
23 | if (speed == 57600) return B57600; else | |
24 | if (speed == 38400) return B38400; else | |
25 | if (speed == 19200) return B19200; else | |
26 | if (speed == 9600) return B9600; else | |
27 | if (speed == 4800) return B4800; else | |
28 | if (speed == 2400) return B2400; else | |
29 | if (speed == 1200) return B1200; else { | |
30 | loge("Error setting baud rate: %d not recognised.", speed); | |
31 | return B0; | |
32 | } | |
33 | ||
34 | } | |
35 | ||
36 | port_t * serial_open(const char *name, int speed) | |
37 | { | |
38 | port_t *pt = NULL; | |
39 | int fd; | |
40 | ||
41 | if ((fd = open(name, O_RDWR | O_NOCTTY))<0) { | |
42 | loge("Error: opening %s: %s", name, strerror(errno)); | |
43 | return NULL; | |
44 | } | |
45 | ||
46 | struct termios adtio; | |
47 | bzero(&adtio, sizeof(adtio)); | |
48 | ||
49 | tcgetattr(fd, &adtio); | |
50 | adtio.c_cflag = CS8 | CLOCAL | CREAD; | |
51 | adtio.c_iflag = IGNPAR | IGNBRK; | |
52 | adtio.c_oflag = 0; | |
53 | adtio.c_lflag = 0; // non-canon, no echo | |
54 | ||
55 | cfmakeraw(&adtio); | |
56 | ||
57 | adtio.c_cc[VTIME] = 0; | |
58 | adtio.c_cc[VMIN] = 1; | |
59 | ||
60 | cfsetispeed(&adtio, baud(speed)); | |
61 | cfsetospeed(&adtio, baud(speed)); | |
62 | ||
63 | tcsetattr(fd, TCSANOW, &adtio); | |
64 | ||
65 | pt = malloc(sizeof(port_t)); | |
66 | pt->fd = fd; | |
67 | ||
68 | return pt; | |
69 | ||
70 | } | |
71 | ||
72 | void serial_close(port_t * pt) | |
73 | { | |
74 | if (pt == NULL) return; | |
75 | if (pt->fd < 0) return; | |
76 | ||
77 | close(pt->fd); | |
78 | pt->fd = -1; | |
79 | ||
80 | return; | |
81 | } | |
82 | ||
83 | int serial_read(port_t * pt, unsigned char * buff, size_t len) | |
84 | { | |
85 | if (pt == NULL || pt->fd < 0) return -1; | |
86 | ||
87 | int ret = 0; | |
88 | int count = 0; | |
89 | unsigned char * p = buff; | |
90 | while (count < len) { | |
91 | ret = read(pt->fd, p, len-count); | |
92 | if (ret <= 0) return ret; | |
93 | p += ret; | |
94 | count += ret; | |
95 | } | |
96 | return count; | |
97 | } | |
98 | ||
99 | int serial_write(port_t * pt, unsigned char * buff, size_t len) | |
100 | { | |
101 | if (pt == NULL || pt->fd < 0) return -1; | |
102 | ||
103 | return write(pt->fd, buff, len); | |
104 | } | |
105 | ||
106 | int serial_break(port_t * pt, int set) | |
107 | { | |
108 | if (pt == NULL || pt->fd < 0) return -1; | |
109 | ||
110 | if (set) | |
111 | ioctl(pt->fd, TIOCSBRK, 0); | |
112 | else | |
113 | ioctl(pt->fd, TIOCCBRK, 0); | |
114 | ||
115 | return 0; | |
116 | } | |
117 |