Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
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
47static void uart_receive_handler(struct uart_periph *periph);
48static void *uart_thread(void *data __attribute__((unused)));
50
51//#define TRACE(fmt,args...) fprintf(stderr, fmt, args)
52#define TRACE(fmt,args...)
53
55{
57
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
68static void *uart_thread(void *data __attribute__((unused)))
69{
71
72 /* file descriptor list */
74 /* maximum file descriptor number */
75 int fdmax = 0;
76
77 /* clear the fd list */
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;
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;
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;
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;
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;
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;
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;
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;
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;
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)) {
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)) {
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)) {
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)) {
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)) {
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)) {
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)) {
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)) {
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)) {
242 }
243 }
244#endif
245 }
246 }
247
248 return 0;
249}
250
251// open serial link
252// close first if already openned
253static 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);
294}
295
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);
304}
305
306void 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
324static 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
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 }
346}
347
349{
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;
354 return ret;
355}
356
358{
360 int available = p->rx_insert_idx - p->rx_extract_idx;
361 if (available < 0) {
362 available += UART_RX_BUFFER_SIZE;
363 }
365 return available;
366}
367
368#if USE_UART0
369void uart0_init(void)
370{
374}
375#endif /* USE_UART0 */
376
377#if USE_UART1
378void uart1_init(void)
379{
383}
384#endif /* USE_UART1 */
385
386#if USE_UART2
387void uart2_init(void)
388{
392}
393#endif /* USE_UART2 */
394
395#if USE_UART3
396void uart3_init(void)
397{
401}
402#endif /* USE_UART3 */
403
404#if USE_UART4
405void uart4_init(void)
406{
410}
411#endif /* USE_UART4 */
412
413#if USE_UART5
414void uart5_init(void)
415{
419}
420#endif /* USE_UART5 */
421
422#if USE_UART6
423void uart6_init(void)
424{
428}
429#endif /* USE_UART6 */
430
431#if USE_UART7
432void uart7_init(void)
433{
437}
438#endif /* USE_UART7 */
439
440#if USE_UART8
441void uart8_init(void)
442{
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
uint16_t foo
Definition main_demo5.c:58
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)
int serial_port_open_raw(struct SerialPort *me, const char *device, speed_t speed)
struct SerialPort * serial_port_new(void)
Definition serial_port.c:74
int serial_port_set_bits_stop_parity(struct SerialPort *me, const int bits, const int stop, const int parity)
int serial_port_set_baudrate(struct SerialPort *me, speed_t speed)
void uart_periph_init(struct uart_periph *p)
Definition uart.c:126
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.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.