Paparazzi UAS  v5.2.2_stable-0-gd6b9f29
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
serial_port.c
Go to the documentation of this file.
1 #include "serial_port.h"
2 
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <fcntl.h>
6 #include <errno.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 
12 //#define TRACE(type,fmt,args...) fprintf(stderr, fmt, args)
13 #define TRACE(type,fmt,args...)
14 #define TRACE_ERROR 1
15 
16 struct SerialPort* serial_port_new(void) {
17  struct SerialPort* me = malloc(sizeof(struct SerialPort));
18  return me;
19 }
20 
21 void serial_port_free(struct SerialPort* me) {
22  free(me);
23 }
24 
25 
26 void serial_port_flush(struct SerialPort* me) {
27  /*
28  * flush any input that might be on the port so we start fresh.
29  */
30  if (tcflush(me->fd, TCIFLUSH)) {
31  TRACE(TRACE_ERROR,"%s, set term attr failed: %s (%d)\n", "", strerror(errno), errno);
32  fprintf(stderr, "flush (%d) failed: %s (%d)\n", me->fd, strerror(errno), errno);
33  }
34 }
35 
37  /*
38  * flush any input that might be on the port so we start fresh.
39  */
40  if (tcflush(me->fd, TCOFLUSH)) {
41  TRACE(TRACE_ERROR,"%s, set term attr failed: %s (%d)\n", "", strerror(errno), errno);
42  fprintf(stderr, "flush (%d) failed: %s (%d)\n", me->fd, strerror(errno), errno);
43  }
44 }
45 
46 int serial_port_open_raw(struct SerialPort* me, const char* device, speed_t speed) {
47  if ((me->fd = open(device, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
48  TRACE(TRACE_ERROR,"%s, open failed: %s (%d)\n", device, strerror(errno), errno);
49  return -1;
50  }
51  if (tcgetattr(me->fd, &me->orig_termios) < 0) {
52  TRACE(TRACE_ERROR,"%s, get term settings failed: %s (%d)\n", device, strerror(errno), errno);
53  close(me->fd);
54  return -1;
55  }
56  me->cur_termios = me->orig_termios;
57  /* input modes */
58  me->cur_termios.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INPCK|ISTRIP|INLCR|IGNCR
59  |ICRNL |IUCLC|IXON|IXANY|IXOFF|IMAXBEL);
60  me->cur_termios.c_iflag |= IGNPAR;
61  /* control modes*/
62  me->cur_termios.c_cflag &= ~(CSIZE|PARENB|CRTSCTS|PARODD|HUPCL|CSTOPB);
63  me->cur_termios.c_cflag |= CREAD|CS8|CLOCAL;
64  /* local modes */
65  me->cur_termios.c_lflag &= ~(ISIG|ICANON|IEXTEN|ECHO|FLUSHO|PENDIN);
66  me->cur_termios.c_lflag |= NOFLSH;
67  if (cfsetispeed(&me->cur_termios, speed)) {
68  TRACE(TRACE_ERROR,"%s, set term speed failed: %s (%d)\n", device, strerror(errno), errno);
69  close(me->fd);
70  return -1;
71  }
72  if (tcsetattr(me->fd, TCSADRAIN, &me->cur_termios)) {
73  TRACE(TRACE_ERROR,"%s, set term attr failed: %s (%d)\n", device, strerror(errno), errno);
74  close(me->fd);
75  return -1;
76  }
78  return 0;
79 }
80 
81 int serial_port_open(struct SerialPort* me, const char* device,
82  void(*term_conf_callback)(struct termios*, speed_t*)) {
83 
84  speed_t speed;
85  if ((me->fd = open(device, O_RDWR | O_NONBLOCK)) < 0) {
86  TRACE(TRACE_ERROR,"%s, open failed: %s (%d)\n", device, strerror(errno), errno);
87  return -1;
88  }
89  if (tcgetattr(me->fd, &me->orig_termios) < 0) {
90  TRACE(TRACE_ERROR,"%s, get term settings failed: %s (%d)\n", device, strerror(errno), errno);
91  close(me->fd);
92  return -1;
93  }
94  me->cur_termios = me->orig_termios;
95  term_conf_callback(&me->cur_termios, &speed);
96  if (cfsetispeed(&me->cur_termios, speed)) {
97  TRACE(TRACE_ERROR,"%s, set term speed failed: %s (%d)\n", device, strerror(errno), errno);
98  close(me->fd);
99  return -1;
100  }
101  if (tcsetattr(me->fd, TCSADRAIN, &me->cur_termios)) {
102  TRACE(TRACE_ERROR,"%s, set term attr failed: %s (%d)\n", device, strerror(errno), errno);
103  close(me->fd);
104  return -1;
105  }
106  serial_port_flush(me);
107  return 0;
108 
109 }
110 
111 void serial_port_close(struct SerialPort* me) {
112 
113  /* if null pointer or file descriptor indicates error just bail */
114  if (!me || me->fd < 0)
115  return;
116  if (tcflush(me->fd, TCIOFLUSH)) {
117  TRACE(TRACE_ERROR,"flushing (%s) (%d)\n", strerror(errno), errno);
118  close(me->fd);
119  return;
120  }
121  if (tcsetattr(me->fd, TCSADRAIN, &me->orig_termios)) { // Restore modes.
122  TRACE(TRACE_ERROR,"restoring term attributes (%s) (%d)\n", strerror(errno), errno);
123  close(me->fd);
124  return;
125  }
126  if (close(me->fd)) {
127  TRACE(TRACE_ERROR,"closing %s (%d)\n", strerror(errno), errno);
128  return;
129  }
130  return;
131 
132 
133 }
void serial_port_flush_output(struct SerialPort *me)
Definition: serial_port.c:36
#define TRACE(type, fmt, args...)
Definition: serial_port.c:13
void serial_port_flush(struct SerialPort *me)
Definition: serial_port.c:26
struct termios orig_termios
Definition: serial_port.h:30
void serial_port_free(struct SerialPort *me)
Definition: serial_port.c:21
struct termios cur_termios
Definition: serial_port.h:31
struct SerialPort * serial_port_new(void)
Definition: serial_port.c:16
void serial_port_close(struct SerialPort *me)
Definition: serial_port.c:111
int serial_port_open_raw(struct SerialPort *me, const char *device, speed_t speed)
Definition: serial_port.c:46
int serial_port_open(struct SerialPort *me, const char *device, void(*term_conf_callback)(struct termios *, speed_t *))
Definition: serial_port.c:81
#define TRACE_ERROR
Definition: serial_port.c:14