Paparazzi UAS  v5.12_stable-4-g9b43e9b
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 }
64 
65 static void *uart_thread(void *data __attribute__((unused)))
66 {
68 
69  /* file descriptor list */
70  fd_set fds_master;
71  /* maximum file descriptor number */
72  int fdmax = 0;
73 
74  /* clear the fd list */
75  FD_ZERO(&fds_master);
76  /* add used fds */
77  int __attribute__ ((unused)) fd;
78 #if USE_UART0
79  if (uart0.reg_addr != NULL) {
80  fd = ((struct SerialPort *)uart0.reg_addr)->fd;
81  FD_SET(fd, &fds_master);
82  if (fd > fdmax) {
83  fdmax =fd;
84  }
85  }
86 #endif
87 #if USE_UART1
88  if (uart1.reg_addr != NULL) {
89  fd = ((struct SerialPort *)uart1.reg_addr)->fd;
90  FD_SET(fd, &fds_master);
91  if (fd > fdmax) {
92  fdmax =fd;
93  }
94  }
95 #endif
96 #if USE_UART2
97  if (uart2.reg_addr != NULL) {
98  fd = ((struct SerialPort *)uart2.reg_addr)->fd;
99  FD_SET(fd, &fds_master);
100  if (fd > fdmax) {
101  fdmax =fd;
102  }
103  }
104 #endif
105 #if USE_UART3
106  if (uart3.reg_addr != NULL) {
107  fd = ((struct SerialPort *)uart3.reg_addr)->fd;
108  FD_SET(fd, &fds_master);
109  if (fd > fdmax) {
110  fdmax =fd;
111  }
112  }
113 #endif
114 #if USE_UART4
115  if (uart4.reg_addr != NULL) {
116  fd = ((struct SerialPort *)uart4.reg_addr)->fd;
117  FD_SET(fd, &fds_master);
118  if (fd > fdmax) {
119  fdmax =fd;
120  }
121  }
122 #endif
123 #if USE_UART5
124  if (uart5.reg_addr != NULL) {
125  fd = ((struct SerialPort *)uart5.reg_addr)->fd;
126  FD_SET(fd, &fds_master);
127  if (fd > fdmax) {
128  fdmax =fd;
129  }
130  }
131 #endif
132 #if USE_UART6
133  if (uart6.reg_addr != NULL) {
134  fd = ((struct SerialPort *)uart6.reg_addr)->fd;
135  FD_SET(fd, &fds_master);
136  if (fd > fdmax) {
137  fdmax =fd;
138  }
139  }
140 #endif
141 
142  /* fds to be read, modified after each select */
143  fd_set fds;
144 
145  while (1) {
146  /* reset list of fds to check */
147  fds = fds_master;
148 
149  if (select(fdmax + 1, &fds, NULL, NULL, NULL) < 0) {
150  fprintf(stderr, "uart_thread: select failed!");
151  }
152  else {
153 #if USE_UART0
154  if (uart0.reg_addr != NULL) {
155  fd = ((struct SerialPort *)uart0.reg_addr)->fd;
156  if (FD_ISSET(fd, &fds)) {
157  uart_receive_handler(&uart0);
158  }
159  }
160 #endif
161 #if USE_UART1
162  if (uart1.reg_addr != NULL) {
163  fd = ((struct SerialPort *)uart1.reg_addr)->fd;
164  if (FD_ISSET(fd, &fds)) {
165  uart_receive_handler(&uart1);
166  }
167  }
168 #endif
169 #if USE_UART2
170  if (uart2.reg_addr != NULL) {
171  fd = ((struct SerialPort *)uart2.reg_addr)->fd;
172  if (FD_ISSET(fd, &fds)) {
173  uart_receive_handler(&uart2);
174  }
175  }
176 #endif
177 #if USE_UART3
178  if (uart3.reg_addr != NULL) {
179  fd = ((struct SerialPort *)uart3.reg_addr)->fd;
180  if (FD_ISSET(fd, &fds)) {
181  uart_receive_handler(&uart3);
182  }
183  }
184 #endif
185 #if USE_UART4
186  if (uart4.reg_addr != NULL) {
187  fd = ((struct SerialPort *)uart4.reg_addr)->fd;
188  if (FD_ISSET(fd, &fds)) {
189  uart_receive_handler(&uart4);
190  }
191  }
192 #endif
193 #if USE_UART5
194  if (uart5.reg_addr != NULL) {
195  fd = ((struct SerialPort *)uart5.reg_addr)->fd;
196  if (FD_ISSET(fd, &fds)) {
197  uart_receive_handler(&uart5);
198  }
199  }
200 #endif
201 #if USE_UART6
202  if (uart6.reg_addr != NULL) {
203  fd = ((struct SerialPort *)uart6.reg_addr)->fd;
204  if (FD_ISSET(fd, &fds)) {
205  uart_receive_handler(&uart6);
206  }
207  }
208 #endif
209  }
210  }
211 
212  return 0;
213 }
214 
215 // open serial link
216 // close first if already openned
217 static void uart_periph_open(struct uart_periph *periph, uint32_t baud)
218 {
219  periph->baudrate = baud;
220 
221  struct SerialPort *port;
222  // close serial port if already open
223  if (periph->reg_addr != NULL) {
224  port = (struct SerialPort *)(periph->reg_addr);
225  serial_port_close(port);
226  serial_port_free(port);
227  }
228  // open serial port
229  port = serial_port_new();
230  // use register address to store SerialPort structure pointer...
231  periph->reg_addr = (void *)port;
232 
233  //TODO: set device name in application and pass as argument
234  // FIXME: paparazzi baud is 9600 for B9600 while open_raw needs 12 for B9600
235  // /printf("opening %s on uart0 at termios.h baud value=%d\n", periph->dev, baud);
236  int ret = serial_port_open_raw(port, periph->dev, baud);
237  if (ret != 0) {
238  TRACE("Error opening %s code %d\n", periph->dev, ret);
239  serial_port_free(port);
240  periph->reg_addr = NULL;
241  }
242 }
243 
245 {
246  periph->baudrate = baud;
247 
248  // open serial port if not done
249  if (periph->reg_addr == NULL) {
250  uart_periph_open(periph, baud);
251  }
252  if (periph->reg_addr == NULL) {
253  // periph not started, do nothiing
254  return;
255  }
256  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
257  serial_port_set_baudrate(port, baud);
258 }
259 
260 void uart_periph_set_bits_stop_parity(struct uart_periph *periph, uint8_t bits, uint8_t stop, uint8_t parity)
261 {
262  if (periph->reg_addr == NULL) {
263  // periph not started, do nothiing
264  return;
265  }
266  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
267  serial_port_set_bits_stop_parity(port, bits, stop, parity);
268 }
269 
270 void uart_put_byte(struct uart_periph *periph, long fd __attribute__((unused)), uint8_t data)
271 {
272  if (periph->reg_addr == NULL) { return; } // device not initialized ?
273 
274  /* write single byte to serial port */
275  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
276 
277  int ret = 0;
278  do{
279  ret = write((int)(port->fd), &data, 1);
280  } while(ret < 1 && errno == EAGAIN); //FIXME: max retry
281 
282  if (ret < 1) {
283  TRACE("uart_put_byte: write %d failed [%d: %s]\n", data, ret, strerror(errno));
284  }
285 }
286 
287 
288 static void __attribute__ ((unused)) uart_receive_handler(struct uart_periph *periph)
289 {
290  unsigned char c = 'D';
291 
292  if (periph->reg_addr == NULL) { return; } // device not initialized ?
293 
294  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
295  int fd = port->fd;
296 
297  pthread_mutex_lock(&uart_mutex);
298 
299  if (read(fd, &c, 1) > 0) {
300  //printf("r %x %c\n",c,c);
301  uint16_t temp = (periph->rx_insert_idx + 1) % UART_RX_BUFFER_SIZE;
302  // check for more room in queue
303  if (temp != periph->rx_extract_idx) {
304  periph->rx_buf[periph->rx_insert_idx] = c;
305  periph->rx_insert_idx = temp; // update insert index
306  }
307  else {
308  TRACE("uart_receive_handler: rx_buf full! discarding received byte: %x %c\n", c, c);
309  }
310  }
311  pthread_mutex_unlock(&uart_mutex);
312 }
313 
315 {
316  pthread_mutex_lock(&uart_mutex);
317  uint8_t ret = p->rx_buf[p->rx_extract_idx];
319  pthread_mutex_unlock(&uart_mutex);
320  return ret;
321 }
322 
324 {
325  pthread_mutex_lock(&uart_mutex);
326  int16_t available = p->rx_insert_idx - p->rx_extract_idx;
327  if (available < 0) {
328  available += UART_RX_BUFFER_SIZE;
329  }
330  pthread_mutex_unlock(&uart_mutex);
331  return (uint16_t)available;
332 }
333 
334 #if USE_UART0
335 void uart0_init(void)
336 {
337  uart_periph_init(&uart0);
338  strncpy(uart0.dev, STRINGIFY(UART0_DEV), UART_DEV_NAME_SIZE);
339  uart_periph_set_baudrate(&uart0, UART0_BAUD);
340 }
341 #endif /* USE_UART0 */
342 
343 #if USE_UART1
344 void uart1_init(void)
345 {
346  uart_periph_init(&uart1);
347  strncpy(uart1.dev, STRINGIFY(UART1_DEV), UART_DEV_NAME_SIZE);
348  uart_periph_set_baudrate(&uart1, UART1_BAUD);
349 }
350 #endif /* USE_UART1 */
351 
352 #if USE_UART2
353 void uart2_init(void)
354 {
355  uart_periph_init(&uart2);
356  strncpy(uart2.dev, STRINGIFY(UART2_DEV), UART_DEV_NAME_SIZE);
357  uart_periph_set_baudrate(&uart2, UART2_BAUD);
358 }
359 #endif /* USE_UART2 */
360 
361 #if USE_UART3
362 void uart3_init(void)
363 {
364  uart_periph_init(&uart3);
365  strncpy(uart3.dev, STRINGIFY(UART3_DEV), UART_DEV_NAME_SIZE);
366  uart_periph_set_baudrate(&uart3, UART3_BAUD);
367 }
368 #endif /* USE_UART3 */
369 
370 #if USE_UART4
371 void uart4_init(void)
372 {
373  uart_periph_init(&uart4);
374  strncpy(uart4.dev, STRINGIFY(UART4_DEV), UART_DEV_NAME_SIZE);
375  uart_periph_set_baudrate(&uart4, UART4_BAUD);
376 }
377 #endif /* USE_UART4 */
378 
379 #if USE_UART5
380 void uart5_init(void)
381 {
382  uart_periph_init(&uart5);
383  strncpy(uart5.dev, STRINGIFY(UART5_DEV), UART_DEV_NAME_SIZE);
384  uart_periph_set_baudrate(&uart5, UART5_BAUD);
385 }
386 #endif /* USE_UART5 */
387 
388 #if USE_UART6
389 void uart6_init(void)
390 {
391  uart_periph_init(&uart6);
392  strncpy(uart6.dev, STRINGIFY(UART6_DEV), UART_DEV_NAME_SIZE);
393  uart_periph_set_baudrate(&uart6, UART6_BAUD);
394 }
395 #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:38
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:323
#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:65
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:288
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:217
signed short int16_t
Definition: types.h:17
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