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