Initial import of the bootloader code
[bootloader] / cli / serial.c
CommitLineData
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
15struct serial_port {
16 int fd;
17};
18
19static 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
36port_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
72void 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
83int 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
99int 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
106int 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