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