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:
parent
08f1f9768d
commit
52107b2416
@ -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 */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user