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_STDIO_UART_SUPPORT_CHARS_AVAILABLE_CALLBACK
15 static void (*chars_available_callback)(void*);
16 static void *chars_available_param;
17 #endif
18
19 #if PICO_NO_BI_STDIO_UART
20 #define stdio_bi_decl_if_func_used(x)
21 #else
22 #define stdio_bi_decl_if_func_used bi_decl_if_func_used
23 #endif
24
25 #ifdef PICO_DEFAULT_UART_TX_PIN
26 #if (PICO_DEFAULT_UART_TX_PIN & 0x1) || (PICO_RP2040 && (PICO_DEFAULT_UART_TX_PIN & 0x2))
27 #error "Specified PICO_DEFAULT_UART_TX_PIN does not support UART TX"
28 #endif
29 #endif
30
31 #ifdef PICO_DEFAULT_UART_RX_PIN
32 #if !(PICO_DEFAULT_UART_RX_PIN & 0x1) || (PICO_RP2040 && (PICO_DEFAULT_UART_TX_PIN & 0x2))
33 #error "Specified PICO_DEFAULT_UART_RX_PIN does not support UART RX"
34 #endif
35 #endif
36
stdio_uart_init(void)37 void stdio_uart_init(void) {
38 #ifdef uart_default
39 int tx_pin = -1;
40 int rx_pin = -1;
41 #ifdef PICO_DEFAULT_UART_TX_PIN
42 tx_pin = PICO_DEFAULT_UART_TX_PIN;
43 #ifdef PICO_DEFAULT_UART_RX_PIN
44 rx_pin = PICO_DEFAULT_UART_RX_PIN;
45 stdio_bi_decl_if_func_used(bi_program_feature("UART stdin / stdout"));
46 #if PICO_DEFAULT_UART_TX_PIN == PICO_DEFAULT_UART_RX_PIN
47 bi_decl_if_func_used(bi_2pins_with_func(PICO_DEFAULT_UART_RX_PIN, PICO_DEFAULT_UART_TX_PIN, uart_get_funcsel(uart_default, PICO_DEFAULT_UART_RX_PIN)));
48 #else
49 bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_TX_PIN, UART_FUNCSEL_NUM(uart_default, PICO_DEFAULT_UART_TX_PIN)));
50 bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_RX_PIN, UART_FUNCSEL_NUM(uart_default, PICO_DEFAULT_UART_RX_PIN)));
51 #endif
52 #else
53 stdio_bi_decl_if_func_used(bi_program_feature("UART stdout"));
54 bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART));
55 #endif
56 #elif defined(PICO_DEFAULT_UART_RX_PIN)
57 rx_pin = PICO_DEFAULT_UART_RX_PIN;
58 stdio_bi_decl_if_func_used(bi_program_feature("UART stdin"));
59 bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_RX_PIN, GPIO_FUNC_UART));
60 #endif
61 #if !defined(PICO_DEFAULT_UART_BAUD_RATE)
62 panic("UART baud rate undefined");
63 #else
64 stdio_uart_init_full(uart_default, PICO_DEFAULT_UART_BAUD_RATE, tx_pin, rx_pin);
65 #endif
66 #endif
67 }
68
stdout_uart_init(void)69 void stdout_uart_init(void) {
70 #if defined(uart_default) && defined(PICO_DEFAULT_UART_TX_PIN)
71 bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_TX_PIN, UART_FUNCSEL_NUM(uart_default, PICO_DEFAULT_UART_TX_PIN)));
72 #if !defined(PICO_DEFAULT_UART_BAUD_RATE)
73 panic("UART baud rate undefined");
74 #else
75 stdio_bi_decl_if_func_used(bi_program_feature("UART stdout"));
76 stdio_uart_init_full(uart_default, PICO_DEFAULT_UART_BAUD_RATE, PICO_DEFAULT_UART_TX_PIN, -1);
77 #endif
78 #endif
79 }
80
stdin_uart_init(void)81 void stdin_uart_init(void) {
82 #if defined(uart_default) && defined(PICO_DEFAULT_UART_RX_PIN)
83 bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_RX_PIN, UART_FUNCSEL_NUM(uart_default, PICO_DEFAULT_UART_RX_PIN)));
84 #if !defined(PICO_DEFAULT_UART_BAUD_RATE)
85 panic("UART baud rate undefined");
86 #else
87 stdio_bi_decl_if_func_used(bi_program_feature("UART stdin"));
88 stdio_uart_init_full(uart_default, PICO_DEFAULT_UART_BAUD_RATE, -1, PICO_DEFAULT_UART_RX_PIN);
89 #endif
90 #endif
91 }
92
stdio_uart_init_full(struct uart_inst * uart,uint baud_rate,int tx_pin,int rx_pin)93 void stdio_uart_init_full(struct uart_inst *uart, uint baud_rate, int tx_pin, int rx_pin) {
94 uart_instance = uart;
95 if (tx_pin >= 0) gpio_set_function((uint)tx_pin, UART_FUNCSEL_NUM(uart, tx_pin));
96 if (rx_pin >= 0) gpio_set_function((uint)rx_pin, UART_FUNCSEL_NUM(uart, rx_pin));
97 uart_init(uart_instance, baud_rate);
98 stdio_set_driver_enabled(&stdio_uart, true);
99 }
100
stdio_uart_deinit(void)101 void stdio_uart_deinit(void) {
102 #ifdef uart_default
103 int tx_pin = -1;
104 int rx_pin = -1;
105 #ifdef PICO_DEFAULT_UART_TX_PIN
106 tx_pin = PICO_DEFAULT_UART_TX_PIN;
107 #endif
108 #ifdef PICO_DEFAULT_UART_RX_PIN
109 rx_pin = PICO_DEFAULT_UART_RX_PIN;
110 #endif
111 stdio_uart_deinit_full(uart_default, tx_pin, rx_pin);
112 #endif
113 }
114
stdout_uart_deinit(void)115 void stdout_uart_deinit(void) {
116 #if defined(uart_default) && defined(PICO_DEFAULT_UART_TX_PIN)
117 stdio_uart_deinit_full(uart_default, PICO_DEFAULT_UART_TX_PIN, -1);
118 #endif
119 }
120
stdin_uart_deinit(void)121 void stdin_uart_deinit(void) {
122 #if defined(uart_default) && defined(PICO_DEFAULT_UART_RX_PIN)
123 stdio_uart_deinit_full(uart_default, -1, PICO_DEFAULT_UART_RX_PIN);
124 #endif
125 }
126
stdio_uart_deinit_full(struct uart_inst * uart,int tx_pin,int rx_pin)127 void stdio_uart_deinit_full(struct uart_inst *uart, int tx_pin, int rx_pin) {
128 uart_instance = uart;
129 stdio_set_driver_enabled(&stdio_uart, false);
130 uart_deinit(uart_instance);
131 #if PICO_RP2040
132 ((void)tx_pin);
133 ((void)rx_pin);
134 #else
135 // Leave pads isolated
136 if (tx_pin >= 0) hw_set_bits(&pads_bank0_hw->io[tx_pin], PADS_BANK0_GPIO0_ISO_BITS);
137 if (rx_pin >= 0) hw_set_bits(&pads_bank0_hw->io[rx_pin], PADS_BANK0_GPIO0_ISO_BITS);
138 #endif
139 }
140
stdio_uart_out_chars(const char * buf,int length)141 static void stdio_uart_out_chars(const char *buf, int length) {
142 for (int i = 0; i <length; i++) {
143 uart_putc(uart_instance, buf[i]);
144 }
145 }
146
stdio_uart_in_chars(char * buf,int length)147 int stdio_uart_in_chars(char *buf, int length) {
148 int i=0;
149 while (i<length && uart_is_readable(uart_instance)) {
150 buf[i++] = uart_getc(uart_instance);
151 }
152 #if PICO_STDIO_UART_SUPPORT_CHARS_AVAILABLE_CALLBACK
153 if (chars_available_callback) {
154 // Re-enable interrupts after reading a character
155 uart_set_irqs_enabled(uart_instance, true, false);
156 }
157 #endif
158 return i ? i : PICO_ERROR_NO_DATA;
159 }
160
161 #if PICO_STDIO_UART_SUPPORT_CHARS_AVAILABLE_CALLBACK
on_uart_rx(void)162 static void on_uart_rx(void) {
163 if (chars_available_callback) {
164 // Interrupts will go off until the uart is read, so disable them
165 uart_set_irqs_enabled(uart_instance, false, false);
166 chars_available_callback(chars_available_param);
167 }
168 }
169
170 #include "hardware/irq.h"
171
stdio_uart_set_chars_available_callback(void (* fn)(void *),void * param)172 static void stdio_uart_set_chars_available_callback(void (*fn)(void*), void *param) {
173 uint irq_num = UART_IRQ_NUM(uart_instance);
174 if (fn && !chars_available_callback) {
175 irq_set_exclusive_handler(irq_num, on_uart_rx);
176 irq_set_enabled(irq_num, true);
177 uart_set_irqs_enabled(uart_instance, true, false);
178 } else if (!fn && chars_available_callback) {
179 uart_set_irqs_enabled(uart_instance, false, false);
180 irq_set_enabled(irq_num, false);
181 irq_remove_handler(irq_num, on_uart_rx);
182 }
183 chars_available_callback = fn;
184 chars_available_param = param;
185 }
186 #endif
187
stdio_uart_out_flush(void)188 static void stdio_uart_out_flush(void) {
189 uart_default_tx_wait_blocking();
190 }
191
192 stdio_driver_t stdio_uart = {
193 .out_chars = stdio_uart_out_chars,
194 .out_flush = stdio_uart_out_flush,
195 .in_chars = stdio_uart_in_chars,
196 #if PICO_STDIO_UART_SUPPORT_CHARS_AVAILABLE_CALLBACK
197 .set_chars_available_callback = stdio_uart_set_chars_available_callback,
198 #endif
199 #if PICO_STDIO_ENABLE_CRLF_SUPPORT
200 .crlf_enabled = PICO_STDIO_UART_DEFAULT_CRLF
201 #endif
202 };
203