Paparazzi UAS  v6.0_unstable-135-g1952e6d-dirty
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
uart_arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 AggieAir, A Remote Sensing Unmanned Aerial System for Scientific Applications
3  * Utah State University, http://aggieair.usu.edu/
4  *
5  * Michal Podhradsky (michal.podhradsky@aggiemail.usu.edu)
6  * Calvin Coopmans (c.r.coopmans@ieee.org)
7  *
8  * Alexandre Bustico <alexandre.bustico@enac.fr>
9  * Gautier Hattenberger <gautier.hattenberger@enac.fr>
10  *
11  * This file is part of paparazzi.
12  *
13  * paparazzi is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2, or (at your option)
16  * any later version.
17  *
18  * paparazzi is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with paparazzi; see the file COPYING. If not, write to
25  * the Free Software Foundation, 59 Temple Place - Suite 330,
26  * Boston, MA 02111-1307, USA.
27  */
37 #include "mcu_periph/uart_arch.h"
38 #include <ch.h>
39 #include <hal.h>
40 #include "mcu_periph/gpio.h"
41 #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 #ifndef UART1_CR1
130 #define UART1_CR1 0
131 #endif
132 
133 #ifndef UART1_CR2
134 #define UART1_CR2 USART_CR2_STOP1_BITS
135 #endif
136 
137 #ifndef UART1_CR3
138 #define UART1_CR3 0
139 #endif
140 
141 static SerialConfig usart1_config = {
142  UART1_BAUD, /* BITRATE */
143  UART1_CR1, /* USART CR1 */
144  UART1_CR2, /* USART CR2 */
145  UART1_CR3 /* USART CR3 */
146 };
147 
148 static struct SerialInit uart1_init_struct = SERIAL_INIT_NULL;
149 
150 // Threads RX and TX
151 #if USE_UART1_RX
152 static MUTEX_DECL(uart1_rx_mtx);
153 static SEMAPHORE_DECL(uart1_rx_sem, 0);
154 
155 static __attribute__((noreturn)) void thd_uart1_rx(void *arg)
156 {
157  (void) arg;
158  chRegSetThreadName("uart1_rx");
159 
160  while (TRUE) {
161  handle_uart_rx(&uart1);
162  }
163 }
164 
165 static THD_WORKING_AREA(wa_thd_uart1_rx, UART_THREAD_STACK_SIZE);
166 #endif
167 
168 #if USE_UART1_TX
169 static MUTEX_DECL(uart1_tx_mtx);
170 static SEMAPHORE_DECL(uart1_tx_sem, 0);
171 
172 static __attribute__((noreturn)) void thd_uart1_tx(void *arg)
173 {
174  (void) arg;
175  chRegSetThreadName("uart1_tx");
176 
177  while (TRUE) {
178  handle_uart_tx(&uart1);
179  }
180 }
181 static THD_WORKING_AREA(wa_thd_uart1_tx, UART_THREAD_STACK_SIZE);
182 #endif
183 
184 void uart1_init(void)
185 {
186  uart_periph_init(&uart1);
187 
188  // Only set pin if enabled and not statically defined in board file
189 #if USE_UART1_TX && defined UART1_GPIO_PORT_TX
191 #endif
192 #if USE_UART1_RX && defined UART1_GPIO_PORT_RX
194 #endif
195 
196  sdStart(&SD1, &usart1_config);
197  uart1.reg_addr = &SD1;
198  uart1.baudrate = UART1_BAUD;
199  uart1.init_struct = &uart1_init_struct;
200  uart1_init_struct.conf = &usart1_config;
201 
202  // Create threads
203 #if USE_UART1_RX
204  uart1_init_struct.rx_mtx = &uart1_rx_mtx;
205  uart1_init_struct.rx_sem = &uart1_rx_sem;
206  chThdCreateStatic(wa_thd_uart1_rx, sizeof(wa_thd_uart1_rx),
207  NORMALPRIO + 1, thd_uart1_rx, NULL);
208 #endif
209 #if USE_UART1_TX
210  uart1_init_struct.tx_mtx = &uart1_tx_mtx;
211  uart1_init_struct.tx_sem = &uart1_tx_sem;
212  chThdCreateStatic(wa_thd_uart1_tx, sizeof(wa_thd_uart1_tx),
213  NORMALPRIO + 1, thd_uart1_tx, NULL);
214 #endif
215 }
216 
217 #endif
218 
219 
220 #if USE_UART2
221 
222 #ifndef UART2_BAUD
223 #define UART2_BAUD SERIAL_DEFAULT_BITRATE
224 #endif
225 
226 /* by default enable UART Tx and Rx */
227 #ifndef USE_UART2_TX
228 #define USE_UART2_TX TRUE
229 #endif
230 #ifndef USE_UART2_RX
231 #define USE_UART2_RX TRUE
232 #endif
233 
234 
235 /* by default disable HW flow control */
236 #ifndef UART2_HW_FLOW_CONTROL
237 #define UART2_HW_FLOW_CONTROL FALSE
238 #endif
239 
240 #if UART2_HW_FLOW_CONTROL && defined(UART2_CR3)
241 #warning "UART2_CR3 reset to your value, HW flow control not enabled! You may want to set USART_CR3_CTSE | USART_CR3_RTSE yourself."
242 #endif
243 
244 #ifndef UART2_CR1
245 #define UART2_CR1 0
246 #endif
247 
248 #ifndef UART2_CR2
249 #define UART2_CR2 USART_CR2_STOP1_BITS
250 #endif
251 
252 #ifndef UART2_CR3
253 #if UART2_HW_FLOW_CONTROL
254 #define UART2_CR3 USART_CR3_CTSE | USART_CR3_RTSE
255 #else
256 #define UART2_CR3 0
257 #endif
258 #endif
259 
260 static SerialConfig usart2_config = {
261  UART2_BAUD, /* BITRATE */
262  UART2_CR1, /* USART CR1 */
263  UART2_CR2, /* USART CR2 */
264  UART2_CR3 /* USART CR3 */
265 };
266 
267 static struct SerialInit uart2_init_struct = SERIAL_INIT_NULL;
268 
269 // Threads RX and TX
270 #if USE_UART2_RX
271 static MUTEX_DECL(uart2_rx_mtx);
272 static SEMAPHORE_DECL(uart2_rx_sem, 0);
273 
274 static __attribute__((noreturn)) void thd_uart2_rx(void *arg)
275 {
276  (void) arg;
277  chRegSetThreadName("uart2_rx");
278 
279  while (TRUE) {
280  handle_uart_rx(&uart2);
281  }
282 }
283 
284 static THD_WORKING_AREA(wa_thd_uart2_rx, UART_THREAD_STACK_SIZE);
285 #endif
286 
287 #if USE_UART2_TX
288 static MUTEX_DECL(uart2_tx_mtx);
289 static SEMAPHORE_DECL(uart2_tx_sem, 0);
290 
291 static __attribute__((noreturn)) void thd_uart2_tx(void *arg)
292 {
293  (void) arg;
294  chRegSetThreadName("uart2_tx");
295 
296  while (TRUE) {
297  handle_uart_tx(&uart2);
298  }
299 }
300 static THD_WORKING_AREA(wa_thd_uart2_tx, UART_THREAD_STACK_SIZE);
301 #endif
302 
303 void uart2_init(void)
304 {
305  uart_periph_init(&uart2);
306 
307  // Only set pin if enabled and not statically defined in board file
308 #if USE_UART2_TX && defined UART2_GPIO_PORT_TX
310 #endif
311 #if USE_UART2_RX && defined UART2_GPIO_PORT_RX
313 #endif
314 
315  sdStart(&SD2, &usart2_config);
316  uart2.reg_addr = &SD2;
317  uart2.baudrate = UART2_BAUD;
318  uart2.init_struct = &uart2_init_struct;
319  uart2_init_struct.conf = &usart2_config;
320 
321  // Create threads
322 #if USE_UART2_RX
323  uart2_init_struct.rx_mtx = &uart2_rx_mtx;
324  uart2_init_struct.rx_sem = &uart2_rx_sem;
325  chThdCreateStatic(wa_thd_uart2_rx, sizeof(wa_thd_uart2_rx),
326  NORMALPRIO + 1, thd_uart2_rx, NULL);
327 #endif
328 #if USE_UART2_TX
329  uart2_init_struct.tx_mtx = &uart2_tx_mtx;
330  uart2_init_struct.tx_sem = &uart2_tx_sem;
331  chThdCreateStatic(wa_thd_uart2_tx, sizeof(wa_thd_uart2_tx),
332  NORMALPRIO + 1, thd_uart2_tx, NULL);
333 #endif
334 }
335 
336 #endif
337 
338 #if USE_UART3
339 
340 #ifndef UART3_BAUD
341 #define UART3_BAUD SERIAL_DEFAULT_BITRATE
342 #endif
343 
344 /* by default enable UART Tx and Rx */
345 #ifndef USE_UART3_TX
346 #define USE_UART3_TX TRUE
347 #endif
348 #ifndef USE_UART3_RX
349 #define USE_UART3_RX TRUE
350 #endif
351 
352 #ifndef UART3_CR1
353 #define UART3_CR1 0
354 #endif
355 
356 #ifndef UART3_CR2
357 #define UART3_CR2 USART_CR2_STOP1_BITS
358 #endif
359 
360 #ifndef UART3_CR3
361 #define UART3_CR3 0
362 #endif
363 
364 static SerialConfig usart3_config = {
365  UART3_BAUD, /* BITRATE */
366  UART3_CR1, /* USART CR1 */
367  UART3_CR2, /* USART CR2 */
368  UART3_CR3 /* USART CR3 */
369 };
370 
371 static struct SerialInit uart3_init_struct = SERIAL_INIT_NULL;
372 
373 // Threads RX and TX
374 #if USE_UART3_RX
375 static MUTEX_DECL(uart3_rx_mtx);
376 static SEMAPHORE_DECL(uart3_rx_sem, 0);
377 
378 static __attribute__((noreturn)) void thd_uart3_rx(void *arg)
379 {
380  (void) arg;
381  chRegSetThreadName("uart3_rx");
382 
383  while (TRUE) {
384  handle_uart_rx(&uart3);
385  }
386 }
387 
388 static THD_WORKING_AREA(wa_thd_uart3_rx, UART_THREAD_STACK_SIZE);
389 #endif
390 
391 #if USE_UART3_TX
392 static MUTEX_DECL(uart3_tx_mtx);
393 static SEMAPHORE_DECL(uart3_tx_sem, 0);
394 
395 static __attribute__((noreturn)) void thd_uart3_tx(void *arg)
396 {
397  (void) arg;
398  chRegSetThreadName("uart3_tx");
399 
400  while (TRUE) {
401  handle_uart_tx(&uart3);
402  }
403 }
404 static THD_WORKING_AREA(wa_thd_uart3_tx, UART_THREAD_STACK_SIZE);
405 #endif
406 
407 void uart3_init(void)
408 {
409  uart_periph_init(&uart3);
410 
411  // Only set pin if enabled and not statically defined in board file
412 #if USE_UART3_TX && defined UART3_GPIO_PORT_TX
414 #endif
415 #if USE_UART3_RX && defined UART3_GPIO_PORT_RX
417 #endif
418 
419  sdStart(&SD3, &usart3_config);
420  uart3.reg_addr = &SD3;
421  uart3.baudrate = UART3_BAUD;
422  uart3.init_struct = &uart3_init_struct;
423  uart3_init_struct.conf = &usart3_config;
424 
425  // Create threads
426 #if USE_UART3_RX
427  uart3_init_struct.rx_mtx = &uart3_rx_mtx;
428  uart3_init_struct.rx_sem = &uart3_rx_sem;
429  chThdCreateStatic(wa_thd_uart3_rx, sizeof(wa_thd_uart3_rx),
430  NORMALPRIO + 1, thd_uart3_rx, NULL);
431 #endif
432 #if USE_UART3_TX
433  uart3_init_struct.tx_mtx = &uart3_tx_mtx;
434  uart3_init_struct.tx_sem = &uart3_tx_sem;
435  chThdCreateStatic(wa_thd_uart3_tx, sizeof(wa_thd_uart3_tx),
436  NORMALPRIO + 1, thd_uart3_tx, NULL);
437 #endif
438 }
439 
440 #endif
441 
442 #if USE_UART4
443 
444 #ifndef UART4_BAUD
445 #define UART4_BAUD SERIAL_DEFAULT_BITRATE
446 #endif
447 
448 /* by default enable UART Tx and Rx */
449 #ifndef USE_UART4_TX
450 #define USE_UART4_TX TRUE
451 #endif
452 #ifndef USE_UART4_RX
453 #define USE_UART4_RX TRUE
454 #endif
455 
456 #ifndef UART4_CR1
457 #define UART4_CR1 0
458 #endif
459 
460 #ifndef UART4_CR2
461 #define UART4_CR2 USART_CR2_STOP1_BITS
462 #endif
463 
464 #ifndef UART4_CR3
465 #define UART4_CR3 0
466 #endif
467 
468 static SerialConfig usart4_config = {
469  UART4_BAUD, /* BITRATE */
470  UART4_CR1, /* USART CR1 */
471  UART4_CR2, /* USART CR2 */
472  UART4_CR3 /* USART CR3 */
473 };
474 
475 static struct SerialInit uart4_init_struct = SERIAL_INIT_NULL;
476 
477 // Threads RX and TX
478 #if USE_UART4_RX
479 static MUTEX_DECL(uart4_rx_mtx);
480 static SEMAPHORE_DECL(uart4_rx_sem, 0);
481 
482 static __attribute__((noreturn)) void thd_uart4_rx(void *arg)
483 {
484  (void) arg;
485  chRegSetThreadName("uart4_rx");
486 
487  while (TRUE) {
488  handle_uart_rx(&uart4);
489  }
490 }
491 
492 static THD_WORKING_AREA(wa_thd_uart4_rx, UART_THREAD_STACK_SIZE);
493 #endif
494 
495 #if USE_UART4_TX
496 static MUTEX_DECL(uart4_tx_mtx);
497 static SEMAPHORE_DECL(uart4_tx_sem, 0);
498 
499 static __attribute__((noreturn)) void thd_uart4_tx(void *arg)
500 {
501  (void) arg;
502  chRegSetThreadName("uart4_tx");
503 
504  while (TRUE) {
505  handle_uart_tx(&uart4);
506  }
507 }
508 static THD_WORKING_AREA(wa_thd_uart4_tx, UART_THREAD_STACK_SIZE);
509 #endif
510 
511 void uart4_init(void)
512 {
513  uart_periph_init(&uart4);
514 
515  // Only set pin if enabled and not statically defined in board file
516 #if USE_UART4_TX && defined UART4_GPIO_PORT_TX
518 #endif
519 #if USE_UART4_RX && defined UART4_GPIO_PORT_RX
521 #endif
522 
523  sdStart(&SD4, &usart4_config);
524  uart4.reg_addr = &SD4;
525  uart4.baudrate = UART4_BAUD;
526  uart4.init_struct = &uart4_init_struct;
527  uart4_init_struct.conf = &usart4_config;
528 
529  // Create threads
530 #if USE_UART4_RX
531  uart4_init_struct.rx_mtx = &uart4_rx_mtx;
532  uart4_init_struct.rx_sem = &uart4_rx_sem;
533  chThdCreateStatic(wa_thd_uart4_rx, sizeof(wa_thd_uart4_rx),
534  NORMALPRIO + 1, thd_uart4_rx, NULL);
535 #endif
536 #if USE_UART4_TX
537  uart4_init_struct.tx_mtx = &uart4_tx_mtx;
538  uart4_init_struct.tx_sem = &uart4_tx_sem;
539  chThdCreateStatic(wa_thd_uart4_tx, sizeof(wa_thd_uart4_tx),
540  NORMALPRIO + 1, thd_uart4_tx, NULL);
541 #endif
542 }
543 
544 #endif
545 
546 #if USE_UART5
547 
548 #ifndef UART5_BAUD
549 #define UART5_BAUD SERIAL_DEFAULT_BITRATE
550 #endif
551 
552 /* by default enable UART Tx and Rx */
553 #ifndef USE_UART5_TX
554 #define USE_UART5_TX TRUE
555 #endif
556 #ifndef USE_UART5_RX
557 #define USE_UART5_RX TRUE
558 #endif
559 
560 #ifndef UART5_CR1
561 #define UART5_CR1 0
562 #endif
563 
564 #ifndef UART5_CR2
565 #define UART5_CR2 USART_CR2_STOP1_BITS
566 #endif
567 
568 #ifndef UART5_CR3
569 #define UART5_CR3 0
570 #endif
571 
572 static SerialConfig usart5_config = {
573  UART5_BAUD, /* BITRATE */
574  UART5_CR1, /* USART CR1 */
575  UART5_CR2, /* USART CR2 */
576  UART5_CR3 /* USART CR3 */
577 };
578 
579 static struct SerialInit uart5_init_struct = SERIAL_INIT_NULL;
580 
581 // Threads RX and TX
582 #if USE_UART5_RX
583 static MUTEX_DECL(uart5_rx_mtx);
584 static SEMAPHORE_DECL(uart5_rx_sem, 0);
585 
586 static __attribute__((noreturn)) void thd_uart5_rx(void *arg)
587 {
588  (void) arg;
589  chRegSetThreadName("uart5_rx");
590 
591  while (TRUE) {
592  handle_uart_rx(&uart5);
593  }
594 }
595 
596 static THD_WORKING_AREA(wa_thd_uart5_rx, UART_THREAD_STACK_SIZE);
597 #endif
598 
599 #if USE_UART5_TX
600 static MUTEX_DECL(uart5_tx_mtx);
601 static SEMAPHORE_DECL(uart5_tx_sem, 0);
602 
603 static __attribute__((noreturn)) void thd_uart5_tx(void *arg)
604 {
605  (void) arg;
606  chRegSetThreadName("uart5_tx");
607 
608  while (TRUE) {
609  handle_uart_tx(&uart5);
610  }
611 }
612 static THD_WORKING_AREA(wa_thd_uart5_tx, UART_THREAD_STACK_SIZE);
613 #endif
614 
615 void uart5_init(void)
616 {
617  uart_periph_init(&uart5);
618 
619  // Only set pin if enabled and not statically defined in board file
620 #if USE_UART5_TX && defined UART5_GPIO_PORT_TX
622 #endif
623 #if USE_UART5_RX && defined UART5_GPIO_PORT_RX
625 #endif
626 
627  sdStart(&SD5, &usart5_config);
628  uart5.reg_addr = &SD5;
629  uart5.baudrate = UART5_BAUD;
630  uart5.init_struct = &uart5_init_struct;
631  uart5_init_struct.conf = &usart5_config;
632 
633  // Create threads
634 #if USE_UART5_RX
635  uart5_init_struct.rx_mtx = &uart5_rx_mtx;
636  uart5_init_struct.rx_sem = &uart5_rx_sem;
637  chThdCreateStatic(wa_thd_uart5_rx, sizeof(wa_thd_uart5_rx),
638  NORMALPRIO + 1, thd_uart5_rx, NULL);
639 #endif
640 #if USE_UART5_TX
641  uart5_init_struct.tx_mtx = &uart5_tx_mtx;
642  uart5_init_struct.tx_sem = &uart5_tx_sem;
643  chThdCreateStatic(wa_thd_uart5_tx, sizeof(wa_thd_uart5_tx),
644  NORMALPRIO + 1, thd_uart5_tx, NULL);
645 #endif
646 }
647 
648 #endif
649 
650 #if USE_UART6
651 
652 #ifndef UART6_BAUD
653 #define UART6_BAUD SERIAL_DEFAULT_BITRATE
654 #endif
655 
656 /* by default enable UART Tx and Rx */
657 #ifndef USE_UART6_TX
658 #define USE_UART6_TX TRUE
659 #endif
660 #ifndef USE_UART6_RX
661 #define USE_UART6_RX TRUE
662 #endif
663 
664 #ifndef UART6_CR1
665 #define UART6_CR1 0
666 #endif
667 
668 #ifndef UART6_CR2
669 #define UART6_CR2 USART_CR2_STOP1_BITS
670 #endif
671 
672 #ifndef UART6_CR3
673 #define UART6_CR3 0
674 #endif
675 
676 static SerialConfig usart6_config = {
677  UART6_BAUD, /* BITRATE */
678  UART6_CR1, /* USART CR1 */
679  UART6_CR2, /* USART CR2 */
680  UART6_CR3 /* USART CR3 */
681 };
682 
683 static struct SerialInit uart6_init_struct = SERIAL_INIT_NULL;
684 
685 // Threads RX and TX
686 #if USE_UART6_RX
687 static MUTEX_DECL(uart6_rx_mtx);
688 static SEMAPHORE_DECL(uart6_rx_sem, 0);
689 
690 static __attribute__((noreturn)) void thd_uart6_rx(void *arg)
691 {
692  (void) arg;
693  chRegSetThreadName("uart6_rx");
694 
695  while (TRUE) {
696  handle_uart_rx(&uart6);
697  }
698 }
699 
700 static THD_WORKING_AREA(wa_thd_uart6_rx, UART_THREAD_STACK_SIZE);
701 #endif
702 
703 #if USE_UART6_TX
704 static MUTEX_DECL(uart6_tx_mtx);
705 static SEMAPHORE_DECL(uart6_tx_sem, 0);
706 
707 static __attribute__((noreturn)) void thd_uart6_tx(void *arg)
708 {
709  (void) arg;
710  chRegSetThreadName("uart6_tx");
711 
712  while (TRUE) {
713  handle_uart_tx(&uart6);
714  }
715 }
716 static THD_WORKING_AREA(wa_thd_uart6_tx, UART_THREAD_STACK_SIZE);
717 #endif
718 
719 void uart6_init(void)
720 {
721  uart_periph_init(&uart6);
722 
723  // Only set pin if enabled and not statically defined in board file
724 #if USE_UART6_TX && defined UART6_GPIO_PORT_TX
726 #endif
727 #if USE_UART6_RX && defined UART6_GPIO_PORT_RX
729 #endif
730 
731  sdStart(&SD6, &usart6_config);
732  uart6.reg_addr = &SD6;
733  uart6.baudrate = UART6_BAUD;
734  uart6.init_struct = &uart6_init_struct;
735  uart6_init_struct.conf = &usart6_config;
736 
737  // Create threads
738 #if USE_UART6_RX
739  uart6_init_struct.rx_mtx = &uart6_rx_mtx;
740  uart6_init_struct.rx_sem = &uart6_rx_sem;
741  chThdCreateStatic(wa_thd_uart6_rx, sizeof(wa_thd_uart6_rx),
742  NORMALPRIO + 1, thd_uart6_rx, NULL);
743 #endif
744 #if USE_UART6_TX
745  uart6_init_struct.tx_mtx = &uart6_tx_mtx;
746  uart6_init_struct.tx_sem = &uart6_tx_sem;
747  chThdCreateStatic(wa_thd_uart6_tx, sizeof(wa_thd_uart6_tx),
748  NORMALPRIO + 1, thd_uart6_tx, NULL);
749 #endif
750 
751 #if defined UART6_GPIO_CTS && defined UART6_GPIO_PORT_CTS
752  uart6_init_struct.cts_pin = UART6_GPIO_CTS;
753  uart6_init_struct.cts_port = UART6_GPIO_PORT_CTS;
754 #endif
755 }
756 
757 #endif
758 
759 #if USE_UART7
760 
761 #ifndef UART7_BAUD
762 #define UART7_BAUD SERIAL_DEFAULT_BITRATE
763 #endif
764 
765 /* by default enable UART Tx and Rx */
766 #ifndef USE_UART7_TX
767 #define USE_UART7_TX TRUE
768 #endif
769 #ifndef USE_UART7_RX
770 #define USE_UART7_RX TRUE
771 #endif
772 
773 #ifndef UART7_CR1
774 #define UART7_CR1 0
775 #endif
776 
777 #ifndef UART7_CR2
778 #define UART7_CR2 USART_CR2_STOP1_BITS
779 #endif
780 
781 #ifndef UART7_CR3
782 #define UART7_CR3 0
783 #endif
784 
785 static SerialConfig usart7_config = {
786  UART7_BAUD, /* BITRATE */
787  UART7_CR1, /* USART CR1 */
788  UART7_CR2, /* USART CR2 */
789  UART7_CR3 /* USART CR3 */
790 };
791 
792 static struct SerialInit uart7_init_struct = SERIAL_INIT_NULL;
793 
794 // Threads RX and TX
795 #if USE_UART7_RX
796 static MUTEX_DECL(uart7_rx_mtx);
797 static SEMAPHORE_DECL(uart7_rx_sem, 0);
798 
799 static __attribute__((noreturn)) void thd_uart7_rx(void *arg)
800 {
801  (void) arg;
802  chRegSetThreadName("uart7_rx");
803 
804  while (TRUE) {
805  handle_uart_rx(&uart7);
806  }
807 }
808 
809 static THD_WORKING_AREA(wa_thd_uart7_rx, UART_THREAD_STACK_SIZE);
810 #endif
811 
812 #if USE_UART7_TX
813 static MUTEX_DECL(uart7_tx_mtx);
814 static SEMAPHORE_DECL(uart7_tx_sem, 0);
815 
816 static __attribute__((noreturn)) void thd_uart7_tx(void *arg)
817 {
818  (void) arg;
819  chRegSetThreadName("uart7_tx");
820 
821  while (TRUE) {
822  handle_uart_tx(&uart7);
823  }
824 }
825 static THD_WORKING_AREA(wa_thd_uart7_tx, UART_THREAD_STACK_SIZE);
826 #endif
827 
828 void uart7_init(void)
829 {
830  uart_periph_init(&uart7);
831 
832  // Only set pin if enabled and not statically defined in board file
833 #if USE_UART7_TX && defined UART7_GPIO_PORT_TX
835 #endif
836 #if USE_UART7_RX && defined UART7_GPIO_PORT_RX
838 #endif
839 
840  sdStart(&SD7, &usart7_config);
841  uart7.reg_addr = &SD7;
842  uart7.baudrate = UART7_BAUD;
843  uart7.init_struct = &uart7_init_struct;
844  uart7_init_struct.conf = &usart7_config;
845 
846  // Create threads
847 #if USE_UART7_RX
848  uart7_init_struct.rx_mtx = &uart7_rx_mtx;
849  uart7_init_struct.rx_sem = &uart7_rx_sem;
850  chThdCreateStatic(wa_thd_uart7_rx, sizeof(wa_thd_uart7_rx),
851  NORMALPRIO + 1, thd_uart7_rx, NULL);
852 #endif
853 #if USE_UART7_TX
854  uart7_init_struct.tx_mtx = &uart7_tx_mtx;
855  uart7_init_struct.tx_sem = &uart7_tx_sem;
856  chThdCreateStatic(wa_thd_uart7_tx, sizeof(wa_thd_uart7_tx),
857  NORMALPRIO + 1, thd_uart7_tx, NULL);
858 #endif
859 }
860 
861 #endif
862 
863 #if USE_UART8
864 
865 #ifndef UART8_BAUD
866 #define UART8_BAUD SERIAL_DEFAULT_BITRATE
867 #endif
868 
869 /* by default enable UART Tx and Rx */
870 #ifndef USE_UART8_TX
871 #define USE_UART8_TX TRUE
872 #endif
873 #ifndef USE_UART8_RX
874 #define USE_UART8_RX TRUE
875 #endif
876 
877 #ifndef UART8_CR1
878 #define UART8_CR1 0
879 #endif
880 
881 #ifndef UART8_CR2
882 #define UART8_CR2 USART_CR2_STOP1_BITS
883 #endif
884 
885 #ifndef UART8_CR3
886 #define UART8_CR3 0
887 #endif
888 
889 static SerialConfig usart8_config = {
890  UART8_BAUD, /* BITRATE */
891  UART8_CR1, /* USART CR1 */
892  UART8_CR2, /* USART CR2 */
893  UART8_CR3 /* USART CR3 */
894 };
895 
896 static struct SerialInit uart8_init_struct = SERIAL_INIT_NULL;
897 
898 // Threads RX and TX
899 #if USE_UART8_RX
900 static MUTEX_DECL(uart8_rx_mtx);
901 static SEMAPHORE_DECL(uart8_rx_sem, 0);
902 
903 static __attribute__((noreturn)) void thd_uart8_rx(void *arg)
904 {
905  (void) arg;
906  chRegSetThreadName("uart8_rx");
907 
908  while (TRUE) {
909  handle_uart_rx(&uart8);
910  }
911 }
912 
913 static THD_WORKING_AREA(wa_thd_uart8_rx, UART_THREAD_STACK_SIZE);
914 #endif
915 
916 #if USE_UART8_TX
917 static MUTEX_DECL(uart8_tx_mtx);
918 static SEMAPHORE_DECL(uart8_tx_sem, 0);
919 
920 static __attribute__((noreturn)) void thd_uart8_tx(void *arg)
921 {
922  (void) arg;
923  chRegSetThreadName("uart8_tx");
924 
925  while (TRUE) {
926  handle_uart_tx(&uart8);
927  }
928 }
929 static THD_WORKING_AREA(wa_thd_uart8_tx, UART_THREAD_STACK_SIZE);
930 #endif
931 
932 void uart8_init(void)
933 {
934  uart_periph_init(&uart8);
935 
936  // Only set pin if enabled and not statically defined in board file
937 #if USE_UART8_TX && defined UART8_GPIO_PORT_TX
939 #endif
940 #if USE_UART8_RX && defined UART8_GPIO_PORT_RX
942 #endif
943 
944  sdStart(&SD8, &usart8_config);
945  uart8.reg_addr = &SD8;
946  uart8.baudrate = UART8_BAUD;
947  uart8.init_struct = &uart8_init_struct;
948  uart8_init_struct.conf = &usart8_config;
949 
950  // Create threads
951 #if USE_UART8_RX
952  uart8_init_struct.rx_mtx = &uart8_rx_mtx;
953  uart8_init_struct.rx_sem = &uart8_rx_sem;
954  chThdCreateStatic(wa_thd_uart8_rx, sizeof(wa_thd_uart8_rx),
955  NORMALPRIO + 1, thd_uart8_rx, NULL);
956 #endif
957 #if USE_UART8_TX
958  uart8_init_struct.tx_mtx = &uart8_tx_mtx;
959  uart8_init_struct.tx_sem = &uart8_tx_sem;
960  chThdCreateStatic(wa_thd_uart8_tx, sizeof(wa_thd_uart8_tx),
961  NORMALPRIO + 1, thd_uart8_tx, NULL);
962 #endif
963 }
964 
965 #endif
966 
967 
969 {
970  //to keep compatibility with loop oriented paparazzi architecture, read is not blocking
971  //struct SerialInit *init_struct = (struct SerialInit*)(p->init_struct);
972  //chSemWait (init_struct->rx_sem);
973  struct SerialInit *init_struct = (struct SerialInit *)(p->init_struct);
974  chMtxLock(init_struct->rx_mtx);
975  uint8_t ret = p->rx_buf[p->rx_extract_idx];
977  chMtxUnlock(init_struct->rx_mtx);
978  return ret;
979 }
980 
985 {
986  struct SerialInit *init_struct = (struct SerialInit *)(p->init_struct);
987  SerialConfig *conf = init_struct->conf;
988  // set new baudrate
989  conf->speed = baud;
990  p->baudrate = baud;
991  // restart periph
992  sdStop((SerialDriver *)(p->reg_addr));
993  sdStart((SerialDriver *)(p->reg_addr), conf);
994 }
995 
999 void uart_periph_set_mode(struct uart_periph *p __attribute__((unused)), bool tx_enabled __attribute__((unused)),
1000  bool rx_enabled __attribute__((unused)), bool hw_flow_control __attribute__((unused))) {}
1001 
1002 #if defined STM32F7
1003 #define __USART_CR1_M USART_CR1_M_0
1004 #elif defined STM32F1 || defined STM32F4 || defined STM32F3
1005 #define __USART_CR1_M USART_CR1_M
1006 #else
1007 #error unsupported board
1008 #endif
1009 
1014  uint8_t bits, uint8_t stop, uint8_t parity)
1015 {
1016  struct SerialInit *init_struct = (struct SerialInit *)(p->init_struct);
1017  SerialConfig *conf = init_struct->conf;
1018 
1019  /* Configure USART parity and data bits */
1020  if (parity == UPARITY_EVEN) {
1021  conf->cr1 |= USART_CR1_PCE; // set parity control bit
1022  conf->cr1 &= ~USART_CR1_PS; // clear parity selection bit
1023  if (bits == UBITS_7) {
1024  conf->cr1 &= ~__USART_CR1_M; // clear word length bit
1025  } else { // 8 data bits by default
1026  conf->cr1 |= __USART_CR1_M; // set word length bit
1027  }
1028  } else if (parity == UPARITY_ODD) {
1029  conf->cr1 |= USART_CR1_PCE; // set parity control bit
1030  conf->cr1 |= USART_CR1_PS; // set parity selection bit
1031  if (bits == UBITS_7) {
1032  conf->cr1 &= ~__USART_CR1_M; // clear word length bit
1033  } else { // 8 data bits by default
1034  conf->cr1 |= __USART_CR1_M; // set word length bit
1035  }
1036  } else { // 8 data bist, NO_PARITY by default
1037  conf->cr1 &= ~USART_CR1_PCE; // clear parity control bit
1038  conf->cr1 &= ~__USART_CR1_M; // clear word length bit
1039  }
1040  /* Configure USART stop bits */
1041  conf->cr2 &= ~USART_CR2_STOP; // clear stop bits
1042  if (stop == USTOP_2) {
1043  conf-> cr2 |= USART_CR2_STOP2_BITS; // set bits for 2 stops
1044  } else { // 1 stop bit by default
1045  conf-> cr2 |= USART_CR2_STOP1_BITS; // set bits for 1 stop
1046  }
1047 
1048  sdStop((SerialDriver *)(p->reg_addr));
1049  sdStart((SerialDriver *)(p->reg_addr), conf);
1050 }
1051 
1052 #ifdef STM32F7
1053 
1056 void uart_periph_invert_data_logic(struct uart_periph *p, bool invert_rx, bool invert_tx)
1057 {
1058  struct SerialInit *init_struct = (struct SerialInit *)(p->init_struct);
1059  SerialConfig *conf = init_struct->conf;
1060  if (invert_rx) {
1061  conf->cr2 |= USART_CR2_RXINV; // set rxinv bit
1062  } else {
1063  conf->cr2 &= ~USART_CR2_RXINV; // clear rxinv bit
1064  }
1065  if (invert_tx) {
1066  conf->cr2 |= USART_CR2_TXINV; // set txinv bit
1067  } else {
1068  conf->cr2 &= ~USART_CR2_TXINV; // clear txinv bit
1069  }
1070  sdStop((SerialDriver *)(p->reg_addr));
1071  sdStart((SerialDriver *)(p->reg_addr), conf);
1072 }
1073 #endif
1074 
1075 // Check free space and set a positive value for fd if valid
1076 // and lock driver with mutex
1077 int uart_check_free_space(struct uart_periph *p, long *fd, uint16_t len)
1078 {
1079  struct SerialInit *init_struct = (struct SerialInit *)(p->init_struct);
1080  int space = p->tx_extract_idx - p->tx_insert_idx - 1;
1081  if (space < 0) {
1082  space += UART_TX_BUFFER_SIZE;
1083  }
1084  if (space >= len) {
1085  *fd = 1;
1086  chMtxLock(init_struct->tx_mtx);
1087  return space;
1088  }
1089  return 0;
1090 }
1091 
1095 void uart_put_byte(struct uart_periph *p, long fd, uint8_t data)
1096 {
1097  struct SerialInit *init_struct = (struct SerialInit *)(p->init_struct);
1098  if (fd == 0) {
1099  // if fd is zero, assume the driver is not already locked
1100  chMtxLock(init_struct->tx_mtx);
1101  uint16_t temp = (p->tx_insert_idx + 1) % UART_TX_BUFFER_SIZE;
1102  if (temp == p->tx_extract_idx) {
1103  chMtxUnlock(init_struct->tx_mtx);
1104  return; // no room
1105  }
1106  p->tx_buf[p->tx_insert_idx] = data;
1107  p->tx_insert_idx = temp;
1108 
1109  chMtxUnlock(init_struct->tx_mtx);
1110  // send signal to start transmission
1111  chSemSignal(init_struct->tx_sem);
1112  } else {
1113  // assume driver is locked and available space have been checked
1114  p->tx_buf[p->tx_insert_idx] = data;
1116  }
1117 }
1118 
1122 void uart_put_buffer(struct uart_periph *p, long fd, const uint8_t *data, uint16_t len)
1123 {
1124  struct SerialInit *init_struct = (struct SerialInit *)(p->init_struct);
1125  if (fd == 0) {
1126  // if fd is zero, assume the driver is not already locked
1127  // and available space should be checked
1128  chMtxLock(init_struct->tx_mtx);
1129  int16_t space = p->tx_extract_idx - p->tx_insert_idx;
1130  if (space <= 0) {
1131  space += UART_TX_BUFFER_SIZE;
1132  }
1133  if ((uint16_t)(space - 1) < len) {
1134  chMtxUnlock(init_struct->tx_mtx);
1135  return; // no room
1136  }
1137  }
1138  // insert data into buffer
1139  int i;
1140  for (i = 0; i < len; i++) {
1141  p->tx_buf[p->tx_insert_idx] = data[i];
1143  }
1144  // unlock if needed
1145  if (fd == 0) {
1146  chMtxUnlock(init_struct->tx_mtx);
1147  // send signal to start transmission
1148  chSemSignal(init_struct->tx_sem);
1149  }
1150 }
1151 
1152 void uart_send_message(struct uart_periph *p, long fd)
1153 {
1154  struct SerialInit *init_struct = (struct SerialInit *)(p->init_struct);
1155  // unlock driver in case it is not done (fd > 0)
1156  if (fd != 0) {
1157  chMtxUnlock(init_struct->tx_mtx);
1158  }
1159  // send signal to start transmission
1160  chSemSignal(init_struct->tx_sem);
1161 }
1162 
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
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:984
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:968
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
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:1122
#define UART_THREAD_STACK_SIZE
Definition: uart_arch.c:45
short int16_t
Typedef defining 16 bit short type.
Definition: vl53l1_types.h:93
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:1152
#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:999
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 UART7_GPIO_PORT_TX
UART7 (Modem with optional flow control disabled by default)
#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
#define UART3_GPIO_AF
Definition: cc3d.h:48
#define UART4_GPIO_PORT_RX
Definition: apogee_1.0.h:124
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:1077
#define UART7_GPIO_TX
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:1095
#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
#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:1013
#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
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
uint16_t tx_extract_idx
Definition: uart.h:78
uint16_t cts_pin
Definition: uart_arch.c:55
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78