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