You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/11/13 14:59:56 UTC

[incubator-nuttx] branch master updated: esp32: Add support to LilyGO_TBeam V1.1 LoRa/GPS board

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 013b15db2d esp32: Add support to LilyGO_TBeam V1.1 LoRa/GPS board
013b15db2d is described below

commit 013b15db2d44a06baefff1f176e36628466b0c4b
Author: Alan Carvalho de Assis <ac...@gmail.com>
AuthorDate: Sat Nov 12 12:53:35 2022 -0300

    esp32: Add support to LilyGO_TBeam V1.1 LoRa/GPS board
---
 boards/Kconfig                                     |  14 +
 boards/xtensa/esp32/lilygo_tbeam_lora_gps/Kconfig  |   8 +
 .../lilygo_tbeam_lora_gps/configs/gps/defconfig    |  52 +++
 .../lilygo_tbeam_lora_gps/configs/nsh/defconfig    |  47 +++
 .../lilygo_tbeam_lora_gps/configs/sx127x/defconfig |  62 +++
 .../esp32/lilygo_tbeam_lora_gps/include/board.h    |  56 +++
 .../include/board_memorymap.h                      | 128 +++++++
 .../esp32/lilygo_tbeam_lora_gps/scripts/.gitignore |   1 +
 .../esp32/lilygo_tbeam_lora_gps/scripts/Make.defs  |  92 +++++
 .../esp32/lilygo_tbeam_lora_gps/src/Make.defs      |  69 ++++
 .../lilygo_tbeam_lora_gps/src/esp32_appinit.c      |  80 ++++
 .../esp32/lilygo_tbeam_lora_gps/src/esp32_boot.c   |  96 +++++
 .../lilygo_tbeam_lora_gps/src/esp32_bringup.c      | 423 +++++++++++++++++++++
 .../lilygo_tbeam_lora_gps/src/esp32_buttons.c      | 166 ++++++++
 .../esp32/lilygo_tbeam_lora_gps/src/esp32_gpio.c   | 392 +++++++++++++++++++
 .../esp32/lilygo_tbeam_lora_gps/src/esp32_reset.c  |  63 +++
 .../esp32/lilygo_tbeam_lora_gps/src/esp32_sx127x.c | 227 +++++++++++
 .../lilygo_tbeam_lora_gps/src/esp32_userleds.c     |  95 +++++
 .../src/lilygo_tbeam_lora_gps.h                    | 172 +++++++++
 19 files changed, 2243 insertions(+)

diff --git a/boards/Kconfig b/boards/Kconfig
index 8fa8111c41..a8c7dd9555 100644
--- a/boards/Kconfig
+++ b/boards/Kconfig
@@ -266,6 +266,16 @@ config ARCH_BOARD_ESP32_WROVERKIT
   			LCD screen
   			MicroSD card slot
 
+config ARCH_BOARD_LILYGO_TBEAM_LORA_GPS
+	bool "LilyGO TBeam V1.1 LoRa/GPS"
+	depends on ARCH_CHIP_ESP32WROOM32
+	select ARCH_HAVE_LEDS
+	select ARCH_HAVE_BUTTONS
+	select ARCH_HAVE_IRQBUTTONS if ESP32_GPIO_IRQ
+	---help---
+		LilyGO_TBeam_V1.1 LoRa/GPS is an ESP32 board with LoRa and GPS.
+		More info: https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series/
+
 config ARCH_BOARD_TTGO_LORA_ESP32
 	bool "TTGO LoRa SX1276 ESP32"
 	depends on ARCH_CHIP_ESP32WROOM32
@@ -2871,6 +2881,7 @@ config ARCH_BOARD
 	default "tm4c1294-launchpad"       if ARCH_BOARD_TM4C1294_LAUNCHPAD
 	default "tm4c129e-launchpad"       if ARCH_BOARD_TM4C129E_LAUNCHPAD
 	default "tms570ls31x-usb-kit"      if ARCH_BOARD_TMS570LS31X_USB_KIT
+	default "lilygo_tbeam_lora_gps"    if ARCH_BOARD_LILYGO_TBEAM_LORA_GPS
 	default "ttgo_lora_esp32"          if ARCH_BOARD_TTGO_LORA_ESP32
 	default "ttgo_t_display_esp32"     if ARCH_BOARD_TTGO_T_DISPLAY_ESP32
 	default "twr-k60n512"              if ARCH_BOARD_TWR_K60N512
@@ -3664,6 +3675,9 @@ endif
 if ARCH_BOARD_ESP32_WROVERKIT
 source "boards/xtensa/esp32/esp32-wrover-kit/Kconfig"
 endif
+if ARCH_BOARD_LILYGO_TBEAM_LORA_GPS
+source "boards/xtensa/esp32/lilygo_tbeam_lora_gps/Kconfig"
+endif
 if ARCH_BOARD_TTGO_LORA_ESP32
 source "boards/xtensa/esp32/ttgo_lora_esp32/Kconfig"
 endif
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/Kconfig b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/Kconfig
new file mode 100644
index 0000000000..1834639805
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/Kconfig
@@ -0,0 +1,8 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+if ARCH_BOARD_LILYGO_TBEAM_LORA_GPS
+
+endif # ARCH_BOARD_LILYGO_TBEAM_LORA_GPS
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/configs/gps/defconfig b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/configs/gps/defconfig
new file mode 100644
index 0000000000..e2e3c4aa55
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/configs/gps/defconfig
@@ -0,0 +1,52 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_ARCH_LEDS is not set
+# CONFIG_ESP32_FLASH_DETECT is not set
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+# CONFIG_NSH_CMDPARMS is not set
+CONFIG_ARCH="xtensa"
+CONFIG_ARCH_BOARD="lilygo_tbeam_lora_gps"
+CONFIG_ARCH_BOARD_COMMON=y
+CONFIG_ARCH_BOARD_LILYGO_TBEAM_LORA_GPS=y
+CONFIG_ARCH_CHIP="esp32"
+CONFIG_ARCH_CHIP_ESP32=y
+CONFIG_ARCH_CHIP_ESP32WROOM32=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_XTENSA=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_ESP32_DEFAULT_CPU_FREQ_80=y
+CONFIG_ESP32_UART0=y
+CONFIG_ESP32_UART1=y
+CONFIG_ESP32_UART1_RXPIN=34
+CONFIG_ESP32_UART1_TXPIN=12
+CONFIG_EXAMPLES_GPS=y
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=3072
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_MM_REGIONS=3
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSTEM_NSH=y
+CONFIG_UART0_SERIAL_CONSOLE=y
+CONFIG_UART1_BAUD=9600
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/configs/nsh/defconfig b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/configs/nsh/defconfig
new file mode 100644
index 0000000000..b2bf897be5
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/configs/nsh/defconfig
@@ -0,0 +1,47 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_ARCH_LEDS is not set
+# CONFIG_ESP32_FLASH_DETECT is not set
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+# CONFIG_NSH_CMDPARMS is not set
+CONFIG_ARCH="xtensa"
+CONFIG_ARCH_BOARD="lilygo_tbeam_lora_gps"
+CONFIG_ARCH_BOARD_COMMON=y
+CONFIG_ARCH_BOARD_LILYGO_TBEAM_LORA_GPS=y
+CONFIG_ARCH_CHIP="esp32"
+CONFIG_ARCH_CHIP_ESP32=y
+CONFIG_ARCH_CHIP_ESP32WROOM32=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_XTENSA=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_ESP32_DEFAULT_CPU_FREQ_80=y
+CONFIG_ESP32_UART0=y
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=3072
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_MM_REGIONS=3
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSTEM_NSH=y
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/configs/sx127x/defconfig b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/configs/sx127x/defconfig
new file mode 100644
index 0000000000..865beb7eb8
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/configs/sx127x/defconfig
@@ -0,0 +1,62 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_ARCH_LEDS is not set
+# CONFIG_ESP32_FLASH_DETECT is not set
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+# CONFIG_NSH_CMDPARMS is not set
+CONFIG_ARCH="xtensa"
+CONFIG_ARCH_BOARD="lilygo_tbeam_lora_gps"
+CONFIG_ARCH_BOARD_COMMON=y
+CONFIG_ARCH_BOARD_LILYGO_TBEAM_LORA_GPS=y
+CONFIG_ARCH_CHIP="esp32"
+CONFIG_ARCH_CHIP_ESP32=y
+CONFIG_ARCH_CHIP_ESP32WROOM32=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_XTENSA=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DRIVERS_LPWAN=y
+CONFIG_DRIVERS_WIRELESS=y
+CONFIG_ESP32_DEFAULT_CPU_FREQ_80=y
+CONFIG_ESP32_SPI2=y
+CONFIG_ESP32_SPI2_CLKPIN=5
+CONFIG_ESP32_SPI2_CSPIN=18
+CONFIG_ESP32_SPI2_MISOPIN=19
+CONFIG_ESP32_SPI2_MOSIPIN=27
+CONFIG_ESP32_UART0=y
+CONFIG_EXAMPLES_SX127X=y
+CONFIG_EXAMPLES_SX127X_RFFREQ=868000000
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=3072
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_LPWAN_SX127X=y
+CONFIG_LPWAN_SX127X_FSKOOK=y
+CONFIG_LPWAN_SX127X_RFFREQ_DEFAULT=868000000
+CONFIG_LPWAN_SX127X_RXSUPPORT=y
+CONFIG_LPWAN_SX127X_TXSUPPORT=y
+CONFIG_MM_REGIONS=3
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSTEM_NSH=y
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/include/board.h b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/include/board.h
new file mode 100644
index 0000000000..15e7e4c3e3
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/include/board.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+ * boards/xtensa/esp32/lilygo_tbeam_lora_gps/include/board.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __BOARDS_XTENSA_ESP32_TTGO_LORA_ESP32_INCLUDE_BOARD_H
+#define __BOARDS_XTENSA_ESP32_TTGO_LORA_ESP32_INCLUDE_BOARD_H
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Clocking *****************************************************************/
+
+/* The LilyGO_TBeam_LoRa_GPS is fitted with a 40MHz crystal */
+
+#ifdef CONFIG_ESP32_XTAL_26MHz
+#  define BOARD_XTAL_FREQUENCY  26000000
+#else
+#  define BOARD_XTAL_FREQUENCY  40000000
+#endif
+
+#ifdef CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ
+#  define BOARD_CLOCK_FREQUENCY (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000)
+#else
+#  define BOARD_CLOCK_FREQUENCY 80000000
+#endif
+
+/* LED definitions **********************************************************/
+
+/* Define how many LEDs this board has (needed by userleds) */
+
+#define BOARD_NLEDS       1
+
+/* GPIO pins used by the GPIO Subsystem */
+
+#define BOARD_NGPIOOUT    1 /* Amount of GPIO Output pins */
+#define BOARD_NGPIOIN     1 /* Amount of GPIO Input without Interruption */
+#define BOARD_NGPIOINT    1 /* Amount of GPIO Input w/ Interruption pins */
+
+#endif /* __BOARDS_XTENSA_ESP32_TTGO_LORA_ESP32_INCLUDE_BOARD_H */
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/include/board_memorymap.h b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/include/board_memorymap.h
new file mode 100644
index 0000000000..69a5fffdfe
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/include/board_memorymap.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+ * boards/xtensa/esp32/lilygo_tbeam_lora_gps/include/board_memorymap.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __BOARDS_XTENSA_ESP32_TTGO_LORA_ESP32_INCLUDE_BOARD_MEMORYMAP_H
+#define __BOARDS_XTENSA_ESP32_TTGO_LORA_ESP32_INCLUDE_BOARD_MEMORYMAP_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Kernel ROM */
+
+#define KIROM_START     (uintptr_t)__kirom_start
+#define KIROM_SIZE      (uintptr_t)__kirom_size
+#define KDROM_START     (uintptr_t)__kdrom_start
+#define KDROM_SIZE      (uintptr_t)__kdrom_size
+
+/* Kernel RAM */
+
+#define KIRAM_0_START   (uintptr_t)__kiram_0_start
+#define KIRAM_0_SIZE    (uintptr_t)__kiram_0_size
+#define KIRAM_0_END     (uintptr_t)__kiram_0_end
+#define KIRAM_1_START   (uintptr_t)__kiram_1_start
+#define KIRAM_1_SIZE    (uintptr_t)__kiram_1_size
+#define KIRAM_1_END     (uintptr_t)__kiram_1_end
+#define KDRAM_0_START   (uintptr_t)__kdram_0_start
+#define KDRAM_0_SIZE    (uintptr_t)__kdram_0_size
+#define KDRAM_0_END     (uintptr_t)__kdram_0_end
+#define KDRAM_1_START   (uintptr_t)__kdram_1_start
+#define KDRAM_1_SIZE    (uintptr_t)__kdram_1_size
+#define KDRAM_1_END     (uintptr_t)__kdram_1_end
+
+/* Exception vectors */
+
+#define VECTORS_START   (uintptr_t)__vectors_start
+#define VECTORS_END     (uintptr_t)__vectors_end
+
+/* User ROM */
+
+#define UIROM_START     (uintptr_t)__uirom_start
+#define UIROM_SIZE      (uintptr_t)__uirom_size
+#define UIROM_END       (uintptr_t)__uirom_end
+#define UDROM_START     (uintptr_t)__udrom_start
+#define UDROM_SIZE      (uintptr_t)__udrom_size
+#define UDROM_END       (uintptr_t)__udrom_end
+
+/* User RAM */
+
+#define UIRAM_START     (uintptr_t)__uiram_start
+#define UIRAM_SIZE      (uintptr_t)__uiram_size
+#define UIRAM_END       (uintptr_t)__uiram_end
+#define UDRAM_START     (uintptr_t)__udram_start
+#define UDRAM_SIZE      (uintptr_t)__udram_size
+#define UDRAM_END       (uintptr_t)__udram_end
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* Kernel ROM (RX)  */
+
+extern uint8_t          __kirom_start[];
+extern uint8_t          __kirom_size[];
+extern uint8_t          __kdrom_start[];
+extern uint8_t          __kdrom_size[];
+
+/* Kernel RAM (RW) */
+
+extern uint8_t          __kiram_0_start[];
+extern uint8_t          __kiram_0_size[];
+extern uint8_t          __kiram_0_end[];
+extern uint8_t          __kiram_1_start[];
+extern uint8_t          __kiram_1_size[];
+extern uint8_t          __kiram_1_end[];
+extern uint8_t          __kdram_0_start[];
+extern uint8_t          __kdram_0_size[];
+extern uint8_t          __kdram_0_end[];
+extern uint8_t          __kdram_1_start[];
+extern uint8_t          __kdram_1_size[];
+extern uint8_t          __kdram_1_end[];
+
+/* Exception vectors */
+
+extern uint8_t          __vectors_start[];
+extern uint8_t          __vectors_end[];
+
+/* User ROM (RX) */
+
+extern uint8_t          __uirom_start[];
+extern uint8_t          __uirom_size[];
+extern uint8_t          __uirom_end[];
+extern uint8_t          __udrom_start[];
+extern uint8_t          __udrom_size[];
+extern uint8_t          __udrom_end[];
+
+/* User RAM (RW) */
+
+extern uint8_t          __uiram_start[];
+extern uint8_t          __uiram_size[];
+extern uint8_t          __uiram_end[];
+extern uint8_t          __udram_start[];
+extern uint8_t          __udram_size[];
+extern uint8_t          __udram_end[];
+
+#endif /* __BOARDS_XTENSA_ESP32_TTGO_LORA_ESP32_INCLUDE_BOARD_MEMORYMAP_H */
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/scripts/.gitignore b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/scripts/.gitignore
new file mode 100644
index 0000000000..461270524b
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/scripts/.gitignore
@@ -0,0 +1 @@
+/esp32_out.ld
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/scripts/Make.defs b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/scripts/Make.defs
new file mode 100644
index 0000000000..89fe0afde0
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/scripts/Make.defs
@@ -0,0 +1,92 @@
+############################################################################
+# boards/xtensa/esp32/ttgo_lora_esp32/scripts/Make.defs
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+include $(TOPDIR)/.config
+include $(TOPDIR)/tools/Config.mk
+include $(TOPDIR)/tools/esp32/Config.mk
+include $(TOPDIR)/arch/xtensa/src/lx6/Toolchain.defs
+
+# This is the generated memory layout linker script.  It will always be
+# generated at the board level.
+
+ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32_out.ld
+
+# Pick the linker scripts from the board level if they exist, if not
+# pick the common linker scripts.
+
+ifneq ($(wildcard $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32.ld),)
+	ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32.ld
+else
+	ifeq ($(CONFIG_BUILD_PROTECTED),y)
+		ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)kernel-space.ld
+	else
+		ifeq ($(CONFIG_ESP32_APP_FORMAT_MCUBOOT),y)
+			ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32_mcuboot.ld
+		else
+			ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32.ld
+		endif
+	endif
+endif
+
+ifneq ($(wildcard $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32_rom.ld),)
+	ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32_rom.ld
+else
+	ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32_rom.ld
+endif
+
+ifneq ($(wildcard $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32.template.ld),)
+	LDSCRIPT_TEMPLATE = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32.template.ld
+else
+	ifeq ($(CONFIG_BUILD_PROTECTED),y)
+		LDSCRIPT_TEMPLATE = $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)protected.template.ld
+	else
+		LDSCRIPT_TEMPLATE = $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)flat.template.ld
+	endif
+endif
+
+ARCHPICFLAGS = -fpic
+
+# if SPIRAM/PSRAM is used then we need to include a workaround
+
+ifeq ($(CONFIG_ESP32_SPIRAM),y)
+  ARCHCFLAGS += -mfix-esp32-psram-cache-issue
+endif
+
+CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
+CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
+CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
+CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
+CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
+AFLAGS := $(CFLAGS) -D__ASSEMBLY__
+
+# Loadable module definitions
+
+CMODULEFLAGS = $(CFLAGS) -mtext-section-literals
+
+LDMODULEFLAGS = -r -e module_initialize
+LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld)
+
+# ELF module definitions
+
+CELFFLAGS = $(CFLAGS) -mtext-section-literals
+CXXELFFLAGS = $(CXXFLAGS) -mtext-section-literals
+
+LDELFFLAGS = -r -e main
+LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld)
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/Make.defs b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/Make.defs
new file mode 100644
index 0000000000..d4e04843c6
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/Make.defs
@@ -0,0 +1,69 @@
+############################################################################
+# boards/xtensa/esp32/ttgo_lora_esp32/src/Make.defs
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+include $(TOPDIR)/Make.defs
+
+CONFIGFILE = $(TOPDIR)$(DELIM)include$(DELIM)nuttx$(DELIM)config.h
+
+CSRCS = esp32_boot.c esp32_bringup.c
+
+ifeq ($(CONFIG_BOARDCTL),y)
+CSRCS += esp32_appinit.c
+ifeq ($(CONFIG_BOARDCTL_RESET),y)
+CSRCS += esp32_reset.c
+endif
+endif
+
+ifeq ($(CONFIG_MMCSD),y)
+CSRCS += esp32_mmcsd.c
+endif
+
+ifeq ($(CONFIG_DEV_GPIO),y)
+CSRCS += esp32_gpio.c
+endif
+
+ifeq ($(CONFIG_USERLED),y)
+CSRCS += esp32_userleds.c
+endif
+
+ifeq ($(CONFIG_ARCH_BUTTONS),y)
+CSRCS += esp32_buttons.c
+endif
+
+ifeq ($(CONFIG_LPWAN_SX127X),y)
+CSRCS += esp32_sx127x.c
+endif
+
+SCRIPTOUT = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32_out.ld
+
+.PHONY = context distclean
+
+$(SCRIPTOUT): $(LDSCRIPT_TEMPLATE) $(CONFIGFILE)
+	$(Q) $(CC) -isystem $(TOPDIR)/include -C -P -x c -E $(LDSCRIPT_TEMPLATE) -o $@
+
+context:: $(SCRIPTOUT)
+
+distclean::
+	$(call DELFILE, $(SCRIPTOUT))
+
+DEPPATH += --dep-path board
+VPATH += :board
+CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)
+
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_appinit.c b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_appinit.c
new file mode 100644
index 0000000000..b181e05158
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_appinit.c
@@ -0,0 +1,80 @@
+/****************************************************************************
+ * boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_appinit.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <nuttx/board.h>
+
+#include "lilygo_tbeam_lora_gps.h"
+
+#ifdef CONFIG_BOARDCTL
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_app_initialize
+ *
+ * Description:
+ *   Perform application specific initialization.  This function is never
+ *   called directly from application code, but only indirectly via the
+ *   (non-standard) boardctl() interface using the command BOARDIOC_INIT.
+ *
+ * Input Parameters:
+ *   arg - The boardctl() argument is passed to the board_app_initialize()
+ *         implementation without modification.  The argument has no
+ *         meaning to NuttX; the meaning of the argument is a contract
+ *         between the board-specific initialization logic and the
+ *         matching application logic.  The value could be such things as a
+ *         mode enumeration value, a set of DIP switch settings, a
+ *         pointer to configuration data read from a file or serial FLASH,
+ *         or whatever you would like to do with it.  Every implementation
+ *         should accept zero/NULL as a default configuration.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned on
+ *   any failure to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int board_app_initialize(uintptr_t arg)
+{
+#ifdef CONFIG_BOARD_LATE_INITIALIZE
+  /* Board initialization already performed by board_late_initialize() */
+
+  return OK;
+#else
+  /* Perform board-specific initialization */
+
+  return esp32_bringup();
+#endif
+}
+
+#endif /* CONFIG_BOARDCTL */
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_boot.c b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_boot.c
new file mode 100644
index 0000000000..c44554a996
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_boot.c
@@ -0,0 +1,96 @@
+/****************************************************************************
+ * boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_boot.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <debug.h>
+
+#include <nuttx/board.h>
+#include <nuttx/mm/mm.h>
+#include <arch/board/board.h>
+#include <arch/esp32/memory_layout.h>
+
+#include "lilygo_tbeam_lora_gps.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_board_initialize
+ *
+ * Description:
+ *   All ESP32 architectures must provide the following entry point.
+ *   This entry point is called early in the initialization -- after all
+ *   memory has been configured and mapped but before any devices have been
+ *   initialized.
+ *
+ ****************************************************************************/
+
+void esp32_board_initialize(void)
+{
+}
+
+/****************************************************************************
+ * Name: board_late_initialize
+ *
+ * Description:
+ *   If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional
+ *   initialization call will be performed in the boot-up sequence to a
+ *   function called board_late_initialize().  board_late_initialize() will
+ *   be called immediately after up_initialize() is called and just before
+ *   the initial application is started.  This additional initialization
+ *   phase may be used, for example, to initialize board-specific device
+ *   drivers.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_BOARD_LATE_INITIALIZE
+void board_late_initialize(void)
+{
+  /* Perform board-specific initialization */
+
+  esp32_bringup();
+
+#ifdef CONFIG_SMP
+  /* To avoid corrupting the heap, this region of memory (~3KB) is not
+   * included until the APP CPU has started.
+   * So we can't add it with the rest of the regions at xtensa_add_region(),
+   * that function is called early from up_initialize().  We wait until the
+   * SMP bringup is complete.
+   */
+
+  umm_addregion((void *)HEAP_REGION_ROMAPP_START,
+                (size_t)(HEAP_REGION_ROMAPP_END - HEAP_REGION_ROMAPP_START));
+#endif
+}
+#endif
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_bringup.c b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_bringup.c
new file mode 100644
index 0000000000..d1b197c142
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_bringup.c
@@ -0,0 +1,423 @@
+/****************************************************************************
+ * boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_bringup.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <syslog.h>
+#include <debug.h>
+#include <stdio.h>
+
+#include <errno.h>
+#if defined(CONFIG_ESP32_EFUSE)
+#include <nuttx/efuse/efuse.h>
+#endif
+#include <nuttx/fs/fs.h>
+#include <nuttx/himem/himem.h>
+
+#if defined(CONFIG_ESP32_EFUSE)
+#include "esp32_efuse.h"
+#endif
+#include "esp32_partition.h"
+
+#ifdef CONFIG_USERLED
+#  include <nuttx/leds/userled.h>
+#endif
+
+#ifdef CONFIG_CAN_MCP2515
+#  include "esp32_mcp2515.h"
+#endif
+
+#ifdef CONFIG_TIMER
+#include <esp32_tim_lowerhalf.h>
+#endif
+
+#ifdef CONFIG_ONESHOT
+#  include "esp32_board_oneshot.h"
+#endif
+
+#ifdef CONFIG_WATCHDOG
+#  include "esp32_board_wdt.h"
+#endif
+
+#ifdef CONFIG_ESP32_SPIFLASH
+#  include "esp32_board_spiflash.h"
+#endif
+
+#ifdef CONFIG_ESP32_BLE
+#  include "esp32_ble.h"
+#endif
+
+#ifdef CONFIG_ESP32_WIFI
+#  include "esp32_board_wlan.h"
+#endif
+
+#ifdef CONFIG_ESP32_I2C
+#  include "esp32_board_i2c.h"
+#endif
+
+#ifdef CONFIG_SENSORS_BMP180
+#  include "esp32_bmp180.h"
+#endif
+
+#ifdef CONFIG_LCD_HT16K33
+#  include "esp32_ht16k33.h"
+#endif
+
+#ifdef CONFIG_ESP32_AES_ACCELERATOR
+#  include "esp32_aes.h"
+#endif
+
+#ifdef CONFIG_ESP32_RT_TIMER
+#  include "esp32_rt_timer.h"
+#endif
+
+#ifdef CONFIG_INPUT_BUTTONS
+#  include <nuttx/input/buttons.h>
+#endif
+
+#ifdef CONFIG_RTC_DRIVER
+#  include "esp32_rtc_lowerhalf.h"
+#endif
+
+#ifdef CONFIG_SPI_DRIVER
+#  include "esp32_spi.h"
+#endif
+
+#include "lilygo_tbeam_lora_gps.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_bringup
+ *
+ * Description:
+ *   Perform architecture-specific initialization
+ *
+ *   CONFIG_BOARD_LATE_INITIALIZE=y :
+ *     Called from board_late_initialize().
+ *
+ *   CONFIG_BOARD_LATE_INITIALIZE=n && CONFIG_BOARDCTL=y :
+ *     Called from the NSH library
+ *
+ ****************************************************************************/
+
+int esp32_bringup(void)
+{
+  int ret;
+
+#ifdef CONFIG_ESP32_AES_ACCELERATOR
+  ret = esp32_aes_init();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR,
+             "ERROR: Failed to initialize AES: %d\n", ret);
+    }
+#endif
+
+#if defined(CONFIG_ESP32_EFUSE)
+  ret = esp32_efuse_initialize("/dev/efuse");
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to init EFUSE: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_FS_PROCFS
+  /* Mount the procfs file system */
+
+  ret = nx_mount(NULL, "/proc", "procfs", 0, NULL);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to mount procfs at /proc: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_FS_TMPFS
+  /* Mount the tmpfs file system */
+
+  ret = nx_mount(NULL, CONFIG_LIBC_TMPDIR, "tmpfs", 0, NULL);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to mount tmpfs at %s: %d\n",
+             CONFIG_LIBC_TMPDIR, ret);
+    }
+#endif
+
+#ifdef CONFIG_ESP32_SPIFLASH
+  ret = esp32_spiflash_init();
+  if (ret)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n");
+      return ret;
+    }
+#endif
+
+#ifdef CONFIG_ESP32_PARTITION_TABLE
+  ret = esp32_partition_init();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to initialize partition error=%d\n",
+             ret);
+      return ret;
+    }
+#endif
+
+#ifdef CONFIG_ESP32_RT_TIMER
+  ret = esp32_rt_timer_init();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "Failed to initialize RT timer: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_LPWAN_SX127X
+  ret = esp32_lpwaninitialize();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR,
+             "ERROR: Failed to initialize wireless driver: %d\n",
+             ret);
+    }
+#endif /* CONFIG_LPWAN_SX127X */
+
+#ifdef CONFIG_ESP32_BLE
+  ret = esp32_ble_initialize();
+  if (ret)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to initialize BLE: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_ESP32_WIFI
+  ret = board_wlan_init();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to initialize wireless subsystem=%d\n",
+             ret);
+      return ret;
+    }
+#endif
+
+/* First, register the timer drivers and let timer 1 for oneshot
+ * if it is enabled.
+ */
+
+#ifdef CONFIG_TIMER
+
+#if defined(CONFIG_ESP32_TIMER0) && !defined(CONFIG_ESP32_RT_TIMER)
+  ret = esp32_timer_initialize("/dev/timer0", TIMER0);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR,
+             "ERROR: Failed to initialize timer driver: %d\n",
+             ret);
+      return ret;
+    }
+#endif
+
+#if defined(CONFIG_ESP32_TIMER1) && !defined(CONFIG_ONESHOT)
+  ret = esp32_timer_initialize("/dev/timer1", TIMER1);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR,
+             "ERROR: Failed to initialize timer driver: %d\n",
+             ret);
+      return ret;
+    }
+#endif
+
+#ifdef CONFIG_ESP32_TIMER2
+  ret = esp32_timer_initialize("/dev/timer2", TIMER2);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR,
+             "ERROR: Failed to initialize timer driver: %d\n",
+             ret);
+      return ret;
+    }
+#endif
+
+#ifdef CONFIG_ESP32_TIMER3
+  ret = esp32_timer_initialize("/dev/timer3", TIMER3);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR,
+             "ERROR: Failed to initialize timer driver: %d\n",
+             ret);
+      return ret;
+    }
+#endif
+
+#endif /* CONFIG_TIMER */
+
+  /* Now register one oneshot driver */
+
+#if defined(CONFIG_ONESHOT) && defined(CONFIG_ESP32_TIMER1)
+
+  ret = esp32_oneshot_init(ONESHOT_TIMER, ONESHOT_RESOLUTION_US);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: esp32_oneshot_init() failed: %d\n", ret);
+    }
+
+#endif /* CONFIG_ONESHOT */
+
+#ifdef CONFIG_USERLED
+  /* Register the LED driver */
+
+  ret = userled_lower_initialize("/dev/userleds");
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: userled_lower_initialize() failed: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_CAN_MCP2515
+  /* Configure and initialize the MCP2515 CAN device */
+
+  ret = board_mcp2515_initialize(0);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: board_mcp2515_initialize() failed: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_WATCHDOG
+  /* Configure watchdog timer */
+
+  ret = board_wdt_init();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR,
+             "ERROR: Failed to initialize watchdog drivers: %d\n",
+             ret);
+    }
+#endif
+
+#ifdef CONFIG_DEV_GPIO
+  ret = esp32_gpio_init();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "Failed to initialize GPIO Driver: %d\n", ret);
+      return ret;
+    }
+#endif
+
+#ifdef CONFIG_I2C_DRIVER
+
+#ifdef CONFIG_ESP32_I2C0
+  ret = esp32_i2c_register(0);
+
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "Failed to initialize I2C Driver for I2C0: %d\n", ret);
+      return ret;
+    }
+#endif
+
+#ifdef CONFIG_ESP32_I2C1
+  ret = esp32_i2c_register(1);
+
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "Failed to initialize I2C Driver for I2C1: %d\n", ret);
+      return ret;
+    }
+#endif
+
+#endif
+
+#ifdef CONFIG_SENSORS_BMP180
+  /* Try to register BMP180 device in I2C0 */
+
+  ret = board_bmp180_initialize(0, 0);
+
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "Failed to initialize BMP180 driver: %d\n", ret);
+      return ret;
+    }
+#endif
+
+#ifdef CONFIG_LCD_HT16K33
+  /* Try to register HT16K33 in the I2C0 */
+
+  ret = board_ht16k33_initialize(0, 0);
+
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "Failed to initialize HT16K33 driver: %d\n", ret);
+      return ret;
+    }
+#endif
+
+#ifdef CONFIG_INPUT_BUTTONS
+  /* Register the BUTTON driver */
+
+  ret = btn_lower_initialize("/dev/buttons");
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_RTC_DRIVER
+  /* Instantiate the ESP32 RTC driver */
+
+  ret = esp32_rtc_driverinit();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR,
+             "ERROR: Failed to Instantiate the RTC driver: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_SPI_DRIVER
+#  ifdef CONFIG_ESP32_SPI2
+  ret = board_spidev_initialize(ESP32_SPI2);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "Failed to initialize SPI%d driver: %d\n",
+             ESP32_SPI2, ret);
+    }
+#  endif
+#endif
+
+  /* If we got here then perhaps not all initialization was successful, but
+   * at least enough succeeded to bring-up NSH with perhaps reduced
+   * capabilities.
+   */
+
+  UNUSED(ret);
+  return OK;
+}
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_buttons.c b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_buttons.c
new file mode 100644
index 0000000000..fce4b49d0e
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_buttons.c
@@ -0,0 +1,166 @@
+/****************************************************************************
+ * boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_buttons.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/board.h>
+#include <nuttx/irq.h>
+#include <arch/irq.h>
+
+#include "esp32_gpio.h"
+
+#include "lilygo_tbeam_lora_gps.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_button_initialize
+ *
+ * Description:
+ *   board_button_initialize() must be called to initialize button resources.
+ *   After that, board_buttons() may be called to collect the current state
+ *   of all buttons or board_button_irq() may be called to register button
+ *   interrupt handlers.
+ *
+ ****************************************************************************/
+
+uint32_t board_button_initialize(void)
+{
+  esp32_configgpio(BUTTON_BOOT, INPUT_FUNCTION_3 | PULLUP);
+  return 1;
+}
+
+/****************************************************************************
+ * Name: board_buttons
+ *
+ * Description:
+ *   After board_button_initialize() has been called, board_buttons() may be
+ *   called to collect the state of all buttons.  board_buttons() returns an
+ *   8-bit bit set with each bit associated with a button.  See the
+ *   BUTTON_*_BIT  definitions in board.h for the meaning of each bit.
+ *
+ ****************************************************************************/
+
+uint32_t board_buttons(void)
+{
+  uint8_t ret = 0;
+  int i = 0;
+  int n = 0;
+
+  bool b0 = esp32_gpioread(BUTTON_BOOT);
+
+  for (i = 0; i < 10; i++)
+    {
+      up_mdelay(1); /* TODO */
+
+      bool b1 = esp32_gpioread(BUTTON_BOOT);
+
+      if (b0 == b1)
+        {
+          n++;
+        }
+      else
+        {
+          n = 0;
+        }
+
+      if (3 == n)
+        {
+          break;
+        }
+
+      b0 = b1;
+    }
+
+  iinfo("b=%d n=%d\n", b0, n);
+
+  /* Low value means that the button is pressed */
+
+  if (!b0)
+    {
+      ret = 0x1;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: board_button_irq
+ *
+ * Description:
+ *   board_button_irq() may be called to register an interrupt handler that
+ *   will be called when a button is depressed or released.  The ID value is
+ *   a button enumeration value that uniquely identifies a button resource.
+ *   See the BUTTON_* definitions in board.h for the meaning of enumeration
+ *   value.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_IRQBUTTONS
+int board_button_irq(int id, xcpt_t irqhandler, void *arg)
+{
+  int ret;
+  DEBUGASSERT(id == BUTTON_BOOT);
+
+  int irq = ESP32_PIN2IRQ(BUTTON_BOOT);
+
+  if (NULL != irqhandler)
+    {
+      /* Make sure the interrupt is disabled */
+
+      esp32_gpioirqdisable(irq);
+
+      ret = irq_attach(irq, irqhandler, arg);
+      if (ret < 0)
+        {
+          syslog(LOG_ERR, "ERROR: irq_attach() failed: %d\n", ret);
+          return ret;
+        }
+
+      gpioinfo("Attach %p\n", irqhandler);
+
+      gpioinfo("Enabling the interrupt\n");
+
+      /* Configure the interrupt for rising and falling edges */
+
+      esp32_gpioirqenable(irq, CHANGE);
+    }
+  else
+    {
+      gpioinfo("Disable the interrupt\n");
+      esp32_gpioirqdisable(irq);
+    }
+
+  return OK;
+}
+#endif
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_gpio.c b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_gpio.c
new file mode 100644
index 0000000000..3b39006701
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_gpio.c
@@ -0,0 +1,392 @@
+/****************************************************************************
+ * boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_gpio.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <nuttx/irq.h>
+#include <arch/irq.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/ioexpander/gpio.h>
+
+#include <arch/board/board.h>
+
+#include "esp32_gpio.h"
+#include "hardware/esp32_gpio_sigmap.h"
+
+#include "lilygo_tbeam_lora_gps.h"
+
+#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if !defined(CONFIG_ESP32_GPIO_IRQ) && BOARD_NGPIOINT > 0
+#  error "NGPIOINT is > 0 and GPIO interrupts aren't enabled"
+#endif
+
+/* Output pins. GPIO15 is used as an example, any other outputs could be
+ * used.
+ */
+
+#define GPIO_OUT1    15
+
+/* Input pins. GPIO18 is used as an example, any other inputs could be
+ * used.
+ */
+
+#define GPIO_IN1     18
+
+/* Interrupt pins.  GPIO22 is used as an example, any other inputs could be
+ * used.
+ */
+
+#define GPIO_IRQPIN1  22
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct esp32gpio_dev_s
+{
+  struct gpio_dev_s gpio;
+  uint8_t id;
+};
+
+struct esp32gpint_dev_s
+{
+  struct esp32gpio_dev_s esp32gpio;
+  pin_interrupt_t callback;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#if BOARD_NGPIOOUT > 0
+static int gpout_read(struct gpio_dev_s *dev, bool *value);
+static int gpout_write(struct gpio_dev_s *dev, bool value);
+#endif
+
+#if BOARD_NGPIOIN > 0
+static int gpin_read(struct gpio_dev_s *dev, bool *value);
+#endif
+
+#if BOARD_NGPIOINT > 0
+static int gpint_read(struct gpio_dev_s *dev, bool *value);
+static int gpint_attach(struct gpio_dev_s *dev,
+                        pin_interrupt_t callback);
+static int gpint_enable(struct gpio_dev_s *dev, bool enable);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#if BOARD_NGPIOOUT > 0
+static const struct gpio_operations_s gpout_ops =
+{
+  .go_read   = gpout_read,
+  .go_write  = gpout_write,
+  .go_attach = NULL,
+  .go_enable = NULL,
+};
+
+/* This array maps the GPIO pins used as OUTPUT */
+
+static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] =
+{
+  GPIO_OUT1
+};
+
+static struct esp32gpio_dev_s g_gpout[BOARD_NGPIOOUT];
+#endif
+
+#if BOARD_NGPIOIN > 0
+static const struct gpio_operations_s gpin_ops =
+{
+  .go_read   = gpin_read,
+  .go_write  = NULL,
+  .go_attach = NULL,
+  .go_enable = NULL,
+};
+
+/* This array maps the GPIO pins used as INTERRUPT INPUTS */
+
+static const uint32_t g_gpioinputs[BOARD_NGPIOIN] =
+{
+  GPIO_IN1
+};
+
+static struct esp32gpio_dev_s g_gpin[BOARD_NGPIOIN];
+#endif
+
+#if BOARD_NGPIOINT > 0
+static const struct gpio_operations_s gpint_ops =
+{
+  .go_read   = gpint_read,
+  .go_write  = NULL,
+  .go_attach = gpint_attach,
+  .go_enable = gpint_enable,
+};
+
+/* This array maps the GPIO pins used as INTERRUPT INPUTS */
+
+static const uint32_t g_gpiointinputs[BOARD_NGPIOINT] =
+{
+  GPIO_IRQPIN1,
+};
+
+static struct esp32gpint_dev_s g_gpint[BOARD_NGPIOINT];
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gpout_read
+ ****************************************************************************/
+
+#if BOARD_NGPIOOUT > 0
+static int gpout_read(struct gpio_dev_s *dev, bool *value)
+{
+  struct esp32gpio_dev_s *esp32gpio = (struct esp32gpio_dev_s *)dev;
+
+  DEBUGASSERT(esp32gpio != NULL && value != NULL);
+  DEBUGASSERT(esp32gpio->id < BOARD_NGPIOOUT);
+  gpioinfo("Reading...\n");
+
+  *value = esp32_gpioread(g_gpiooutputs[esp32gpio->id]);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: gpout_write
+ ****************************************************************************/
+
+static int gpout_write(struct gpio_dev_s *dev, bool value)
+{
+  struct esp32gpio_dev_s *esp32gpio = (struct esp32gpio_dev_s *)dev;
+
+  DEBUGASSERT(esp32gpio != NULL);
+  DEBUGASSERT(esp32gpio->id < BOARD_NGPIOOUT);
+  gpioinfo("Writing %d\n", (int)value);
+
+  esp32_gpiowrite(g_gpiooutputs[esp32gpio->id], value);
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: gpin_read
+ ****************************************************************************/
+
+#if BOARD_NGPIOIN > 0
+static int gpin_read(struct gpio_dev_s *dev, bool *value)
+{
+  struct esp32gpio_dev_s *esp32gpio = (struct esp32gpio_dev_s *)dev;
+
+  DEBUGASSERT(esp32gpio != NULL && value != NULL);
+  DEBUGASSERT(esp32gpio->id < BOARD_NGPIOIN);
+  gpioinfo("Reading... pin %d\n", g_gpioinputs[esp32gpio->id]);
+
+  *value = esp32_gpioread(g_gpioinputs[esp32gpio->id]);
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32gpio_interrupt
+ ****************************************************************************/
+
+#if BOARD_NGPIOINT > 0
+static int esp32gpio_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32gpint_dev_s *esp32gpint =
+    (struct esp32gpint_dev_s *)arg;
+
+  DEBUGASSERT(esp32gpint != NULL && esp32gpint->callback != NULL);
+  gpioinfo("Interrupt! callback=%p\n", esp32gpint->callback);
+
+  esp32gpint->callback(&esp32gpint->esp32gpio.gpio,
+                       esp32gpint->esp32gpio.id);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: gpint_read
+ ****************************************************************************/
+
+static int gpint_read(struct gpio_dev_s *dev, bool *value)
+{
+  struct esp32gpint_dev_s *esp32gpint =
+    (struct esp32gpint_dev_s *)dev;
+
+  DEBUGASSERT(esp32gpint != NULL && value != NULL);
+  DEBUGASSERT(esp32gpint->esp32gpio.id < BOARD_NGPIOINT);
+  gpioinfo("Reading int pin...\n");
+
+  *value = esp32_gpioread(g_gpiointinputs[esp32gpint->esp32gpio.id]);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: gpint_attach
+ ****************************************************************************/
+
+static int gpint_attach(struct gpio_dev_s *dev,
+                        pin_interrupt_t callback)
+{
+  struct esp32gpint_dev_s *esp32gpint =
+    (struct esp32gpint_dev_s *)dev;
+  int irq = ESP32_PIN2IRQ(g_gpiointinputs[esp32gpint->esp32gpio.id]);
+  int ret;
+
+  gpioinfo("Attaching the callback\n");
+
+  /* Make sure the interrupt is disabled */
+
+  esp32_gpioirqdisable(irq);
+  ret = irq_attach(irq,
+                   esp32gpio_interrupt,
+                   &g_gpint[esp32gpint->esp32gpio.id]);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: gpint_attach() failed: %d\n", ret);
+      return ret;
+    }
+
+  gpioinfo("Attach %p\n", callback);
+  esp32gpint->callback = callback;
+  return OK;
+}
+
+/****************************************************************************
+ * Name: gpint_enable
+ ****************************************************************************/
+
+static int gpint_enable(struct gpio_dev_s *dev, bool enable)
+{
+  struct esp32gpint_dev_s *esp32gpint =
+    (struct esp32gpint_dev_s *)dev;
+  int irq = ESP32_PIN2IRQ(g_gpiointinputs[esp32gpint->esp32gpio.id]);
+
+  if (enable)
+    {
+      if (esp32gpint->callback != NULL)
+        {
+          gpioinfo("Enabling the interrupt\n");
+
+          /* Configure the interrupt for rising edge */
+
+          esp32_gpioirqenable(irq, RISING);
+        }
+    }
+  else
+    {
+      gpioinfo("Disable the interrupt\n");
+      esp32_gpioirqdisable(irq);
+    }
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_gpio_init
+ ****************************************************************************/
+
+int esp32_gpio_init(void)
+{
+  int pincount = 0;
+  int i;
+
+#if BOARD_NGPIOOUT > 0
+  for (i = 0; i < BOARD_NGPIOOUT; i++)
+    {
+      /* Setup and register the GPIO pin */
+
+      g_gpout[i].gpio.gp_pintype = GPIO_OUTPUT_PIN;
+      g_gpout[i].gpio.gp_ops     = &gpout_ops;
+      g_gpout[i].id              = i;
+      gpio_pin_register(&g_gpout[i].gpio, pincount);
+
+      /* Configure the pins that will be used as output */
+
+      esp32_gpio_matrix_out(g_gpiooutputs[i], SIG_GPIO_OUT_IDX, 0, 0);
+      esp32_configgpio(g_gpiooutputs[i], OUTPUT_FUNCTION_3 |
+                       INPUT_FUNCTION_3);
+      esp32_gpiowrite(g_gpiooutputs[i], 0);
+
+      pincount++;
+    }
+#endif
+
+#if BOARD_NGPIOIN > 0
+  for (i = 0; i < BOARD_NGPIOIN; i++)
+    {
+      /* Setup and register the GPIO pin */
+
+      g_gpin[i].gpio.gp_pintype = GPIO_INPUT_PIN;
+      g_gpin[i].gpio.gp_ops     = &gpin_ops;
+      g_gpin[i].id              = i;
+      gpio_pin_register(&g_gpin[i].gpio, pincount);
+
+      /* Configure the pins that will be used as INPUT */
+
+      esp32_configgpio(g_gpioinputs[i], INPUT_FUNCTION_3);
+
+      pincount++;
+    }
+#endif
+
+#if BOARD_NGPIOINT > 0
+  for (i = 0; i < BOARD_NGPIOINT; i++)
+    {
+      /* Setup and register the GPIO pin */
+
+      g_gpint[i].esp32gpio.gpio.gp_pintype = GPIO_INTERRUPT_PIN;
+      g_gpint[i].esp32gpio.gpio.gp_ops     = &gpint_ops;
+      g_gpint[i].esp32gpio.id              = i;
+      gpio_pin_register(&g_gpint[i].esp32gpio.gpio, pincount);
+
+      /* Configure the pins that will be used as interrupt input */
+
+      esp32_configgpio(g_gpiointinputs[i], INPUT_FUNCTION_3 | PULLDOWN);
+
+      pincount++;
+    }
+#endif
+
+  return OK;
+}
+#endif /* CONFIG_DEV_GPIO && !CONFIG_GPIO_LOWER_HALF */
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_reset.c b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_reset.c
new file mode 100644
index 0000000000..b7afcc4cb8
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_reset.c
@@ -0,0 +1,63 @@
+/****************************************************************************
+ * boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_reset.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/board.h>
+
+#ifdef CONFIG_BOARDCTL_RESET
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_reset
+ *
+ * Description:
+ *   Reset board.  Support for this function is required by board-level
+ *   logic if CONFIG_BOARDCTL_RESET is selected.
+ *
+ * Input Parameters:
+ *   status - Status information provided with the reset event.  This
+ *            meaning of this status information is board-specific.  If not
+ *            used by a board, the value zero may be provided in calls to
+ *            board_reset().
+ *
+ * Returned Value:
+ *   If this function returns, then it was not possible to power-off the
+ *   board due to some constraints.  The return value in this case is a
+ *   board-specific reason for the failure to shutdown.
+ *
+ ****************************************************************************/
+
+int board_reset(int status)
+{
+  up_systemreset();
+
+  return 0;
+}
+
+#endif /* CONFIG_BOARDCTL_RESET */
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_sx127x.c b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_sx127x.c
new file mode 100644
index 0000000000..d9e78183eb
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_sx127x.c
@@ -0,0 +1,227 @@
+/****************************************************************************
+ * boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_sx127x.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/board.h>
+#include <nuttx/signal.h>
+#include <nuttx/wireless/lpwan/sx127x.h>
+#include <arch/board/board.h>
+
+#include "esp32_gpio.h"
+#include "esp32_spi.h"
+#include "hardware/esp32_gpio_sigmap.h"
+
+#include "lilygo_tbeam_lora_gps.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* SX127X on SPI2 bus */
+
+#define SX127X_SPI 2
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void sx127x_chip_reset(void);
+static int sx127x_opmode_change(int opmode);
+static int sx127x_freq_select(uint32_t freq);
+static int sx127x_pa_select(bool enable);
+static int sx127x_irq0_attach(xcpt_t isr, void *arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct sx127x_lower_s lower =
+{
+  .irq0attach    = sx127x_irq0_attach,
+  .reset         = sx127x_chip_reset,
+  .opmode_change = sx127x_opmode_change,
+  .freq_select   = sx127x_freq_select,
+  .pa_select     = sx127x_pa_select,
+  .pa_force      = true
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sx127x_irq0_attach
+ ****************************************************************************/
+
+static int sx127x_irq0_attach(xcpt_t isr, void *arg)
+{
+  int irq = ESP32_PIN2IRQ(GPIO_SX127X_DIO0);
+  int ret;
+
+  /* Make sure the interrupt is disabled */
+
+  esp32_gpioirqdisable(irq);
+
+  wlinfo("Attach DIO0 IRQ\n");
+
+  /* Attach to IRQ on pin connected to DIO0 */
+
+  ret = irq_attach(irq, isr, arg);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: gpint_attach() failed: %d\n", ret);
+      return ret;
+    }
+
+  /* IRQ on rising edge */
+
+  esp32_gpioirqenable(irq, RISING);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: sx127x_chip_reset
+ ****************************************************************************/
+
+static void sx127x_chip_reset(void)
+{
+  wlinfo("SX127X RESET\n");
+
+  /* Configure reset as output */
+
+  esp32_gpio_matrix_out(GPIO_SX127X_RESET, SIG_GPIO_OUT_IDX, 0, 0);
+  esp32_configgpio(GPIO_SX127X_RESET, OUTPUT_FUNCTION_3 | INPUT_FUNCTION_3);
+
+  /* Set pin to zero */
+
+  esp32_gpiowrite(GPIO_SX127X_RESET, 0);
+
+  /* Wait 1 ms */
+
+  nxsig_usleep(1000);
+
+  /* Set pin to high */
+
+  esp32_gpiowrite(GPIO_SX127X_RESET, 1);
+
+  /* Wait 10 ms */
+
+  nxsig_usleep(10000);
+}
+
+/****************************************************************************
+ * Name: sx127x_opmode_change
+ ****************************************************************************/
+
+static int sx127x_opmode_change(int opmode)
+{
+  /* Do nothing */
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: sx127x_freq_select
+ ****************************************************************************/
+
+static int sx127x_freq_select(uint32_t freq)
+{
+  int ret = OK;
+
+  /* NOTE: this depends on your module version */
+
+  if (freq > SX127X_HFBAND_THR)
+    {
+      ret = -EINVAL;
+      wlerr("HF band not supported\n");
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: sx127x_pa_select
+ ****************************************************************************/
+
+static int sx127x_pa_select(bool enable)
+{
+  int ret = OK;
+
+  /* Only PA_BOOST output connected to antenna */
+
+  if (enable == false)
+    {
+      ret = -EINVAL;
+      wlerr("Module supports only PA_BOOST pin,"
+            " so PA_SELECT must be enabled!\n");
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int esp32_lpwaninitialize(void)
+{
+  struct spi_dev_s *spidev;
+  int ret = OK;
+
+  wlinfo("Register the sx127x module\n");
+
+  /* Setup DIO0 */
+
+  esp32_configgpio(GPIO_SX127X_DIO0, INPUT_FUNCTION_3 | PULLDOWN);
+
+  /* Init SPI bus */
+
+  spidev = esp32_spibus_initialize(SX127X_SPI);
+  if (!spidev)
+    {
+      wlerr("ERROR: Failed to initialize SPI %d bus\n", SX127X_SPI);
+      ret = -ENODEV;
+      goto errout;
+    }
+
+  /* Initialize SX127X */
+
+  ret = sx127x_register(spidev, &lower);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to register sx127x\n");
+      goto errout;
+    }
+
+errout:
+  return ret;
+}
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_userleds.c b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_userleds.c
new file mode 100644
index 0000000000..e4ddaecc07
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_userleds.c
@@ -0,0 +1,95 @@
+/****************************************************************************
+ * boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_userleds.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <debug.h>
+
+#include <nuttx/board.h>
+#include <arch/board/board.h>
+
+#include "esp32_gpio.h"
+#include "lilygo_tbeam_lora_gps.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* This array maps an LED number to GPIO pin configuration */
+
+static const uint32_t g_ledcfg[BOARD_NLEDS] =
+{
+  GPIO_LED1,
+};
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_userled_initialize
+ ****************************************************************************/
+
+uint32_t board_userled_initialize(void)
+{
+  uint8_t i;
+
+  for (i = 0; i < BOARD_NLEDS; i++)
+    {
+      esp32_configgpio(g_ledcfg[i], OUTPUT);
+    }
+
+  return BOARD_NLEDS;
+}
+
+/****************************************************************************
+ * Name: board_userled
+ ****************************************************************************/
+
+void board_userled(int led, bool ledon)
+{
+  if ((unsigned)led < BOARD_NLEDS)
+    {
+      esp32_gpiowrite(g_ledcfg[led], ledon);
+    }
+}
+
+/****************************************************************************
+ * Name: board_userled_all
+ ****************************************************************************/
+
+void board_userled_all(uint32_t ledset)
+{
+  uint8_t i;
+
+  /* Configure LED1-8 GPIOs for output */
+
+  for (i = 0; i < BOARD_NLEDS; i++)
+    {
+      esp32_gpiowrite(g_ledcfg[i], (ledset & (1 << i)) != 0);
+    }
+}
+
diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/lilygo_tbeam_lora_gps.h b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/lilygo_tbeam_lora_gps.h
new file mode 100644
index 0000000000..bd64856ffb
--- /dev/null
+++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/lilygo_tbeam_lora_gps.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+ * boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/lilygo_tbeam_lora_gps.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __BOARDS_XTENSA_ESP32_LILYGO_TBEAM_SRC_LILYGO_TBEAM_LORA_GPS_H
+#define __BOARDS_XTENSA_ESP32_LILYGO_TBEAM_SRC_LILYGO_TBEAM_LORA_GPS_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+#include <stdint.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* TTGO-LoRa-SX1276-ESP32 GPIOs *********************************************/
+
+/* OLED SSD1306 */
+
+#define HAVE_SSD1306 1
+
+#if !defined(CONFIG_ESP32_I2C) || !defined(CONFIG_ESP32_I2C0) || \
+    !defined(CONFIG_LCD_SSD1306_I2C)
+#  undef HAVE_SSD1306
+#endif
+
+#define GPIO_SSD1306_RST    16
+
+/* SX1276 pins */
+
+#define GPIO_SX127X_RESET   23    /* RESET connected to IO23 */
+#define GPIO_SX127X_DIO0    26    /* DIO0 connected to IO26  */
+
+/* BOOT Button */
+
+#define BUTTON_BOOT  0
+
+/* LED
+ *
+ * This is an externally connected LED used for testing.
+ */
+
+#define GPIO_LED1             4
+
+/* TIMERS */
+
+#define TIMER0 0
+#define TIMER1 1
+#define TIMER2 2
+#define TIMER3 3
+
+/* ONESHOT */
+
+#define ONESHOT_TIMER         1
+#define ONESHOT_RESOLUTION_US 1
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_bringup
+ *
+ * Description:
+ *   Perform architecture-specific initialization
+ *
+ *   CONFIG_BOARD_LATE_INITIALIZE=y :
+ *     Called from board_late_initialize().
+ *
+ *   CONFIG_BOARD_LATE_INITIALIZE=y && CONFIG_BOARDCTL=y :
+ *     Called from the NSH library via board_app_initialize()
+ *
+ ****************************************************************************/
+
+int esp32_bringup(void);
+
+/****************************************************************************
+ * Name: esp32_mmcsd_initialize
+ *
+ * Description:
+ *   Initialize SPI-based SD card and card detect thread.
+ ****************************************************************************/
+
+int esp32_mmcsd_initialize(int minor);
+
+/****************************************************************************
+ * Name: esp32_spiflash_init
+ *
+ * Description:
+ *   Initialize the SPIFLASH and register the MTD device.
+ ****************************************************************************/
+
+int esp32_spiflash_init(void);
+
+/****************************************************************************
+ * Name: esp32_gpio_init
+ ****************************************************************************/
+
+#ifdef CONFIG_DEV_GPIO
+int esp32_gpio_init(void);
+#endif
+
+/****************************************************************************
+ * Name: board_spidev_initialize
+ *
+ * Description:
+ *   Initialize SPI driver and register the /dev/spi device.
+ *
+ * Input Parameters:
+ *   bus - The SPI bus number, used to build the device path as /dev/spiN
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; A negated errno value is returned
+ *   to indicate the nature of any failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SPI_DRIVER
+int board_spidev_initialize(int bus);
+#endif
+
+/****************************************************************************
+ * Name: esp32_lpwaninitialize
+ *
+ * Description:
+ *   Initialize the SX127x driver
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; A negated errno value is returned
+ *   to indicate the nature of any failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_LPWAN_SX127X
+int esp32_lpwaninitialize(void);
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __BOARDS_XTENSA_ESP32_LILYGO_TBEAM_SRC_LILYGO_TBEAM_LORA_GPS_H */