1 /*
2  * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "pico/stdio/driver.h"
8 #include "pico/stdio_uart.h"
9 #include "pico/binary_info.h"
10 #include "hardware/gpio.h"
11 
12 static uart_inst_t *uart_instance;
13 
14 #if PICO_NO_BI_STDIO_UART
15 #define stdio_bi_decl_if_func_used(x)
16 #else
17 #define stdio_bi_decl_if_func_used bi_decl_if_func_used
18 #endif
19 
stdio_uart_init()20 void stdio_uart_init() {
21     int tx_pin = -1;
22     int rx_pin = -1;
23 #if defined(PICO_DEFAULT_UART_TX_PIN) && PICO_DEFAULT_UART_TX_PIN != -1
24     tx_pin = PICO_DEFAULT_UART_TX_PIN;
25 #if defined(PICO_DEFAULT_UART_RX_PIN) && PICO_DEFAULT_UART_RX_PIN != -1
26     rx_pin = PICO_DEFAULT_UART_RX_PIN;
27     stdio_bi_decl_if_func_used(bi_program_feature("UART stdin / stdout"));
28     bi_decl_if_func_used(bi_2pins_with_func(PICO_DEFAULT_UART_RX_PIN, PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART));
29 #else
30     stdio_bi_decl_if_func_used(bi_program_feature("UART stdout"));
31     bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART));
32 #endif
33 #elif defined(PICO_DEFAULT_UART_RX_PIN) && PICO_DEFAULT_UART_RX_PIN != -1
34     rx_pin = PICO_DEFAULT_UART_RX_PIN;
35     stdio_bi_decl_if_func_used(bi_program_feature("UART stdin"));
36     bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_RX_PIN, GPIO_FUNC_UART));
37 #endif
38 #if !defined(PICO_DEFAULT_UART_BAUD_RATE) || !defined(uart_default)
39     panic("UART baud rate undefined");
40 #else
41     stdio_uart_init_full(uart_default, PICO_DEFAULT_UART_BAUD_RATE, tx_pin, rx_pin);
42 #endif
43 }
44 
stdout_uart_init()45 void stdout_uart_init() {
46 #ifdef PICO_DEFAULT_UART_TX_PIN
47     bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART));
48 #if !defined(PICO_DEFAULT_UART_BAUD_RATE) || !defined(uart_default)
49     panic("UART baud rate undefined");
50 #else
51     stdio_bi_decl_if_func_used(bi_program_feature("UART stdout"));
52     stdio_uart_init_full(uart_default, PICO_DEFAULT_UART_BAUD_RATE, PICO_DEFAULT_UART_TX_PIN, -1);
53 #endif
54 #endif
55 }
56 
stdin_uart_init()57 void stdin_uart_init() {
58 #ifdef PICO_DEFAULT_UART_RX_PIN
59     bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_RX_PIN, GPIO_FUNC_UART));
60 #if !defined(PICO_DEFAULT_UART_BAUD_RATE) || !defined(uart_default)
61     panic("UART baud rate undefined");
62 #else
63     stdio_bi_decl_if_func_used(bi_program_feature("UART stdin"));
64     stdio_uart_init_full(uart_default, PICO_DEFAULT_UART_BAUD_RATE, -1, PICO_DEFAULT_UART_RX_PIN);
65 #endif
66 #endif
67 }
68 
stdio_uart_init_full(struct uart_inst * uart,uint baud_rate,int tx_pin,int rx_pin)69 void stdio_uart_init_full(struct uart_inst *uart, uint baud_rate, int tx_pin, int rx_pin) {
70     uart_instance = uart;
71     uart_init(uart_instance, baud_rate);
72     if (tx_pin != -1) gpio_set_function(tx_pin, GPIO_FUNC_UART);
73     if (rx_pin != -1) gpio_set_function(rx_pin, GPIO_FUNC_UART);
74     stdio_set_driver_enabled(&stdio_uart, true);
75 }
76 
stdio_uart_out_chars(const char * buf,int length)77 static void stdio_uart_out_chars(const char *buf, int length) {
78     for (uint i = 0; i <length; i++) {
79         uart_putc(uart_default, buf[i]);
80     }
81 }
82 
stdio_uart_in_chars(char * buf,int length)83 int stdio_uart_in_chars(char *buf, int length) {
84     int i=0;
85     while (i<length && uart_is_readable(uart_default)) {
86         buf[i++] = uart_getc(uart_default);
87     }
88     return i ? i : PICO_ERROR_NO_DATA;
89 }
90 
91 stdio_driver_t stdio_uart = {
92     .out_chars = stdio_uart_out_chars,
93     .in_chars = stdio_uart_in_chars,
94 #if PICO_STDIO_ENABLE_CRLF_SUPPORT
95     .crlf_enabled = PICO_STDIO_UART_DEFAULT_CRLF
96 #endif
97 };
98