From 17f7f6e86d9c045df53c65213d0c83487746d61d Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Nihei Date: Tue, 24 Jan 2023 10:31:15 -0300 Subject: [PATCH] risc-v: Add Espressif chip family support on top of esp-hal-3rdparty Initially supporting ESP32-C3 chip, to be followed by other RISC-V-based chips from Espressif. Signed-off-by: Gustavo Henrique Nihei --- arch/risc-v/Kconfig | 9 + arch/risc-v/include/espressif/.gitignore | 1 + arch/risc-v/include/espressif/chip.h | 32 + arch/risc-v/src/espressif/.gitignore | 4 + arch/risc-v/src/espressif/Bootloader.mk | 31 + arch/risc-v/src/espressif/Kconfig | 282 ++++ arch/risc-v/src/espressif/Make.defs | 78 ++ arch/risc-v/src/espressif/chip.h | 40 + arch/risc-v/src/espressif/esp_allocateheap.c | 106 ++ arch/risc-v/src/espressif/esp_config.h | 66 + arch/risc-v/src/espressif/esp_gpio.c | 205 +++ arch/risc-v/src/espressif/esp_gpio.h | 196 +++ arch/risc-v/src/espressif/esp_head.S | 78 ++ arch/risc-v/src/espressif/esp_idle.c | 74 + arch/risc-v/src/espressif/esp_irq.c | 577 ++++++++ arch/risc-v/src/espressif/esp_irq.h | 152 ++ arch/risc-v/src/espressif/esp_libc_stubs.c | 414 ++++++ arch/risc-v/src/espressif/esp_libc_stubs.h | 51 + arch/risc-v/src/espressif/esp_lowputc.c | 364 +++++ arch/risc-v/src/espressif/esp_lowputc.h | 186 +++ arch/risc-v/src/espressif/esp_memorymap.h | 44 + arch/risc-v/src/espressif/esp_serial.c | 1232 +++++++++++++++++ arch/risc-v/src/espressif/esp_start.c | 138 ++ arch/risc-v/src/espressif/esp_start.h | 49 + arch/risc-v/src/espressif/esp_timerisr.c | 161 +++ arch/risc-v/src/espressif/esp_vectors.S | 58 + arch/risc-v/src/espressif/esp_wdt.c | 58 + arch/risc-v/src/espressif/esp_wdt.h | 50 + arch/risc-v/src/espressif/hal_esp32c3.mk | 94 ++ boards/Kconfig | 16 + boards/risc-v/espressif/common/Kconfig | 13 + boards/risc-v/espressif/common/Makefile | 33 + .../espressif/common/scripts/.gitignore | 1 + .../common/scripts/esp32c3_aliases.ld | 29 + .../common/scripts/esp32c3_flat_memory.ld | 112 ++ .../common/scripts/esp32c3_legacy_sections.ld | 289 ++++ boards/risc-v/espressif/common/src/Make.defs | 27 + .../risc-v/espressif/esp32c3-generic/Kconfig | 8 + .../esp32c3-generic/configs/nsh/defconfig | 55 + .../espressif/esp32c3-generic/include/board.h | 25 + .../esp32c3-generic/scripts/Make.defs | 60 + .../espressif/esp32c3-generic/src/Make.defs | 31 + .../esp32c3-generic/src/esp32c3-generic.h | 72 + .../esp32c3-generic/src/esp32c3_appinit.c | 81 ++ .../esp32c3-generic/src/esp32c3_boot.c | 89 ++ .../esp32c3-generic/src/esp32c3_bringup.c | 98 ++ tools/espressif/Config.mk | 142 ++ 47 files changed, 6011 insertions(+) create mode 100644 arch/risc-v/include/espressif/.gitignore create mode 100644 arch/risc-v/include/espressif/chip.h create mode 100644 arch/risc-v/src/espressif/.gitignore create mode 100644 arch/risc-v/src/espressif/Bootloader.mk create mode 100644 arch/risc-v/src/espressif/Kconfig create mode 100644 arch/risc-v/src/espressif/Make.defs create mode 100644 arch/risc-v/src/espressif/chip.h create mode 100644 arch/risc-v/src/espressif/esp_allocateheap.c create mode 100644 arch/risc-v/src/espressif/esp_config.h create mode 100644 arch/risc-v/src/espressif/esp_gpio.c create mode 100644 arch/risc-v/src/espressif/esp_gpio.h create mode 100644 arch/risc-v/src/espressif/esp_head.S create mode 100644 arch/risc-v/src/espressif/esp_idle.c create mode 100644 arch/risc-v/src/espressif/esp_irq.c create mode 100644 arch/risc-v/src/espressif/esp_irq.h create mode 100644 arch/risc-v/src/espressif/esp_libc_stubs.c create mode 100644 arch/risc-v/src/espressif/esp_libc_stubs.h create mode 100644 arch/risc-v/src/espressif/esp_lowputc.c create mode 100644 arch/risc-v/src/espressif/esp_lowputc.h create mode 100644 arch/risc-v/src/espressif/esp_memorymap.h create mode 100644 arch/risc-v/src/espressif/esp_serial.c create mode 100644 arch/risc-v/src/espressif/esp_start.c create mode 100644 arch/risc-v/src/espressif/esp_start.h create mode 100644 arch/risc-v/src/espressif/esp_timerisr.c create mode 100644 arch/risc-v/src/espressif/esp_vectors.S create mode 100644 arch/risc-v/src/espressif/esp_wdt.c create mode 100644 arch/risc-v/src/espressif/esp_wdt.h create mode 100644 arch/risc-v/src/espressif/hal_esp32c3.mk create mode 100644 boards/risc-v/espressif/common/Kconfig create mode 100644 boards/risc-v/espressif/common/Makefile create mode 100644 boards/risc-v/espressif/common/scripts/.gitignore create mode 100644 boards/risc-v/espressif/common/scripts/esp32c3_aliases.ld create mode 100644 boards/risc-v/espressif/common/scripts/esp32c3_flat_memory.ld create mode 100644 boards/risc-v/espressif/common/scripts/esp32c3_legacy_sections.ld create mode 100644 boards/risc-v/espressif/common/src/Make.defs create mode 100644 boards/risc-v/espressif/esp32c3-generic/Kconfig create mode 100644 boards/risc-v/espressif/esp32c3-generic/configs/nsh/defconfig create mode 100644 boards/risc-v/espressif/esp32c3-generic/include/board.h create mode 100644 boards/risc-v/espressif/esp32c3-generic/scripts/Make.defs create mode 100644 boards/risc-v/espressif/esp32c3-generic/src/Make.defs create mode 100644 boards/risc-v/espressif/esp32c3-generic/src/esp32c3-generic.h create mode 100644 boards/risc-v/espressif/esp32c3-generic/src/esp32c3_appinit.c create mode 100644 boards/risc-v/espressif/esp32c3-generic/src/esp32c3_boot.c create mode 100644 boards/risc-v/espressif/esp32c3-generic/src/esp32c3_bringup.c create mode 100644 tools/espressif/Config.mk diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 37f532027b..ceedca8a63 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -110,6 +110,11 @@ config ARCH_CHIP_ESP32C6 ---help--- Espressif ESP32-C6 (RV32IMAC). +config ARCH_CHIP_ESPRESSIF + bool "Espressif ESP32 family" + ---help--- + Family of RISC-V based microcontrollers from Espressif Systems. + config ARCH_CHIP_C906 bool "THEAD C906" select ARCH_RV64 @@ -223,6 +228,7 @@ config ARCH_CHIP default "bl602" if ARCH_CHIP_BL602 default "esp32c3" if ARCH_CHIP_ESP32C3 default "esp32c6" if ARCH_CHIP_ESP32C6 + default "espressif" if ARCH_CHIP_ESPRESSIF default "c906" if ARCH_CHIP_C906 default "mpfs" if ARCH_CHIP_MPFS default "rv32m1" if ARCH_CHIP_RV32M1 @@ -363,6 +369,9 @@ endif if ARCH_CHIP_ESP32C6 source "arch/risc-v/src/esp32c6/Kconfig" endif +if ARCH_CHIP_ESPRESSIF +source "arch/risc-v/src/espressif/Kconfig" +endif if ARCH_CHIP_C906 source "arch/risc-v/src/c906/Kconfig" endif diff --git a/arch/risc-v/include/espressif/.gitignore b/arch/risc-v/include/espressif/.gitignore new file mode 100644 index 0000000000..4cebf84fe7 --- /dev/null +++ b/arch/risc-v/include/espressif/.gitignore @@ -0,0 +1 @@ +/irq.h diff --git a/arch/risc-v/include/espressif/chip.h b/arch/risc-v/include/espressif/chip.h new file mode 100644 index 0000000000..58e4ba5435 --- /dev/null +++ b/arch/risc-v/include/espressif/chip.h @@ -0,0 +1,32 @@ +/**************************************************************************** + * arch/risc-v/include/espressif/chip.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 __ARCH_RISCV_INCLUDE_ESPRESSIF_CHIP_H +#define __ARCH_RISCV_INCLUDE_ESPRESSIF_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#endif /* __ARCH_RISCV_INCLUDE_ESPRESSIF_CHIP_H */ diff --git a/arch/risc-v/src/espressif/.gitignore b/arch/risc-v/src/espressif/.gitignore new file mode 100644 index 0000000000..a3e86dd8af --- /dev/null +++ b/arch/risc-v/src/espressif/.gitignore @@ -0,0 +1,4 @@ +/esp-wireless-drivers-3rdparty +/esp-nuttx-bootloader +/*.zip +/esp-hal-3rdparty diff --git a/arch/risc-v/src/espressif/Bootloader.mk b/arch/risc-v/src/espressif/Bootloader.mk new file mode 100644 index 0000000000..a54ea5435e --- /dev/null +++ b/arch/risc-v/src/espressif/Bootloader.mk @@ -0,0 +1,31 @@ +############################################################################ +# arch/risc-v/src/espressif/Bootloader.mk +# +# 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. +# +############################################################################ + +BOOTLOADER_VERSION = latest +BOOTLOADER_URL = https://github.com/espressif/esp-nuttx-bootloader/releases/download/$(BOOTLOADER_VERSION) + +bootloader: + $(Q) echo "Downloading Bootloader binaries" + $(call DOWNLOAD,$(BOOTLOADER_URL),bootloader-$(CONFIG_ESPRESSIF_CHIP_SERIES).bin,$(TOPDIR)/bootloader-$(CONFIG_ESPRESSIF_CHIP_SERIES).bin) + $(call DOWNLOAD,$(BOOTLOADER_URL),partition-table-$(CONFIG_ESPRESSIF_CHIP_SERIES).bin,$(TOPDIR)/partition-table-$(CONFIG_ESPRESSIF_CHIP_SERIES).bin) + +clean_bootloader: + $(call DELFILE,$(TOPDIR)/bootloader-$(CONFIG_ESPRESSIF_CHIP_SERIES).bin) + $(call DELFILE,$(TOPDIR)/partition-table-$(CONFIG_ESPRESSIF_CHIP_SERIES).bin) diff --git a/arch/risc-v/src/espressif/Kconfig b/arch/risc-v/src/espressif/Kconfig new file mode 100644 index 0000000000..49f8611099 --- /dev/null +++ b/arch/risc-v/src/espressif/Kconfig @@ -0,0 +1,282 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_ESPRESSIF + +choice ESPRESSIF_CHIP_SERIES + prompt "Chip Series" + default ESPRESSIF_ESP32C3 + +config ESPRESSIF_ESP32C3 + bool "ESP32-C3" + select ARCH_RV32 + select ARCH_RV_ISA_M + select ARCH_RV_ISA_C + select ARCH_VECNOTIRQ + select ARCH_HAVE_BOOTLOADER + select ARCH_HAVE_MPU + select ARCH_HAVE_RESET + select LIBC_ARCH_ATOMIC + select LIBC_ARCH_MEMCPY + select LIBC_ARCH_MEMCHR + select LIBC_ARCH_MEMCMP + select LIBC_ARCH_MEMMOVE + select LIBC_ARCH_MEMSET + select LIBC_ARCH_STRCHR + select LIBC_ARCH_STRCMP + select LIBC_ARCH_STRCPY + select LIBC_ARCH_STRLCPY + select LIBC_ARCH_STRNCPY + select LIBC_ARCH_STRLEN + select LIBC_ARCH_STRNLEN + ---help--- + ESP32-C3 chip with a single RISC-V IMC core, no embedded Flash memory + +endchoice # ESPRESSIF_CHIP_SERIES + +config ESPRESSIF_CHIP_SERIES + string + default "esp32c3" if ESPRESSIF_ESP32C3 + default "unknown" + +choice ESPRESSIF_FLASH + prompt "Flash Size" + default ESPRESSIF_FLASH_4M if ESPRESSIF_ESP32C3 + +config ESPRESSIF_FLASH_2M + bool "2 MB" + +config ESPRESSIF_FLASH_4M + bool "4 MB" + +endchoice # ESPRESSIF_FLASH + +config ESPRESSIF_FLASH_DETECT + bool "Auto-detect FLASH size" + default n + ---help--- + Auto detect flash size when flashing. + +choice ESPRESSIF_CPU_FREQ + prompt "CPU frequency" + default ESPRESSIF_CPU_FREQ_160 if ESPRESSIF_ESP32C3 + ---help--- + CPU frequency to be set on application startup. + +config ESPRESSIF_CPU_FREQ_40 + bool "40 MHz" + ---help--- + Set the CPU to 40 MHz. This frequency is obtained from the XTAL. + +config ESPRESSIF_CPU_FREQ_80 + bool "80 MHz" + ---help--- + Set the CPU to 80 MHz. This frequency is obtained from the 480 MHz PLL. + +config ESPRESSIF_CPU_FREQ_160 + bool "160 MHz" + ---help--- + Set the CPU to 160 MHz. This frequency is obtained from the 480 MHz PLL. + +endchoice # ESPRESSIF_CPU_FREQ + +config ESPRESSIF_CPU_FREQ_MHZ + int + default 40 if ESPRESSIF_CPU_FREQ_40 + default 80 if ESPRESSIF_CPU_FREQ_80 + default 160 if ESPRESSIF_CPU_FREQ_160 + +config ESPRESSIF_REGION_PROTECTION + bool "Enable region protection" + default y + select ARCH_USE_MPU + ---help--- + Configure the MPU to disable access to invalid memory regions. + +config ESPRESSIF_RUN_IRAM + bool "Run from IRAM" + default n + ---help--- + This loads all of NuttX inside IRAM. Used to test somewhat small + images that can fit entirely in IRAM. + +menu "Peripheral Support" + +config ESPRESSIF_UART + bool + default n + +config ESPRESSIF_UART0 + bool "UART0" + default y + select ESPRESSIF_UART + select UART0_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS + +config ESPRESSIF_UART1 + bool "UART1" + default n + select ESPRESSIF_UART + select UART1_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS + +config ESPRESSIF_BROWNOUT_DET + bool "Brownout Detector" + default y + ---help--- + A built-in brownout detector which can detect if the voltage is lower + than a specific value. If this happens, it will reset the chip in + order to prevent unintended behaviour. + +endmenu # Peripheral Support + +menu "UART Configuration" + depends on ESPRESSIF_UART + +if ESPRESSIF_UART0 + +config ESPRESSIF_UART0_TXPIN + int "UART0 TX Pin" + default 21 if ESPRESSIF_ESP32C3 + +config ESPRESSIF_UART0_RXPIN + int "UART0 RX Pin" + default 20 if ESPRESSIF_ESP32C3 + +config ESPRESSIF_UART0_RTSPIN + int "UART0 RTS Pin" + depends on SERIAL_IFLOWCONTROL + default 16 if ESPRESSIF_ESP32C3 + range 0 21 + +config ESPRESSIF_UART0_CTSPIN + int "UART0 CTS Pin" + depends on SERIAL_OFLOWCONTROL + default 15 if ESPRESSIF_ESP32C3 + range 0 21 + +endif # ESPRESSIF_UART0 + +if ESPRESSIF_UART1 + +config ESPRESSIF_UART1_TXPIN + int "UART1 TX Pin" + default 8 if ESPRESSIF_ESP32C3 + +config ESPRESSIF_UART1_RXPIN + int "UART1 RX Pin" + default 9 if ESPRESSIF_ESP32C3 + +config ESPRESSIF_UART1_RTSPIN + int "UART1 RTS Pin" + depends on SERIAL_IFLOWCONTROL + default 1 if ESPRESSIF_ESP32C3 + range 0 21 + +config ESPRESSIF_UART1_CTSPIN + int "UART1 CTS Pin" + depends on SERIAL_OFLOWCONTROL + default 2 if ESPRESSIF_ESP32C3 + range 0 21 + +endif # ESPRESSIF_UART1 + +endmenu # UART Configuration + +menu "SPI Flash Configuration" + +choice ESPRESSIF_FLASH_MODE + prompt "SPI Flash mode" + default ESPRESSIF_FLASH_MODE_DIO + ---help--- + These options control how many I/O pins are used for communication with the attached SPI Flash chip. + The option selected here is then used by esptool when flashing. + +config ESPRESSIF_FLASH_MODE_DIO + bool "Dual IO (DIO)" + +config ESPRESSIF_FLASH_MODE_DOUT + bool "Dual Output (DOUT)" + +config ESPRESSIF_FLASH_MODE_QIO + bool "Quad IO (QIO)" + +config ESPRESSIF_FLASH_MODE_QOUT + bool "Quad Output (QOUT)" + +endchoice # ESPRESSIF_FLASH_MODE + +choice ESPRESSIF_FLASH_FREQ + prompt "SPI Flash frequency" + default ESPRESSIF_FLASH_FREQ_40M + ---help--- + SPI Flash frequency. + +config ESPRESSIF_FLASH_FREQ_80M + bool "80 MHz" + +config ESPRESSIF_FLASH_FREQ_40M + bool "40 MHz" + +config ESPRESSIF_FLASH_FREQ_26M + bool "26 MHz" + +config ESPRESSIF_FLASH_FREQ_20M + bool "20 MHz" + +endchoice # ESPRESSIF_FLASH_FREQ + +endmenu # SPI Flash Configuration + +menu "Application Image Configuration" + +config ESPRESSIF_PARTITION_TABLE_OFFSET + hex "Partition Table offset" + default 0x8000 + +endmenu # Application Image Configuration + +menu "Brownout Detector Configuration" + depends on ESPRESSIF_BROWNOUT_DET + +choice ESPRESSIF_BROWNOUT_DET_LVL_SEL + prompt "Brownout voltage level" + default ESPRESSIF_BROWNOUT_DET_LVL_SEL_7 + ---help--- + The brownout detector will reset the chip when the supply voltage is + approximately below this level. Note that there may be some variation + of brownout voltage level between each chip. + + config ESPRESSIF_BROWNOUT_DET_LVL_SEL_7 + bool "2.51V" + + config ESPRESSIF_BROWNOUT_DET_LVL_SEL_6 + bool "2.64V" + + config ESPRESSIF_BROWNOUT_DET_LVL_SEL_5 + bool "2.76V" + + config ESPRESSIF_BROWNOUT_DET_LVL_SEL_4 + bool "2.92V" + + config ESPRESSIF_BROWNOUT_DET_LVL_SEL_3 + bool "3.10V" + + config ESPRESSIF_BROWNOUT_DET_LVL_SEL_2 + bool "3.27V" +endchoice + +config ESPRESSIF_BROWNOUT_DET_LVL + int + default 2 if ESPRESSIF_BROWNOUT_DET_LVL_SEL_2 + default 3 if ESPRESSIF_BROWNOUT_DET_LVL_SEL_3 + default 4 if ESPRESSIF_BROWNOUT_DET_LVL_SEL_4 + default 5 if ESPRESSIF_BROWNOUT_DET_LVL_SEL_5 + default 6 if ESPRESSIF_BROWNOUT_DET_LVL_SEL_6 + default 7 if ESPRESSIF_BROWNOUT_DET_LVL_SEL_7 + +endmenu # ESPRESSIF_BROWNOUT_DET + +endif # ARCH_CHIP_ESPRESSIF diff --git a/arch/risc-v/src/espressif/Make.defs b/arch/risc-v/src/espressif/Make.defs new file mode 100644 index 0000000000..1a00303f26 --- /dev/null +++ b/arch/risc-v/src/espressif/Make.defs @@ -0,0 +1,78 @@ +############################################################################ +# arch/risc-v/src/espressif/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 chip/Bootloader.mk +include common/Make.defs + +# The start-up, "head", file. May be either a .S or a .c file. + +HEAD_ASRC = esp_head.S + +# Skip common RISC-V vector table in favor of Espressif's custom vector +# table. + +CMN_ASRCS := $(filter-out riscv_vectors.S,$(CMN_ASRCS)) +CHIP_ASRCS = esp_vectors.S + +# Required Espressif chip's files (arch/risc-v/src/espressif) + +CHIP_CSRCS = esp_allocateheap.c esp_start.c esp_idle.c +CHIP_CSRCS += esp_irq.c esp_gpio.c esp_libc_stubs.c +CHIP_CSRCS += esp_lowputc.c esp_serial.c +CHIP_CSRCS += esp_timerisr.c esp_wdt.c + +############################################################################# +# Espressif HAL for 3rd Party Platforms +############################################################################# + +# Fetch source files and add them to build + +ESP_HAL_3RDPARTY_UNPACK = esp-hal-3rdparty +ESP_HAL_3RDPARTY_ID = nuttx-20230310 +ESP_HAL_3RDPARTY_ZIP = $(ESP_HAL_3RDPARTY_ID).zip +ESP_HAL_3RDPARTY_URL = https://github.com/espressif/esp-hal-3rdparty/archive + +$(ESP_HAL_3RDPARTY_ZIP): + $(Q) echo "Downloading: Espressif HAL for 3rd Party Platforms" + $(call DOWNLOAD,$(ESP_HAL_3RDPARTY_URL),$(ESP_HAL_3RDPARTY_ZIP),chip/$(ESP_HAL_3RDPARTY_ZIP)) + +chip/$(ESP_HAL_3RDPARTY_UNPACK): $(ESP_HAL_3RDPARTY_ZIP) + $(Q) echo "Unpacking: Espressif HAL for 3rd Party Platforms" + $(Q) unzip -oqq chip/$(ESP_HAL_3RDPARTY_ZIP) -d chip/ + $(Q) mv chip/$(ESP_HAL_3RDPARTY_UNPACK)-$(ESP_HAL_3RDPARTY_ID)* chip/$(ESP_HAL_3RDPARTY_UNPACK) + $(Q) touch chip/$(ESP_HAL_3RDPARTY_UNPACK) + +# Silent preprocessor warnings + +CFLAGS += -Wno-undef -Wno-unused-variable + +# Remove quotes from CONFIG_ESPRESSIF_CHIP_SERIES configuration + +CHIP_SERIES = $(patsubst "%",%,$(CONFIG_ESPRESSIF_CHIP_SERIES)) + +include chip/hal_${CHIP_SERIES}.mk + +context:: chip/$(ESP_HAL_3RDPARTY_UNPACK) + $(call COPYFILE,chip/$(ESP_HAL_3RDPARTY_UNPACK)/nuttx/$(CONFIG_ESPRESSIF_CHIP_SERIES)/include/irq.h,../include/chip/) + +distclean:: + $(call DELFILE,../include/chip/irq.h) + $(call DELFILE,chip/$(ESP_HAL_3RDPARTY_ZIP)) + $(call DELDIR,chip/$(ESP_HAL_3RDPARTY_UNPACK)) diff --git a/arch/risc-v/src/espressif/chip.h b/arch/risc-v/src/espressif/chip.h new file mode 100644 index 0000000000..67b4071ed5 --- /dev/null +++ b/arch/risc-v/src/espressif/chip.h @@ -0,0 +1,40 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/chip.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 __ARCH_RISCV_SRC_ESPRESSIF_CHIP_H +#define __ARCH_RISCV_SRC_ESPRESSIF_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "esp_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Section for exception handler. */ + +#define EXCEPTION_SECTION .iram1 + +#endif /* __ARCH_RISCV_SRC_ESPRESSIF_CHIP_H */ diff --git a/arch/risc-v/src/espressif/esp_allocateheap.c b/arch/risc-v/src/espressif/esp_allocateheap.c new file mode 100644 index 0000000000..c8383a9b1b --- /dev/null +++ b/arch/risc-v/src/espressif/esp_allocateheap.c @@ -0,0 +1,106 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_allocateheap.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 + +#include +#include + +#include +#include +#include +#include + +#include "rom/rom_layout.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel and + * userspace heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, userspace heap. + * + * If a protected kernel heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * Input Parameters: + * None. + * + * Output Parameters: + * heap_start - Address of the beginning of the (initial) memory region. + * heap_size - The size (in bytes) if the (initial) memory region. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_allocate_heap(void **heap_start, size_t *heap_size) +{ + /* These values come from the linker scripts + * (__sections.ld and _flat_memory.ld). + * Check boards/risc-v/espressif. + */ + + extern uint8_t _sheap[]; + + board_autoled_on(LED_HEAPALLOCATE); + + *heap_start = _sheap; + *heap_size = (uintptr_t)ets_rom_layout_p->dram0_rtos_reserved_start - + (uintptr_t)_sheap; +} + +/**************************************************************************** + * Name: riscv_addregion + * + * Description: + * RAM may be added in non-contiguous chunks. This routine adds all chunks + * that may be used for heap. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void riscv_addregion(void) +{ +} +#endif + diff --git a/arch/risc-v/src/espressif/esp_config.h b/arch/risc-v/src/espressif/esp_config.h new file mode 100644 index 0000000000..390128f68c --- /dev/null +++ b/arch/risc-v/src/espressif/esp_config.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_config.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 __ARCH_RISCV_SRC_ESPRESSIF_ESP_CONFIG_H +#define __ARCH_RISCV_SRC_ESPRESSIF_ESP_CONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* UARTs ********************************************************************/ + +/* Are any UARTs enabled? */ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_ESPRESSIF_UART0) || defined(CONFIG_ESPRESSIF_UART1) +# define HAVE_UART_DEVICE 1 /* Flag to indicate a UART has been selected */ +#endif + +/* Serial Console ***********************************************************/ + +/* Is there a serial console? There should be no more than one defined. It + * could be on any UARTn. n E {0,1} + */ + +#undef HAVE_SERIAL_CONSOLE +#undef CONSOLE_UART +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_ESPRESSIF_UART0) +# undef CONFIG_UART1_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +# define CONSOLE_UART 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_ESPRESSIF_UART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +# define CONSOLE_UART 1 +#else +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +#endif + +#endif /* __ARCH_RISCV_SRC_ESPRESSIF_ESP_CONFIG_H */ diff --git a/arch/risc-v/src/espressif/esp_gpio.c b/arch/risc-v/src/espressif/esp_gpio.c new file mode 100644 index 0000000000..e8853b4129 --- /dev/null +++ b/arch/risc-v/src/espressif/esp_gpio.c @@ -0,0 +1,205 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_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 + +#include +#include +#include +#include + +#include +#include +#include + +#include "riscv_internal.h" + +#include "esp_gpio.h" + +#include "esp_rom_gpio.h" +#include "hal/gpio_hal.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static gpio_hal_context_t g_gpio_hal = +{ + .dev = GPIO_HAL_GET_HW(GPIO_PORT_0) +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_configgpio + * + * Description: + * Configure a GPIO pin based on encoded pin attributes. + * + * Input Parameters: + * pin - GPIO pin to be configured. + * attr - Attributes to be configured for the selected GPIO pin. + * The following attributes are accepted: + * - Direction (OUTPUT or INPUT) + * - Pull (PULLUP, PULLDOWN or OPENDRAIN) + * - Function (if not provided, assume function GPIO by + * default) + * - Drive strength (if not provided, assume DRIVE_2 by + * default) + * + * Returned Value: + * Zero (OK) on success, or -1 (ERROR) in case of failure. + * + ****************************************************************************/ + +int esp_configgpio(int pin, gpio_pinattr_t attr) +{ + DEBUGASSERT(pin >= 0 && pin < SOC_GPIO_PIN_COUNT); + + /* Handle input pins */ + + if ((attr & INPUT) != 0) + { + gpio_hal_input_enable(&g_gpio_hal, pin); + } + else + { + gpio_hal_input_disable(&g_gpio_hal, pin); + } + + if ((attr & OPEN_DRAIN) != 0) + { + gpio_hal_od_enable(&g_gpio_hal, pin); + } + else + { + gpio_hal_od_disable(&g_gpio_hal, pin); + } + + if ((attr & OUTPUT) != 0) + { + gpio_hal_output_enable(&g_gpio_hal, pin); + } + else + { + gpio_hal_output_disable(&g_gpio_hal, pin); + } + + if ((attr & PULLUP) != 0) + { + gpio_hal_pullup_en(&g_gpio_hal, pin); + } + else + { + gpio_hal_pullup_dis(&g_gpio_hal, pin); + } + + if ((attr & PULLDOWN) != 0) + { + gpio_hal_pulldown_en(&g_gpio_hal, pin); + } + else + { + gpio_hal_pulldown_dis(&g_gpio_hal, pin); + } + + if ((attr & DRIVE_MASK) != 0) + { + uint32_t val = ((attr & DRIVE_MASK) >> DRIVE_SHIFT) - 1; + gpio_hal_set_drive_capability(&g_gpio_hal, pin, val); + } + else + { + gpio_hal_set_drive_capability(&g_gpio_hal, pin, + GPIO_DRIVE_CAP_DEFAULT); + } + + if ((attr & FUNCTION_MASK) != 0) + { + uint32_t val = ((attr & FUNCTION_MASK) >> FUNCTION_SHIFT) - 1; + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[pin], val); + } + else + { + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[pin], PIN_FUNC_GPIO); + } + + return OK; +} + +/**************************************************************************** + * Name: esp_gpio_matrix_in + * + * Description: + * Set GPIO input to a signal. + * NOTE: one GPIO can receive inputs from several signals. + * + * Input Parameters: + * pin - GPIO pin to be configured. + * - If pin == 0x3c, cancel input to the signal, input 0 + * to signal. + * - If pin == 0x3a, input nothing to signal. + * - If pin == 0x38, cancel input to the signal, input 1 + * to signal. + * signal_idx - Signal index. + * inv - Flag indicating whether the signal is inverted. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_gpio_matrix_in(uint32_t pin, uint32_t signal_idx, bool inv) +{ + esp_rom_gpio_connect_in_signal(pin, signal_idx, inv); +} + +/**************************************************************************** + * Name: esp_gpio_matrix_out + * + * Description: + * Set signal output to GPIO. + * NOTE: one signal can output to several GPIOs. + * + * Input Parameters: + * pin - GPIO pin to be configured. + * signal_idx - Signal index. + * - If signal_idx == 0x100, cancel output to the GPIO. + * out_inv - Flag indicating whether the signal output is inverted. + * oen_inv - Flag indicating whether the signal output enable is + * inverted. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_gpio_matrix_out(uint32_t pin, uint32_t signal_idx, bool out_inv, + bool oen_inv) +{ + esp_rom_gpio_connect_out_signal(pin, signal_idx, out_inv, oen_inv); +} + diff --git a/arch/risc-v/src/espressif/esp_gpio.h b/arch/risc-v/src/espressif/esp_gpio.h new file mode 100644 index 0000000000..ce49d562f2 --- /dev/null +++ b/arch/risc-v/src/espressif/esp_gpio.h @@ -0,0 +1,196 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_gpio.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 __ARCH_RISCV_SRC_ESPRESSIF_ESP_GPIO_H +#define __ARCH_RISCV_SRC_ESPRESSIF_ESP_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Bit-encoded input to esp_configgpio() ************************************/ + +/* Encoded pin attributes used with esp_configgpio() + * + * 11 10 9 8 7 6 5 4 3 2 1 0 + * -- -- -- -- -- -- -- -- -- -- -- -- + * DR DR DR FN FN FN OD PD PU F O I + */ + +#define MODE_SHIFT 0 +#define MODE_MASK (7 << MODE_SHIFT) +# define INPUT (1 << 0) +# define OUTPUT (1 << 1) +# define FUNCTION (1 << 2) + +#define PULL_SHIFT 3 +#define PULL_MASK (7 << PULL_SHIFT) +# define PULLUP (1 << 3) +# define PULLDOWN (1 << 4) +# define OPEN_DRAIN (1 << 5) + +#define FUNCTION_SHIFT 6 +#define FUNCTION_MASK (7 << FUNCTION_SHIFT) +# define FUNCTION_1 (1 << FUNCTION_SHIFT) +# define FUNCTION_2 (2 << FUNCTION_SHIFT) +# define FUNCTION_3 (3 << FUNCTION_SHIFT) +# define FUNCTION_4 (4 << FUNCTION_SHIFT) +# define FUNCTION_5 (5 << FUNCTION_SHIFT) +# define FUNCTION_6 (6 << FUNCTION_SHIFT) + +#define DRIVE_SHIFT 9 +#define DRIVE_MASK (7 << DRIVE_SHIFT) +# define DRIVE_0 (1 << DRIVE_SHIFT) +# define DRIVE_1 (2 << DRIVE_SHIFT) +# define DRIVE_2 (3 << DRIVE_SHIFT) +# define DRIVE_3 (4 << DRIVE_SHIFT) + +#define INPUT_PULLUP (INPUT | PULLUP) +#define INPUT_PULLDOWN (INPUT | PULLDOWN) +#define OUTPUT_OPEN_DRAIN (OUTPUT | OPEN_DRAIN) +#define INPUT_FUNCTION (INPUT | FUNCTION) +# define INPUT_FUNCTION_1 (INPUT_FUNCTION | FUNCTION_1) +# define INPUT_FUNCTION_2 (INPUT_FUNCTION | FUNCTION_2) +# define INPUT_FUNCTION_3 (INPUT_FUNCTION | FUNCTION_3) +# define INPUT_FUNCTION_4 (INPUT_FUNCTION | FUNCTION_4) +# define INPUT_FUNCTION_5 (INPUT_FUNCTION | FUNCTION_5) +# define INPUT_FUNCTION_6 (INPUT_FUNCTION | FUNCTION_6) +#define OUTPUT_FUNCTION (OUTPUT | FUNCTION) +# define OUTPUT_FUNCTION_1 (OUTPUT_FUNCTION | FUNCTION_1) +# define OUTPUT_FUNCTION_2 (OUTPUT_FUNCTION | FUNCTION_2) +# define OUTPUT_FUNCTION_3 (OUTPUT_FUNCTION | FUNCTION_3) +# define OUTPUT_FUNCTION_4 (OUTPUT_FUNCTION | FUNCTION_4) +# define OUTPUT_FUNCTION_5 (OUTPUT_FUNCTION | FUNCTION_5) +# define OUTPUT_FUNCTION_6 (OUTPUT_FUNCTION | FUNCTION_6) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Must be big enough to hold the above encodings */ + +typedef uint16_t gpio_pinattr_t; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_configgpio + * + * Description: + * Configure a GPIO pin based on encoded pin attributes. + * + * Input Parameters: + * pin - GPIO pin to be configured. + * attr - Attributes to be configured for the selected GPIO pin. + * The following attributes are accepted: + * - Direction (OUTPUT or INPUT) + * - Pull (PULLUP, PULLDOWN or OPENDRAIN) + * - Function (if not provided, assume function GPIO by + * default) + * - Drive strength (if not provided, assume DRIVE_2 by + * default) + * + * Returned Value: + * Zero (OK) on success, or -1 (ERROR) in case of failure. + * + ****************************************************************************/ + +int esp_configgpio(int pin, gpio_pinattr_t attr); + +/**************************************************************************** + * Name: esp_gpio_matrix_in + * + * Description: + * Set GPIO input to a signal. + * NOTE: one GPIO can receive inputs from several signals. + * + * Input Parameters: + * pin - GPIO pin to be configured. + * - If pin == 0x3c, cancel input to the signal, input 0 + * to signal. + * - If pin == 0x3a, input nothing to signal. + * - If pin == 0x38, cancel input to the signal, input 1 + * to signal. + * signal_idx - Signal index. + * inv - Flag indicating whether the signal is inverted. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_gpio_matrix_in(uint32_t pin, uint32_t signal_idx, bool inv); + +/**************************************************************************** + * Name: esp_gpio_matrix_out + * + * Description: + * Set signal output to GPIO. + * NOTE: one signal can output to several GPIOs. + * + * Input Parameters: + * pin - GPIO pin to be configured. + * signal_idx - Signal index. + * - If signal_idx == 0x100, cancel output to the GPIO. + * out_inv - Flag indicating whether the signal output is inverted. + * oen_inv - Flag indicating whether the signal output enable is + * inverted. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_gpio_matrix_out(uint32_t pin, uint32_t signal_idx, bool out_inv, + bool oen_inv); + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_ESPRESSIF_ESP_GPIO_H */ diff --git a/arch/risc-v/src/espressif/esp_head.S b/arch/risc-v/src/espressif/esp_head.S new file mode 100644 index 0000000000..7286186eb3 --- /dev/null +++ b/arch/risc-v/src/espressif/esp_head.S @@ -0,0 +1,78 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_head.S + * + * 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 + +#include + +#include "chip.h" + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .global __start + +/**************************************************************************** + * Section: .text + ****************************************************************************/ + + .section .text + +/**************************************************************************** + * Name: __start + ****************************************************************************/ + +__start: + .option push + .option norelax + + /* Set stack pointer to the idle thread stack */ + + lui sp, %hi(ESP_IDLESTACK_TOP) + addi sp, sp, %lo(ESP_IDLESTACK_TOP) + + /* Set gp pointer */ + + la gp, __global_pointer$ + + /* Disable all interrupts (i.e. timer, external) in mstatus */ + + csrw mstatus, zero + + .option pop + + /* Initialize the Machine Trap-Vector */ + + lui t0, %hi(_vector_table) + addi t0, t0, %lo(_vector_table) + csrw mtvec, t0 + + /* Jump to __esp_start */ + + jal x1, __esp_start + + /* We shouldn't return from __esp_start */ + + ret diff --git a/arch/risc-v/src/espressif/esp_idle.c b/arch/risc-v/src/espressif/esp_idle.c new file mode 100644 index 0000000000..b0da079765 --- /dev/null +++ b/arch/risc-v/src/espressif/esp_idle.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_idle.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 + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + nxsched_process_timer(); +#else + /* This would be an appropriate place to put some MCU-specific logic to + * sleep in a reduced power mode until an interrupt occurs to save power + */ + + asm("WFI"); + +#endif +} diff --git a/arch/risc-v/src/espressif/esp_irq.c b/arch/risc-v/src/espressif/esp_irq.c new file mode 100644 index 0000000000..d42e6e5cd7 --- /dev/null +++ b/arch/risc-v/src/espressif/esp_irq.c @@ -0,0 +1,577 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_irq.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 + +#include +#include +#include +#include +#include + +#include +#include + +#include "riscv_internal.h" + +#include "esp_irq.h" + +#include "esp_attr.h" +#include "esp_bit_defs.h" +#include "esp_cpu.h" +#include "esp_rom_sys.h" +#include "riscv/interrupt.h" +#include "soc/soc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ESP_DEFAULT_INT_THRESHOLD 1 + +#define IRQ_UNMAPPED 0xff + +/* Helper macros for working with cpuint_mapentry_t fields */ + +#define CPUINT_DISABLE(cpuint) ((cpuint).cpuint_en = 0) +#define CPUINT_ENABLE(cpuint) ((cpuint).cpuint_en = 1) +#define CPUINT_ASSIGN(cpuint,in_irq) do \ + { \ + (cpuint).assigned = 1; \ + (cpuint).cpuint_en = 1; \ + (cpuint).irq = (in_irq); \ + } \ + while(0) +#define CPUINT_GETIRQ(cpuint) ((cpuint).irq) +#define CPUINT_FREE(cpuint) ((cpuint).val = 0) +#define CPUINT_ISENABLED(cpuint) ((cpuint).cpuint_en == 1) +#define CPUINT_ISASSIGNED(cpuint) ((cpuint).assigned == 1) +#define CPUINT_ISFREE(cpuint) (!CPUINT_ISASSIGNED(cpuint)) + +/* CPU interrupts can be detached from any interrupt source by setting the + * map register to ETS_INVALID_INUM, which is an invalid CPU interrupt index. + */ + +#define NO_CPUINT ETS_INVALID_INUM + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* CPU interrupts to IRQ index mapping */ + +typedef union cpuint_mapentry_u +{ + struct + { + uint16_t assigned:1; + uint16_t cpuint_en:1; + uint16_t irq:10; + uint16_t reserved0:4; + }; + + uint16_t val; +} cpuint_mapentry_t; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Map a CPU interrupt to the IRQ of the attached interrupt source */ + +static cpuint_mapentry_t g_cpuint_map[ESP_NCPUINTS]; + +/* Map an IRQ to a CPU interrupt to which the interrupt source is + * attached to. + */ + +static volatile uint8_t g_irq_map[NR_IRQS]; + +/* Bitsets for free, unallocated CPU interrupts available to peripheral + * devices. + */ + +static uint32_t g_cpuint_freelist = ESP_CPUINT_PERIPHSET; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_cpuint_alloc + * + * Description: + * Allocate a free CPU interrupt for a peripheral device. This function + * will not ignore all of the pre-allocated CPU interrupts for internal + * devices. + * + * Input Parameters: + * irq - IRQ number. + * + * Returned Value: + * On success, a CPU interrupt number is returned. + * A negated errno is returned on failure. + * + ****************************************************************************/ + +static int esp_cpuint_alloc(int irq) +{ + uint32_t bitmask; + uint32_t intset; + int cpuint; + + /* Check if there are CPU interrupts with the requested properties + * available. + */ + + intset = g_cpuint_freelist; + if (intset != 0) + { + /* Skip over initial unavailable CPU interrupts quickly in groups + * of 8 interrupt. + */ + + for (cpuint = 0, bitmask = 0xff; + cpuint < ESP_NCPUINTS && (intset & bitmask) == 0; + cpuint += 8, bitmask <<= 8); + + /* Search for an unallocated CPU interrupt number in the remaining + * intset. + */ + + for (; cpuint < ESP_NCPUINTS; cpuint++) + { + /* If the bit corresponding to the CPU interrupt is '1', then + * that CPU interrupt is available. + */ + + bitmask = BIT(cpuint); + if ((intset & bitmask) != 0) + { + /* Got it! */ + + g_cpuint_freelist &= ~bitmask; + break; + } + } + } + + if (cpuint == ESP_NCPUINTS) + { + /* No unallocated CPU interrupt found */ + + return -ENOMEM; + } + + DEBUGASSERT(CPUINT_ISFREE(g_cpuint_map[cpuint])); + + CPUINT_ASSIGN(g_cpuint_map[cpuint], irq); + g_irq_map[irq] = cpuint; + + return cpuint; +} + +/**************************************************************************** + * Name: esp_cpuint_free + * + * Description: + * Free a previously allocated CPU interrupt. + * + * Input Parameters: + * cpuint - CPU interrupt to be freed. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp_cpuint_free(int cpuint) +{ + uint32_t bitmask; + + DEBUGASSERT(cpuint >= 0 && cpuint < ESP_NCPUINTS); + DEBUGASSERT(CPUINT_ISASSIGNED(g_cpuint_map[cpuint])); + + int irq = CPUINT_GETIRQ(g_cpuint_map[cpuint]); + g_irq_map[irq] = IRQ_UNMAPPED; + CPUINT_FREE(g_cpuint_map[cpuint]); + + /* Mark the CPU interrupt as available */ + + bitmask = BIT(cpuint); + + DEBUGASSERT((g_cpuint_freelist & bitmask) == 0); + + g_cpuint_freelist |= bitmask; +} + +/**************************************************************************** + * Name: esp_cpuint_initialize + * + * Description: + * Initialize CPU interrupts. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp_cpuint_initialize(void) +{ + /* Unmap CPU interrupts from every interrupt source */ + + for (int source = 0; source < ESP_NSOURCES; source++) + { + esp_rom_route_intr_matrix(PRO_CPU_NUM, source, NO_CPUINT); + } + + /* Set CPU interrupt threshold level */ + + esprv_intc_int_set_threshold(ESP_DEFAULT_INT_THRESHOLD); + + /* Indicate that no interrupt sources are assigned to CPU interrupts */ + + memset(g_cpuint_map, 0, sizeof(g_cpuint_map)); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + * + * Description: + * Complete initialization of the interrupt system and enable normal, + * interrupt processing. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Indicate that no interrupt sources are assigned to CPU interrupts */ + + for (int i = 0; i < NR_IRQS; i++) + { + g_irq_map[i] = IRQ_UNMAPPED; + } + + /* Initialize CPU interrupts */ + + esp_cpuint_initialize(); + + /* Attach the common interrupt handler */ + + riscv_exception_attach(); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the interrupt specified by 'irq'. + * + * Input Parameters: + * irq - IRQ number. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + int cpuint = g_irq_map[irq]; + + irqinfo("irq=%d | cpuint=%d \n", irq, cpuint); + + DEBUGASSERT(cpuint >= 0 && cpuint < ESP_NCPUINTS); + + irqstate_t irqstate = enter_critical_section(); + + CPUINT_ENABLE(g_cpuint_map[cpuint]); + esprv_intc_int_enable(BIT(cpuint)); + + leave_critical_section(irqstate); +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the interrupt specified by 'irq'. + * + * Input Parameters: + * irq - IRQ number. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + int cpuint = g_irq_map[irq]; + + irqinfo("irq=%d | cpuint=%d \n", irq, cpuint); + + DEBUGASSERT(cpuint >= 0 && cpuint < ESP_NCPUINTS); + + irqstate_t irqstate = enter_critical_section(); + + CPUINT_DISABLE(g_cpuint_map[cpuint]); + esprv_intc_int_disable(BIT(cpuint)); + + leave_critical_section(irqstate); +} + +/**************************************************************************** + * Name: esp_route_intr + * + * Description: + * Assign an interrupt source to a pre-allocated CPU interrupt. + * + * Input Parameters: + * source - Interrupt source (see irq.h) to be assigned to a CPU + * interrupt. + * cpuint - Pre-allocated CPU interrupt to which the interrupt + * source will be assigned. + * priority - Interrupt priority. + * type - Interrupt trigger type. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_route_intr(int source, int cpuint, irq_priority_t priority, + irq_trigger_t type) +{ + /* Ensure the CPU interrupt is disabled */ + + esprv_intc_int_disable(BIT(cpuint)); + + /* Set the interrupt priority */ + + esprv_intc_int_set_priority(cpuint, priority); + + /* Set the interrupt trigger type (Edge or Level) */ + + if (type == ESP_IRQ_TRIGGER_EDGE) + { + esprv_intc_int_set_type(cpuint, INTR_TYPE_EDGE); + } + else + { + esprv_intc_int_set_type(cpuint, INTR_TYPE_LEVEL); + } + + /* Route the interrupt source to the provided CPU interrupt */ + + esp_rom_route_intr_matrix(PRO_CPU_NUM, source, cpuint); +} + +/**************************************************************************** + * Name: esp_setup_irq + * + * Description: + * Configure an IRQ. It allocates a CPU interrupt of the given + * priority and type and attaches a given interrupt source to it. + * + * Input Parameters: + * source - Interrupt source (see irq.h) to be assigned to + * a CPU interrupt. + * priority - Interrupt priority. + * type - Interrupt trigger type. + * + * Returned Value: + * The allocated CPU interrupt on success, a negated errno value on + * failure. + * + ****************************************************************************/ + +int esp_setup_irq(int source, irq_priority_t priority, irq_trigger_t type) +{ + irqstate_t irqstate; + int irq; + int cpuint; + + irqinfo("source = %d\n", source); + + DEBUGASSERT(source >= 0 && source < ESP_NSOURCES); + + irqstate = enter_critical_section(); + + /* Setting up an IRQ includes the following steps: + * 1. Allocate a CPU interrupt. + * 2. Map the CPU interrupt to the IRQ to ease searching later. + * 3. Attach the interrupt source to the newly allocated CPU interrupt. + */ + + irq = ESP_SOURCE2IRQ(source); + cpuint = esp_cpuint_alloc(irq); + if (cpuint < 0) + { + irqerr("Unable to allocate CPU interrupt for priority=%d and type=%d", + priority, type); + leave_critical_section(irqstate); + + return cpuint; + } + + esp_route_intr(source, cpuint, priority, type); + + leave_critical_section(irqstate); + + return cpuint; +} + +/**************************************************************************** + * Name: esp_teardown_irq + * + * Description: + * This function undoes the operations done by esp_setup_irq. + * It detaches an interrupt source from a CPU interrupt and frees the + * CPU interrupt. + * + * Input Parameters: + * source - Interrupt source (see irq.h) to be detached from the + * CPU interrupt. + * cpuint - CPU interrupt from which the interrupt source will + * be detached. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_teardown_irq(int source, int cpuint) +{ + irqstate_t irqstate = enter_critical_section(); + + /* Tearing down an IRQ includes the following steps: + * 1. Free the previously allocated CPU interrupt. + * 2. Unmap the IRQ from the IRQ-to-cpuint map. + * 3. Detach the interrupt source from the CPU interrupt. + */ + + esp_cpuint_free(cpuint); + + DEBUGASSERT(source >= 0 && source < ESP_NSOURCES); + + esp_rom_route_intr_matrix(PRO_CPU_NUM, source, NO_CPUINT); + + leave_critical_section(irqstate); +} + +/**************************************************************************** + * Name: riscv_dispatch_irq + * + * Description: + * Process interrupt and its callback function. + * + * Input Parameters: + * mcause - RISC-V "mcause" register. + * regs - Saved registers reference. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +IRAM_ATTR uintptr_t *riscv_dispatch_irq(uintptr_t mcause, uintptr_t *regs) +{ + int irq; + bool is_irq = (RISCV_IRQ_BIT & mcause) != 0; + bool is_edge = false; + + if (is_irq) + { + uint8_t cpuint = mcause & RISCV_IRQ_MASK; + + DEBUGASSERT(cpuint >= 0 && cpuint < ESP_NCPUINTS); + DEBUGASSERT(CPUINT_ISENABLED(g_cpuint_map[cpuint])); + DEBUGASSERT(CPUINT_ISASSIGNED(g_cpuint_map[cpuint])); + + irq = g_cpuint_map[cpuint].irq; + + is_edge = esprv_intc_int_get_type(cpuint) == INTR_TYPE_EDGE; + if (is_edge) + { + /* Clear edge interrupts. */ + + esp_cpu_intr_edge_ack(cpuint); + } + } + else + { + /* It's exception */ + + irq = mcause; + } + + regs = riscv_doirq(irq, regs); + + return regs; +} + +/**************************************************************************** + * Name: up_irq_enable + * + * Description: + * Enable interrupts globally. + * + * Input Parameters: + * None. + * + * Returned Value: + * The interrupt state prior to enabling interrupts. + * + ****************************************************************************/ + +irqstate_t up_irq_enable(void) +{ + irqstate_t flags; + + /* Read mstatus & set machine interrupt enable (MIE) in mstatus */ + + flags = READ_AND_SET_CSR(mstatus, MSTATUS_MIE); + return flags; +} diff --git a/arch/risc-v/src/espressif/esp_irq.h b/arch/risc-v/src/espressif/esp_irq.h new file mode 100644 index 0000000000..64cb0feccb --- /dev/null +++ b/arch/risc-v/src/espressif/esp_irq.h @@ -0,0 +1,152 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_irq.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 __ARCH_RISCV_SRC_ESPRESSIF_ESP_IRQ_H +#define __ARCH_RISCV_SRC_ESPRESSIF_ESP_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* CPU interrupt types. */ + +typedef enum irq_trigger_e +{ + ESP_IRQ_TRIGGER_LEVEL = 0, /* Level-triggered interrupts */ + ESP_IRQ_TRIGGER_EDGE = 1, /* Edge-triggered interrupts */ +} irq_trigger_t; + +/* CPU interrupt types. */ + +typedef enum irq_priority_e +{ + ESP_IRQ_PRIORITY_1 = 1, /* Priority Level 1 */ + ESP_IRQ_PRIORITY_2 = 2, /* Priority Level 2 */ + ESP_IRQ_PRIORITY_3 = 3, /* Priority Level 3 */ + ESP_IRQ_PRIORITY_4 = 4, /* Priority Level 4 */ + ESP_IRQ_PRIORITY_5 = 5, /* Priority Level 5 */ + ESP_IRQ_PRIORITY_6 = 6, /* Priority Level 6 */ + ESP_IRQ_PRIORITY_7 = 7, /* Priority Level 7 */ + ESP_IRQ_PRIORITY_8 = 8, /* Priority Level 8 */ + ESP_IRQ_PRIORITY_9 = 9, /* Priority Level 9 */ + ESP_IRQ_PRIORITY_10 = 10, /* Priority Level 10 */ + ESP_IRQ_PRIORITY_11 = 11, /* Priority Level 11 */ + ESP_IRQ_PRIORITY_12 = 12, /* Priority Level 12 */ + ESP_IRQ_PRIORITY_13 = 13, /* Priority Level 13 */ + ESP_IRQ_PRIORITY_14 = 14, /* Priority Level 14 */ + ESP_IRQ_PRIORITY_15 = 15, /* Priority Level 15 */ + ESP_IRQ_PRIORITY_DEFAULT = ESP_IRQ_PRIORITY_1 /* Default Priority */ +} irq_priority_t; + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_route_intr + * + * Description: + * Assign an interrupt source to a pre-allocated CPU interrupt. + * + * Input Parameters: + * source - Interrupt source (see irq.h) to be assigned to a CPU + * interrupt. + * cpuint - Pre-allocated CPU interrupt to which the interrupt + * source will be assigned. + * priority - Interrupt priority. + * type - Interrupt trigger type. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_route_intr(int source, int cpuint, irq_priority_t priority, + irq_trigger_t type); + +/**************************************************************************** + * Name: esp_setup_irq + * + * Description: + * This function sets up the IRQ. It allocates a CPU interrupt of the given + * priority and type and attaches it to a given interrupt source. + * + * Input Parameters: + * source - The interrupt source from irq.h to be assigned to + * a CPU interrupt. + * priority - Interrupt priority. + * type - Interrupt trigger type. + * + * Returned Value: + * The allocated CPU interrupt on success, a negated errno value on + * failure. + * + ****************************************************************************/ + +int esp_setup_irq(int source, irq_priority_t priority, irq_trigger_t type); + +/**************************************************************************** + * Name: esp_teardown_irq + * + * Description: + * This function undoes the operations done by esp_setup_irq. + * It detaches an interrupt source from a CPU interrupt and frees the + * CPU interrupt. + * + * Input Parameters: + * source - The interrupt source from irq.h to be detached from the + * CPU interrupt. + * cpuint - The CPU interrupt from which the interrupt source will + * be detached. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_teardown_irq(int source, int cpuint); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_ESPRESSIF_ESP_IRQ_H */ diff --git a/arch/risc-v/src/espressif/esp_libc_stubs.c b/arch/risc-v/src/espressif/esp_libc_stubs.c new file mode 100644 index 0000000000..711d6c0b7f --- /dev/null +++ b/arch/risc-v/src/espressif/esp_libc_stubs.c @@ -0,0 +1,414 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_libc_stubs.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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "esp_rom_caps.h" +#include "rom/libc_stubs.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define _lock_t int + +#define ROM_MUTEX_MAGIC 0xbb10c433 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Forward declaration */ + +struct _reent; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static mutex_t g_nxlock_common; +static mutex_t g_nxlock_recursive; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int _close_r(struct _reent *r, int fd) +{ + return close(fd); +} + +int _fstat_r(struct _reent *r, int fd, struct stat *statbuf) +{ + return fstat(fd, statbuf); +} + +int _getpid_r(struct _reent *r) +{ + return getpid(); +} + +int _kill_r(struct _reent *r, int pid, int sig) +{ + return kill(pid, sig); +} + +int _link_r(struct _reent *r, const char *oldpath, const char *newpath) +{ + /* TODO */ + + return 0; +} + +int lseek_r(struct _reent *r, int fd, int offset, int whence) +{ + return lseek(fd, offset, whence); +} + +int _open_r(struct _reent *r, const char *pathname, int flags, int mode) +{ + return open(pathname, flags, mode); +} + +int read_r(struct _reent *r, int fd, void *buf, int count) +{ + return read(fd, buf, count); +} + +int _rename_r(struct _reent *r, const char *oldpath, const char *newpath) +{ + return rename(oldpath, newpath); +} + +void *_sbrk_r(struct _reent *r, ptrdiff_t increment) +{ + /* TODO: sbrk is only supported on Kernel mode */ + + errno = -ENOMEM; + return (void *) -1; +} + +int _stat_r(struct _reent *r, const char *pathname, struct stat *statbuf) +{ + return stat(pathname, statbuf); +} + +clock_t _times_r(struct _reent *r, struct tms *buf) +{ + return times(buf); +} + +int _unlink_r(struct _reent *r, const char *pathname) +{ + return unlink(pathname); +} + +int write_r(struct _reent *r, int fd, const void *buf, int count) +{ + return write(fd, buf, count); +} + +int _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz) +{ + return gettimeofday(tv, tz); +} + +void *_malloc_r(struct _reent *r, size_t size) +{ + return malloc(size); +} + +void *_realloc_r(struct _reent *r, void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +void *_calloc_r(struct _reent *r, size_t nmemb, size_t size) +{ + return calloc(nmemb, size); +} + +void _free_r(struct _reent *r, void *ptr) +{ + free(ptr); +} + +void _abort(void) +{ + abort(); +} + +void _raise_r(struct _reent *r) +{ + /* FIXME */ +} + +void _lock_init(_lock_t *lock) +{ + nxmutex_init(&g_nxlock_common); + nxsem_get_value(&g_nxlock_common.sem, lock); +} + +void _lock_init_recursive(_lock_t *lock) +{ + nxmutex_init(&g_nxlock_recursive); + nxsem_get_value(&g_nxlock_recursive.sem, lock); +} + +void _lock_close(_lock_t *lock) +{ + nxmutex_destroy(&g_nxlock_common); + *lock = 0; +} + +void _lock_close_recursive(_lock_t *lock) +{ + nxmutex_destroy(&g_nxlock_recursive); + *lock = 0; +} + +void _lock_acquire(_lock_t *lock) +{ + nxmutex_lock(&g_nxlock_common); + nxsem_get_value(&g_nxlock_common.sem, lock); +} + +void _lock_acquire_recursive(_lock_t *lock) +{ + nxmutex_lock(&g_nxlock_recursive); + nxsem_get_value(&g_nxlock_recursive.sem, lock); +} + +int _lock_try_acquire(_lock_t *lock) +{ + nxmutex_trylock(&g_nxlock_common); + nxsem_get_value(&g_nxlock_common.sem, lock); + return 0; +} + +int _lock_try_acquire_recursive(_lock_t *lock) +{ + nxmutex_trylock(&g_nxlock_recursive); + nxsem_get_value(&g_nxlock_recursive.sem, lock); + return 0; +} + +void _lock_release(_lock_t *lock) +{ + nxmutex_unlock(&g_nxlock_common); + nxsem_get_value(&g_nxlock_common.sem, lock); +} + +void _lock_release_recursive(_lock_t *lock) +{ + nxmutex_unlock(&g_nxlock_recursive); + nxsem_get_value(&g_nxlock_recursive.sem, lock); +} + +#if ESP_ROM_HAS_RETARGETABLE_LOCKING +void __retarget_lock_init(_LOCK_T *lock) +{ + _lock_init(lock); +} + +void __retarget_lock_init_recursive(_LOCK_T *lock) +{ + _lock_init_recursive(lock); +} + +void __retarget_lock_close(_LOCK_T lock) +{ + _lock_close(&lock); +} + +void __retarget_lock_close_recursive(_LOCK_T lock) +{ + _lock_close_recursive(&lock); +} + +void __retarget_lock_acquire(_LOCK_T lock) +{ + _lock_acquire(&lock); +} + +void __retarget_lock_acquire_recursive(_LOCK_T lock) +{ + _lock_acquire_recursive(&lock); +} + +int __retarget_lock_try_acquire(_LOCK_T lock) +{ + return _lock_try_acquire(&lock); +} + +int __retarget_lock_try_acquire_recursive(_LOCK_T lock) +{ + return _lock_try_acquire_recursive(&lock); +} + +void __retarget_lock_release(_LOCK_T lock) +{ + _lock_release(&lock); +} + +void __retarget_lock_release_recursive(_LOCK_T lock) +{ + _lock_release_recursive(&lock); +} +#endif + +struct _reent *__getreent(void) +{ + /* TODO */ + + return (struct _reent *) NULL; +} + +int _system_r(struct _reent *r, const char *command) +{ + /* TODO: Implement system() */ + + return 0; +} + +void noreturn_function __assert_func(const char *file, int line, + const char *func, const char *expr) +{ + __assert(file, line, expr); +} + +void _cleanup_r(struct _reent *r) +{ +} + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct syscall_stub_table g_stub_table = +{ + .__getreent = &__getreent, + ._malloc_r = &_malloc_r, + ._free_r = &_free_r, + ._realloc_r = &_realloc_r, + ._calloc_r = &_calloc_r, + ._abort = &_abort, + ._system_r = &_system_r, + ._rename_r = &_rename_r, + ._times_r = &_times_r, + ._gettimeofday_r = &_gettimeofday_r, + ._raise_r = &_raise_r, + ._unlink_r = &_unlink_r, + ._link_r = &_link_r, + ._stat_r = &_stat_r, + ._fstat_r = &_fstat_r, + ._sbrk_r = &_sbrk_r, + ._getpid_r = &_getpid_r, + ._kill_r = &_kill_r, + ._exit_r = NULL, + ._close_r = &_close_r, + ._open_r = &_open_r, + ._write_r = &write_r, + ._lseek_r = &lseek_r, + ._read_r = &read_r, +#if ESP_ROM_HAS_RETARGETABLE_LOCKING + ._retarget_lock_init = &__retarget_lock_init, + ._retarget_lock_init_recursive = &__retarget_lock_init_recursive, + ._retarget_lock_close = &__retarget_lock_close, + ._retarget_lock_close_recursive = &__retarget_lock_close_recursive, + ._retarget_lock_acquire = &__retarget_lock_acquire, + ._retarget_lock_acquire_recursive = &__retarget_lock_acquire_recursive, + ._retarget_lock_try_acquire = &__retarget_lock_try_acquire, + ._retarget_lock_try_acquire_recursive = + &__retarget_lock_try_acquire_recursive, + ._retarget_lock_release = &__retarget_lock_release, + ._retarget_lock_release_recursive = &__retarget_lock_release_recursive, +#else + ._lock_init = &_lock_init, + ._lock_init_recursive = &_lock_init_recursive, + ._lock_close = &_lock_close, + ._lock_close_recursive = &_lock_close_recursive, + ._lock_acquire = &_lock_acquire, + ._lock_acquire_recursive = &_lock_acquire_recursive, + ._lock_try_acquire = &_lock_try_acquire, + ._lock_try_acquire_recursive = &_lock_try_acquire_recursive, + ._lock_release = &_lock_release, + ._lock_release_recursive = &_lock_release_recursive, +#endif + ._printf_float = NULL, + ._scanf_float = NULL, + .__assert_func = &__assert_func, + .__sinit = (void *)abort, + ._cleanup_r = &_cleanup_r +}; + +/**************************************************************************** + * Name: esp_setup_syscall_table + * + * Description: + * Configure the syscall table used by the ROM code for calling C library + * functions. + * ROM code from Espressif's chips contains implementations of some of C + * library functions. Whenever a function in ROM needs to use a syscall, + * it calls a pointer to the corresponding syscall implementation defined + * in the syscall_stub_table struct. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_setup_syscall_table(void) +{ + syscall_table_ptr = (struct syscall_stub_table *)&g_stub_table; + + /* Newlib 3.3.0 is used in ROM, built with _RETARGETABLE_LOCKING. + * No access to lock variables for the purpose of ECO forward + * compatibility, however we have an API to initialize lock variables used + * in the ROM. + */ + + extern void esp_rom_newlib_init_common_mutexes(_LOCK_T, _LOCK_T); + + int magic_val = ROM_MUTEX_MAGIC; + _LOCK_T magic_mutex = (_LOCK_T) &magic_val; + esp_rom_newlib_init_common_mutexes(magic_mutex, magic_mutex); +} + diff --git a/arch/risc-v/src/espressif/esp_libc_stubs.h b/arch/risc-v/src/espressif/esp_libc_stubs.h new file mode 100644 index 0000000000..9ed6084e1e --- /dev/null +++ b/arch/risc-v/src/espressif/esp_libc_stubs.h @@ -0,0 +1,51 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_libc_stubs.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 __ARCH_RISCV_SRC_ESPRESSIF_ESP_LIBC_STUBS_H +#define __ARCH_RISCV_SRC_ESPRESSIF_ESP_LIBC_STUBS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Name: esp_setup_syscall_table + * + * Description: + * Configure the syscall table used by the ROM code for calling C library + * functions. + * ROM code from Espressif's chips contains implementations of some of C + * library functions. Whenever a function in ROM needs to use a syscall, + * it calls a pointer to the corresponding syscall implementation defined + * in the syscall_stub_table struct. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_setup_syscall_table(void); + +#endif /* __ARCH_RISCV_SRC_ESPRESSIF_ESP_LIBC_STUBS_H */ diff --git a/arch/risc-v/src/espressif/esp_lowputc.c b/arch/risc-v/src/espressif/esp_lowputc.c new file mode 100644 index 0000000000..87fd53b263 --- /dev/null +++ b/arch/risc-v/src/espressif/esp_lowputc.c @@ -0,0 +1,364 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_lowputc.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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "riscv_internal.h" + +#include "esp_config.h" +#include "esp_gpio.h" +#include "esp_irq.h" +#include "esp_lowputc.h" + +#include "hal/uart_hal.h" +#include "periph_ctrl.h" +#include "soc/gpio_sig_map.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE + +#ifdef CONFIG_ESPRESSIF_UART0 + +static uart_hal_context_t g_uart0_hal = +{ + .dev = &UART0 +}; + +struct esp_uart_s g_uart0_config = +{ + .source = UART0_INTR_SOURCE, + .cpuint = -ENOMEM, + .int_pri = ESP_IRQ_PRIORITY_DEFAULT, + .id = 0, + .irq = ESP_IRQ_UART0, + .baud = CONFIG_UART0_BAUD, + .stop_b2 = CONFIG_UART0_2STOP, + .bits = CONFIG_UART0_BITS, + .parity = CONFIG_UART0_PARITY, + .txpin = CONFIG_ESPRESSIF_UART0_TXPIN, + .txsig = U0TXD_OUT_IDX, + .rxpin = CONFIG_ESPRESSIF_UART0_RXPIN, + .rxsig = U0RXD_IN_IDX, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rtspin = CONFIG_ESPRESSIF_UART0_RTSPIN, + .rtssig = U0RTS_OUT_IDX, +#ifdef CONFIG_UART0_IFLOWCONTROL + .iflow = true, /* input flow control (RTS) enabled */ +#else + .iflow = false, /* input flow control (RTS) disabled */ +#endif +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .ctspin = CONFIG_ESPRESSIF_UART0_CTSPIN, + .ctssig = U0CTS_IN_IDX, +#ifdef CONFIG_UART0_OFLOWCONTROL + .oflow = true, /* output flow control (CTS) enabled */ +#else + .oflow = false, /* output flow control (CTS) disabled */ +#endif +#endif + .hal = &g_uart0_hal +}; + +#endif /* CONFIG_ESPRESSIF_UART0 */ + +#ifdef CONFIG_ESPRESSIF_UART1 + +static uart_hal_context_t g_uart1_hal = +{ + .dev = &UART1 +}; + +struct esp_uart_s g_uart1_config = +{ + .source = UART1_INTR_SOURCE, + .cpuint = -ENOMEM, + .int_pri = ESP_IRQ_PRIORITY_DEFAULT, + .id = 1, + .irq = ESP_IRQ_UART1, + .baud = CONFIG_UART1_BAUD, + .stop_b2 = CONFIG_UART1_2STOP, + .bits = CONFIG_UART1_BITS, + .parity = CONFIG_UART1_PARITY, + .txpin = CONFIG_ESPRESSIF_UART1_TXPIN, + .txsig = U1TXD_OUT_IDX, + .rxpin = CONFIG_ESPRESSIF_UART1_RXPIN, + .rxsig = U1RXD_IN_IDX, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rtspin = CONFIG_ESPRESSIF_UART1_RTSPIN, + .rtssig = U1RTS_OUT_IDX, +#ifdef CONFIG_UART1_IFLOWCONTROL + .iflow = true, /* input flow control (RTS) enabled */ +#else + .iflow = false, /* input flow control (RTS) disabled */ +#endif +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .ctspin = CONFIG_ESPRESSIF_UART1_CTSPIN, + .ctssig = U1CTS_IN_IDX, +#ifdef CONFIG_UART1_OFLOWCONTROL + .oflow = true, /* output flow control (CTS) enabled */ +#else + .oflow = false, /* output flow control (CTS) disabled */ +#endif +#endif + .hal = &g_uart1_hal +}; + +#endif /* CONFIG_ESPRESSIF_UART1 */ +#endif /* HAVE_UART_DEVICE */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_lowputc_send_byte + * + * Description: + * Send one byte. + * + * Parameters: + * priv - Pointer to the private driver struct. + * byte - Byte to be sent. + * + ****************************************************************************/ + +void esp_lowputc_send_byte(const struct esp_uart_s *priv, char byte) +{ + uint32_t write_size; + uart_hal_write_txfifo(priv->hal, (const uint8_t *)&byte, 1, &write_size); +} + +/**************************************************************************** + * Name: esp_lowputc_enable_sysclk + * + * Description: + * Enable clock for the UART using the System register. + * + * Parameters: + * priv - Pointer to the private driver struct. + * + ****************************************************************************/ + +void esp_lowputc_enable_sysclk(const struct esp_uart_s *priv) +{ + periph_module_enable(PERIPH_UART0_MODULE + priv->id); +} + +/**************************************************************************** + * Name: esp_lowputc_disable_all_uart_int + * + * Description: + * Disable all UART interrupts. + * + * Parameters: + * priv - Pointer to the private driver struct. + * current_status - Pointer to a variable to store the current status of + * the interrupt enable register before disabling + * UART interrupts. + * + ****************************************************************************/ + +void esp_lowputc_disable_all_uart_int(const struct esp_uart_s *priv, + uint32_t *current_status) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + if (current_status != NULL) + { + /* Save current status */ + + *current_status = uart_hal_get_intr_ena_status(priv->hal); + } + + /* Disable all UART int */ + + uart_hal_disable_intr_mask(priv->hal, UINT32_MAX); + + /* Clear all ints */ + + uart_hal_clr_intsts_mask(priv->hal, UINT32_MAX); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: esp_lowputc_restore_all_uart_int + * + * Description: + * Restore all UART interrupts. + * + * Parameters: + * priv - Pointer to the private driver struct. + * last_status - Pointer to a variable that stored the last state of the + * interrupt enable register. + * + ****************************************************************************/ + +void esp_lowputc_restore_all_uart_int(const struct esp_uart_s *priv, + uint32_t *last_status) +{ + /* Restore the previous behaviour */ + + uart_hal_ena_intr_mask(priv->hal, *last_status); +} + +/**************************************************************************** + * Name: esp_lowputc_config_pins + * + * Description: + * Configure TX and RX UART pins. + * + * Parameters: + * priv - Pointer to the private driver struct. + * + ****************************************************************************/ + +void esp_lowputc_config_pins(const struct esp_uart_s *priv) +{ + /* Configure the pins */ + + esp_configgpio(priv->txpin, OUTPUT); + esp_gpio_matrix_out(priv->txpin, priv->txsig, 0, 0); + + esp_configgpio(priv->rxpin, INPUT | PULLUP); + esp_gpio_matrix_in(priv->rxpin, priv->rxsig, 0); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + esp_configgpio(priv->rtspin, OUTPUT); + esp_gpio_matrix_out(priv->rtspin, priv->rtssig, 0, 0); + } + +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->oflow) + { + esp_configgpio(priv->ctspin, INPUT | PULLUP); + esp_gpio_matrix_in(priv->ctspin, priv->ctssig, 0); + } +#endif +} + +/**************************************************************************** + * Name: esp_lowputc_restore_pins + * + * Description: + * Configure both pins back to INPUT mode and detach the TX pin from the + * output signal and the RX pin from the input signal. + * + * Parameters: + * priv - Pointer to the private driver struct. + * + ****************************************************************************/ + +void esp_lowputc_restore_pins(const struct esp_uart_s *priv) +{ + /* Configure the pins */ + + esp_configgpio(priv->txpin, INPUT); + esp_gpio_matrix_out(priv->txpin, 0x100, false, false); + + esp_configgpio(priv->rxpin, INPUT); + esp_gpio_matrix_in(priv->rxpin, 0x3c, false); +} + +/**************************************************************************** + * Name: riscv_lowputc + * + * Description: + * Output one byte on the serial console. + * + * Parameters: + * ch - Byte to be sent. + * + ****************************************************************************/ + +void riscv_lowputc(char ch) +{ +#ifdef CONSOLE_UART +# if defined(CONFIG_UART0_SERIAL_CONSOLE) + struct esp_uart_s *priv = &g_uart0_config; +# elif defined (CONFIG_UART1_SERIAL_CONSOLE) + struct esp_uart_s *priv = &g_uart1_config; +#endif + + /* Wait until the TX FIFO has space to insert new char */ + + while (uart_hal_get_txfifo_len(priv->hal) == 0); + + /* Then send the character */ + + esp_lowputc_send_byte(priv, ch); +#endif /* CONSOLE_UART */ +} + +/**************************************************************************** + * Name: esp_lowsetup + * + * Description: + * This performs only the basic configuration for UART pins. + * + ****************************************************************************/ + +void esp_lowsetup(void) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + +#ifdef CONFIG_ESPRESSIF_UART0 + esp_lowputc_enable_sysclk(&g_uart0_config); + esp_lowputc_config_pins(&g_uart0_config); +#endif + +#ifdef CONFIG_ESPRESSIF_UART1 + esp_lowputc_enable_sysclk(&g_uart1_config); + esp_lowputc_config_pins(&g_uart1_config); +#endif + +#endif /* !CONFIG_SUPPRESS_UART_CONFIG */ +} diff --git a/arch/risc-v/src/espressif/esp_lowputc.h b/arch/risc-v/src/espressif/esp_lowputc.h new file mode 100644 index 0000000000..39d99cd654 --- /dev/null +++ b/arch/risc-v/src/espressif/esp_lowputc.h @@ -0,0 +1,186 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_lowputc.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 __ARCH_RISCV_SRC_ESPRESSIF_ESP_LOWPUTC_H +#define __ARCH_RISCV_SRC_ESPRESSIF_ESP_LOWPUTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "esp_irq.h" +#include "hal/uart_hal.h" + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Store information used for interfacing with the UART driver */ + +struct esp_uart_s +{ + int source; /* UART interrupt source */ + int cpuint; /* CPU interrupt assigned to this UART */ + irq_priority_t int_pri; /* UART Interrupt Priority */ + int id; /* UART ID */ + int irq; /* IRQ associated with this UART */ + uint32_t baud; /* Configured baud rate */ + bool stop_b2; /* Flag for using 2 stop bits */ + uint8_t bits; /* Data length (5 to 8 bits) */ + uint8_t parity; /* 0=no parity, 1=odd, 2=even */ + uint8_t txpin; /* TX pin */ + uint8_t txsig; /* TX signal */ + uint8_t rxpin; /* RX pin */ + uint8_t rxsig; /* RX signal */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + uint8_t rtspin; /* RTS pin number */ + uint8_t rtssig; /* RTS signal */ + bool iflow; /* Input flow control (RTS) enabled */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + uint8_t ctspin; /* CTS pin number */ + uint8_t ctssig; /* CTS signal */ + bool oflow; /* Output flow control (CTS) enabled */ +#endif + uart_hal_context_t *hal; /* HAL context */ +}; + +extern struct esp_uart_s g_uart0_config; +extern struct esp_uart_s g_uart1_config; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_lowputc_send_byte + * + * Description: + * Send one byte. + * + * Parameters: + * priv - Pointer to the private driver struct. + * byte - Byte to be sent. + * + ****************************************************************************/ + +void esp_lowputc_send_byte(const struct esp_uart_s *priv, + char byte); + +/**************************************************************************** + * Name: esp_lowputc_enable_sysclk + * + * Description: + * Enable clock for the UART using the System register. + * + * Parameters: + * priv - Pointer to the private driver struct. + * + ****************************************************************************/ + +void esp_lowputc_enable_sysclk(const struct esp_uart_s *priv); + +/**************************************************************************** + * Name: esp_lowputc_disable_all_uart_int + * + * Description: + * Disable all UART interrupts. + * + * Parameters: + * priv - Pointer to the private driver struct. + * current_status - Pointer to a variable to store the current status of + * the interrupt enable register before disabling + * UART interrupts. + * + ****************************************************************************/ + +void esp_lowputc_disable_all_uart_int(const struct esp_uart_s *priv, + uint32_t *current_status); + +/**************************************************************************** + * Name: esp_lowputc_restore_all_uart_int + * + * Description: + * Restore all UART interrupts. + * + * Parameters: + * priv - Pointer to the private driver struct. + * last_status - Pointer to a variable that stored the last state of the + * interrupt enable register. + * + ****************************************************************************/ + +void esp_lowputc_restore_all_uart_int(const struct esp_uart_s *priv, + uint32_t *last_status); + +/**************************************************************************** + * Name: esp_lowputc_config_pins + * + * Description: + * Configure TX and RX UART pins. + * + * Parameters: + * priv - Pointer to the private driver struct. + * + ****************************************************************************/ + +void esp_lowputc_config_pins(const struct esp_uart_s *priv); + +/**************************************************************************** + * Name: esp_lowputc_restore_pins + * + * Description: + * Configure both pins back to INPUT mode and detach the TX pin from the + * output signal and the RX pin from the input signal. + * + * Parameters: + * priv - Pointer to the private driver struct. + * + ****************************************************************************/ + +void esp_lowputc_restore_pins(const struct esp_uart_s *priv); + +/**************************************************************************** + * Name: esp_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output available as soon + * as possible. + * + ****************************************************************************/ + +void esp_lowsetup(void); + +#endif /* __ARCH_RISCV_SRC_ESPRESSIF_ESP_LOWPUTC_H */ diff --git a/arch/risc-v/src/espressif/esp_memorymap.h b/arch/risc-v/src/espressif/esp_memorymap.h new file mode 100644 index 0000000000..d30ed4b589 --- /dev/null +++ b/arch/risc-v/src/espressif/esp_memorymap.h @@ -0,0 +1,44 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_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 __ARCH_RISCV_SRC_ESPRESSIF_ESP_MEMORYMAP_H +#define __ARCH_RISCV_SRC_ESPRESSIF_ESP_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Idle thread stack starts from _ebss */ + +#ifndef __ASSEMBLY__ +#define ESP_IDLESTACK_BASE (uint32_t)&g_idlestack +#else +#define ESP_IDLESTACK_BASE g_idlestack +#endif + +#define ESP_IDLESTACK_TOP (ESP_IDLESTACK_BASE + CONFIG_IDLETHREAD_STACKSIZE) + +#endif /* __ARCH_RISCV_SRC_ESPRESSIF_ESP_MEMORYMAP_H */ diff --git a/arch/risc-v/src/espressif/esp_serial.c b/arch/risc-v/src/espressif/esp_serial.c new file mode 100644 index 0000000000..b99cfb99c7 --- /dev/null +++ b/arch/risc-v/src/espressif/esp_serial.c @@ -0,0 +1,1232 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_serial.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 + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif +#include + +#include +#include +#include +#include + +#include "riscv_internal.h" +#include "chip.h" +#include "esp_config.h" +#include "esp_irq.h" +#include "esp_lowputc.h" + +#include "clk_tree.h" +#include "hal/uart_hal.h" +#include "soc/clk_tree_defs.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The console is enabled and it's not the syslog device, so it should be a + * serial device. + */ + +#ifdef USE_SERIALDRIVER + +/* Which UART will be designated to ttyS0/console and which one will be + * designated to ttyS1? + */ + +/* First pick the console and ttyS0. + * Console can use either UART0 or UART1, but will always be ttyS0. + */ + +/* In case a UART was assigned to be the console and the corresponding + * peripheral was also selected. + */ + +#ifdef CONSOLE_UART +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0_dev /* UART0 is console */ +# define TTYS0_DEV g_uart0_dev /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1_dev /* UART1 is console */ +# define TTYS0_DEV g_uart1_dev /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# endif /* CONFIG_UART0_SERIAL_CONSOLE */ +#else /* No UART console */ +# undef CONSOLE_DEV +# if defined(CONFIG_ESPRESSIF_UART0) +# define TTYS0_DEV g_uart0_dev /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +# elif defined(CONFIG_ESPRESSIF_UART1) +# define TTYS0_DEV g_uart1_dev /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# endif +#endif /* CONSOLE_UART */ + +/* Pick ttyS1 */ + +#if defined(CONFIG_ESPRESSIF_UART0) && !defined(UART0_ASSIGNED) +# define TTYS1_DEV g_uart0_dev /* UART0 is ttyS1 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_ESPRESSIF_UART1) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1_dev /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#endif + +#ifdef HAVE_UART_DEVICE + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_UART + +/* Serial driver methods */ + +static int esp_setup(uart_dev_t *dev); +static void esp_shutdown(uart_dev_t *dev); +static int esp_attach(uart_dev_t *dev); +static void esp_detach(uart_dev_t *dev); +static void esp_txint(uart_dev_t *dev, bool enable); +static void esp_rxint(uart_dev_t *dev, bool enable); +static bool esp_rxavailable(uart_dev_t *dev); +static bool esp_txready(uart_dev_t *dev); +static bool esp_txempty(uart_dev_t *dev); +static void esp_send(uart_dev_t *dev, int ch); +static int esp_receive(uart_dev_t *dev, unsigned int *status); +static int esp_ioctl(struct file *filep, int cmd, unsigned long arg); +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool esp_rxflowcontrol(uart_dev_t *dev, + unsigned int nbuffered, bool upper); +#endif +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_UART + +/* Operations */ + +static struct uart_ops_s g_uart_ops = +{ + .setup = esp_setup, + .shutdown = esp_shutdown, + .attach = esp_attach, + .detach = esp_detach, + .txint = esp_txint, + .rxint = esp_rxint, + .rxavailable = esp_rxavailable, + .txready = esp_txready, + .txempty = esp_txempty, + .send = esp_send, + .receive = esp_receive, + .ioctl = esp_ioctl, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = esp_rxflowcontrol +#endif +}; + +/* UART 0 */ + +#ifdef CONFIG_ESPRESSIF_UART0 + +static char g_uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0_txbuffer[CONFIG_UART0_TXBUFSIZE]; + +/* Fill only the requested fields */ + +static uart_dev_t g_uart0_dev = +{ +#ifdef CONFIG_UART0_SERIAL_CONSOLE + .isconsole = true, +#else + .isconsole = false, +#endif + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0_txbuffer, + }, + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0_rxbuffer, + }, + + .ops = &g_uart_ops, + .priv = &g_uart0_config +}; + +#endif + +/* UART 1 */ + +#ifdef CONFIG_ESPRESSIF_UART1 + +static char g_uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1_txbuffer[CONFIG_UART1_TXBUFSIZE]; + +/* Fill only the requested fields */ + +static uart_dev_t g_uart1_dev = +{ +#ifdef CONFIG_UART1_SERIAL_CONSOLE + .isconsole = true, +#else + .isconsole = false, +#endif + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1_txbuffer, + }, + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1_rxbuffer, + }, + + .ops = &g_uart_ops, + .priv = &g_uart1_config +}; + +#endif + +#endif /* CONFIG_ESPRESSIF_UART */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_UART + +/**************************************************************************** + * Name: uart_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt is received on the 'irq'. It should call uart_xmitchars or + * uart_recvchars to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + * Input Parameters: + * irq - IRQ associated to that interrupt. + * context - Interrupt register state save info. + * arg - A pointer to the argument provided when the interrupt + * was registered. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int uart_handler(int irq, void *context, void *arg) +{ + uart_dev_t *dev = (uart_dev_t *)arg; + struct esp_uart_s *priv = dev->priv; + uint32_t tx_mask = UART_INTR_TXFIFO_EMPTY | UART_INTR_TX_DONE; + uint32_t rx_mask = UART_INTR_RXFIFO_TOUT | UART_INTR_RXFIFO_FULL; + uint32_t int_status = uart_hal_get_intsts_mask(priv->hal); + + /* Tx fifo empty interrupt or UART tx done int */ + + if ((int_status & tx_mask) != 0) + { + uart_xmitchars(dev); + uart_hal_clr_intsts_mask(priv->hal, tx_mask); + } + + /* Rx fifo timeout interrupt or rx fifo full interrupt */ + + if ((int_status & rx_mask) != 0) + { + uart_recvchars(dev); + uart_hal_clr_intsts_mask(priv->hal, rx_mask); + } + + return OK; +} + +/**************************************************************************** + * Name: set_data_length + * + * Description: + * Set the data bits length, according to the value in the private driver + * struct. + * + * Input Parameters: + * priv - Pointer to the private driver struct. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void set_data_length(const struct esp_uart_s *priv) +{ + uint32_t length = (priv->bits - 5); + + /* If it is the allowed range */ + + DEBUGASSERT(length >= UART_DATA_5_BITS && length <= UART_DATA_8_BITS); + + uart_hal_set_data_bit_num(priv->hal, length); +} + +/**************************************************************************** + * Name: set_stop_length + * + * Description: + * Set the stop bits length, according to the value in the private driver + * struct. + * + * Input Parameters: + * priv - Pointer to the private driver struct. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void set_stop_length(const struct esp_uart_s *priv) +{ + uart_stop_bits_t stop_bits; + + if (priv->stop_b2) + { + stop_bits = UART_STOP_BITS_2; + } + else + { + stop_bits = UART_STOP_BITS_1; + } + + uart_hal_set_stop_bits(priv->hal, stop_bits); +} + +/**************************************************************************** + * Name: esp_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This method is + * called the first time that the serial port is opened. + * For the serial console, this will occur very early in initialization, + * for other serial ports this will occur when the port is first opened. + * This setup does not include attaching or enabling interrupts. + * That portion of the UART setup is performed when the attach() method + * is called. + * + * Input Parameters: + * dev - Pointer to the serial driver struct. + * + * Returned Values: + * Zero (OK) is returned. + * + ****************************************************************************/ + +static int esp_setup(uart_dev_t *dev) +{ + struct esp_uart_s *priv = dev->priv; + uint32_t sclk_freq; + + /* Enable the UART Clock */ + + esp_lowputc_enable_sysclk(priv); + + clk_tree_src_get_freq_hz((soc_module_clk_t)UART_SCLK_DEFAULT, + CLK_TREE_SRC_FREQ_PRECISION_CACHED, + &sclk_freq); + + /* Initialize UART module */ + + uart_hal_init(priv->hal, priv->id); + uart_hal_set_mode(priv->hal, UART_MODE_UART); + uart_hal_set_sclk(priv->hal, UART_SCLK_DEFAULT); + uart_hal_set_baudrate(priv->hal, priv->baud, sclk_freq); + uart_hal_set_parity(priv->hal, priv->parity); + set_data_length(priv); + set_stop_length(priv); + uart_hal_set_tx_idle_num(priv->hal, 0); + + /* Define 0 as the threshold that means TX FIFO buffer is empty. */ + + uart_hal_set_txfifo_empty_thr(priv->hal, 10); + + /* Define a threshold to trigger an RX FIFO FULL interrupt. + * Define just one byte to read data immediately. + */ + + uart_hal_set_rxfifo_full_thr(priv->hal, 120); + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || \ + defined(CONFIG_SERIAL_OFLOWCONTROL) + uart_hw_flowcontrol_t flow_ctrl = UART_HW_FLOWCTRL_DISABLE; + uint32_t rx_thrs = 0; + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + /* Configure the input flow control */ + + if (priv->iflow) + { + /* Enable input flow control and set the RX FIFO threshold + * to assert the RTS line to half the RX FIFO buffer. + * It will then save some space on the hardware fifo to + * remaining bytes that may arrive after RTS be asserted + * and before the transmitter stops sending data. + */ + + flow_ctrl |= UART_HW_FLOWCTRL_RTS; + rx_thrs = SOC_UART_FIFO_LEN / 2; + } +#endif + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + /* Configure the output flow control */ + + if (priv->oflow) + { + flow_ctrl |= UART_HW_FLOWCTRL_CTS; + } +#endif + + uart_hal_set_hw_flow_ctrl(priv->hal, flow_ctrl, rx_thrs); +#endif /* CONFIG_SERIAL_IFLOWCONTROL || CONFIG_SERIAL_OFLOWCONTROL */ + + /* Clear FIFOs */ + + uart_hal_rxfifo_rst(priv->hal); + uart_hal_txfifo_rst(priv->hal); + + return OK; +} + +/**************************************************************************** + * Name: esp_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed. + * This method reverses the operation of the setup method. Note that the + * serial console is never shutdown. + * + * Input Parameters: + * dev - Pointer to the serial driver struct. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp_shutdown(uart_dev_t *dev) +{ + struct esp_uart_s *priv = dev->priv; + + /* Disable interrupts */ + + esp_lowputc_disable_all_uart_int(priv, NULL); +} + +/**************************************************************************** + * Name: esp_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method + * is called when the serial port is opened. Normally, this is just after + * the the setup() method is called, however, the serial console may + * operate in a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless + * the hardware supports multiple levels of interrupt enabling). The RX + * and TX interrupts are not enabled until the txint() and rxint() methods + * are called. + * + * Input Parameters: + * dev - Pointer to the serial driver struct. + * + * Returned Values: + * Zero (OK) is returned on success; a negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +static int esp_attach(uart_dev_t *dev) +{ + struct esp_uart_s *priv = dev->priv; + int ret; + + DEBUGASSERT(priv->cpuint == -ENOMEM); + + /* Set up to receive peripheral interrupts */ + + priv->cpuint = esp_setup_irq(priv->source, priv->int_pri, + ESP_IRQ_TRIGGER_LEVEL); + if (priv->cpuint < 0) + { + return priv->cpuint; + } + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, uart_handler, dev); + if (ret == OK) + { + up_enable_irq(priv->irq); + } + else + { + up_disable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: esp_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The + * exception is the serial console which is never shutdown. + * + * Input Parameters: + * dev - Pointer to the serial driver struct. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp_detach(uart_dev_t *dev) +{ + struct esp_uart_s *priv = dev->priv; + + DEBUGASSERT(priv->cpuint != -ENOMEM); + + /* Disable and detach the CPU interrupt */ + + up_disable_irq(priv->irq); + irq_detach(priv->irq); + + /* Disassociate the peripheral interrupt from the CPU interrupt */ + + esp_teardown_irq(priv->source, priv->cpuint); + priv->cpuint = -ENOMEM; +} + +/**************************************************************************** + * Name: esp_txint + * + * Description: + * Enable or disable TX interrupts. + * + * Input Parameters: + * dev - Pointer to the serial driver struct. + * enable - If true enables the TX interrupt, if false disables it. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp_txint(uart_dev_t *dev, bool enable) +{ + struct esp_uart_s *priv = dev->priv; + uint32_t ints_mask = UART_INTR_TXFIFO_EMPTY | UART_INTR_TX_DONE; + + if (enable) + { + /* Set to receive an interrupt when the TX holding register register + * is empty + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + uart_hal_ena_intr_mask(priv->hal, ints_mask); +#endif + } + else + { + /* Disable the TX interrupt */ + + uart_hal_disable_intr_mask(priv->hal, ints_mask); + } +} + +/**************************************************************************** + * Name: esp_rxint + * + * Description: + * Enable or disable RX interrupts. + * + * Input Parameters: + * dev - Pointer to the serial driver struct. + * enable - If true enables the RX interrupt, if false disables it. + * + ****************************************************************************/ + +static void esp_rxint(uart_dev_t *dev, bool enable) +{ + struct esp_uart_s *priv = dev->priv; + uint32_t ints_mask = UART_INTR_RXFIFO_TOUT | UART_INTR_RXFIFO_FULL; + + if (enable) + { + /* Receive an interrupt when there is anything in the RX data register + * (or an RX timeout occurs). + * NOTE: RX timeout feature needs to be enabled. + */ +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + uart_hal_set_rx_timeout(priv->hal, 0xa); + uart_hal_ena_intr_mask(priv->hal, ints_mask); +#endif + } + else + { + uart_hal_set_rx_timeout(priv->hal, 0); + uart_hal_disable_intr_mask(priv->hal, ints_mask); + } +} + +/**************************************************************************** + * Name: esp_rxavailable + * + * Description: + * Check if there is any data available to be read. + * + * Input Parameters: + * dev - Pointer to the serial driver struct. + * + * Returned Values: + * Return true if the RX FIFO is not empty and false if RX FIFO is empty. + * + ****************************************************************************/ + +static bool esp_rxavailable(uart_dev_t *dev) +{ + struct esp_uart_s *priv = dev->priv; + + return uart_hal_get_rxfifo_len(priv->hal) > 0; +} + +/**************************************************************************** + * Name: esp_txready + * + * Description: + * Check if the transmit hardware is ready to send another byte. + * This is used to determine if send() method can be called. + * + * Input Parameters: + * dev - Pointer to the serial driver struct. + * + * Returned Values: + * Return true if the transmit hardware is ready to send another byte, + * false otherwise. + * + ****************************************************************************/ + +static bool esp_txready(uart_dev_t *dev) +{ + struct esp_uart_s *priv = dev->priv; + + return uart_hal_get_txfifo_len(priv->hal) > 0; +} + +/**************************************************************************** + * Name: esp_txempty + * + * Description: + * Verify if all characters have been sent. If for example, the UART + * hardware implements FIFOs, then this would mean the transmit FIFO is + * empty. This method is called when the driver needs to make sure that + * all characters are "drained" from the TX hardware. + * + * Input Parameters: + * dev - Pointer to the serial driver struct. + * + * Returned Values: + * Return true if the TX FIFO is empty, false if it is not. + * + ****************************************************************************/ + +static bool esp_txempty(uart_dev_t *dev) +{ + struct esp_uart_s *priv = dev->priv; + + return priv->hal->dev->int_raw.txfifo_empty != 0; +} + +/**************************************************************************** + * Name: esp_send + * + * Description: + * Send a unique character. + * + * Input Parameters: + * dev - Pointer to the serial driver struct. + * ch - Byte to be sent. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp_send(uart_dev_t *dev, int ch) +{ + esp_lowputc_send_byte(dev->priv, ch); +} + +/**************************************************************************** + * Name: esp_receive + * + * Description: + * Called (usually) from the interrupt handler to receive one character + * from the UART. Error bits associated with receive are provided in the + * return 'status'. + * + * Input Parameters: + * dev - Pointer to the serial driver struct. + * + * Output Parameters: + * status - Pointer to a variable to store eventual error bits. + * + * Returned Values: + * Return the byte read from the RX FIFO. + * + ****************************************************************************/ + +static int esp_receive(uart_dev_t *dev, unsigned int *status) +{ + struct esp_uart_s *priv = dev->priv; + int inout_rd_len = 1; + uint8_t buf; + + uart_hal_read_rxfifo(priv->hal, &buf, &inout_rd_len); + + /* Since we don't have error bits associated with receive, we set zero */ + + *status = 0; + + return (int)buf; +} + +/**************************************************************************** + * Name: esp_ioctl + * + * Description: + * All ioctl calls will be routed through this method. + * Here it's employed to implement the TERMIOS ioctls and TIOCSERGSTRUCT. + * + * Input Parameters: + * filep - Pointer to a file structure instance. + * cmd - The ioctl command. + * arg - The argument of the ioctl cmd. + * + * Returned Value: + * Returns a non-negative number on success; a negated errno value is + * returned on any failure (see comments ioctl() for a list of appropriate + * errno values). + * + ****************************************************************************/ + +static int esp_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + /* Get access to the internal instance of the driver through the file + * pointer. + */ + +#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) + struct inode *inode = filep->f_inode; + uart_dev_t *dev = inode->i_private; +#endif + int ret = OK; + + /* Run the requested ioctl command. */ + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + + /* Get the internal driver data structure for debug purposes */ + + case TIOCSERGSTRUCT: + { + struct esp_uart_s *user = (struct esp_uart_s *)arg; + if (user == NULL) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev->priv, sizeof(struct esp_uart_s)); + } + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + + /* Fill a termios structure with the required information */ + + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + struct esp_uart_s *priv = (struct esp_uart_s *)dev->priv; + if (termiosp == NULL) + { + ret = -EINVAL; + break; + } + + /* Return parity (0 = no parity, 1 = odd parity, 2 = even parity) */ + + termiosp->c_cflag = ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0); + + /* Return stop bits */ + + termiosp->c_cflag |= (priv->stop_b2) ? CSTOPB : 0; + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + termiosp->c_cflag |= (priv->oflow) ? CCTS_OFLOW : 0; +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + termiosp->c_cflag |= (priv->iflow) ? CRTS_IFLOW : 0; +#endif + + /* Set the baud rate in termiosp using the cfsetispeed interface */ + + cfsetispeed(termiosp, priv->baud); + + /* Return number of bits */ + + switch (priv->bits) + { + case 5: + termiosp->c_cflag |= CS5; + break; + + case 6: + termiosp->c_cflag |= CS6; + break; + + case 7: + termiosp->c_cflag |= CS7; + break; + + case 8: + default: + termiosp->c_cflag |= CS8; + break; + } + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + struct esp_uart_s *priv = (struct esp_uart_s *)dev->priv; + uint32_t baud; + uint32_t current_int_sts; + uint8_t parity; + uint8_t bits; + uint8_t stop2; +#ifdef CONFIG_SERIAL_IFLOWCONTROL + bool iflow; +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + bool oflow; +#endif + + if (termiosp == NULL) + { + ret = -EINVAL; + break; + } + + /* Get the target baud rate to change */ + + baud = cfgetispeed(termiosp); + + /* Decode number of bits */ + + switch (termiosp->c_cflag & CSIZE) + { + case CS5: + bits = 5; + break; + + case CS6: + bits = 6; + break; + + case CS7: + bits = 7; + break; + + case CS8: + bits = 8; + break; + + default: + ret = -EINVAL; + break; + } + + /* Decode parity */ + + if ((termiosp->c_cflag & PARENB) != 0) + { + parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + parity = 0; + } + + /* Decode stop bits */ + + stop2 = (termiosp->c_cflag & CSTOPB) ? 1 : 0; + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0; +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0; +#endif + + /* Verify if all settings are valid before performing the changes */ + + if (ret == OK) + { + /* Fill the private struct fields */ + + priv->baud = baud; + priv->parity = parity; + priv->bits = bits; + priv->stop_b2 = stop2; +#ifdef CONFIG_SERIAL_IFLOWCONTROL + priv->iflow = iflow; +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + priv->oflow = oflow; +#endif + + /* Effect the changes immediately - note that we do not implement + * TCSADRAIN or TCSAFLUSH, only TCSANOW option. + * See nuttx/libs/libc/termios/lib_tcsetattr.c + */ + + esp_lowputc_disable_all_uart_int(priv, ¤t_int_sts); + ret = esp_setup(dev); + + /* Restore the interrupt state */ + + esp_lowputc_restore_all_uart_int(priv, ¤t_int_sts); + } + } + break; +#endif /* CONFIG_SERIAL_TERMIOS */ + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: esp_rxflowcontrol + * + * Description: + * Called when upper half RX buffer is full (or exceeds configured + * watermark levels if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is defined). + * Return true if UART activated RX flow control to block more incoming + * data. + * NOTE: Espressif chips have a hardware RX FIFO threshold mechanism to + * control RTS line and to stop receiving data. This is very similar to the + * concept behind upper watermark level. The hardware threshold is used + * here to control the RTS line. When setting the threshold to zero, RTS + * will immediately be asserted. If nbuffered = 0 or the lower watermark is + * crossed and the serial driver decides to disable RX flow control, the + * threshold will be changed to UART_RX_FLOW_THRHD_VALUE, which is almost + * half the HW RX FIFO capacity. It keeps some space to keep the data + * received between the RTS assertion and the stop by the sender. + * + * Input Parameters: + * dev - UART device instance + * nbuffered - the number of characters currently buffered + * (if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is + * not defined the value will be 0 for an empty buffer or + * the defined buffer size for a full buffer) + * upper - true indicates the upper watermark was crossed where + * false indicates the lower watermark has been crossed + * + * Returned Value: + * true if RX flow control activated. + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool esp_rxflowcontrol(uart_dev_t *dev, unsigned int nbuffered, + bool upper) +{ + bool ret = false; + struct esp_uart_s *priv = dev->priv; + if (priv->iflow) + { + if (nbuffered == 0 || !upper) + { + /* Empty buffer, RTS should be de-asserted and logic in above + * layers should re-enable RX interrupt. + */ + + esp_lowputc_set_iflow(priv, (uint8_t)(UART_RX_FIFO_SIZE / 2), + true); + esp_rxint(dev, true); + ret = false; + } + else + { + /* If the RX buffer is not zero and watermarks are not enabled, + * then this function is called to announce RX buffer is full. + * The first thing it should do is to immediately assert RTS. + * Software RX FIFO is full, so besides asserting RTS, it's + * necessary to disable RX interrupts to prevent remaining bytes + * (that arrive after asserting RTS) to be pushed to the + * SW RX FIFO. + */ + + esp_lowputc_set_iflow(priv, 0 , true); + esp_rxint(dev, false); + ret = true; + } + } + + return ret; +} +#endif +#endif /* CONFIG_ESPRESSIF_UART */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT + +/**************************************************************************** + * Name: riscv_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before riscv_serialinit. + * NOTE: This function depends on GPIO pin configuration performed in + * in up_consoleinit() and main clock initialization performed in + * up_clkinitialize(). + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void riscv_earlyserialinit(void) +{ + /* NOTE: All GPIO configuration for the UARTs was performed in + * esp_lowsetup. + */ + + /* Disable all UARTS interrupts */ + +#ifdef TTYS0_DEV + esp_lowputc_disable_all_uart_int(TTYS0_DEV.priv, NULL); +#endif + +#ifdef TTYS1_DEV + esp_lowputc_disable_all_uart_int(TTYS1_DEV.priv, NULL); +#endif + + /* Configure console in early step. + * Setup for other serials will be perfomed when the serial driver is + * open. + */ + +#ifdef CONSOLE_UART + esp_setup(&CONSOLE_DEV); +#endif +} + +#endif /* USE_EARLYSERIALINIT */ + +/**************************************************************************** + * Name: riscv_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * riscv_earlyserialinit has been called previously. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void riscv_serialinit(void) +{ +#ifdef HAVE_SERIAL_CONSOLE + uart_register("/dev/console", &CONSOLE_DEV); +#endif + +#ifdef TTYS0_DEV + uart_register("/dev/ttyS0", &TTYS0_DEV); +#endif + +#ifdef TTYS1_DEV + uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes. + * + * Input Parameters: + * ch - Character to be output to the console. + * + * Returned Value: + * On success, the character is echoed back to the caller. A negated + * errno value is returned on any failure. + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef CONSOLE_UART + uint32_t int_status; + + esp_lowputc_disable_all_uart_int(CONSOLE_DEV.priv, &int_status); +#endif + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + riscv_lowputc('\r'); + } + + riscv_lowputc(ch); + +#ifdef CONSOLE_UART + esp_lowputc_restore_all_uart_int(CONSOLE_DEV.priv, &int_status); +#endif + return ch; +} + +#else /* HAVE_UART_DEVICE */ + +/**************************************************************************** + * Name: riscv_earlyserialinit, riscv_serialinit, and up_putc + * + * Description: + * Stubs that may be needed. These stubs will be used if all UARTs are + * disabled. In that case, the logic in common/xtensa_initialize.c is not + * smart enough to know that there are not UARTs and will still expect + * these interfaces to be provided. + * This may be a special case where the upper and lower half serial layers + * are added but other device is used as console. + * For more details, take a look at: nuttx/arch/xtensa/src/common/xtensa.h + * + ****************************************************************************/ + +void riscv_earlyserialinit(void) +{ +} + +void riscv_serialinit(void) +{ +} + +int up_putc(int ch) +{ + return ch; +} + +#endif /* HAVE_UART_DEVICE */ + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes. + * + * Input Parameters: + * ch - Character to be output to the console. + * + * Returned Value: + * On success, the character is echoed back to the caller. A negated + * errno value is returned on any failure. + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + riscv_lowputc('\r'); + } + + riscv_lowputc(ch); +#endif /* HAVE_SERIAL_CONSOLE */ + + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/risc-v/src/espressif/esp_start.c b/arch/risc-v/src/espressif/esp_start.c new file mode 100644 index 0000000000..54cd8f291e --- /dev/null +++ b/arch/risc-v/src/espressif/esp_start.c @@ -0,0 +1,138 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_start.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 + +#include + +#include +#include + +#include "riscv_internal.h" + +#include "esp_irq.h" +#include "esp_libc_stubs.h" +#include "esp_lowputc.h" +#include "esp_start.h" +#include "esp_wdt.h" + +#include "brownout.h" +#include "esp_clk_internal.h" +#include "esp_cpu.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +# define showprogress(c) riscv_lowputc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Address of the IDLE thread */ + +uint8_t g_idlestack[CONFIG_IDLETHREAD_STACKSIZE] + aligned_data(16) locate_data(".noinit"); +uintptr_t g_idle_topstack = ESP_IDLESTACK_TOP; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: __esp_start + ****************************************************************************/ + +void __esp_start(void) +{ +#ifdef CONFIG_ESPRESSIF_REGION_PROTECTION + /* Configure region protection */ + + esp_cpu_configure_region_protection(); +#endif + + /* Configures the CPU clock, RTC slow and fast clocks, and performs + * RTC slow clock calibration. + */ + + esp_clk_init(); + + /* Disable clock of unused peripherals */ + + esp_perip_clk_init(); + +#ifdef CONFIG_ESPRESSIF_BROWNOUT_DET + /* Initialize hardware brownout check and reset */ + + esp_brownout_init(); +#endif + + /* Configure the UART so we can get debug output */ + + esp_lowsetup(); + +#ifdef USE_EARLYSERIALINIT + /* Perform early serial initialization */ + + riscv_earlyserialinit(); +#endif + + showprogress('A'); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (uint32_t *dest = (uint32_t *)_sbss; dest < (uint32_t *)_ebss; ) + { + *dest++ = 0; + } + + /* Setup the syscall table needed by the ROM code */ + + esp_setup_syscall_table(); + + showprogress('B'); + + /* Disable watchdog timers enabled by the bootloader */ + + esp_wdt_early_deinit(); + + /* Initialize onboard resources */ + + esp_board_initialize(); + + showprogress('C'); + + /* Bring up NuttX */ + + nx_start(); + + for (; ; ); +} diff --git a/arch/risc-v/src/espressif/esp_start.h b/arch/risc-v/src/espressif/esp_start.h new file mode 100644 index 0000000000..99b056e576 --- /dev/null +++ b/arch/risc-v/src/espressif/esp_start.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_start.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 __ARCH_RISCV_SRC_ESPRESSIF_ESP_START_H +#define __ARCH_RISCV_SRC_ESPRESSIF_ESP_START_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Name: esp_board_initialize + * + * Description: + * All Espressif boards 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. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_board_initialize(void); + +#endif /* __ARCH_RISCV_SRC_ESPRESSIF_ESP_START_H */ diff --git a/arch/risc-v/src/espressif/esp_timerisr.c b/arch/risc-v/src/espressif/esp_timerisr.c new file mode 100644 index 0000000000..6c4eb0ba86 --- /dev/null +++ b/arch/risc-v/src/espressif/esp_timerisr.c @@ -0,0 +1,161 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_timerisr.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 + +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "esp_irq.h" + +#include "hal/systimer_hal.h" +#include "hal/systimer_ll.h" +#include "periph_ctrl.h" +#include "systimer.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if SOC_SYSTIMER_INT_LEVEL +# define SYSTIMER_TRIGGER_TYPE ESP_IRQ_TRIGGER_LEVEL +#else +# define SYSTIMER_TRIGGER_TYPE ESP_IRQ_TRIGGER_EDGE +#endif /* SOC_SYSTIMER_INT_LEVEL */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Systimer HAL layer object */ + +static systimer_hal_context_t systimer_hal; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: systimer_irq_handler + * + * Description: + * Handler to be executed by the Systimer ISR. + * + * Input Parameters: + * irq - IRQ associated to that interrupt. + * context - Interrupt register state save info. + * arg - A pointer to the argument provided when the interrupt + * was registered. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int systimer_irq_handler(int irq, void *context, void *arg) +{ + systimer_ll_clear_alarm_int(systimer_hal.dev, + SYSTIMER_ALARM_OS_TICK_CORE0); + + /* Process timer interrupt */ + + nxsched_process_timer(); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + periph_module_enable(PERIPH_SYSTIMER_MODULE); + systimer_hal_init(&systimer_hal); + systimer_hal_tick_rate_ops_t ops = + { + .ticks_to_us = systimer_ticks_to_us, + .us_to_ticks = systimer_us_to_ticks, + }; + + systimer_hal_set_tick_rate_ops(&systimer_hal, &ops); + systimer_ll_set_counter_value(systimer_hal.dev, + SYSTIMER_COUNTER_OS_TICK, + 0); + systimer_ll_apply_counter_value(systimer_hal.dev, + SYSTIMER_COUNTER_OS_TICK); + systimer_hal_counter_can_stall_by_cpu(&systimer_hal, + SYSTIMER_COUNTER_OS_TICK, 0, + false); + + systimer_hal_connect_alarm_counter(&systimer_hal, + SYSTIMER_ALARM_OS_TICK_CORE0, + SYSTIMER_COUNTER_OS_TICK); + systimer_hal_set_alarm_period(&systimer_hal, + SYSTIMER_ALARM_OS_TICK_CORE0, + CONFIG_USEC_PER_TICK); + systimer_hal_select_alarm_mode(&systimer_hal, + SYSTIMER_ALARM_OS_TICK_CORE0, + SYSTIMER_ALARM_MODE_PERIOD); + systimer_hal_counter_can_stall_by_cpu(&systimer_hal, + SYSTIMER_COUNTER_OS_TICK, 0, + true); + systimer_hal_enable_alarm_int(&systimer_hal, + SYSTIMER_ALARM_OS_TICK_CORE0); + systimer_hal_enable_counter(&systimer_hal, SYSTIMER_COUNTER_OS_TICK); + + esp_setup_irq(SYSTIMER_TARGET0_EDGE_INTR_SOURCE, + ESP_IRQ_PRIORITY_DEFAULT, + SYSTIMER_TRIGGER_TYPE); + + /* Attach the timer interrupt. */ + + irq_attach(ESP_IRQ_SYSTIMER_TARGET0_EDGE, + (xcpt_t)systimer_irq_handler, + NULL); + + /* Enable the allocated CPU interrupt. */ + + up_enable_irq(ESP_IRQ_SYSTIMER_TARGET0_EDGE); +} diff --git a/arch/risc-v/src/espressif/esp_vectors.S b/arch/risc-v/src/espressif/esp_vectors.S new file mode 100644 index 0000000000..96c44e4442 --- /dev/null +++ b/arch/risc-v/src/espressif/esp_vectors.S @@ -0,0 +1,58 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_vectors.S + * + * 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 + +#include +#include + +#include "chip.h" + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .global _vector_table + +/**************************************************************************** + * Section: .exception_vectors.text + ****************************************************************************/ + + .section .exception_vectors.text + +/**************************************************************************** + * Name: _vector_table + ****************************************************************************/ + + .balign 0x100 + .type _vector_table, @function + +_vector_table: + .option push + .option norvc + + .rept (32) + j exception_common + .endr + diff --git a/arch/risc-v/src/espressif/esp_wdt.c b/arch/risc-v/src/espressif/esp_wdt.c new file mode 100644 index 0000000000..3eca74c77e --- /dev/null +++ b/arch/risc-v/src/espressif/esp_wdt.c @@ -0,0 +1,58 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_wdt.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 + +#include "esp_wdt.h" + +#include "hal/wdt_hal.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static wdt_hal_context_t rtc_wdt_ctx; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_wdt_early_deinit + * + * Description: + * Disable watchdog timers enabled by the bootloader. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_wdt_early_deinit(void) +{ + wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false); +} diff --git a/arch/risc-v/src/espressif/esp_wdt.h b/arch/risc-v/src/espressif/esp_wdt.h new file mode 100644 index 0000000000..af47076511 --- /dev/null +++ b/arch/risc-v/src/espressif/esp_wdt.h @@ -0,0 +1,50 @@ +/**************************************************************************** + * arch/risc-v/src/espressif/esp_wdt.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 __ARCH_RISCV_SRC_ESPRESSIF_ESP_WDT_H +#define __ARCH_RISCV_SRC_ESPRESSIF_ESP_WDT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_wdt_early_deinit + * + * Description: + * Disable watchdog timers enabled by the bootloader. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_wdt_early_deinit(void); + +#endif /* __ARCH_RISCV_SRC_ESPRESSIF_ESP_WDT_H */ diff --git a/arch/risc-v/src/espressif/hal_esp32c3.mk b/arch/risc-v/src/espressif/hal_esp32c3.mk new file mode 100644 index 0000000000..99fb1dba59 --- /dev/null +++ b/arch/risc-v/src/espressif/hal_esp32c3.mk @@ -0,0 +1,94 @@ +############################################################################ +# arch/risc-v/src/espressif/esp32c3.mk +# +# 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 header paths + +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/driver/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/efuse/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/efuse/private_include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/efuse/$(CHIP_SERIES)/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/efuse/$(CHIP_SERIES)/private_include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_common/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/include/esp_private +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/include/soc +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/port/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/port/$(CHIP_SERIES) +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/port/$(CHIP_SERIES)/private_include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_rom/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_rom/include/$(CHIP_SERIES) +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_rom/$(CHIP_SERIES) +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_system/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_system/port/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_system/port/include/private/esp_private +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_system/port/public_compat +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/hal/$(CHIP_SERIES)/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/hal/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/hal/platform_port/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/log +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/log/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/riscv/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/soc/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/soc/$(CHIP_SERIES)/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/nuttx/$(CHIP_SERIES)/include + +# Linker scripts + +ARCHSCRIPT += $(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_rom/$(CHIP_SERIES)/ld/$(CHIP_SERIES).rom.ld +ARCHSCRIPT += $(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_rom/$(CHIP_SERIES)/ld/$(CHIP_SERIES).rom.eco3.ld +ARCHSCRIPT += $(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_rom/$(CHIP_SERIES)/ld/$(CHIP_SERIES).rom.api.ld +ARCHSCRIPT += $(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_rom/$(CHIP_SERIES)/ld/$(CHIP_SERIES).rom.newlib.ld +ARCHSCRIPT += $(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_rom/$(CHIP_SERIES)/ld/$(CHIP_SERIES).rom.version.ld +ARCHSCRIPT += $(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/soc/$(CHIP_SERIES)/ld/$(CHIP_SERIES).peripherals.ld + +# Source files + +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/efuse/src/esp_efuse_api.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/efuse/src/esp_efuse_utility.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/efuse/$(CHIP_SERIES)/esp_efuse_fields.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/efuse/$(CHIP_SERIES)/esp_efuse_table.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/efuse/$(CHIP_SERIES)/esp_efuse_utility.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/cpu.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/esp_clk.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/periph_ctrl.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/regi2c_ctrl.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/port/clk_tree_common.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/port/$(CHIP_SERIES)/cpu_region_protect.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/port/$(CHIP_SERIES)/clk_tree.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/port/$(CHIP_SERIES)/rtc_clk.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/port/$(CHIP_SERIES)/rtc_init.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/port/$(CHIP_SERIES)/rtc_sleep.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/port/$(CHIP_SERIES)/rtc_time.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/port/$(CHIP_SERIES)/sar_periph_ctrl.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_hw_support/port/$(CHIP_SERIES)/systimer.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_system/port/brownout.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/esp_system/port/soc/$(CHIP_SERIES)/clk.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/hal/brownout_hal.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/hal/efuse_hal.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/hal/systimer_hal.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/hal/uart_hal.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/hal/uart_hal_iram.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/hal/wdt_hal_iram.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/hal/$(CHIP_SERIES)/clk_tree_hal.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/hal/$(CHIP_SERIES)/efuse_hal.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/log/log.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/log/log_noos.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/riscv/interrupt.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_UNPACK)/components/soc/$(CHIP_SERIES)/gpio_periph.c diff --git a/boards/Kconfig b/boards/Kconfig index e904275394..df77728a36 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -351,6 +351,15 @@ config ARCH_BOARD_ESP32C3_DEVKIT_RUST1 This board includes the ESP32-C3-MINI-1 module, a 6DoF IMU, a temperature and humidity sensor, a Li-Ion battery charger, and a Type-C USB. +config ARCH_BOARD_ESP32C3_GENERIC + bool "Espressif ESP32-C3 Generic DevKit" + depends on ESPRESSIF_ESP32C3 + ---help--- + The ESP32-C3 DevKit features the ESP32-C3 CPU with a RISC-V core. + It comes in two flavors, the ESP32-C3-DevKitM-1 and the ESP32-C3-DevKitC-02. + The ESP32-C3-DevKitM-1 version contains the ESP32-C3-MINI-1 module and the + ESP32-C3-DevKitC-02 version the ESP32-C3-WROOM-02. + config ARCH_BOARD_ESP32S2_KALUGA_1 bool "Espressif ESP32-S2-Kaluga-1 V1.3" depends on ARCH_CHIP_ESP32S2WROVER @@ -2771,6 +2780,7 @@ config ARCH_BOARD default "esp32-wrover-kit" if ARCH_BOARD_ESP32_WROVERKIT default "esp32c3-devkit" if ARCH_BOARD_ESP32C3_DEVKIT default "esp32c3-devkit-rust-1" if ARCH_BOARD_ESP32C3_DEVKIT_RUST1 + default "esp32c3-generic" if ARCH_BOARD_ESP32C3_GENERIC default "esp32s2-kaluga-1" if ARCH_BOARD_ESP32S2_KALUGA_1 default "esp32s2-saola-1" if ARCH_BOARD_ESP32S2_SAOLA_1 default "franzininho-wifi" if ARCH_BOARD_FRANZININHO_WIFI @@ -3748,6 +3758,9 @@ endif if ARCH_BOARD_ESP32C3_DEVKIT_RUST1 source "boards/risc-v/esp32c3/esp32c3-devkit-rust-1/Kconfig" endif +if ARCH_BOARD_ESP32C3_GENERIC +source "boards/risc-v/espressif/esp32c3-generic/Kconfig" +endif if ARCH_BOARD_ESP32S2_KALUGA_1 source "boards/xtensa/esp32s2/esp32s2-kaluga-1/Kconfig" endif @@ -3884,6 +3897,9 @@ endif if ARCH_CHIP_ESP32C3 source "boards/risc-v/esp32c3/common/Kconfig" endif +if ARCH_CHIP_ESPRESSIF +source "boards/risc-v/espressif/common/Kconfig" +endif if ARCH_CHIP_SAMV7 source "boards/arm/samv7/common/Kconfig" endif diff --git a/boards/risc-v/espressif/common/Kconfig b/boards/risc-v/espressif/common/Kconfig new file mode 100644 index 0000000000..f2a26a919c --- /dev/null +++ b/boards/risc-v/espressif/common/Kconfig @@ -0,0 +1,13 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config ESPRESSIF_MERGE_BINS + bool "Merge raw binary files into a single file" + default n + ---help--- + Merge the raw binary files into a single file for flashing to the + device. + This is only useful when the path to binary files (e.g. bootloader) + is provided via the ESPTOOL_BINDIR variable. diff --git a/boards/risc-v/espressif/common/Makefile b/boards/risc-v/espressif/common/Makefile new file mode 100644 index 0000000000..4e236d4722 --- /dev/null +++ b/boards/risc-v/espressif/common/Makefile @@ -0,0 +1,33 @@ +############################################################################# +# boards/risc-v/espressif/common/Makefile +# +# 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 + +include board/Make.defs +include src/Make.defs + +DEPPATH += --dep-path board +DEPPATH += --dep-path src + +include $(TOPDIR)/boards/Board.mk + +ARCHSRCDIR = $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src +BOARDDIR = $(ARCHSRCDIR)$(DELIM)board +CFLAGS += $(shell $(INCDIR) "$(CC)" $(BOARDDIR)$(DELIM)include) diff --git a/boards/risc-v/espressif/common/scripts/.gitignore b/boards/risc-v/espressif/common/scripts/.gitignore new file mode 100644 index 0000000000..0fa3d8108a --- /dev/null +++ b/boards/risc-v/espressif/common/scripts/.gitignore @@ -0,0 +1 @@ +/*.ld.tmp diff --git a/boards/risc-v/espressif/common/scripts/esp32c3_aliases.ld b/boards/risc-v/espressif/common/scripts/esp32c3_aliases.ld new file mode 100644 index 0000000000..4c83b34ef1 --- /dev/null +++ b/boards/risc-v/espressif/common/scripts/esp32c3_aliases.ld @@ -0,0 +1,29 @@ +/**************************************************************************** + * boards/risc-v/espressif/common/scripts/esp32c3_aliases.ld + * + * 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. + * + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_BLE + +/* Lower-case aliases for BLE library symbols not compliant to nxstyle */ + +api_vhci_host_check_send_available = API_vhci_host_check_send_available; +api_vhci_host_send_packet = API_vhci_host_send_packet; +api_vhci_host_register_callback = API_vhci_host_register_callback; + +#endif diff --git a/boards/risc-v/espressif/common/scripts/esp32c3_flat_memory.ld b/boards/risc-v/espressif/common/scripts/esp32c3_flat_memory.ld new file mode 100644 index 0000000000..1f49ec2444 --- /dev/null +++ b/boards/risc-v/espressif/common/scripts/esp32c3_flat_memory.ld @@ -0,0 +1,112 @@ +/**************************************************************************** + * boards/risc-v/espressif/common/scripts/esp32c3_flat_memory.ld + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * ESP32-C3 Linker Script Memory Layout + * + * This file describes the memory layout (memory blocks) as virtual + * memory addresses. + * + * esp32c3__sections.ld contains output sections to link compiler + * output into these memory blocks. + * + ****************************************************************************/ + +#include + +#define SRAM_IRAM_START 0x4037c000 +#define SRAM_DRAM_START 0x3fc7c000 + +/* ICache size is fixed to 16KB on ESP32-C3 */ + +#define ICACHE_SIZE 0x4000 +#define I_D_SRAM_OFFSET (SRAM_IRAM_START - SRAM_DRAM_START) + +/* 2nd stage bootloader iram_loader_seg start address */ + +#define SRAM_DRAM_END 0x403d0000 - I_D_SRAM_OFFSET + +#define SRAM_IRAM_ORG (SRAM_IRAM_START + ICACHE_SIZE) +#define SRAM_DRAM_ORG (SRAM_DRAM_START + ICACHE_SIZE) + +#define I_D_SRAM_SIZE SRAM_DRAM_END - SRAM_DRAM_ORG + +#ifdef CONFIG_ESPRESSIF_FLASH_2M +# define FLASH_SIZE 0x200000 +#elif defined (CONFIG_ESPRESSIF_FLASH_4M) +# define FLASH_SIZE 0x400000 +#elif defined (CONFIG_ESPRESSIF_FLASH_8M) +# define FLASH_SIZE 0x800000 +#elif defined (CONFIG_ESPRESSIF_FLASH_16M) +# define FLASH_SIZE 0x1000000 +#endif + +MEMORY +{ + /* Below values assume the flash cache is on, and have the blocks this + * uses subtracted from the length of the various regions. The 'data access + * port' dram/drom regions map to the same iram/irom regions but are + * connected to the data port of the CPU and e.g. allow bytewise access. + */ + + iram0_0_seg (RX) : org = SRAM_IRAM_ORG, len = I_D_SRAM_SIZE + + /* Flash mapped instruction data. + * + * The 0x20 offset is a convenience for the app binary image generation. + * Flash cache has 64KB pages. The .bin file which is flashed to the chip + * has a 0x18 byte file header, and each segment has a 0x08 byte segment + * header. Setting this offset makes it simple to meet the flash cache MMU's + * constraint that (paddr % 64KB == vaddr % 64KB). + */ + + irom0_0_seg (RX) : org = 0x42000020, len = FLASH_SIZE - 0x20 + + /* Shared data RAM, excluding memory reserved for ROM bss/data/stack. */ + + dram0_0_seg (RW) : org = SRAM_DRAM_ORG, len = I_D_SRAM_SIZE + + /* Flash mapped constant data. + * + * The 0x20 offset is a convenience for the app binary image generation. + * Flash cache has 64KB pages. The .bin file which is flashed to the chip + * has a 0x18 byte file header, and each segment has a 0x08 byte segment + * header. Setting this offset makes it simple to meet the flash cache MMU's + * constraint that (paddr % 64KB == vaddr % 64KB). + */ + + drom0_0_seg (R) : org = 0x3c000020, len = FLASH_SIZE - 0x20 + + /* RTC fast memory. Persists over deep sleep. */ + + rtc_seg(RWX) : org = 0x50000000, len = 0x2000 +} + +#if CONFIG_ESPRESSIF_RUN_IRAM + REGION_ALIAS("default_rodata_seg", dram0_0_seg); + REGION_ALIAS("default_code_seg", iram0_0_seg); +#else + REGION_ALIAS("default_rodata_seg", drom0_0_seg); + REGION_ALIAS("default_code_seg", irom0_0_seg); +#endif /* CONFIG_ESPRESSIF_RUN_IRAM */ + +/* Mark the end of the RTC heap (top of the RTC region) */ + +_ertcheap = 0x50001fff; diff --git a/boards/risc-v/espressif/common/scripts/esp32c3_legacy_sections.ld b/boards/risc-v/espressif/common/scripts/esp32c3_legacy_sections.ld new file mode 100644 index 0000000000..e20d0a9797 --- /dev/null +++ b/boards/risc-v/espressif/common/scripts/esp32c3_legacy_sections.ld @@ -0,0 +1,289 @@ +/**************************************************************************** + * boards/risc-v/espressif/common/scripts/esp32c3_legacy_sections.ld + * + * 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. + * + ****************************************************************************/ + +/* Default entry point: */ + +ENTRY(__start); + +SECTIONS +{ + .iram0.text : + { + _iram_start = ABSOLUTE(.); + + /* Vectors go to start of IRAM */ + + KEEP(*(.exception_vectors.text)); + . = ALIGN(4); + + *(.iram1) + *(.iram1.*) + + *libarch.a:brownout.*(.text .text.* .literal .literal.*) + *libarch.a:cpu.*(.text .text.* .literal .literal.*) + *libarch.a:gpio_hal.*(.text .text.* .literal .literal.*) + *libarch.a:periph_ctrl.*(.text .text.* .literal .literal.*) + *libarch.a:rtc_clk.*(.text .text.* .literal .literal.*) + *libarch.a:rtc_sleep.*(.text .text.* .literal .literal.*) + *libarch.a:rtc_time.*(.text .text.* .literal .literal.*) + *libarch.a:systimer.*(.text .text.* .literal .literal.*) + *libarch.a:systimer_hal.*(.text .text.* .literal .literal.*) + *libarch.a:uart_hal_iram.*(.text .text.* .literal .literal.*) + *libarch.a:wdt_hal_iram.*(.text .text.* .literal .literal.*) + *libsched.a:irq_dispatch.*(.text .text.* .literal .literal.*) + } >iram0_0_seg + + /* This section is required to skip .iram0.text area because iram0_0_seg + * and dram0_0_seg reflect the same address space on different buses. + */ + + .dram0.dummy (NOLOAD): + { + . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start; + } >dram0_0_seg + + /* Shared RAM */ + + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + _sbss = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.share.mem) + *(.gnu.linkonce.b.*) + *(COMMON) + + . = ALIGN (8); + _ebss = ABSOLUTE(.); + } >dram0_0_seg + + .noinit (NOLOAD): + { + /* This section contains data that is not initialized during load, + * or during the application's initialization sequence. + */ + + *(.noinit) + *(.noinit.*) + } >dram0_0_seg + + .dram0.data : + { + _sdata = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + __global_pointer$ = . + 0x800; + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + *(.jcr) + *(.dram1) + *(.dram1.*) + + *libarch.a:brownout.*(.rodata .rodata.*) + *libarch.a:cpu.*(.rodata .rodata.*) + *libarch.a:gpio_hal.*(.rodata .rodata.*) + *libarch.a:periph_ctrl.*(.rodata .rodata.*) + *libarch.a:rtc_clk.*(.rodata .rodata.*) + *libarch.a:rtc_sleep.*(.rodata .rodata.*) + *libarch.a:rtc_time.*(.rodata .rodata.*) + *libarch.a:systimer.*(.rodata .rodata.*) + *libarch.a:systimer_hal.*(.rodata .rodata.*) + *libarch.a:uart_hal_iram.*(.rodata .rodata.*) + *libarch.a:wdt_hal_iram.*(.rodata .rodata.*) + *libsched.a:irq_dispatch.*(.rodata .rodata.*) + . = ALIGN(4); + _edata = ABSOLUTE(.); + + /* Heap starts at the end of .data */ + + _sheap = ABSOLUTE(.); + } >dram0_0_seg + + .flash.text : + { + _stext = .; + + *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + _etext = .; + + /* Similar to _iram_start, this symbol goes here so it is + * resolved by addr2line in preference to the first symbol in + * the flash.text segment. + */ + + _flash_cache_start = ABSOLUTE(0); + } >default_code_seg + + .flash_rodata_dummy (NOLOAD): + { + /* Start at the same alignment constraint than .flash.text */ + + . = ALIGN(ALIGNOF(.flash.text)); + + /* Create an empty gap as big as .flash.text section */ + + . = . + SIZEOF(.flash.text); + + /* Prepare the alignment of the section above. Few bytes (0x20) must be + * added for the mapping header. + */ + + . = ALIGN(0x10000) + 0x20; + } >default_rodata_seg + + .flash.rodata : ALIGN(0x10) + { + _srodata = ABSOLUTE(.); + + *(.rodata) + *(.rodata.*) + + *(.srodata.*) + + *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table .gcc_except_table.*) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + . = (. + 3) & ~ 3; + __eh_frame = ABSOLUTE(.); + KEEP(*(.eh_frame)) + . = (. + 7) & ~ 3; + + /* C++ constructor and destructor tables: + * RISC-V GCC is configured with --enable-initfini-array so it emits an + * .init_array section instead. + */ + + _sinit = ABSOLUTE(.); + KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) + KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) + _einit = ABSOLUTE(.); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + + /* C++ exception handlers table: */ + + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + _erodata = ABSOLUTE(.); + + /* Literals are also RO data. */ + + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + } >default_rodata_seg + + /* Marks the end of IRAM code segment */ + + .iram0.text_end (NOLOAD) : + { + . = ALIGN (16); + } >iram0_0_seg + + .iram0.data : + { + . = ALIGN(16); + *(.iram.data) + *(.iram.data*) + } >iram0_0_seg + + .iram0.bss (NOLOAD) : + { + . = ALIGN(16); + *(.iram.bss) + *(.iram.bss*) + + . = ALIGN(16); + _iram_end = ABSOLUTE(.); + } >iram0_0_seg + + /* RTC fast memory holds RTC wake stub code !*/ + + .rtc.text : + { + . = ALIGN(4); + *(.rtc.literal .rtc.text) + } >rtc_seg + + /* This section is required to skip rtc.text area because the text and + * data segments reflect the same address space on different buses. + */ + + .rtc.dummy : + { + . = SIZEOF(.rtc.text); + } >rtc_seg + + /* RTC BSS section. */ + + .rtc.bss (NOLOAD) : + { + *(.rtc.bss) + } >rtc_seg + + /* RTC data section holds RTC wake stub data/rodata. */ + + .rtc.data : + { + *(.rtc.data) + *(.rtc.rodata) + + /* Whatever is left from the RTC memory is used as a special heap. */ + + _srtcheap = ABSOLUTE(.); + + } >rtc_seg +} + diff --git a/boards/risc-v/espressif/common/src/Make.defs b/boards/risc-v/espressif/common/src/Make.defs new file mode 100644 index 0000000000..b984381108 --- /dev/null +++ b/boards/risc-v/espressif/common/src/Make.defs @@ -0,0 +1,27 @@ +############################################################################# +# boards/risc-v/espressif/common/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. +# +############################################################################# + +ifeq ($(CONFIG_ARCH_BOARD_COMMON),y) + +DEPPATH += --dep-path src +VPATH += :src +CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src) + +endif diff --git a/boards/risc-v/espressif/esp32c3-generic/Kconfig b/boards/risc-v/espressif/esp32c3-generic/Kconfig new file mode 100644 index 0000000000..98f0ee2b5e --- /dev/null +++ b/boards/risc-v/espressif/esp32c3-generic/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_ESP32C3_GENERIC + +endif # ARCH_BOARD_ESP32C3_GENERIC diff --git a/boards/risc-v/espressif/esp32c3-generic/configs/nsh/defconfig b/boards/risc-v/espressif/esp32c3-generic/configs/nsh/defconfig new file mode 100644 index 0000000000..65b27633e4 --- /dev/null +++ b/boards/risc-v/espressif/esp32c3-generic/configs/nsh/defconfig @@ -0,0 +1,55 @@ +# +# 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_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="esp32c3-generic" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32C3_GENERIC=y +CONFIG_ARCH_CHIP="espressif" +CONFIG_ARCH_CHIP_ESPRESSIF=y +CONFIG_ARCH_INTERRUPTSTACK=1536 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=15000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_ERROR=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_WARN=y +CONFIG_DEV_ZERO=y +CONFIG_FRAME_POINTER=y +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NDEBUG=y +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=0 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_BACKTRACE=y +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=29 +CONFIG_START_MONTH=11 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_DUMPSTACK=y +CONFIG_SYSTEM_NSH=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y diff --git a/boards/risc-v/espressif/esp32c3-generic/include/board.h b/boards/risc-v/espressif/esp32c3-generic/include/board.h new file mode 100644 index 0000000000..c197572659 --- /dev/null +++ b/boards/risc-v/espressif/esp32c3-generic/include/board.h @@ -0,0 +1,25 @@ +/**************************************************************************** + * boards/risc-v/espressif/esp32c3-generic/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_RISCV_ESPRESSIF_ESP32C3_GENERIC_INCLUDE_BOARD_H +#define __BOARDS_RISCV_ESPRESSIF_ESP32C3_GENERIC_INCLUDE_BOARD_H + +#endif /* __BOARDS_RISCV_ESPRESSIF_ESP32C3_GENERIC_INCLUDE_BOARD_H */ + diff --git a/boards/risc-v/espressif/esp32c3-generic/scripts/Make.defs b/boards/risc-v/espressif/esp32c3-generic/scripts/Make.defs new file mode 100644 index 0000000000..2d95f0edfb --- /dev/null +++ b/boards/risc-v/espressif/esp32c3-generic/scripts/Make.defs @@ -0,0 +1,60 @@ +############################################################################ +# boards/risc-v/espressif/esp32c3-generic/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/espressif/Config.mk +include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs + +# Remove quotes from CONFIG_ESPRESSIF_CHIP_SERIES configuration + +CHIP_SERIES = $(patsubst "%",%,$(CONFIG_ESPRESSIF_CHIP_SERIES)) + +# Pick the linker scripts from the board level if they exist, if not +# pick the common linker scripts. + +ARCHSCRIPT += $(BOARD_COMMON_DIR)/scripts/$(CHIP_SERIES)_aliases.ld + +ARCHSCRIPT += $(call FINDSCRIPT,$(CHIP_SERIES)_flat_memory.ld) +ARCHSCRIPT += $(call FINDSCRIPT,$(CHIP_SERIES)_legacy_sections.ld) + +ARCHPICFLAGS = -fpic + +CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe -Werror=return-type -Werror +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) + +LDMODULEFLAGS = -melf32lriscv -r -e module_initialize +LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld) + +# ELF module definitions + +CELFFLAGS = $(CFLAGS) +CXXELFFLAGS = $(CXXFLAGS) + +LDELFFLAGS = -melf32lriscv -r -e main +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/libelf/gnu-elf.ld) diff --git a/boards/risc-v/espressif/esp32c3-generic/src/Make.defs b/boards/risc-v/espressif/esp32c3-generic/src/Make.defs new file mode 100644 index 0000000000..c3fa143123 --- /dev/null +++ b/boards/risc-v/espressif/esp32c3-generic/src/Make.defs @@ -0,0 +1,31 @@ +############################################################################# +# boards/risc-v/espressif/esp32c3-generic/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 + +CSRCS = esp32c3_boot.c esp32c3_bringup.c + +ifeq ($(CONFIG_BOARDCTL),y) + CSRCS += esp32c3_appinit.c +endif + +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/risc-v/espressif/esp32c3-generic/src/esp32c3-generic.h b/boards/risc-v/espressif/esp32c3-generic/src/esp32c3-generic.h new file mode 100644 index 0000000000..81f3e8ed5d --- /dev/null +++ b/boards/risc-v/espressif/esp32c3-generic/src/esp32c3-generic.h @@ -0,0 +1,72 @@ +/**************************************************************************** + * boards/risc-v/espressif/esp32c3-generic/src/esp32c3-generic.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_RISCV_ESPRESSIF_ESP32C3_GENERIC_SRC_ESP32C3_GENERIC_H +#define __BOARDS_RISCV_ESPRESSIF_ESP32C3_GENERIC_SRC_ESP32C3_GENERIC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_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(). + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int esp_bringup(void); + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_RISCV_ESPRESSIF_ESP32C3_GENERIC_SRC_ESP32C3_GENERIC_H */ diff --git a/boards/risc-v/espressif/esp32c3-generic/src/esp32c3_appinit.c b/boards/risc-v/espressif/esp32c3-generic/src/esp32c3_appinit.c new file mode 100644 index 0000000000..c79226c3b1 --- /dev/null +++ b/boards/risc-v/espressif/esp32c3-generic/src/esp32c3_appinit.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * boards/risc-v/espressif/esp32c3-generic/src/esp32c3_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 + +#include + +#include + +#include "esp32c3-generic.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 esp_bringup(); +#endif +} + +#endif /* CONFIG_BOARDCTL */ diff --git a/boards/risc-v/espressif/esp32c3-generic/src/esp32c3_boot.c b/boards/risc-v/espressif/esp32c3-generic/src/esp32c3_boot.c new file mode 100644 index 0000000000..771f211aac --- /dev/null +++ b/boards/risc-v/espressif/esp32c3-generic/src/esp32c3_boot.c @@ -0,0 +1,89 @@ +/**************************************************************************** + * boards/risc-v/espressif/esp32c3-generic/src/esp32c3_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 + +#include "riscv_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_board_initialize + * + * Description: + * All Espressif boards 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. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_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. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARD_LATE_INITIALIZE +void board_late_initialize(void) +{ + /* Perform board-specific initialization */ + + esp_bringup(); +} +#endif diff --git a/boards/risc-v/espressif/esp32c3-generic/src/esp32c3_bringup.c b/boards/risc-v/espressif/esp32c3-generic/src/esp32c3_bringup.c new file mode 100644 index 0000000000..25c07058b3 --- /dev/null +++ b/boards/risc-v/espressif/esp32c3-generic/src/esp32c3_bringup.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * boards/risc-v/espressif/esp32c3-generic/src/esp32c3_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 + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "esp32c3-generic.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_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(). + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int esp_bringup(void) +{ + int ret = OK; + +#ifdef CONFIG_FS_PROCFS + /* Mount the procfs file system */ + + ret = nx_mount(NULL, "/proc", "procfs", 0, NULL); + if (ret < 0) + { + _err("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) + { + _err("Failed to mount tmpfs at %s: %d\n", CONFIG_LIBC_TMPDIR, ret); + } +#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. + */ + + return ret; +} diff --git a/tools/espressif/Config.mk b/tools/espressif/Config.mk new file mode 100644 index 0000000000..2c92c65a8c --- /dev/null +++ b/tools/espressif/Config.mk @@ -0,0 +1,142 @@ +############################################################################ +# tools/espressif/Config.mk +# +# 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. +# +############################################################################ + +# Remove quotes from CONFIG_ESPRESSIF_CHIP_SERIES configuration + +CHIP_SERIES = $(patsubst "%",%,$(CONFIG_ESPRESSIF_CHIP_SERIES)) + +# These are the macros that will be used in the NuttX make system to compile +# and assemble source files and to insert the resulting object files into an +# archive. These replace the default definitions at tools/Config.mk + +ifeq ($(CONFIG_ESPRESSIF_FLASH_2M),y) + FLASH_SIZE := 2MB +else ifeq ($(CONFIG_ESPRESSIF_FLASH_4M),y) + FLASH_SIZE := 4MB +else ifeq ($(CONFIG_ESPRESSIF_FLASH_8M),y) + FLASH_SIZE := 8MB +else ifeq ($(CONFIG_ESPRESSIF_FLASH_16M),y) + FLASH_SIZE := 16MB +endif + +ifeq ($(CONFIG_ESPRESSIF_FLASH_MODE_DIO),y) + FLASH_MODE := dio +else ifeq ($(CONFIG_ESPRESSIF_FLASH_MODE_DOUT),y) + FLASH_MODE := dout +else ifeq ($(CONFIG_ESPRESSIF_FLASH_MODE_QIO),y) + FLASH_MODE := qio +else ifeq ($(CONFIG_ESPRESSIF_FLASH_MODE_QOUT),y) + FLASH_MODE := qout +endif + +ifeq ($(CONFIG_ESPRESSIF_FLASH_FREQ_80M),y) + FLASH_FREQ := 80m +else ifeq ($(CONFIG_ESPRESSIF_FLASH_FREQ_40M),y) + FLASH_FREQ := 40m +else ifeq ($(CONFIG_ESPRESSIF_FLASH_FREQ_26M),y) + FLASH_FREQ := 26m +else ifeq ($(CONFIG_ESPRESSIF_FLASH_FREQ_20M),y) + FLASH_FREQ := 20m +endif + +# Configure the variables according to build environment + +ifdef ESPTOOL_BINDIR + BL_OFFSET := 0x0 + PT_OFFSET := $(CONFIG_ESPRESSIF_PARTITION_TABLE_OFFSET) + BOOTLOADER := $(ESPTOOL_BINDIR)/bootloader-$(CHIP_SERIES).bin + PARTITION_TABLE := $(ESPTOOL_BINDIR)/partition-table-$(CHIP_SERIES).bin + FLASH_BL := $(BL_OFFSET) $(BOOTLOADER) + FLASH_PT := $(PT_OFFSET) $(PARTITION_TABLE) + ESPTOOL_BINS := $(FLASH_BL) $(FLASH_PT) +endif + +APP_OFFSET := 0x10000 +APP_IMAGE := nuttx.bin +FLASH_APP := $(APP_OFFSET) $(APP_IMAGE) + +ESPTOOL_BINS += $(FLASH_APP) + +ifeq ($(CONFIG_BUILD_PROTECTED),y) + ESPTOOL_BINS += $(CONFIG_ESPRESSIF_USER_IMAGE_OFFSET) nuttx_user.bin +endif + +# MERGEBIN -- Merge raw binary files into a single file + +define MERGEBIN + $(Q) if [ -z $(ESPTOOL_BINDIR) ]; then \ + echo "MERGEBIN error: Missing argument for binary files directory."; \ + echo "USAGE: make ESPTOOL_BINDIR="; \ + exit 1; \ + fi + $(Q) if [ -z $(FLASH_SIZE) ]; then \ + echo "Missing Flash memory size configuration."; \ + exit 1; \ + fi + esptool.py -c $(CHIP_SERIES) merge_bin --output nuttx.merged.bin $(ESPTOOL_BINS) + $(Q) echo nuttx.merged.bin >> nuttx.manifest + $(Q) echo "Generated: nuttx.merged.bin" +endef + +# MKIMAGE -- Convert an ELF file into a compatible binary file + +define MKIMAGE + $(Q) echo "MKIMAGE: NuttX binary" + $(Q) if ! esptool.py version 1>/dev/null 2>&1; then \ + echo ""; \ + echo "esptool.py not found. Please run: \"pip install esptool\""; \ + echo ""; \ + echo "Run make again to create the nuttx.bin image."; \ + exit 1; \ + fi + $(Q) if [ -z $(FLASH_SIZE) ]; then \ + echo "Missing Flash memory size configuration."; \ + exit 1; \ + fi + $(eval ELF2IMAGE_OPTS := -fs $(FLASH_SIZE) -fm $(FLASH_MODE) -ff $(FLASH_FREQ)) + esptool.py -c $(CHIP_SERIES) elf2image $(ELF2IMAGE_OPTS) -o nuttx.bin nuttx + $(Q) echo nuttx.bin >> nuttx.manifest + $(Q) echo "Generated: nuttx.bin" +endef + +# POSTBUILD -- Perform post build operations + +define POSTBUILD + $(call MKIMAGE) + $(if $(CONFIG_ESPRESSIF_MERGE_BINS),$(call MERGEBIN)) +endef + +# ESPTOOL_BAUD -- Serial port baud rate used when flashing/reading via esptool.py + +ESPTOOL_BAUD ?= 921600 + +# FLASH -- Download a binary image via esptool.py + +define FLASH + $(Q) if [ -z $(ESPTOOL_PORT) ]; then \ + echo "FLASH error: Missing serial port device argument."; \ + echo "USAGE: make flash ESPTOOL_PORT= [ ESPTOOL_BAUD= ]"; \ + exit 1; \ + fi + + $(eval ESPTOOL_OPTS := -c $(CHIP_SERIES) -p $(ESPTOOL_PORT) -b $(ESPTOOL_BAUD) $(if $(CONFIG_ESPRESSIF_ESPTOOLPY_NO_STUB),--no-stub)) + $(eval WRITEFLASH_OPTS := $(if $(CONFIG_ESPRESSIF_MERGE_BINS),0x0 nuttx.merged.bin,$(if $(CONFIG_ESPRESSIF_FLASH_DETECT),-fs detect) -fm dio $(ESPTOOL_BINS))) + esptool.py $(ESPTOOL_OPTS) write_flash $(WRITEFLASH_OPTS) +endef