37 #include "mcu_periph/uart_arch.h"
46 #ifndef UART_THREAD_STACK_SIZE
47 #define UART_THREAD_STACK_SIZE 512
60 #define SERIAL_INIT_NULL { NULL, NULL, NULL, NULL, NULL, 0, 0 }
68 uint8_t c = sdGet((SerialDriver *)(
p->reg_addr));
70 struct SerialInit *init_struct = (
struct SerialInit *)(
p->init_struct);
71 chMtxLock(init_struct->rx_mtx);
74 p->rx_buf[
p->rx_insert_idx] = c;
76 if (temp !=
p->rx_extract_idx) {
77 p->rx_insert_idx = temp;
79 chMtxUnlock(init_struct->rx_mtx);
80 chSemSignal(init_struct->rx_sem);
91 struct SerialInit *init_struct = (
struct SerialInit *)(
p->init_struct);
92 chSemWait(init_struct->tx_sem);
94 while (
p->tx_insert_idx !=
p->tx_extract_idx) {
95 #if USE_UART_SOFT_FLOW_CONTROL
96 if (init_struct->cts_port != 0) {
98 while (
gpio_get(init_struct->cts_port, init_struct->cts_pin) == 1) ;
101 uint8_t data =
p->tx_buf[
p->tx_extract_idx];
102 sdPut((SerialDriver *)
p->reg_addr, data);
103 chMtxLock(init_struct->tx_mtx);
106 chMtxUnlock(init_struct->tx_mtx);
107 #if USE_UART_SOFT_FLOW_CONTROL
108 if (init_struct->cts_port != 0) {
110 while ((((SerialDriver *)
p->reg_addr)->usart->SR & USART_SR_TC) == 0) ;
114 p->tx_running =
false;
120 #define UART1_BAUD SERIAL_DEFAULT_BITRATE
125 #define USE_UART1_TX TRUE
128 #define USE_UART1_RX TRUE
136 #define UART1_CR2 USART_CR2_STOP1_BITS
143 static SerialConfig usart1_config = {
150 static struct SerialInit uart1_init_struct = SERIAL_INIT_NULL;
157 static __attribute__((noreturn))
void thd_uart1_rx(
void *arg)
160 chRegSetThreadName(
"uart1_rx");
163 handle_uart_rx(&uart1);
174 static __attribute__((noreturn))
void thd_uart1_tx(
void *arg)
177 chRegSetThreadName(
"uart1_tx");
180 handle_uart_tx(&uart1);
186 void uart1_init(
void)
191 #if USE_UART1_TX && defined UART1_GPIO_PORT_TX
194 #if USE_UART1_RX && defined UART1_GPIO_PORT_RX
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;
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);
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);
225 #define UART2_BAUD SERIAL_DEFAULT_BITRATE
230 #define USE_UART2_TX TRUE
233 #define USE_UART2_RX TRUE
238 #ifndef UART2_HW_FLOW_CONTROL
239 #define UART2_HW_FLOW_CONTROL FALSE
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."
251 #define UART2_CR2 USART_CR2_STOP1_BITS
255 #if UART2_HW_FLOW_CONTROL
256 #define UART2_CR3 USART_CR3_CTSE | USART_CR3_RTSE
262 static SerialConfig usart2_config = {
269 static struct SerialInit uart2_init_struct = SERIAL_INIT_NULL;
276 static __attribute__((noreturn))
void thd_uart2_rx(
void *arg)
279 chRegSetThreadName(
"uart2_rx");
282 handle_uart_rx(&uart2);
293 static __attribute__((noreturn))
void thd_uart2_tx(
void *arg)
296 chRegSetThreadName(
"uart2_tx");
299 handle_uart_tx(&uart2);
305 void uart2_init(
void)
310 #if USE_UART2_TX && defined UART2_GPIO_PORT_TX
313 #if USE_UART2_RX && defined UART2_GPIO_PORT_RX
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;
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);
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);
343 #define UART3_BAUD SERIAL_DEFAULT_BITRATE
348 #define USE_UART3_TX TRUE
351 #define USE_UART3_RX TRUE
359 #define UART3_CR2 USART_CR2_STOP1_BITS
366 static SerialConfig usart3_config = {
373 static struct SerialInit uart3_init_struct = SERIAL_INIT_NULL;
380 static __attribute__((noreturn))
void thd_uart3_rx(
void *arg)
383 chRegSetThreadName(
"uart3_rx");
386 handle_uart_rx(&uart3);
397 static __attribute__((noreturn))
void thd_uart3_tx(
void *arg)
400 chRegSetThreadName(
"uart3_tx");
403 handle_uart_tx(&uart3);
409 void uart3_init(
void)
414 #if USE_UART3_TX && defined UART3_GPIO_PORT_TX
417 #if USE_UART3_RX && defined UART3_GPIO_PORT_RX
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;
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);
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);
447 #define UART4_BAUD SERIAL_DEFAULT_BITRATE
452 #define USE_UART4_TX TRUE
455 #define USE_UART4_RX TRUE
463 #define UART4_CR2 USART_CR2_STOP1_BITS
470 static SerialConfig usart4_config = {
477 static struct SerialInit uart4_init_struct = SERIAL_INIT_NULL;
484 static __attribute__((noreturn))
void thd_uart4_rx(
void *arg)
487 chRegSetThreadName(
"uart4_rx");
490 handle_uart_rx(&uart4);
501 static __attribute__((noreturn))
void thd_uart4_tx(
void *arg)
504 chRegSetThreadName(
"uart4_tx");
507 handle_uart_tx(&uart4);
513 void uart4_init(
void)
518 #if USE_UART4_TX && defined UART4_GPIO_PORT_TX
521 #if USE_UART4_RX && defined UART4_GPIO_PORT_RX
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;
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);
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);
551 #define UART5_BAUD SERIAL_DEFAULT_BITRATE
556 #define USE_UART5_TX TRUE
559 #define USE_UART5_RX TRUE
567 #define UART5_CR2 USART_CR2_STOP1_BITS
574 static SerialConfig usart5_config = {
581 static struct SerialInit uart5_init_struct = SERIAL_INIT_NULL;
588 static __attribute__((noreturn))
void thd_uart5_rx(
void *arg)
591 chRegSetThreadName(
"uart5_rx");
594 handle_uart_rx(&uart5);
605 static __attribute__((noreturn))
void thd_uart5_tx(
void *arg)
608 chRegSetThreadName(
"uart5_tx");
611 handle_uart_tx(&uart5);
617 void uart5_init(
void)
622 #if USE_UART5_TX && defined UART5_GPIO_PORT_TX
625 #if USE_UART5_RX && defined UART5_GPIO_PORT_RX
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;
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);
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);
655 #define UART6_BAUD SERIAL_DEFAULT_BITRATE
660 #define USE_UART6_TX TRUE
663 #define USE_UART6_RX TRUE
671 #define UART6_CR2 USART_CR2_STOP1_BITS
678 static SerialConfig usart6_config = {
685 static struct SerialInit uart6_init_struct = SERIAL_INIT_NULL;
692 static __attribute__((noreturn))
void thd_uart6_rx(
void *arg)
695 chRegSetThreadName(
"uart6_rx");
698 handle_uart_rx(&uart6);
709 static __attribute__((noreturn))
void thd_uart6_tx(
void *arg)
712 chRegSetThreadName(
"uart6_tx");
715 handle_uart_tx(&uart6);
721 void uart6_init(
void)
726 #if USE_UART6_TX && defined UART6_GPIO_PORT_TX
729 #if USE_UART6_RX && defined UART6_GPIO_PORT_RX
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;
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);
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);
753 #if defined UART6_GPIO_CTS && defined UART6_GPIO_PORT_CTS
764 #define UART7_BAUD SERIAL_DEFAULT_BITRATE
769 #define USE_UART7_TX TRUE
772 #define USE_UART7_RX TRUE
780 #define UART7_CR2 USART_CR2_STOP1_BITS
787 static SerialConfig usart7_config = {
794 static struct SerialInit uart7_init_struct = SERIAL_INIT_NULL;
801 static __attribute__((noreturn))
void thd_uart7_rx(
void *arg)
804 chRegSetThreadName(
"uart7_rx");
807 handle_uart_rx(&uart7);
818 static __attribute__((noreturn))
void thd_uart7_tx(
void *arg)
821 chRegSetThreadName(
"uart7_tx");
824 handle_uart_tx(&uart7);
830 void uart7_init(
void)
835 #if USE_UART7_TX && defined UART7_GPIO_PORT_TX
838 #if USE_UART7_RX && defined UART7_GPIO_PORT_RX
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;
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);
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);
868 #define UART8_BAUD SERIAL_DEFAULT_BITRATE
873 #define USE_UART8_TX TRUE
876 #define USE_UART8_RX TRUE
884 #define UART8_CR2 USART_CR2_STOP1_BITS
891 static SerialConfig usart8_config = {
898 static struct SerialInit uart8_init_struct = SERIAL_INIT_NULL;
905 static __attribute__((noreturn))
void thd_uart8_rx(
void *arg)
908 chRegSetThreadName(
"uart8_rx");
911 handle_uart_rx(&uart8);
922 static __attribute__((noreturn))
void thd_uart8_tx(
void *arg)
925 chRegSetThreadName(
"uart8_tx");
928 handle_uart_tx(&uart8);
934 void uart8_init(
void)
939 #if USE_UART8_TX && defined UART8_GPIO_PORT_TX
942 #if USE_UART8_RX && defined UART8_GPIO_PORT_RX
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;
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);
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);
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];
979 chMtxUnlock(init_struct->rx_mtx);
988 struct SerialInit *init_struct = (
struct SerialInit *)(
p->init_struct);
989 SerialConfig *conf = init_struct->conf;
994 sdStop((SerialDriver *)(
p->reg_addr));
995 sdStart((SerialDriver *)(
p->reg_addr), conf);
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
1010 #error Unsupported board
1019 struct SerialInit *init_struct = (
struct SerialInit *)(
p->init_struct);
1020 SerialConfig *conf = init_struct->conf;
1024 conf->cr1 |= USART_CR1_PCE;
1025 conf->cr1 &= ~USART_CR1_PS;
1027 conf->cr1 &= ~__USART_CR1_M;
1029 conf->cr1 |= __USART_CR1_M;
1032 conf->cr1 |= USART_CR1_PCE;
1033 conf->cr1 |= USART_CR1_PS;
1035 conf->cr1 &= ~__USART_CR1_M;
1037 conf->cr1 |= __USART_CR1_M;
1040 conf->cr1 &= ~USART_CR1_PCE;
1041 conf->cr1 &= ~__USART_CR1_M;
1044 conf->cr2 &= ~USART_CR2_STOP;
1046 conf-> cr2 |= USART_CR2_STOP2_BITS;
1048 conf-> cr2 |= USART_CR2_STOP1_BITS;
1051 sdStop((SerialDriver *)(
p->reg_addr));
1052 sdStart((SerialDriver *)(
p->reg_addr), conf);
1055 #if defined(STM32F7XX) || defined(STM32H7XX)
1061 struct SerialInit *init_struct = (
struct SerialInit *)(
p->init_struct);
1062 SerialConfig *conf = init_struct->conf;
1064 conf->cr2 |= USART_CR2_RXINV;
1066 conf->cr2 &= ~USART_CR2_RXINV;
1069 conf->cr2 |= USART_CR2_TXINV;
1071 conf->cr2 &= ~USART_CR2_TXINV;
1073 sdStop((SerialDriver *)(
p->reg_addr));
1074 sdStart((SerialDriver *)(
p->reg_addr), conf);
1082 struct SerialInit *init_struct = (
struct SerialInit *)(
p->init_struct);
1083 int space =
p->tx_extract_idx -
p->tx_insert_idx - 1;
1089 chMtxLock(init_struct->tx_mtx);
1100 struct SerialInit *init_struct = (
struct SerialInit *)(
p->init_struct);
1103 chMtxLock(init_struct->tx_mtx);
1105 if (temp ==
p->tx_extract_idx) {
1106 chMtxUnlock(init_struct->tx_mtx);
1109 p->tx_buf[
p->tx_insert_idx] = data;
1110 p->tx_insert_idx = temp;
1112 chMtxUnlock(init_struct->tx_mtx);
1114 chSemSignal(init_struct->tx_sem);
1117 p->tx_buf[
p->tx_insert_idx] = data;
1127 struct SerialInit *init_struct = (
struct SerialInit *)(
p->init_struct);
1131 chMtxLock(init_struct->tx_mtx);
1132 int16_t space =
p->tx_extract_idx -
p->tx_insert_idx;
1137 chMtxUnlock(init_struct->tx_mtx);
1143 for (i = 0; i < len; i++) {
1144 p->tx_buf[
p->tx_insert_idx] = data[i];
1149 chMtxUnlock(init_struct->tx_mtx);
1151 chSemSignal(init_struct->tx_sem);
1157 struct SerialInit *init_struct = (
struct SerialInit *)(
p->init_struct);
1160 chMtxUnlock(init_struct->tx_mtx);
1163 chSemSignal(init_struct->tx_sem);
#define UART4_GPIO_PORT_RX
#define UART1_GPIO_PORT_TX
#define UART6_GPIO_PORT_RX
#define UART2_GPIO_PORT_RX
#define UART1_GPIO_PORT_RX
#define UART6_GPIO_PORT_TX
#define UART4_GPIO_PORT_TX
#define UART3_GPIO_PORT_TX
#define UART3_GPIO_PORT_RX
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.
static uint8_t gpio_get(ioportid_t port, uint16_t pin)
Get level of a gpio.
static MUTEX_DECL(sys_time_mtx)
#define UART8_GPIO_PORT_RX
#define UART7_GPIO_PORT_RX
#define UART8_GPIO_PORT_TX
#define UART2_GPIO_PORT_TX
UART2 (with optional flow control activated by default)
#define UART1_GPIO_AF
UART defines.
#define UART6_GPIO_PORT_CTS
#define UART5_GPIO_PORT_TX
#define UART5_GPIO_PORT_RX
Some architecture independent helper functions for GPIOs.
void uart_put_byte(struct uart_periph *periph, long fd, uint8_t data)
void uart_periph_set_bits_stop_parity(struct uart_periph *periph, uint8_t bits, uint8_t stop, uint8_t parity)
uint8_t uart_getch(struct uart_periph *p)
void uart_periph_set_baudrate(struct uart_periph *periph, uint32_t baud)
#define UART_TX_BUFFER_SIZE
#define UART_RX_BUFFER_SIZE
THD_WORKING_AREA(wa_thd_ap, THD_WORKING_AREA_MAIN)
#define UART7_GPIO_PORT_TX
UART7 (Modem with optional flow control disabled by default)
void uart_periph_set_mode(struct uart_periph *p, bool tx_enabled, bool rx_enabled, bool hw_flow_control)
void WEAK uart_send_message(struct uart_periph *p, long fd)
void uart_periph_init(struct uart_periph *p)
void WEAK uart_put_buffer(struct uart_periph *p, long fd, const uint8_t *data, uint16_t len)
void WEAK uart_periph_invert_data_logic(struct uart_periph *p, bool invert_rx, bool invert_tx)
int WEAK uart_check_free_space(struct uart_periph *p, long *fd, uint16_t len)
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
short int16_t
Typedef defining 16 bit short type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
static SEMAPHORE_DECL(we_ukf_sem, 0)