/* * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */ #include "pico/stdio/driver.h" #include "pico/stdio_uart.h" #include "pico/binary_info.h" #include "hardware/gpio.h" static uart_inst_t *uart_instance; #if PICO_STDIO_UART_SUPPORT_CHARS_AVAILABLE_CALLBACK static void (*chars_available_callback)(void*); static void *chars_available_param; #endif #if PICO_NO_BI_STDIO_UART #define stdio_bi_decl_if_func_used(x) #else #define stdio_bi_decl_if_func_used bi_decl_if_func_used #endif #ifdef PICO_DEFAULT_UART_TX_PIN #if (PICO_DEFAULT_UART_TX_PIN & 0x1) || (PICO_RP2040 && (PICO_DEFAULT_UART_TX_PIN & 0x2)) #error "Specified PICO_DEFAULT_UART_TX_PIN does not support UART TX" #endif #endif #ifdef PICO_DEFAULT_UART_RX_PIN #if !(PICO_DEFAULT_UART_RX_PIN & 0x1) || (PICO_RP2040 && (PICO_DEFAULT_UART_TX_PIN & 0x2)) #error "Specified PICO_DEFAULT_UART_RX_PIN does not support UART RX" #endif #endif void stdio_uart_init(void) { #ifdef uart_default int tx_pin = -1; int rx_pin = -1; #ifdef PICO_DEFAULT_UART_TX_PIN tx_pin = PICO_DEFAULT_UART_TX_PIN; #ifdef PICO_DEFAULT_UART_RX_PIN rx_pin = PICO_DEFAULT_UART_RX_PIN; stdio_bi_decl_if_func_used(bi_program_feature("UART stdin / stdout")); #if PICO_DEFAULT_UART_TX_PIN == PICO_DEFAULT_UART_RX_PIN 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))); #else bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_TX_PIN, UART_FUNCSEL_NUM(uart_default, PICO_DEFAULT_UART_TX_PIN))); bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_RX_PIN, UART_FUNCSEL_NUM(uart_default, PICO_DEFAULT_UART_RX_PIN))); #endif #else stdio_bi_decl_if_func_used(bi_program_feature("UART stdout")); bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART)); #endif #elif defined(PICO_DEFAULT_UART_RX_PIN) rx_pin = PICO_DEFAULT_UART_RX_PIN; stdio_bi_decl_if_func_used(bi_program_feature("UART stdin")); bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_RX_PIN, GPIO_FUNC_UART)); #endif #if !defined(PICO_DEFAULT_UART_BAUD_RATE) panic("UART baud rate undefined"); #else stdio_uart_init_full(uart_default, PICO_DEFAULT_UART_BAUD_RATE, tx_pin, rx_pin); #endif #endif } void stdout_uart_init(void) { #if defined(uart_default) && defined(PICO_DEFAULT_UART_TX_PIN) bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_TX_PIN, UART_FUNCSEL_NUM(uart_default, PICO_DEFAULT_UART_TX_PIN))); #if !defined(PICO_DEFAULT_UART_BAUD_RATE) panic("UART baud rate undefined"); #else stdio_bi_decl_if_func_used(bi_program_feature("UART stdout")); stdio_uart_init_full(uart_default, PICO_DEFAULT_UART_BAUD_RATE, PICO_DEFAULT_UART_TX_PIN, -1); #endif #endif } void stdin_uart_init(void) { #if defined(uart_default) && defined(PICO_DEFAULT_UART_RX_PIN) bi_decl_if_func_used(bi_1pin_with_func(PICO_DEFAULT_UART_RX_PIN, UART_FUNCSEL_NUM(uart_default, PICO_DEFAULT_UART_RX_PIN))); #if !defined(PICO_DEFAULT_UART_BAUD_RATE) panic("UART baud rate undefined"); #else stdio_bi_decl_if_func_used(bi_program_feature("UART stdin")); stdio_uart_init_full(uart_default, PICO_DEFAULT_UART_BAUD_RATE, -1, PICO_DEFAULT_UART_RX_PIN); #endif #endif } void stdio_uart_init_full(struct uart_inst *uart, uint baud_rate, int tx_pin, int rx_pin) { uart_instance = uart; if (tx_pin >= 0) gpio_set_function((uint)tx_pin, UART_FUNCSEL_NUM(uart, tx_pin)); if (rx_pin >= 0) gpio_set_function((uint)rx_pin, UART_FUNCSEL_NUM(uart, rx_pin)); uart_init(uart_instance, baud_rate); stdio_set_driver_enabled(&stdio_uart, true); } void stdio_uart_deinit(void) { #ifdef uart_default int tx_pin = -1; int rx_pin = -1; #ifdef PICO_DEFAULT_UART_TX_PIN tx_pin = PICO_DEFAULT_UART_TX_PIN; #endif #ifdef PICO_DEFAULT_UART_RX_PIN rx_pin = PICO_DEFAULT_UART_RX_PIN; #endif stdio_uart_deinit_full(uart_default, tx_pin, rx_pin); #endif } void stdout_uart_deinit(void) { #if defined(uart_default) && defined(PICO_DEFAULT_UART_TX_PIN) stdio_uart_deinit_full(uart_default, PICO_DEFAULT_UART_TX_PIN, -1); #endif } void stdin_uart_deinit(void) { #if defined(uart_default) && defined(PICO_DEFAULT_UART_RX_PIN) stdio_uart_deinit_full(uart_default, -1, PICO_DEFAULT_UART_RX_PIN); #endif } void stdio_uart_deinit_full(struct uart_inst *uart, int tx_pin, int rx_pin) { uart_instance = uart; stdio_set_driver_enabled(&stdio_uart, false); uart_deinit(uart_instance); #if PICO_RP2040 ((void)tx_pin); ((void)rx_pin); #else // Leave pads isolated if (tx_pin >= 0) hw_set_bits(&pads_bank0_hw->io[tx_pin], PADS_BANK0_GPIO0_ISO_BITS); if (rx_pin >= 0) hw_set_bits(&pads_bank0_hw->io[rx_pin], PADS_BANK0_GPIO0_ISO_BITS); #endif } static void stdio_uart_out_chars(const char *buf, int length) { for (int i = 0; i