Paparazzi UAS  v5.14.0_stable-0-g3f680d1
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 
145  /* fds to be read, modified after each select */
146  fd_set fds;
147 
148  while (1) {
149  /* reset list of fds to check */
150  fds = fds_master;
151 
152  if (select(fdmax + 1, &fds, NULL, NULL, NULL) < 0) {
153  fprintf(stderr, "uart_thread: select failed!");
154  } else {
155 #if USE_UART0
156  if (uart0.reg_addr != NULL) {
157  fd = ((struct SerialPort *)uart0.reg_addr)->fd;
158  if (FD_ISSET(fd, &fds)) {
159  uart_receive_handler(&uart0);
160  }
161  }
162 #endif
163 #if USE_UART1
164  if (uart1.reg_addr != NULL) {
165  fd = ((struct SerialPort *)uart1.reg_addr)->fd;
166  if (FD_ISSET(fd, &fds)) {
167  uart_receive_handler(&uart1);
168  }
169  }
170 #endif
171 #if USE_UART2
172  if (uart2.reg_addr != NULL) {
173  fd = ((struct SerialPort *)uart2.reg_addr)->fd;
174  if (FD_ISSET(fd, &fds)) {
175  uart_receive_handler(&uart2);
176  }
177  }
178 #endif
179 #if USE_UART3
180  if (uart3.reg_addr != NULL) {
181  fd = ((struct SerialPort *)uart3.reg_addr)->fd;
182  if (FD_ISSET(fd, &fds)) {
183  uart_receive_handler(&uart3);
184  }
185  }
186 #endif
187 #if USE_UART4
188  if (uart4.reg_addr != NULL) {
189  fd = ((struct SerialPort *)uart4.reg_addr)->fd;
190  if (FD_ISSET(fd, &fds)) {
191  uart_receive_handler(&uart4);
192  }
193  }
194 #endif
195 #if USE_UART5
196  if (uart5.reg_addr != NULL) {
197  fd = ((struct SerialPort *)uart5.reg_addr)->fd;
198  if (FD_ISSET(fd, &fds)) {
199  uart_receive_handler(&uart5);
200  }
201  }
202 #endif
203 #if USE_UART6
204  if (uart6.reg_addr != NULL) {
205  fd = ((struct SerialPort *)uart6.reg_addr)->fd;
206  if (FD_ISSET(fd, &fds)) {
207  uart_receive_handler(&uart6);
208  }
209  }
210 #endif
211  }
212  }
213 
214  return 0;
215 }
216 
217 // open serial link
218 // close first if already openned
219 static void uart_periph_open(struct uart_periph *periph, uint32_t baud)
220 {
221  periph->baudrate = baud;
222 
223  struct SerialPort *port;
224  // close serial port if already open
225  if (periph->reg_addr != NULL) {
226  port = (struct SerialPort *)(periph->reg_addr);
227  serial_port_close(port);
228  serial_port_free(port);
229  }
230  // open serial port
231  port = serial_port_new();
232  // use register address to store SerialPort structure pointer...
233  periph->reg_addr = (void *)port;
234 
235  //TODO: set device name in application and pass as argument
236  // FIXME: paparazzi baud is 9600 for B9600 while open_raw needs 12 for B9600
237  // /printf("opening %s on uart0 at termios.h baud value=%d\n", periph->dev, baud);
238  int ret = serial_port_open_raw(port, periph->dev, baud);
239  if (ret != 0) {
240  TRACE("Error opening %s code %d\n", periph->dev, ret);
241  serial_port_free(port);
242  periph->reg_addr = NULL;
243  }
244 }
245 
247 {
248  periph->baudrate = baud;
249 
250  // open serial port if not done
251  if (periph->reg_addr == NULL) {
252  uart_periph_open(periph, baud);
253  }
254  if (periph->reg_addr == NULL) {
255  // periph not started, do nothiing
256  return;
257  }
258  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
259  serial_port_set_baudrate(port, baud);
260 }
261 
262 void uart_periph_set_bits_stop_parity(struct uart_periph *periph, uint8_t bits, uint8_t stop, uint8_t parity)
263 {
264  if (periph->reg_addr == NULL) {
265  // periph not started, do nothiing
266  return;
267  }
268  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
269  serial_port_set_bits_stop_parity(port, bits, stop, parity);
270 }
271 
272 void uart_put_byte(struct uart_periph *periph, long fd __attribute__((unused)), uint8_t data)
273 {
274  if (periph->reg_addr == NULL) { return; } // device not initialized ?
275 
276  /* write single byte to serial port */
277  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
278 
279  int ret = 0;
280  do {
281  ret = write((int)(port->fd), &data, 1);
282  } while (ret < 1 && errno == EAGAIN); //FIXME: max retry
283 
284  if (ret < 1) {
285  TRACE("uart_put_byte: write %d failed [%d: %s]\n", data, ret, strerror(errno));
286  }
287 }
288 
289 
290 static void __attribute__((unused)) uart_receive_handler(struct uart_periph *periph)
291 {
292  unsigned char c = 'D';
293 
294  if (periph->reg_addr == NULL) { return; } // device not initialized ?
295 
296  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
297  int fd = port->fd;
298 
299  pthread_mutex_lock(&uart_mutex);
300 
301  if (read(fd, &c, 1) > 0) {
302  //printf("r %x %c\n",c,c);
303  uint16_t temp = (periph->rx_insert_idx + 1) % UART_RX_BUFFER_SIZE;
304  // check for more room in queue
305  if (temp != periph->rx_extract_idx) {
306  periph->rx_buf[periph->rx_insert_idx] = c;
307  periph->rx_insert_idx = temp; // update insert index
308  } else {
309  TRACE("uart_receive_handler: rx_buf full! discarding received byte: %x %c\n", c, c);
310  }
311  }
312  pthread_mutex_unlock(&uart_mutex);
313 }
314 
316 {
317  pthread_mutex_lock(&uart_mutex);
318  uint8_t ret = p->rx_buf[p->rx_extract_idx];
320  pthread_mutex_unlock(&uart_mutex);
321  return ret;
322 }
323 
325 {
326  pthread_mutex_lock(&uart_mutex);
327  int16_t available = p->rx_insert_idx - p->rx_extract_idx;
328  if (available < 0) {
329  available += UART_RX_BUFFER_SIZE;
330  }
331  pthread_mutex_unlock(&uart_mutex);
332  return (uint16_t)available;
333 }
334 
335 #if USE_UART0
336 void uart0_init(void)
337 {
338  uart_periph_init(&uart0);
339  strncpy(uart0.dev, STRINGIFY(UART0_DEV), UART_DEV_NAME_SIZE);
340  uart_periph_set_baudrate(&uart0, UART0_BAUD);
341 }
342 #endif /* USE_UART0 */
343 
344 #if USE_UART1
345 void uart1_init(void)
346 {
347  uart_periph_init(&uart1);
348  strncpy(uart1.dev, STRINGIFY(UART1_DEV), UART_DEV_NAME_SIZE);
349  uart_periph_set_baudrate(&uart1, UART1_BAUD);
350 }
351 #endif /* USE_UART1 */
352 
353 #if USE_UART2
354 void uart2_init(void)
355 {
356  uart_periph_init(&uart2);
357  strncpy(uart2.dev, STRINGIFY(UART2_DEV), UART_DEV_NAME_SIZE);
358  uart_periph_set_baudrate(&uart2, UART2_BAUD);
359 }
360 #endif /* USE_UART2 */
361 
362 #if USE_UART3
363 void uart3_init(void)
364 {
365  uart_periph_init(&uart3);
366  strncpy(uart3.dev, STRINGIFY(UART3_DEV), UART_DEV_NAME_SIZE);
367  uart_periph_set_baudrate(&uart3, UART3_BAUD);
368 }
369 #endif /* USE_UART3 */
370 
371 #if USE_UART4
372 void uart4_init(void)
373 {
374  uart_periph_init(&uart4);
375  strncpy(uart4.dev, STRINGIFY(UART4_DEV), UART_DEV_NAME_SIZE);
376  uart_periph_set_baudrate(&uart4, UART4_BAUD);
377 }
378 #endif /* USE_UART4 */
379 
380 #if USE_UART5
381 void uart5_init(void)
382 {
383  uart_periph_init(&uart5);
384  strncpy(uart5.dev, STRINGIFY(UART5_DEV), UART_DEV_NAME_SIZE);
385  uart_periph_set_baudrate(&uart5, UART5_BAUD);
386 }
387 #endif /* USE_UART5 */
388 
389 #if USE_UART6
390 void uart6_init(void)
391 {
392  uart_periph_init(&uart6);
393  strncpy(uart6.dev, STRINGIFY(UART6_DEV), UART_DEV_NAME_SIZE);
394  uart_periph_set_baudrate(&uart6, UART6_BAUD);
395 }
396 #endif /* USE_UART6 */
unsigned short uint16_t
Definition: types.h:16
#define UART_DEV_NAME_SIZE
Definition: uart.h:51
uint8_t rx_buf[UART_RX_BUFFER_SIZE]
Receive buffer.
Definition: uart.h:72
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
#define UART3_DEV
uart connected to SBUS input
Definition: disco.h:57
void uart_periph_set_baudrate(struct uart_periph *p, uint32_t baud)
Set baudrate.
Definition: uart_arch.c:856
#define TRACE(fmt, args...)
Definition: uart_arch.c:52
uint8_t uart_getch(struct uart_periph *p)
Definition: uart_arch.c:840
#define UART4_DEV
int serial_port_set_bits_stop_parity(struct SerialPort *me, const int bits, const int stop, const int parity)
Definition: serial_port.c:221
uint16_t uart_char_available(struct uart_periph *p)
Check UART for available chars in receive buffer.
Definition: uart_arch.c:324
#define UART1_DEV
Definition: ardrone2.h:7
#define UART_RX_BUFFER_SIZE
Definition: uart_arch.h:31
void * reg_addr
UART Register.
Definition: uart.h:81
Functions to obtain rt priority or set the nice level.
void serial_port_free(struct SerialPort *me)
Definition: serial_port.c:80
void uart_arch_init(void)
Definition: uart_arch.c:54
static void * uart_thread(void *data)
Definition: uart_arch.c:68
uint16_t rx_insert_idx
Definition: uart.h:73
#define UART_THREAD_PRIO
Definition: uart_arch.c:44
UART peripheral.
Definition: uart.h:70
static void uart_receive_handler(struct uart_periph *periph)
Definition: uart_arch.c:290
void uart_periph_init(struct uart_periph *p)
Definition: uart.c:231
unsigned long uint32_t
Definition: types.h:18
static void uart_periph_open(struct uart_periph *periph, uint32_t baud)
Definition: uart_arch.c:219
signed short int16_t
Definition: types.h:17
#define UART6_DEV
Definition: bebop.h:50
uint16_t rx_extract_idx
Definition: uart.h:74
#define UART2_DEV
void uart_put_byte(struct uart_periph *p, long fd, uint8_t data)
Uart transmit implementation.
Definition: uart_arch.c:967
unsigned char uint8_t
Definition: types.h:14
char dev[UART_DEV_NAME_SIZE]
UART Dev (linux)
Definition: uart.h:87
void uart_periph_set_bits_stop_parity(struct uart_periph *p, uint8_t bits, uint8_t stop, uint8_t parity)
Set parity and stop bits.
Definition: uart_arch.c:885
struct SerialPort * serial_port_new(void)
Definition: serial_port.c:74
void serial_port_close(struct SerialPort *me)
Definition: serial_port.c:181
int fd
Definition: serial.c:26
int serial_port_open_raw(struct SerialPort *me, const char *device, speed_t speed)
Definition: serial_port.c:111
int baudrate
UART Baudrate.
Definition: uart.h:83
static float p[2][2]
static int get_rt_prio(int prio)
Definition: rt_priority.h:32
int serial_port_set_baudrate(struct SerialPort *me, speed_t speed)
Definition: serial_port.c:207
static pthread_mutex_t uart_mutex
Definition: uart_arch.c:49
#define UART5_DEV
Definition: bebop.h:47