Paparazzi UAS  v5.10_stable-5-g83a0da5-dirty
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 
217 {
218  periph->baudrate = baud;
219 
220  struct SerialPort *port;
221  // close serial port if already open
222  if (periph->reg_addr != NULL) {
223  port = (struct SerialPort *)(periph->reg_addr);
224  serial_port_close(port);
225  serial_port_free(port);
226  }
227  // open serial port
228  port = serial_port_new();
229  // use register address to store SerialPort structure pointer...
230  periph->reg_addr = (void *)port;
231 
232  //TODO: set device name in application and pass as argument
233  // FIXME: paparazzi baud is 9600 for B9600 while open_raw needs 12 for B9600
234  // /printf("opening %s on uart0 at termios.h baud value=%d\n", periph->dev, baud);
235  int ret = serial_port_open_raw(port, periph->dev, baud);
236  if (ret != 0) {
237  TRACE("Error opening %s code %d\n", periph->dev, ret);
238  serial_port_free(port);
239  periph->reg_addr = NULL;
240  }
241 }
242 
243 void uart_put_byte(struct uart_periph *periph, long fd __attribute__((unused)), uint8_t data)
244 {
245  if (periph->reg_addr == NULL) { return; } // device not initialized ?
246 
247  /* write single byte to serial port */
248  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
249 
250  int ret = 0;
251  do{
252  ret = write((int)(port->fd), &data, 1);
253  } while(ret < 1 && errno == EAGAIN); //FIXME: max retry
254 
255  if (ret < 1) {
256  TRACE("uart_put_byte: write %d failed [%d: %s]\n", data, ret, strerror(errno));
257  }
258 }
259 
260 
261 static void __attribute__ ((unused)) uart_receive_handler(struct uart_periph *periph)
262 {
263  unsigned char c = 'D';
264 
265  if (periph->reg_addr == NULL) { return; } // device not initialized ?
266 
267  struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
268  int fd = port->fd;
269 
270  pthread_mutex_lock(&uart_mutex);
271 
272  if (read(fd, &c, 1) > 0) {
273  //printf("r %x %c\n",c,c);
274  uint16_t temp = (periph->rx_insert_idx + 1) % UART_RX_BUFFER_SIZE;
275  // check for more room in queue
276  if (temp != periph->rx_extract_idx) {
277  periph->rx_buf[periph->rx_insert_idx] = c;
278  periph->rx_insert_idx = temp; // update insert index
279  }
280  else {
281  TRACE("uart_receive_handler: rx_buf full! discarding received byte: %x %c\n", c, c);
282  }
283  }
284  pthread_mutex_unlock(&uart_mutex);
285 }
286 
288 {
289  pthread_mutex_lock(&uart_mutex);
290  uint8_t ret = p->rx_buf[p->rx_extract_idx];
292  pthread_mutex_unlock(&uart_mutex);
293  return ret;
294 }
295 
297 {
298  pthread_mutex_lock(&uart_mutex);
299  int16_t available = p->rx_insert_idx - p->rx_extract_idx;
300  if (available < 0) {
301  available += UART_RX_BUFFER_SIZE;
302  }
303  pthread_mutex_unlock(&uart_mutex);
304  return (uint16_t)available;
305 }
306 
307 #if USE_UART0
308 void uart0_init(void)
309 {
310  uart_periph_init(&uart0);
311  strncpy(uart0.dev, STRINGIFY(UART0_DEV), UART_DEV_NAME_SIZE);
312  uart_periph_set_baudrate(&uart0, UART0_BAUD);
313 }
314 #endif /* USE_UART0 */
315 
316 #if USE_UART1
317 void uart1_init(void)
318 {
319  uart_periph_init(&uart1);
320  strncpy(uart1.dev, STRINGIFY(UART1_DEV), UART_DEV_NAME_SIZE);
321  uart_periph_set_baudrate(&uart1, UART1_BAUD);
322 }
323 #endif /* USE_UART1 */
324 
325 #if USE_UART2
326 void uart2_init(void)
327 {
328  uart_periph_init(&uart2);
329  strncpy(uart2.dev, STRINGIFY(UART2_DEV), UART_DEV_NAME_SIZE);
330  uart_periph_set_baudrate(&uart2, UART2_BAUD);
331 }
332 #endif /* USE_UART2 */
333 
334 #if USE_UART3
335 void uart3_init(void)
336 {
337  uart_periph_init(&uart3);
338  strncpy(uart3.dev, STRINGIFY(UART3_DEV), UART_DEV_NAME_SIZE);
339  uart_periph_set_baudrate(&uart3, UART3_BAUD);
340 }
341 #endif /* USE_UART3 */
342 
343 #if USE_UART4
344 void uart4_init(void)
345 {
346  uart_periph_init(&uart4);
347  strncpy(uart4.dev, STRINGIFY(UART4_DEV), UART_DEV_NAME_SIZE);
348  uart_periph_set_baudrate(&uart4, UART4_BAUD);
349 }
350 #endif /* USE_UART4 */
351 
352 #if USE_UART5
353 void uart5_init(void)
354 {
355  uart_periph_init(&uart5);
356  strncpy(uart5.dev, STRINGIFY(UART5_DEV), UART_DEV_NAME_SIZE);
357  uart_periph_set_baudrate(&uart5, UART5_BAUD);
358 }
359 #endif /* USE_UART5 */
360 
361 #if USE_UART6
362 void uart6_init(void)
363 {
364  uart_periph_init(&uart6);
365  strncpy(uart6.dev, STRINGIFY(UART6_DEV), UART_DEV_NAME_SIZE);
366  uart_periph_set_baudrate(&uart6, UART6_BAUD);
367 }
368 #endif /* USE_UART6 */
#define UART_THREAD_PRIO
Definition: uart_arch.c:44
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
void uart_periph_set_baudrate(struct uart_periph *p, uint32_t baud)
Set baudrate.
Definition: uart_arch.c:838
uint8_t uart_getch(struct uart_periph *p)
Definition: uart_arch.c:822
#define UART4_DEV
uint16_t uart_char_available(struct uart_periph *p)
Check UART for available chars in receive buffer.
Definition: uart_arch.c:296
#define UART1_DEV
Definition: ardrone2.h:7
#define UART_RX_BUFFER_SIZE
Definition: uart_arch.h:31
#define TRACE(fmt, args...)
Definition: uart_arch.c:52
void * reg_addr
UART Register.
Definition: uart.h:81
Functions to obtain rt priority or set the nice level.
static void * uart_thread(void *data)
Definition: uart_arch.c:65
void serial_port_free(struct SerialPort *me)
Definition: serial_port.c:28
void uart_arch_init(void)
Definition: uart_arch.c:54
uint16_t rx_insert_idx
Definition: uart.h:73
static void uart_receive_handler(struct uart_periph *periph)
Definition: uart_arch.c:261
UART peripheral.
Definition: uart.h:70
void uart_periph_init(struct uart_periph *p)
Definition: uart.c:231
unsigned long uint32_t
Definition: types.h:18
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:917
static pthread_mutex_t uart_mutex
Definition: uart_arch.c:49
unsigned char uint8_t
Definition: types.h:14
char dev[UART_DEV_NAME_SIZE]
UART Dev (linux)
Definition: uart.h:87
struct SerialPort * serial_port_new(void)
Definition: serial_port.c:22
void serial_port_close(struct SerialPort *me)
Definition: serial_port.c:126
int fd
Definition: serial.c:26
int serial_port_open_raw(struct SerialPort *me, const char *device, speed_t speed)
Definition: serial_port.c:56
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