Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
uart_arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009 Antoine Drouin <poinix@gmail.com>
3  *
4  * This file is part of Paparazzi.
5  *
6  * Paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * Paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
26 #include BOARD_CONFIG
27 
28 #include "mcu_periph/uart.h"
29 
30 #include <stdint.h>
31 #include <unistd.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <errno.h>
36 
37 #include "serial_port.h"
38 #include "rt_priority.h"
39 
40 #include <pthread.h>
41 #include <sys/select.h>
42 
43 #ifndef UART_THREAD_PRIO
44 #define UART_THREAD_PRIO 11
45 #endif
46 
47 static void uart_receive_handler(struct uart_periph *periph);
48 static void *uart_thread(void *data __attribute__((unused)));
49 static pthread_mutex_t uart_mutex = PTHREAD_MUTEX_INITIALIZER;
50 
51 //#define TRACE(fmt,args...) fprintf(stderr, fmt, args)
52 #define TRACE(fmt,args...)
53 
54 void uart_arch_init(void)
55 {
56  pthread_mutex_init(&uart_mutex, NULL);
57 
58  pthread_t tid;
59  if (pthread_create(&tid, NULL, uart_thread, NULL) != 0) {
60  fprintf(stderr, "uart_arch_init: Could not create UART reading thread.\n");
61  return;
62  }
63 #ifndef __APPLE__
64  pthread_setname_np(tid, "uart");
65 #endif
66 }
67 
68 static void *uart_thread(void *data __attribute__((unused)))
69 {
71 
72  /* file descriptor list */
73  fd_set fds_master;
74  /* maximum file descriptor number */
75  int fdmax = 0;
76 
77  /* clear the fd list */
78  FD_ZERO(&fds_master);
79  /* add used fds */
80  int __attribute__((unused)) fd;
81 #if USE_UART0
82  if (uart0.reg_addr != NULL) {
83  fd = ((struct SerialPort *)uart0.reg_addr)->fd;
84  FD_SET(fd, &fds_master);
85  if (fd > fdmax) {
86  fdmax = fd;
87  }
88  }
89 #endif
90 #if USE_UART1
91  if (uart1.reg_addr != NULL) {
92  fd = ((struct SerialPort *)uart1.reg_addr)->fd;
93  FD_SET(fd, &fds_master);
94  if (fd > fdmax) {
95  fdmax = fd;
96  }
97  }
98 #endif
99 #if USE_UART2
100  if (uart2.reg_addr != NULL) {
101  fd = ((struct SerialPort *)uart2.reg_addr)->fd;
102  FD_SET(fd, &fds_master);
103  if (fd > fdmax) {
104  fdmax = fd;
105  }
106  }
107 #endif
108 #if USE_UART3
109  if (uart3.reg_addr != NULL) {
110  fd = ((struct SerialPort *)uart3.reg_addr)->fd;
111  FD_SET(fd, &fds_master);
112  if (fd > fdmax) {
113  fdmax = fd;
114  }
115  }
116 #endif
117 #if USE_UART4
118  if (uart4.reg_addr != NULL) {
119  fd = ((struct SerialPort *)uart4.reg_addr)->fd;
120  FD_SET(fd, &fds_master);
121  if (fd > fdmax) {
122  fdmax = fd;
123  }
124  }
125 #endif
126 #if USE_UART5
127  if (uart5.reg_addr != NULL) {
128  fd = ((struct SerialPort *)uart5.reg_addr)->fd;
129  FD_SET(fd, &fds_master);
130  if (fd > fdmax) {
131  fdmax = fd;
132  }
133  }
134 #endif
135 #if USE_UART6
136  if (uart6.reg_addr != NULL) {
137  fd = ((struct SerialPort *)uart6.reg_addr)->fd;
138  FD_SET(fd, &fds_master);
139  if (fd > fdmax) {
140  fdmax = fd;
141  }
142  }
143 #endif
144 #if USE_UART7
145  if (uart7.reg_addr != NULL) {
146  fd = ((struct SerialPort *)uart7.reg_addr)->fd;
147  FD_SET(fd, &fds_master);
148  if (fd > fdmax) {
149  fdmax = fd;
150  }
151  }
152 #endif
153 #if USE_UART8
154  if (uart8.reg_addr != NULL) {
155  fd = ((struct SerialPort *)uart8.reg_addr)->fd;
156  FD_SET(fd, &fds_master);
157  if (fd > fdmax) {
158  fdmax = fd;
159  }
160  }
161 #endif
162 
163  /* fds to be read, modified after each select */
164  fd_set fds;
165 
166  while (1) {
167  /* reset list of fds to check */
168  fds = fds_master;
169 
170  if (select(fdmax + 1, &fds, NULL, NULL, NULL) < 0) {
171  fprintf(stderr, "uart_thread: select failed!");
172  } else {
173 #if USE_UART0
174  if (uart0.reg_addr != NULL) {
175  fd = ((struct SerialPort *)uart0.reg_addr)->fd;
176  if (FD_ISSET(fd, &fds)) {
177  uart_receive_handler(&uart0);
178  }
179  }
180 #endif
181 #if USE_UART1
182  if (uart1.reg_addr != NULL) {
183  fd = ((struct SerialPort *)uart1.reg_addr)->fd;
184  if (FD_ISSET(fd, &fds)) {
185  uart_receive_handler(&uart1);
186  }
187  }
188 #endif
189 #if USE_UART2
190  if (uart2.reg_addr != NULL) {
191  fd = ((struct SerialPort *)uart2.reg_addr)->fd;
192  if (FD_ISSET(fd, &fds)) {
193  uart_receive_handler(&uart2);
194  }
195  }
196 #endif
197 #if USE_UART3
198  if (uart3.reg_addr != NULL) {
199  fd = ((struct SerialPort *)uart3.reg_addr)->fd;
200  if (FD_ISSET(fd, &fds)) {
201  uart_receive_handler(&uart3);
202  }
203  }
204 #endif
205 #if USE_UART4
206  if (uart4.reg_addr != NULL) {
207  fd = ((struct SerialPort *)uart4.reg_addr)->fd;
208  if (FD_ISSET(fd, &fds)) {
209  uart_receive_handler(&uart4);
210  }
211  }
212 #endif
213 #if USE_UART5
214  if (uart5.reg_addr != NULL) {
215  fd = ((struct SerialPort *)uart5.reg_addr)->fd;
216  if (FD_ISSET(fd, &fds)) {
217  uart_receive_handler(&uart5);
218  }
219  }
220 #endif
221 #if USE_UART6
222  if (uart6.reg_addr != NULL) {
223  fd = ((struct SerialPort *)uart6.reg_addr)->fd;
224  if (FD_ISSET(fd, &fds)) {
225  uart_receive_handler(&uart6);
226  }
227  }
228 #endif
229 #if USE_UART7
230  if (uart7.reg_addr != NULL) {
231  fd = ((struct SerialPort *)uart7.reg_addr)->fd;
232  if (FD_ISSET(fd, &fds)) {
233  uart_receive_handler(&uart7);
234  }
235  }
236 #endif
237 #if USE_UART8
238  if (uart8.reg_addr != NULL) {
239  fd = ((struct SerialPort *)uart8.reg_addr)->fd;
240  if (FD_ISSET(fd, &fds)) {
241  uart_receive_handler(&uart8);
242  }
243  }
244 #endif
245  }
246  }
247 
248  return 0;
249 }
250 
251 // open serial link
252 // close first if already openned
253 static void uart_periph_open(struct uart_periph *periph, uint32_t baud)
254 {
255  periph->baudrate = baud;
256 
257  struct SerialPort *port;
258  // close serial port if already open
259  if (periph->reg_addr != NULL) {
260  port = (struct SerialPort *)(periph->reg_addr);
261  serial_port_close(port);
262  serial_port_free(port);
263  }
264  // open serial port
265  port = serial_port_new();
266  // use register address to store SerialPort structure pointer...
267  periph->reg_addr = (void *)port;
268 
269  //TODO: set device name in application and pass as argument
270  // FIXME: paparazzi baud is 9600 for B9600 while open_raw needs 12 for B9600
271  // /printf("opening %s on uart0 at termios.h baud value=%d\n", periph->dev, baud);
272  int ret = serial_port_open_raw(port, periph->dev, baud);
273  if (ret != 0) {
274  TRACE("Error opening %s code %d\n", periph->dev, ret);
275  serial_port_free(port);
276  periph->reg_addr = NULL;
277  }
278 }
279 
281 {
282  periph->baudrate = baud;
283 
284  // open serial port if not done
285  if (periph->reg_addr == NULL) {
286  uart_periph_open(periph, baud);
287  }
288  if (periph->reg_addr == NULL) {
289  // periph not started, do nothiing
290  return;
291  }
292  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
293  serial_port_set_baudrate(port, baud);
294 }
295 
296 void uart_periph_set_bits_stop_parity(struct uart_periph *periph, uint8_t bits, uint8_t stop, uint8_t parity)
297 {
298  if (periph->reg_addr == NULL) {
299  // periph not started, do nothiing
300  return;
301  }
302  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
303  serial_port_set_bits_stop_parity(port, bits, stop, parity);
304 }
305 
306 void uart_put_byte(struct uart_periph *periph, long fd __attribute__((unused)), uint8_t data)
307 {
308  if (periph->reg_addr == NULL) { return; } // device not initialized ?
309 
310  /* write single byte to serial port */
311  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
312 
313  int ret = 0;
314  do {
315  ret = write((int)(port->fd), &data, 1);
316  } while (ret < 1 && errno == EAGAIN); //FIXME: max retry
317 
318  if (ret < 1) {
319  TRACE("uart_put_byte: write %d failed [%d: %s]\n", data, ret, strerror(errno));
320  }
321 }
322 
323 
324 static void __attribute__((unused)) uart_receive_handler(struct uart_periph *periph)
325 {
326  unsigned char c = 'D';
327 
328  if (periph->reg_addr == NULL) { return; } // device not initialized ?
329 
330  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
331  int fd = port->fd;
332 
333  pthread_mutex_lock(&uart_mutex);
334 
335  while (read(fd, &c, 1) > 0) {
336  uint16_t temp = (periph->rx_insert_idx + 1) % UART_RX_BUFFER_SIZE;
337  // check for more room in queue
338  if (temp != periph->rx_extract_idx) {
339  periph->rx_buf[periph->rx_insert_idx] = c;
340  periph->rx_insert_idx = temp; // update insert index
341  } else {
342  TRACE("uart_receive_handler: rx_buf full! discarding received byte: %x %c\n", c, c);
343  }
344  }
345  pthread_mutex_unlock(&uart_mutex);
346 }
347 
349 {
350  pthread_mutex_lock(&uart_mutex);
351  uint8_t ret = p->rx_buf[p->rx_extract_idx];
352  p->rx_extract_idx = (p->rx_extract_idx + 1) % UART_RX_BUFFER_SIZE;
353  pthread_mutex_unlock(&uart_mutex);
354  return ret;
355 }
356 
358 {
359  pthread_mutex_lock(&uart_mutex);
360  int available = p->rx_insert_idx - p->rx_extract_idx;
361  if (available < 0) {
362  available += UART_RX_BUFFER_SIZE;
363  }
364  pthread_mutex_unlock(&uart_mutex);
365  return available;
366 }
367 
368 #if USE_UART0
369 void uart0_init(void)
370 {
371  uart_periph_init(&uart0);
372  strncpy(uart0.dev, STRINGIFY(UART0_DEV), UART_DEV_NAME_SIZE);
373  uart_periph_set_baudrate(&uart0, UART0_BAUD);
374 }
375 #endif /* USE_UART0 */
376 
377 #if USE_UART1
378 void uart1_init(void)
379 {
380  uart_periph_init(&uart1);
381  strncpy(uart1.dev, STRINGIFY(UART1_DEV), UART_DEV_NAME_SIZE);
382  uart_periph_set_baudrate(&uart1, UART1_BAUD);
383 }
384 #endif /* USE_UART1 */
385 
386 #if USE_UART2
387 void uart2_init(void)
388 {
389  uart_periph_init(&uart2);
390  strncpy(uart2.dev, STRINGIFY(UART2_DEV), UART_DEV_NAME_SIZE);
391  uart_periph_set_baudrate(&uart2, UART2_BAUD);
392 }
393 #endif /* USE_UART2 */
394 
395 #if USE_UART3
396 void uart3_init(void)
397 {
398  uart_periph_init(&uart3);
399  strncpy(uart3.dev, STRINGIFY(UART3_DEV), UART_DEV_NAME_SIZE);
400  uart_periph_set_baudrate(&uart3, UART3_BAUD);
401 }
402 #endif /* USE_UART3 */
403 
404 #if USE_UART4
405 void uart4_init(void)
406 {
407  uart_periph_init(&uart4);
408  strncpy(uart4.dev, STRINGIFY(UART4_DEV), UART_DEV_NAME_SIZE);
409  uart_periph_set_baudrate(&uart4, UART4_BAUD);
410 }
411 #endif /* USE_UART4 */
412 
413 #if USE_UART5
414 void uart5_init(void)
415 {
416  uart_periph_init(&uart5);
417  strncpy(uart5.dev, STRINGIFY(UART5_DEV), UART_DEV_NAME_SIZE);
418  uart_periph_set_baudrate(&uart5, UART5_BAUD);
419 }
420 #endif /* USE_UART5 */
421 
422 #if USE_UART6
423 void uart6_init(void)
424 {
425  uart_periph_init(&uart6);
426  strncpy(uart6.dev, STRINGIFY(UART6_DEV), UART_DEV_NAME_SIZE);
427  uart_periph_set_baudrate(&uart6, UART6_BAUD);
428 }
429 #endif /* USE_UART6 */
430 
431 #if USE_UART7
432 void uart7_init(void)
433 {
434  uart_periph_init(&uart7);
435  strncpy(uart7.dev, STRINGIFY(UART7_DEV), UART_DEV_NAME_SIZE);
436  uart_periph_set_baudrate(&uart7, UART7_BAUD);
437 }
438 #endif /* USE_UART7 */
439 
440 #if USE_UART8
441 void uart8_init(void)
442 {
443  uart_periph_init(&uart8);
444  strncpy(uart8.dev, STRINGIFY(UART8_DEV), UART_DEV_NAME_SIZE);
445  uart_periph_set_baudrate(&uart8, UART8_BAUD);
446 }
447 #endif /* USE_UART8 */
#define UART1_DEV
Definition: ardrone2.h:7
#define UART2_DEV
#define UART4_DEV
#define UART5_DEV
Definition: bebop.h:46
#define UART6_DEV
Definition: bebop.h:49
#define UART3_DEV
uart connected to SBUS input
Definition: disco.h:52
static float p[2][2]
void uart_put_byte(struct uart_periph *periph, long fd, uint8_t data)
Definition: uart_arch.c:306
#define TRACE(fmt, args...)
Definition: uart_arch.c:52
static void uart_receive_handler(struct uart_periph *periph)
Definition: uart_arch.c:324
int uart_char_available(struct uart_periph *p)
Check UART for available chars in receive buffer.
Definition: uart_arch.c:357
static void * uart_thread(void *data)
Definition: uart_arch.c:68
void uart_arch_init(void)
Definition: uart_arch.c:54
void uart_periph_set_bits_stop_parity(struct uart_periph *periph, uint8_t bits, uint8_t stop, uint8_t parity)
Definition: uart_arch.c:296
static void uart_periph_open(struct uart_periph *periph, uint32_t baud)
Definition: uart_arch.c:253
static pthread_mutex_t uart_mutex
Definition: uart_arch.c:49
uint8_t uart_getch(struct uart_periph *p)
Definition: uart_arch.c:348
void uart_periph_set_baudrate(struct uart_periph *periph, uint32_t baud)
Definition: uart_arch.c:280
#define UART_THREAD_PRIO
Definition: uart_arch.c:44
#define UART_RX_BUFFER_SIZE
Definition: uart_arch.h:31
Functions to obtain rt priority or set the nice level.
static int get_rt_prio(int prio)
Definition: rt_priority.h:32
int fd
Definition: serial.c:26
void serial_port_free(struct SerialPort *me)
Definition: serial_port.c:80
void serial_port_close(struct SerialPort *me)
Definition: serial_port.c:184
int serial_port_open_raw(struct SerialPort *me, const char *device, speed_t speed)
Definition: serial_port.c:111
int serial_port_set_bits_stop_parity(struct SerialPort *me, const int bits, const int stop, const int parity)
Definition: serial_port.c:224
struct SerialPort * serial_port_new(void)
Definition: serial_port.c:74
int serial_port_set_baudrate(struct SerialPort *me, speed_t speed)
Definition: serial_port.c:210
void uart_periph_init(struct uart_periph *p)
Definition: uart.c:231
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
uint16_t rx_insert_idx
Definition: uart.h:75
#define UART_DEV_NAME_SIZE
Definition: uart.h:53
char dev[UART_DEV_NAME_SIZE]
UART Dev (linux)
Definition: uart.h:89
uint16_t rx_extract_idx
Definition: uart.h:76
uint8_t rx_buf[UART_RX_BUFFER_SIZE]
Receive buffer.
Definition: uart.h:74
int baudrate
UART Baudrate.
Definition: uart.h:85
void * reg_addr
UART Register.
Definition: uart.h:83
UART peripheral.
Definition: uart.h:72
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98