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