1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

esp8266: Support UART1 and other UART0 pins.

The esp8266 CPU has actually two hardware UART peripherals. UART0 is
used by the boot ROM for flashing and serial output during boot,
typically at a baudrate of 74880 bps until the bootloader or application
sets the more standard 115200 baudrate. This UART0 device has two
possible pins for TXD, GPIO1 and GPIO2, which are both set to TXD by the
boot ROM. esp8266 modules will typically have GPIO1 labeled as the TX
pin, but it is possible to use GPIO2 for that purpose even while
flashing the device with esptool.py.

The second device, UART1, also has two options for TXD, GPIO2 and GPIO7,
and only one option for RXD, GPIO8. However, GPIO7 and GPIO8 are used
by the flash internally so those options are not very useful unless
maybe while running from IRAM with the flash disabled, for example for
a debugger over UART1.

This patch allows boards to override UART{0,1}_{R,T}XD in their
periph_conf.h to configure the uart selection. Defining UART1_TX will
make the UART_DEV(1) device available.

Tested with:

```CFLAGS='-DUART1_TXD=GPIO2' make -C tests/periph_uart BOARD=esp8266-esp-12x flash term```

* Connected one USB-UART to the standard GPIO1 and GPIO3 for flashing
  and console. After flashing we see the manual test output at 115200
  bps

* Connected a second USB-UART with RX to GPIO2 running at 74880.

Then run on the first console:
```
> init 1 74880
> send 1 hello
```

The word "hello" appears on the second UART connection.

Note that GPIO2 is used during boot for UART0's TX until the application
or bootloader set it to a regular GPIO, so some boot ROM messages at
74880 bps are visible. After running `init 1 74880` it is set to UART1's
TX.
This commit is contained in:
iosabi 2021-04-25 03:34:38 +02:00
parent 08f1f9768d
commit 52107b2416
4 changed files with 71 additions and 16 deletions

View File

@ -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 */
};
/**

View File

@ -20,6 +20,7 @@
#define PERIPH_CPU_H
#include <stdint.h>
#include <limits.h>
#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

View File

@ -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 */

View File

@ -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 */