diff --git a/boards/common/esp8266/include/periph_conf_common.h b/boards/common/esp8266/include/periph_conf_common.h index 7f90e018d5..2ca9c9cd82 100644 --- a/boards/common/esp8266/include/periph_conf_common.h +++ b/boards/common/esp8266/include/periph_conf_common.h @@ -208,17 +208,41 @@ static const spi_conf_t spi_config[] = { /** * @name UART configuration * - * All ESP8266 boards have exactly one UART device with fixed pin mapping. - * This UART device is used for flashing and as a console interface. - * Therefore, the number of UART devices is fixed and can not be overridden. - * Used pins are determined by the MCU implementation and are defined here - * only for documentation reasons. + * All ESP8266 boards have two UART devices with two options of pin mappings + * each, however most board will only expose only UART0 and in the GPIO1 and + * GPIO3 pins, although other combinations are possible. In particular, the + * boot ROM will map both GPIO1 and GPIO2 as TX for UART0 on boot, so either + * one can be used for serial communication or flashing the device. + * While UART1 is also available, the only option for UART1 RX pin (GPIO8) is + * used for the board flash, but UART1 TX can be used separately + * + * Pin mapping available: + * UART0 TX: GPIO1 and GPIO2 (both enabled by the boot ROM) + * UART0 RX: GPIO3 + * UART1 TX: GPIO2 and GPIO7 (GPIO7 is used by the flash) + * UART0 RX: GPIO8 (GPIO8 is used by the flash) + * + * UART0 device is used for flashing and as a console interface. UART1 if + * UART1_TXD is defined can be used for communication with other peripherals at + * a different baudrate if desired. * * @{ */ - +#ifndef UART0_TXD #define UART0_TXD GPIO1 /**< TxD pin of UART_DEV(0) */ +#endif /* UART0_TXD */ + +#ifndef UART0_RXD #define UART0_RXD GPIO3 /**< RxD pin of UART_DEV(0) */ +#endif /* UART0_RXD */ + +#ifdef DOXYGEN +#define UART1_TXD GPIO2 /**< TxD pin of UART_DEV(1) */ +#endif /* DOXYGEN */ + +#ifndef UART1_RXD +#define UART1_RXD GPIO_UNDEF /**< RxD pin of UART_DEV(1) */ +#endif /* UART1_RXD */ /** * @brief Static array with configuration for declared UART devices @@ -228,6 +252,12 @@ static const uart_conf_t uart_config[] = { .txd = UART0_TXD, .rxd = UART0_RXD, }, +#ifdef UART1_TXD + { + .txd = UART1_TXD, + .rxd = UART1_RXD, + }, +#endif /* UART1_TXD */ }; /** diff --git a/cpu/esp8266/include/periph_cpu.h b/cpu/esp8266/include/periph_cpu.h index 4ec7c46965..01836bee74 100644 --- a/cpu/esp8266/include/periph_cpu.h +++ b/cpu/esp8266/include/periph_cpu.h @@ -20,6 +20,7 @@ #define PERIPH_CPU_H #include +#include #include "eagle_soc.h" @@ -302,7 +303,7 @@ typedef struct { /** * @brief Maximum number of UART interfaces */ -#define UART_NUMOF_MAX (1) +#define UART_NUMOF_MAX (2) /** @} */ #ifdef __cplusplus diff --git a/cpu/esp8266/periph/gpio.c b/cpu/esp8266/periph/gpio.c index 60e7604edb..0bedcfd360 100644 --- a/cpu/esp8266/periph/gpio.c +++ b/cpu/esp8266/periph/gpio.c @@ -52,9 +52,11 @@ gpio_pin_usage_t _gpio_pin_usage [GPIO_PIN_NUMOF] = { _GPIO, /* gpio0 */ - _UART, /* gpio1 UART0 RxD */ - _GPIO, /* gpio2 */ - _UART, /* gpio3 UART0 TxD */ + /* UART0 is initialized by the boot ROM, this only reflects our selection so + * other devices don't step on it. */ + UART0_TXD == GPIO1 ? _UART : _GPIO, /* gpio1 */ + UART0_TXD == GPIO2 ? _UART : _GPIO, /* gpio2 */ + UART0_RXD == GPIO3 ? _UART : _GPIO, /* gpio3 */ _GPIO, /* gpio4 */ _GPIO, /* gpio5 */ _SPIF, /* gpio6 SPI flash CLK */ diff --git a/cpu/esp_common/periph/uart.c b/cpu/esp_common/periph/uart.c index 9e7316215b..1367bae82c 100644 --- a/cpu/esp_common/periph/uart.c +++ b/cpu/esp_common/periph/uart.c @@ -36,13 +36,13 @@ #include "esp/common_macros.h" #include "rom/ets_sys.h" #include "xtensa/xtensa_api.h" +#include "gpio_arch.h" #define ENABLE_DEBUG 0 #include "debug.h" #ifdef MCU_ESP32 -#include "gpio_arch.h" #include "driver/periph_ctrl.h" #include "soc/gpio_reg.h" #include "soc/gpio_sig_map.h" @@ -56,6 +56,7 @@ #else /* MCU_ESP32 */ +#include "esp/iomux_regs.h" #include "esp8266/uart_struct.h" #ifdef MODULE_ESP_QEMU @@ -98,7 +99,9 @@ static struct uart_hw_t _uarts[] = { .signal_txd = U0TXD_OUT_IDX, .signal_rxd = U0RXD_IN_IDX, .int_src = ETS_UART0_INTR_SOURCE +#endif /* MCU_ESP32 */ }, +#if defined(UART1_TXD) || defined(MCU_ESP32) { .regs = &UART1, .used = false, @@ -106,11 +109,15 @@ static struct uart_hw_t _uarts[] = { .data = UART_DATA_BITS_8, .stop = UART_STOP_BITS_1, .parity = UART_PARITY_NONE, +#ifdef MCU_ESP32 .mod = PERIPH_UART1_MODULE, .signal_txd = U1TXD_OUT_IDX, .signal_rxd = U1RXD_IN_IDX, .int_src = ETS_UART1_INTR_SOURCE +#endif /* MCU_ESP32 */ }, +#endif /* defined(UART1_TXD) || defined(MCU_ESP32) */ +#ifdef MCU_ESP32 { .regs = &UART2, .used = false, @@ -122,8 +129,8 @@ static struct uart_hw_t _uarts[] = { .signal_txd = U2TXD_OUT_IDX, .signal_rxd = U2RXD_IN_IDX, .int_src = ETS_UART2_INTR_SOURCE -#endif /* MCU_ESP32 */ }, +#endif /* MCU_ESP32 */ }; /* declaration of external functions */ @@ -146,7 +153,6 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) assert(uart < UART_NUMOF_MAX); assert(uart < UART_NUMOF); -#ifdef MCU_ESP32 /* UART1 and UART2 have configurable pins */ if ((UART_NUMOF > 0 && uart == UART_DEV(1)) || (UART_NUMOF > 1 && uart == UART_DEV(2))) { @@ -160,8 +166,10 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) } /* try to initialize the pins as GPIOs first */ - if (gpio_init(uart_config[uart].txd, GPIO_OUT) || - gpio_init(uart_config[uart].rxd, GPIO_IN)) { + if ((uart_config[uart].txd != GPIO_UNDEF && + gpio_init(uart_config[uart].txd, GPIO_OUT)) || + (uart_config[uart].rxd != GPIO_UNDEF && + gpio_init(uart_config[uart].rxd, GPIO_IN))) { return -1; } @@ -169,6 +177,7 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) gpio_set_pin_usage(uart_config[uart].txd, _UART); gpio_set_pin_usage(uart_config[uart].rxd, _UART); +#ifdef MCU_ESP32 /* connect TxD pin to the TxD output signal through the GPIO matrix */ GPIO.func_out_sel_cfg[uart_config[uart].txd].func_sel = _uarts[uart].signal_txd; @@ -176,8 +185,21 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) GPIO.func_in_sel_cfg[_uarts[uart].signal_rxd].sig_in_sel = 1; GPIO.func_in_sel_cfg[_uarts[uart].signal_rxd].sig_in_inv = 0; GPIO.func_in_sel_cfg[_uarts[uart].signal_rxd].func_sel = uart_config[uart].rxd; - } +#else + if (uart_config[uart].txd != GPIO_UNDEF) { + uint8_t mux = _gpio_to_iomux[uart_config[uart].txd]; + IOMUX.PIN[mux] = (IOMUX.PIN[mux] & ~IOMUX_PIN_FUNC_MASK) | + IOMUX_FUNC(uart_config[uart].txd == GPIO2 ? 2 : 4); + } + if (uart_config[uart].rxd != GPIO_UNDEF) { + /* There's really only GPIO8 / FUNC(4) for this, but it is normally + * unusable because it is used by the internal flash. */ + uint8_t mux = _gpio_to_iomux[uart_config[uart].rxd]; + IOMUX.PIN[mux] = (IOMUX.PIN[mux] & ~IOMUX_PIN_FUNC_MASK) | + IOMUX_FUNC(4); + } #endif + } _uarts[uart].baudrate = baudrate; /* register interrupt context */