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) 2013 AggieAir, A Remote Sensing Unmanned Aerial System for Scientific Applications
3  * Utah State University, http://aggieair.usu.edu/
4  *
5  * Michal Podhradsky (michal.podhradsky@aggiemail.usu.edu)
6  * Calvin Coopmans (c.r.coopmans@ieee.org)
7  *
8  * Alexandre Bustico <alexandre.bustico@enac.fr>
9  * Gautier Hattenberger <gautier.hattenberger@enac.fr>
10  *
11  * This file is part of paparazzi.
12  *
13  * paparazzi is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2, or (at your option)
16  * any later version.
17  *
18  * paparazzi is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with paparazzi; see the file COPYING. If not, write to
25  * the Free Software Foundation, 59 Temple Place - Suite 330,
26  * Boston, MA 02111-1307, USA.
27  */
37 #include "mcu_periph/uart_arch.h"
38 #include <ch.h>
39 #include <hal.h>
40 #include "mcu_periph/gpio.h"
41 
42 struct SerialInit {
43  SerialConfig *conf;
44  semaphore_t *rx_sem;
45  semaphore_t *tx_sem;
46  mutex_t *rx_mtx;
47  mutex_t *tx_mtx;
48 };
49 
53 static void handle_uart_rx(struct uart_periph *p)
54 {
55  // wait for next incoming byte
56  uint8_t c = sdGet((SerialDriver*)(p->reg_addr));
57 
58  struct SerialInit *init_struct = (struct SerialInit*)(p->init_struct);
59  chMtxLock(init_struct->rx_mtx);
60  uint16_t temp = (p->rx_insert_idx + 1) % UART_RX_BUFFER_SIZE;;
61  // insert new byte
62  p->rx_buf[p->rx_insert_idx] = c;
63  // check for more room in queue
64  if (temp != p->rx_extract_idx) {
65  p->rx_insert_idx = temp; // update insert index
66  }
67  chMtxUnlock(init_struct->rx_mtx);
68  chSemSignal(init_struct->rx_sem);
69 }
70 
74 static void handle_uart_tx(struct uart_periph *p)
75 {
76  // check if more data to send
77  struct SerialInit *init_struct = (struct SerialInit*)(p->init_struct);
78  chSemWait (init_struct->tx_sem);
79  while (p->tx_insert_idx != p->tx_extract_idx) {
80  uint8_t data = p->tx_buf[p->tx_extract_idx];
81  p->tx_running = true;
82  sdWrite((SerialDriver *)p->reg_addr, &data, sizeof(data));
83  p->tx_running = false;
84  // TODO send by block (be careful with circular buffer)
85  chMtxLock(init_struct->tx_mtx);
86  p->tx_extract_idx++;
88  chMtxUnlock(init_struct->tx_mtx);
89  }
90 }
91 
92 #if USE_UART1
93 
94 #ifndef UART1_BAUD
95 #define UART1_BAUD SERIAL_DEFAULT_BITRATE
96 #endif
97 
98 /* by default enable UART Tx and Rx */
99 #ifndef USE_UART1_TX
100 #define USE_UART1_TX TRUE
101 #endif
102 #ifndef USE_UART1_RX
103 #define USE_UART1_RX TRUE
104 #endif
105 
106 static SerialConfig usart1_config = {
107  UART1_BAUD, /* BITRATE */
108  0, /* USART CR1 */
109  USART_CR2_STOP1_BITS, /* USART CR2 */
110  0 /* USART CR3 */
111 };
112 
113 static struct SerialInit uart1_init_struct = { NULL, NULL, NULL, NULL, NULL };
114 
115 // Threads RX and TX
116 #if USE_UART1_RX
117 static MUTEX_DECL(uart1_rx_mtx);
118 static SEMAPHORE_DECL(uart1_rx_sem, 0);
119 
120 static __attribute__((noreturn)) void thd_uart1_rx(void *arg)
121 {
122  (void) arg;
123  chRegSetThreadName("uart1_rx");
124 
125  while (TRUE) {
126  handle_uart_rx(&uart1);
127  }
128 }
129 
130 static THD_WORKING_AREA(wa_thd_uart1_rx, 1024);
131 #endif
132 
133 #if USE_UART1_TX
134 static MUTEX_DECL(uart1_tx_mtx);
135 static SEMAPHORE_DECL(uart1_tx_sem, 0);
136 
137 static __attribute__((noreturn)) void thd_uart1_tx(void *arg)
138 {
139  (void) arg;
140  chRegSetThreadName("uart1_tx");
141 
142  while (TRUE) {
143  handle_uart_tx(&uart1);
144  }
145 }
146 static THD_WORKING_AREA(wa_thd_uart1_tx, 1024);
147 #endif
148 
149 void uart1_init(void)
150 {
151  uart_periph_init(&uart1);
152 
153  // Only set pin if enabled and not statically defined in board file
154 #if USE_UART1_TX && defined UART1_GPIO_PORT_TX
156 #endif
157 #if USE_UART1_RX && defined UART1_GPIO_PORT_RX
159 #endif
160 
161  sdStart(&SD1, &usart1_config);
162  uart1.reg_addr = &SD1;
163  uart1.init_struct = &uart1_init_struct;
164  uart1_init_struct.conf = &usart1_config;
165 
166  // Create threads
167 #if USE_UART1_RX
168  uart1_init_struct.rx_mtx = &uart1_rx_mtx;
169  uart1_init_struct.rx_sem = &uart1_rx_sem;
170  chThdCreateStatic(wa_thd_uart1_rx, sizeof(wa_thd_uart1_rx),
171  NORMALPRIO+1, thd_uart1_rx, NULL);
172 #endif
173 #if USE_UART1_TX
174  uart1_init_struct.tx_mtx = &uart1_tx_mtx;
175  uart1_init_struct.tx_sem = &uart1_tx_sem;
176  chThdCreateStatic(wa_thd_uart1_tx, sizeof(wa_thd_uart1_tx),
177  NORMALPRIO+1, thd_uart1_tx, NULL);
178 #endif
179 }
180 
181 #endif
182 
183 
184 #if USE_UART2
185 
186 #ifndef UART2_BAUD
187 #define UART2_BAUD SERIAL_DEFAULT_BITRATE
188 #endif
189 
190 /* by default enable UART Tx and Rx */
191 #ifndef USE_UART2_TX
192 #define USE_UART2_TX TRUE
193 #endif
194 #ifndef USE_UART2_RX
195 #define USE_UART2_RX TRUE
196 #endif
197 
198 static SerialConfig usart2_config = {
199  UART2_BAUD, /* BITRATE */
200  0, /* USART CR1 */
201  USART_CR2_STOP1_BITS, /* USART CR2 */
202  0 /* USART CR3 */
203 };
204 
205 static struct SerialInit uart2_init_struct = { NULL, NULL, NULL, NULL, NULL };
206 
207 // Threads RX and TX
208 #if USE_UART2_RX
209 static MUTEX_DECL(uart2_rx_mtx);
210 static SEMAPHORE_DECL(uart2_rx_sem, 0);
211 
212 static __attribute__((noreturn)) void thd_uart2_rx(void *arg)
213 {
214  (void) arg;
215  chRegSetThreadName("uart2_rx");
216 
217  while (TRUE) {
218  handle_uart_rx(&uart2);
219  }
220 }
221 
222 static THD_WORKING_AREA(wa_thd_uart2_rx, 1024);
223 #endif
224 
225 #if USE_UART2_TX
226 static MUTEX_DECL(uart2_tx_mtx);
227 static SEMAPHORE_DECL(uart2_tx_sem, 0);
228 
229 static __attribute__((noreturn)) void thd_uart2_tx(void *arg)
230 {
231  (void) arg;
232  chRegSetThreadName("uart2_tx");
233 
234  while (TRUE) {
235  handle_uart_tx(&uart2);
236  }
237 }
238 static THD_WORKING_AREA(wa_thd_uart2_tx, 1024);
239 #endif
240 
241 void uart2_init(void)
242 {
243  uart_periph_init(&uart2);
244 
245  // Only set pin if enabled and not statically defined in board file
246 #if USE_UART2_TX && defined UART2_GPIO_PORT_TX
248 #endif
249 #if USE_UART2_RX && defined UART2_GPIO_PORT_RX
251 #endif
252 
253  sdStart(&SD2, &usart2_config);
254  uart2.reg_addr = &SD2;
255  uart2.init_struct = &uart2_init_struct;
256  uart2_init_struct.conf = &usart2_config;
257 
258  // Create threads
259 #if USE_UART2_RX
260  uart2_init_struct.rx_mtx = &uart2_rx_mtx;
261  uart2_init_struct.rx_sem = &uart2_rx_sem;
262  chThdCreateStatic(wa_thd_uart2_rx, sizeof(wa_thd_uart2_rx),
263  NORMALPRIO, thd_uart2_rx, NULL);
264 #endif
265 #if USE_UART2_TX
266  uart2_init_struct.tx_mtx = &uart2_tx_mtx;
267  uart2_init_struct.tx_sem = &uart2_tx_sem;
268  chThdCreateStatic(wa_thd_uart2_tx, sizeof(wa_thd_uart2_tx),
269  NORMALPRIO, thd_uart2_tx, NULL);
270 #endif
271 }
272 
273 #endif
274 
275 #if USE_UART3
276 
277 #ifndef UART3_BAUD
278 #define UART3_BAUD SERIAL_DEFAULT_BITRATE
279 #endif
280 
281 /* by default enable UART Tx and Rx */
282 #ifndef USE_UART3_TX
283 #define USE_UART3_TX TRUE
284 #endif
285 #ifndef USE_UART3_RX
286 #define USE_UART3_RX TRUE
287 #endif
288 
289 static SerialConfig usart3_config = {
290  UART3_BAUD, /* BITRATE */
291  0, /* USART CR1 */
292  USART_CR2_STOP1_BITS, /* USART CR2 */
293  0 /* USART CR3 */
294 };
295 
296 static struct SerialInit uart3_init_struct = { NULL, NULL, NULL, NULL, NULL };
297 
298 // Threads RX and TX
299 #if USE_UART3_RX
300 static MUTEX_DECL(uart3_rx_mtx);
301 static SEMAPHORE_DECL(uart3_rx_sem, 0);
302 
303 static __attribute__((noreturn)) void thd_uart3_rx(void *arg)
304 {
305  (void) arg;
306  chRegSetThreadName("uart3_rx");
307 
308  while (TRUE) {
309  handle_uart_rx(&uart3);
310  }
311 }
312 
313 static THD_WORKING_AREA(wa_thd_uart3_rx, 1024);
314 #endif
315 
316 #if USE_UART3_TX
317 static MUTEX_DECL(uart3_tx_mtx);
318 static SEMAPHORE_DECL(uart3_tx_sem, 0);
319 
320 static __attribute__((noreturn)) void thd_uart3_tx(void *arg)
321 {
322  (void) arg;
323  chRegSetThreadName("uart3_tx");
324 
325  while (TRUE) {
326  handle_uart_tx(&uart3);
327  }
328 }
329 static THD_WORKING_AREA(wa_thd_uart3_tx, 1024);
330 #endif
331 
332 void uart3_init(void)
333 {
334  uart_periph_init(&uart3);
335 
336  // Only set pin if enabled and not statically defined in board file
337 #if USE_UART3_TX && defined UART3_GPIO_PORT_TX
339 #endif
340 #if USE_UART3_RX && defined UART3_GPIO_PORT_RX
342 #endif
343 
344  sdStart(&SD3, &usart3_config);
345  uart3.reg_addr = &SD3;
346  uart3.init_struct = &uart3_init_struct;
347  uart3_init_struct.conf = &usart3_config;
348 
349  // Create threads
350 #if USE_UART3_RX
351  uart3_init_struct.rx_mtx = &uart3_rx_mtx;
352  uart3_init_struct.rx_sem = &uart3_rx_sem;
353  chThdCreateStatic(wa_thd_uart3_rx, sizeof(wa_thd_uart3_rx),
354  NORMALPRIO, thd_uart3_rx, NULL);
355 #endif
356 #if USE_UART3_TX
357  uart3_init_struct.tx_mtx = &uart3_tx_mtx;
358  uart3_init_struct.tx_sem = &uart3_tx_sem;
359  chThdCreateStatic(wa_thd_uart3_tx, sizeof(wa_thd_uart3_tx),
360  NORMALPRIO, thd_uart3_tx, NULL);
361 #endif
362 }
363 
364 #endif
365 
366 #if USE_UART4
367 
368 #ifndef UART4_BAUD
369 #define UART4_BAUD SERIAL_DEFAULT_BITRATE
370 #endif
371 
372 /* by default enable UART Tx and Rx */
373 #ifndef USE_UART4_TX
374 #define USE_UART4_TX TRUE
375 #endif
376 #ifndef USE_UART4_RX
377 #define USE_UART4_RX TRUE
378 #endif
379 
380 static SerialConfig usart4_config = {
381  UART4_BAUD, /* BITRATE */
382  0, /* USART CR1 */
383  USART_CR2_STOP1_BITS, /* USART CR2 */
384  0 /* USART CR3 */
385 };
386 
387 static struct SerialInit uart4_init_struct = { NULL, NULL, NULL, NULL, NULL };
388 
389 // Threads RX and TX
390 #if USE_UART4_RX
391 static MUTEX_DECL(uart4_rx_mtx);
392 static SEMAPHORE_DECL(uart4_rx_sem, 0);
393 
394 static __attribute__((noreturn)) void thd_uart4_rx(void *arg)
395 {
396  (void) arg;
397  chRegSetThreadName("uart4_rx");
398 
399  while (TRUE) {
400  handle_uart_rx(&uart4);
401  }
402 }
403 
404 static THD_WORKING_AREA(wa_thd_uart4_rx, 1024);
405 #endif
406 
407 #if USE_UART4_TX
408 static MUTEX_DECL(uart4_tx_mtx);
409 static SEMAPHORE_DECL(uart4_tx_sem, 0);
410 
411 static __attribute__((noreturn)) void thd_uart4_tx(void *arg)
412 {
413  (void) arg;
414  chRegSetThreadName("uart4_tx");
415 
416  while (TRUE) {
417  handle_uart_tx(&uart4);
418  }
419 }
420 static THD_WORKING_AREA(wa_thd_uart4_tx, 1024);
421 #endif
422 
423 void uart4_init(void)
424 {
425  uart_periph_init(&uart4);
426 
427  // Only set pin if enabled and not statically defined in board file
428 #if USE_UART4_TX && defined UART4_GPIO_PORT_TX
430 #endif
431 #if USE_UART4_RX && defined UART4_GPIO_PORT_RX
433 #endif
434 
435  sdStart(&SD4, &usart4_config);
436  uart4.reg_addr = &SD4;
437  uart4.init_struct = &uart4_init_struct;
438  uart4_init_struct.conf = &usart4_config;
439 
440  // Create threads
441 #if USE_UART4_RX
442  uart4_init_struct.rx_mtx = &uart4_rx_mtx;
443  uart4_init_struct.rx_sem = &uart4_rx_sem;
444  chThdCreateStatic(wa_thd_uart4_rx, sizeof(wa_thd_uart4_rx),
445  NORMALPRIO, thd_uart4_rx, NULL);
446 #endif
447 #if USE_UART4_TX
448  uart4_init_struct.tx_mtx = &uart4_tx_mtx;
449  uart4_init_struct.tx_sem = &uart4_tx_sem;
450  chThdCreateStatic(wa_thd_uart4_tx, sizeof(wa_thd_uart4_tx),
451  NORMALPRIO, thd_uart4_tx, NULL);
452 #endif
453 }
454 
455 #endif
456 
457 #if USE_UART5
458 
459 #ifndef UART5_BAUD
460 #define UART5_BAUD SERIAL_DEFAULT_BITRATE
461 #endif
462 
463 /* by default enable UART Tx and Rx */
464 #ifndef USE_UART5_TX
465 #define USE_UART5_TX TRUE
466 #endif
467 #ifndef USE_UART5_RX
468 #define USE_UART5_RX TRUE
469 #endif
470 
471 static SerialConfig usart5_config = {
472  UART5_BAUD, /* BITRATE */
473  0, /* USART CR1 */
474  USART_CR2_STOP1_BITS, /* USART CR2 */
475  0 /* USART CR3 */
476 };
477 
478 static struct SerialInit uart5_init_struct = { NULL, NULL, NULL, NULL, NULL };
479 
480 // Threads RX and TX
481 #if USE_UART5_RX
482 static MUTEX_DECL(uart5_rx_mtx);
483 static SEMAPHORE_DECL(uart5_rx_sem, 0);
484 
485 static __attribute__((noreturn)) void thd_uart5_rx(void *arg)
486 {
487  (void) arg;
488  chRegSetThreadName("uart5_rx");
489 
490  while (TRUE) {
491  handle_uart_rx(&uart5);
492  }
493 }
494 
495 static THD_WORKING_AREA(wa_thd_uart5_rx, 1024);
496 #endif
497 
498 #if USE_UART5_TX
499 static MUTEX_DECL(uart5_tx_mtx);
500 static SEMAPHORE_DECL(uart5_tx_sem, 0);
501 
502 static __attribute__((noreturn)) void thd_uart5_tx(void *arg)
503 {
504  (void) arg;
505  chRegSetThreadName("uart5_tx");
506 
507  while (TRUE) {
508  handle_uart_tx(&uart5);
509  }
510 }
511 static THD_WORKING_AREA(wa_thd_uart5_tx, 1024);
512 #endif
513 
514 void uart5_init(void)
515 {
516  uart_periph_init(&uart5);
517 
518  // Only set pin if enabled and not statically defined in board file
519 #if USE_UART5_TX && defined UART5_GPIO_PORT_TX
521 #endif
522 #if USE_UART5_RX && defined UART5_GPIO_PORT_RX
524 #endif
525 
526  sdStart(&SD5, &usart5_config);
527  uart5.reg_addr = &SD5;
528  uart5.init_struct = &uart5_init_struct;
529  uart5_init_struct.conf = &usart5_config;
530 
531  // Create threads
532 #if USE_UART5_RX
533  uart5_init_struct.rx_mtx = &uart5_rx_mtx;
534  uart5_init_struct.rx_sem = &uart5_rx_sem;
535  chThdCreateStatic(wa_thd_uart5_rx, sizeof(wa_thd_uart5_rx),
536  NORMALPRIO, thd_uart5_rx, NULL);
537 #endif
538 #if USE_UART5_TX
539  uart5_init_struct.tx_mtx = &uart5_tx_mtx;
540  uart5_init_struct.tx_sem = &uart5_tx_sem;
541  chThdCreateStatic(wa_thd_uart5_tx, sizeof(wa_thd_uart5_tx),
542  NORMALPRIO, thd_uart5_tx, NULL);
543 #endif
544 }
545 
546 #endif
547 
548 #if USE_UART6
549 
550 #ifndef UART6_BAUD
551 #define UART6_BAUD SERIAL_DEFAULT_BITRATE
552 #endif
553 
554 /* by default enable UART Tx and Rx */
555 #ifndef USE_UART6_TX
556 #define USE_UART6_TX TRUE
557 #endif
558 #ifndef USE_UART6_RX
559 #define USE_UART6_RX TRUE
560 #endif
561 
562 static SerialConfig usart6_config = {
563  UART6_BAUD, /* BITRATE */
564  0, /* USART CR1 */
565  USART_CR2_STOP1_BITS, /* USART CR2 */
566  0 /* USART CR3 */
567 };
568 
569 static struct SerialInit uart6_init_struct = { NULL, NULL, NULL, NULL, NULL };
570 
571 // Threads RX and TX
572 #if USE_UART6_RX
573 static MUTEX_DECL(uart6_rx_mtx);
574 static SEMAPHORE_DECL(uart6_rx_sem, 0);
575 
576 static __attribute__((noreturn)) void thd_uart6_rx(void *arg)
577 {
578  (void) arg;
579  chRegSetThreadName("uart6_rx");
580 
581  while (TRUE) {
582  handle_uart_rx(&uart6);
583  }
584 }
585 
586 static THD_WORKING_AREA(wa_thd_uart6_rx, 1024);
587 #endif
588 
589 #if USE_UART6_TX
590 static MUTEX_DECL(uart6_tx_mtx);
591 static SEMAPHORE_DECL(uart6_tx_sem, 0);
592 
593 static __attribute__((noreturn)) void thd_uart6_tx(void *arg)
594 {
595  (void) arg;
596  chRegSetThreadName("uart6_tx");
597 
598  while (TRUE) {
599  handle_uart_tx(&uart6);
600  }
601 }
602 static THD_WORKING_AREA(wa_thd_uart6_tx, 1024);
603 #endif
604 
605 void uart6_init(void)
606 {
607  uart_periph_init(&uart6);
608 
609  // Only set pin if enabled and not statically defined in board file
610 #if USE_UART6_TX && defined UART6_GPIO_PORT_TX
612 #endif
613 #if USE_UART6_RX && defined UART6_GPIO_PORT_RX
615 #endif
616 
617  sdStart(&SD6, &usart6_config);
618  uart6.reg_addr = &SD6;
619  uart6.init_struct = &uart6_init_struct;
620  uart6_init_struct.conf = &usart6_config;
621 
622  // Create threads
623 #if USE_UART6_RX
624  uart6_init_struct.rx_mtx = &uart6_rx_mtx;
625  uart6_init_struct.rx_sem = &uart6_rx_sem;
626  chThdCreateStatic(wa_thd_uart6_rx, sizeof(wa_thd_uart6_rx),
627  NORMALPRIO, thd_uart6_rx, NULL);
628 #endif
629 #if USE_UART6_TX
630  uart6_init_struct.tx_mtx = &uart6_tx_mtx;
631  uart6_init_struct.tx_sem = &uart6_tx_sem;
632  chThdCreateStatic(wa_thd_uart6_tx, sizeof(wa_thd_uart6_tx),
633  NORMALPRIO, thd_uart6_tx, NULL);
634 #endif
635 }
636 
637 #endif
638 
639 #if USE_UART7
640 
641 #ifndef UART7_BAUD
642 #define UART7_BAUD SERIAL_DEFAULT_BITRATE
643 #endif
644 
645 /* by default enable UART Tx and Rx */
646 #ifndef USE_UART7_TX
647 #define USE_UART7_TX TRUE
648 #endif
649 #ifndef USE_UART7_RX
650 #define USE_UART7_RX TRUE
651 #endif
652 
653 static SerialConfig usart7_config = {
654  UART7_BAUD, /* BITRATE */
655  0, /* USART CR1 */
656  USART_CR2_STOP1_BITS, /* USART CR2 */
657  0 /* USART CR3 */
658 };
659 
660 static struct SerialInit uart7_init_struct = { NULL, NULL, NULL, NULL, NULL };
661 
662 // Threads RX and TX
663 #if USE_UART7_RX
664 static MUTEX_DECL(uart7_rx_mtx);
665 static SEMAPHORE_DECL(uart7_rx_sem, 0);
666 
667 static __attribute__((noreturn)) void thd_uart7_rx(void *arg)
668 {
669  (void) arg;
670  chRegSetThreadName("uart7_rx");
671 
672  while (TRUE) {
673  handle_uart_rx(&uart7);
674  }
675 }
676 
677 static THD_WORKING_AREA(wa_thd_uart7_rx, 1024);
678 #endif
679 
680 #if USE_UART7_TX
681 static MUTEX_DECL(uart7_tx_mtx);
682 static SEMAPHORE_DECL(uart7_tx_sem, 0);
683 
684 static __attribute__((noreturn)) void thd_uart7_tx(void *arg)
685 {
686  (void) arg;
687  chRegSetThreadName("uart7_tx");
688 
689  while (TRUE) {
690  handle_uart_tx(&uart7);
691  }
692 }
693 static THD_WORKING_AREA(wa_thd_uart7_tx, 1024);
694 #endif
695 
696 void uart7_init(void)
697 {
698  uart_periph_init(&uart7);
699 
700  // Only set pin if enabled and not statically defined in board file
701 #if USE_UART7_TX && defined UART7_GPIO_PORT_TX
703 #endif
704 #if USE_UART7_RX && defined UART7_GPIO_PORT_RX
706 #endif
707 
708  sdStart(&SD7, &usart7_config);
709  uart7.reg_addr = &SD7;
710  uart7.init_struct = &uart7_init_struct;
711  uart7_init_struct.conf = &usart7_config;
712 
713  // Create threads
714 #if USE_UART7_RX
715  uart7_init_struct.rx_mtx = &uart7_rx_mtx;
716  uart7_init_struct.rx_sem = &uart7_rx_sem;
717  chThdCreateStatic(wa_thd_uart7_rx, sizeof(wa_thd_uart7_rx),
718  NORMALPRIO, thd_uart7_rx, NULL);
719 #endif
720 #if USE_UART7_TX
721  uart7_init_struct.tx_mtx = &uart7_tx_mtx;
722  uart7_init_struct.tx_sem = &uart7_tx_sem;
723  chThdCreateStatic(wa_thd_uart7_tx, sizeof(wa_thd_uart7_tx),
724  NORMALPRIO, thd_uart7_tx, NULL);
725 #endif
726 }
727 
728 #endif
729 
730 #if USE_UART8
731 
732 #ifndef UART8_BAUD
733 #define UART8_BAUD SERIAL_DEFAULT_BITRATE
734 #endif
735 
736 /* by default enable UART Tx and Rx */
737 #ifndef USE_UART8_TX
738 #define USE_UART8_TX TRUE
739 #endif
740 #ifndef USE_UART8_RX
741 #define USE_UART8_RX TRUE
742 #endif
743 
744 static SerialConfig usart8_config = {
745  UART8_BAUD, /* BITRATE */
746  0, /* USART CR1 */
747  USART_CR2_STOP1_BITS, /* USART CR2 */
748  0 /* USART CR3 */
749 };
750 
751 static struct SerialInit uart8_init_struct = { NULL, NULL, NULL, NULL, NULL };
752 
753 // Threads RX and TX
754 #if USE_UART8_RX
755 static MUTEX_DECL(uart8_rx_mtx);
756 static SEMAPHORE_DECL(uart8_rx_sem, 0);
757 
758 static __attribute__((noreturn)) void thd_uart8_rx(void *arg)
759 {
760  (void) arg;
761  chRegSetThreadName("uart8_rx");
762 
763  while (TRUE) {
764  handle_uart_rx(&uart8);
765  }
766 }
767 
768 static THD_WORKING_AREA(wa_thd_uart8_rx, 1024);
769 #endif
770 
771 #if USE_UART8_TX
772 static MUTEX_DECL(uart8_tx_mtx);
773 static SEMAPHORE_DECL(uart8_tx_sem, 0);
774 
775 static __attribute__((noreturn)) void thd_uart8_tx(void *arg)
776 {
777  (void) arg;
778  chRegSetThreadName("uart8_tx");
779 
780  while (TRUE) {
781  handle_uart_tx(&uart8);
782  }
783 }
784 static THD_WORKING_AREA(wa_thd_uart8_tx, 1024);
785 #endif
786 
787 void uart8_init(void)
788 {
789  uart_periph_init(&uart8);
790 
791  // Only set pin if enabled and not statically defined in board file
792 #if USE_UART8_TX && defined UART8_GPIO_PORT_TX
794 #endif
795 #if USE_UART8_RX && defined UART8_GPIO_PORT_RX
797 #endif
798 
799  sdStart(&SD8, &usart8_config);
800  uart8.reg_addr = &SD8;
801  uart8.init_struct = &uart8_init_struct;
802  uart8_init_struct.conf = &usart8_config;
803 
804  // Create threads
805 #if USE_UART8_RX
806  uart8_init_struct.rx_mtx = &uart8_rx_mtx;
807  uart8_init_struct.rx_sem = &uart8_rx_sem;
808  chThdCreateStatic(wa_thd_uart8_rx, sizeof(wa_thd_uart8_rx),
809  NORMALPRIO, thd_uart8_rx, NULL);
810 #endif
811 #if USE_UART8_TX
812  uart8_init_struct.tx_mtx = &uart8_tx_mtx;
813  uart8_init_struct.tx_sem = &uart8_tx_sem;
814  chThdCreateStatic(wa_thd_uart8_tx, sizeof(wa_thd_uart8_tx),
815  NORMALPRIO, thd_uart8_tx, NULL);
816 #endif
817 }
818 
819 #endif
820 
821 
823 {
824  //to keep compatibility with loop oriented paparazzi architecture, read is not blocking
825  //struct SerialInit *init_struct = (struct SerialInit*)(p->init_struct);
826  //chSemWait (init_struct->rx_sem);
827  struct SerialInit *init_struct = (struct SerialInit*)(p->init_struct);
828  chMtxLock(init_struct->rx_mtx);
829  uint8_t ret = p->rx_buf[p->rx_extract_idx];
831  chMtxUnlock(init_struct->rx_mtx);
832  return ret;
833 }
834 
839 {
840  struct SerialInit *init_struct = (struct SerialInit*)(p->init_struct);
841  SerialConfig *conf = init_struct->conf;
842  // set new baudrate
843  conf->speed = baud;
844  // restart periph
845  sdStop((SerialDriver*)(p->reg_addr));
846  sdStart((SerialDriver*)(p->reg_addr), conf);
847 }
848 
852 void uart_periph_set_mode(struct uart_periph *p __attribute__((unused)), bool tx_enabled __attribute__((unused)),
853  bool rx_enabled __attribute__((unused)), bool hw_flow_control __attribute__((unused))) {}
854 
859  uint8_t bits, uint8_t stop, uint8_t parity)
860 {
861  struct SerialInit *init_struct = (struct SerialInit*)(p->init_struct);
862  SerialConfig *conf = init_struct->conf;
863 
864  /* Configure USART parity and data bits */
865  if (parity == UPARITY_EVEN) {
866  conf->cr1 |= USART_CR1_PCE; // set parity control bit
867  conf->cr1 &= ~USART_CR1_PS; // clear parity selection bit
868  if (bits == UBITS_7) {
869  conf->cr1 &= ~USART_CR1_M; // clear word length bit
870  } else { // 8 data bits by default
871  conf->cr1 |= USART_CR1_M; // set word length bit
872  }
873  } else if (parity == UPARITY_ODD) {
874  conf->cr1 |= USART_CR1_PCE; // set parity control bit
875  conf->cr1 |= USART_CR1_PS; // set parity selection bit
876  if (bits == UBITS_7) {
877  conf->cr1 &= ~USART_CR1_M; // clear word length bit
878  } else { // 8 data bits by default
879  conf->cr1 |= USART_CR1_M; // set word length bit
880  }
881  } else { // 8 data bist, NO_PARITY by default
882  conf->cr1 &= ~USART_CR1_PCE; // clear parity control bit
883  conf->cr1 &= ~USART_CR1_M; // clear word length bit
884  }
885  /* Configure USART stop bits */
886  conf->cr2 &= ~USART_CR2_STOP; // clear stop bits
887  if (stop == USTOP_2) {
888  conf-> cr2 |= USART_CR2_STOP2_BITS; // set bits for 2 stops
889  } else { // 1 stop bit by default
890  conf-> cr2 |= USART_CR2_STOP1_BITS; // set bits for 1 stop
891  }
892 
893  sdStop((SerialDriver*)(p->reg_addr));
894  sdStart((SerialDriver*)(p->reg_addr), conf);
895 }
896 
897 // Check free space and set a positive value for fd if valid
898 // and lock driver with mutex
899 bool uart_check_free_space(struct uart_periph *p, long *fd, uint16_t len)
900 {
901  struct SerialInit *init_struct = (struct SerialInit*)(p->init_struct);
902  int16_t space = p->tx_extract_idx - p->tx_insert_idx;
903  if (space <= 0) {
904  space += UART_TX_BUFFER_SIZE;
905  }
906  if ((uint16_t)(space - 1) >= len) {
907  *fd = 1;
908  chMtxLock(init_struct->tx_mtx);
909  return true;
910  }
911  return false;
912 }
913 
917 void uart_put_byte(struct uart_periph *p, long fd, uint8_t data)
918 {
919  struct SerialInit *init_struct = (struct SerialInit*)(p->init_struct);
920  if (fd == 0) {
921  // if fd is zero, assume the driver is not already locked
922  chMtxLock(init_struct->tx_mtx);
923  uint16_t temp = (p->tx_insert_idx + 1) % UART_TX_BUFFER_SIZE;
924  if (temp == p->tx_extract_idx) {
925  chMtxUnlock(init_struct->tx_mtx);
926  return; // no room
927  }
928  p->tx_buf[p->tx_insert_idx] = data;
929  p->tx_insert_idx = temp;
930 
931  chMtxUnlock(init_struct->tx_mtx);
932  // send signal to start transmission
933  chSemSignal (init_struct->tx_sem);
934  }
935  else {
936  // assume driver is locked and available space have been checked
937  p->tx_buf[p->tx_insert_idx] = data;
939  }
940 }
941 
945 void uart_put_buffer(struct uart_periph *p, long fd, const uint8_t *data, uint16_t len)
946 {
947  struct SerialInit *init_struct = (struct SerialInit*)(p->init_struct);
948  if (fd == 0) {
949  // if fd is zero, assume the driver is not already locked
950  // and available space should be checked
951  chMtxLock(init_struct->tx_mtx);
952  int16_t space = p->tx_extract_idx - p->tx_insert_idx;
953  if (space <= 0) {
954  space += UART_TX_BUFFER_SIZE;
955  }
956  if ((uint16_t)(space - 1) < len) {
957  chMtxUnlock(init_struct->tx_mtx);
958  return; // no room
959  }
960  }
961  // insert data into buffer
962  int i;
963  for (i = 0; i < len; i++) {
964  p->tx_buf[p->tx_insert_idx] = data[i];
966  }
967  // unlock if needed
968  if (fd == 0) {
969  chMtxUnlock(init_struct->tx_mtx);
970  // send signal to start transmission
971  chSemSignal (init_struct->tx_sem);
972  }
973 }
974 
975 void uart_send_message(struct uart_periph *p, long fd)
976 {
977  struct SerialInit *init_struct = (struct SerialInit*)(p->init_struct);
978  // unlock driver in case it is not done (fd > 0)
979  if (fd != 0) {
980  chMtxUnlock(init_struct->tx_mtx);
981  }
982  // send signal to start transmission
983  chSemSignal (init_struct->tx_sem);
984 }
985 
semaphore_t * tx_sem
Definition: uart_arch.c:45
uint8_t tx_buf[UART_TX_BUFFER_SIZE]
Transmit buffer.
Definition: uart.h:76
unsigned short uint16_t
Definition: types.h:16
uint8_t rx_buf[UART_RX_BUFFER_SIZE]
Receive buffer.
Definition: uart.h:72
void uart_periph_set_baudrate(struct uart_periph *p, uint32_t baud)
Set baudrate.
Definition: uart_arch.c:838
volatile uint8_t tx_running
Definition: uart.h:79
#define UART8_GPIO_RX
Definition: px4fmu_2.4.h:70
#define UART7_GPIO_AF
Definition: px4fmu_2.4.h:61
#define UART5_GPIO_RX
Definition: elle0_common.h:113
#define UART6_GPIO_AF
Definition: apogee_1.0.h:129
uint8_t uart_getch(struct uart_periph *p)
Definition: uart_arch.c:822
SerialConfig * conf
Definition: uart_arch.c:43
Some architecture independent helper functions for GPIOs.
void * init_struct
User init struct.
Definition: uart.h:85
static void handle_uart_tx(struct uart_periph *p)
TX handler.
Definition: uart_arch.c:74
void uart_put_buffer(struct uart_periph *p, long fd, const uint8_t *data, uint16_t len)
Uart transmit buffer implementation.
Definition: uart_arch.c:945
#define UART4_GPIO_AF
Definition: apogee_1.0.h:123
#define UART2_GPIO_RX
Definition: apogee_1.0.h:120
#define UART8_GPIO_AF
Definition: px4fmu_2.4.h:68
#define UART2_GPIO_TX
Definition: elle0_common.h:103
#define UART_RX_BUFFER_SIZE
Definition: uart_arch.h:31
bool uart_check_free_space(struct uart_periph *p, long *fd, uint16_t len)
Definition: uart_arch.c:899
#define UART5_GPIO_TX
Definition: elle0_common.h:115
void uart_send_message(struct uart_periph *p, long fd)
Definition: uart_arch.c:975
#define UART3_GPIO_TX
Definition: cc3d.h:52
#define UART7_GPIO_PORT_RX
Definition: px4fmu_2.4.h:62
void uart_periph_set_mode(struct uart_periph *p, bool tx_enabled, bool rx_enabled, bool hw_flow_control)
Set mode (not necessary, or can be set by SerialConfig)
Definition: uart_arch.c:852
void * reg_addr
UART Register.
Definition: uart.h:81
#define FALSE
Definition: std.h:5
static SEMAPHORE_DECL(spi1_sem, 0)
Configure SPI peripherals.
#define UPARITY_ODD
Definition: uart.h:64
#define UPARITY_EVEN
Definition: uart.h:65
mutex_t * rx_mtx
Definition: uart_arch.c:46
mutex_t * tx_mtx
Definition: uart_arch.c:47
#define TRUE
Definition: std.h:4
#define UBITS_7
Definition: uart.h:57
#define UART5_GPIO_AF
Definition: elle0_common.h:111
#define UART3_GPIO_PORT_RX
Definition: cc3d.h:49
uint16_t rx_insert_idx
Definition: uart.h:73
#define UART5_GPIO_PORT_TX
Definition: elle0_common.h:114
#define UART1_GPIO_RX
Definition: apogee_1.0.h:114
UART peripheral.
Definition: uart.h:70
#define UART6_GPIO_PORT_TX
Definition: apogee_1.0.h:132
void uart_periph_init(struct uart_periph *p)
Definition: uart.c:231
unsigned long uint32_t
Definition: types.h:18
#define UART3_GPIO_AF
Definition: cc3d.h:48
#define UART4_GPIO_PORT_RX
Definition: apogee_1.0.h:124
signed short int16_t
Definition: types.h:17
#define UART7_GPIO_RX
Definition: px4fmu_2.4.h:63
semaphore_t * rx_sem
Definition: uart_arch.c:44
#define UART1_GPIO_TX
Definition: apogee_1.0.h:116
uint16_t rx_extract_idx
Definition: uart.h:74
#define UART6_GPIO_PORT_RX
Definition: apogee_1.0.h:130
uint16_t tx_insert_idx
Definition: uart.h:77
void uart_put_byte(struct uart_periph *p, long fd, uint8_t data)
Uart transmit implementation.
Definition: uart_arch.c:917
#define UART1_GPIO_PORT_RX
Definition: apogee_1.0.h:113
void gpio_setup_pin_af(ioportid_t port, uint16_t pin, uint8_t af)
Setup a gpio for input or output with alternate function.
Definition: gpio_arch.c:61
#define UART6_GPIO_RX
Definition: apogee_1.0.h:131
#define UART8_GPIO_TX
Definition: px4fmu_2.4.h:72
#define UART5_GPIO_PORT_RX
Definition: elle0_common.h:112
unsigned char uint8_t
Definition: types.h:14
#define UART4_GPIO_RX
Definition: apogee_1.0.h:125
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:858
#define UART2_GPIO_PORT_RX
Definition: apogee_1.0.h:119
#define UART4_GPIO_PORT_TX
Definition: apogee_1.0.h:126
#define UART8_GPIO_PORT_RX
Definition: px4fmu_2.4.h:69
static MUTEX_DECL(sys_time_mtx)
int fd
Definition: serial.c:26
#define UART3_GPIO_PORT_TX
Definition: cc3d.h:51
#define USTOP_2
Definition: uart.h:61
#define UART2_GPIO_AF
Definition: apogee_1.0.h:118
#define UART_TX_BUFFER_SIZE
Definition: uart_arch.h:34
static float p[2][2]
#define UART8_GPIO_PORT_TX
Definition: px4fmu_2.4.h:71
#define UART3_GPIO_RX
Definition: cc3d.h:50
#define UART1_GPIO_PORT_TX
Definition: apogee_1.0.h:115
#define UART2_GPIO_PORT_TX
Definition: elle0_common.h:102
#define UART1_GPIO_AF
Definition: apogee_1.0.h:112
#define UART6_GPIO_TX
Definition: apogee_1.0.h:133
#define UART4_GPIO_TX
Definition: apogee_1.0.h:127
#define UART7_GPIO_PORT_TX
Definition: px4fmu_2.4.h:64
static void handle_uart_rx(struct uart_periph *p)
RX handler.
Definition: uart_arch.c:53
uint16_t tx_extract_idx
Definition: uart.h:78
static THD_WORKING_AREA(wa_thd_spi1, 1024)
#define UART7_GPIO_TX
Definition: px4fmu_2.4.h:65