From 43d71f276dc902d2a8fe96b409623afa458c1bb0 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Wed, 20 Jul 2022 07:00:00 +0200 Subject: [PATCH] cpu/esp32: add ESP32-C3 support in peripheral drivers --- cpu/esp32/periph/adc_arch_esp32c3.c | 75 ++++++++++++++++++++++ cpu/esp32/periph/gpio.c | 8 +++ cpu/esp32/periph/gpio_arch_esp32c3.c | 93 ++++++++++++++++++++++++++++ cpu/esp32/periph/spi.c | 4 +- cpu/esp32/periph/timer.c | 23 +++++++ cpu/esp_common/periph/i2c_sw.c | 9 +++ 6 files changed, 210 insertions(+), 2 deletions(-) create mode 100644 cpu/esp32/periph/adc_arch_esp32c3.c create mode 100644 cpu/esp32/periph/gpio_arch_esp32c3.c diff --git a/cpu/esp32/periph/adc_arch_esp32c3.c b/cpu/esp32/periph/adc_arch_esp32c3.c new file mode 100644 index 0000000000..2961a83efa --- /dev/null +++ b/cpu/esp32/periph/adc_arch_esp32c3.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2019 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_esp32 + * @{ + * + * @file + * @brief Architecture-specific ADC/DAC definitions for ESP32-C3 variant (family) + * + * @author Gunar Schorcht + * + * @} + */ + +#include "board.h" + +#include "adc_arch_private.h" +#include "esp_common.h" +#include "soc/adc_channel.h" + +#define ENABLE_DEBUG 0 +#include "debug.h" + +/** + * @brief ADC hardware descriptor table (for internal use only) + * + * @note The index of entries in the table MUST correspond to the + * RTCIO GPIO number. + */ +const _adc_hw_desc_t _adc_hw[] = { + /* rtcio, gpio, adc_ctrl, adc_channel, pad_name */ + { RTCIO_GPIO(0), ADC1_CHANNEL_0_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_0, "XTAL_32K_P" }, + { RTCIO_GPIO(1), ADC1_CHANNEL_1_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_1, "XTAL_32K_P" }, + { RTCIO_GPIO(2), ADC1_CHANNEL_2_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_2, "GPIO2" }, + { RTCIO_GPIO(3), ADC1_CHANNEL_3_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_3, "GPIO3" }, + { RTCIO_GPIO(4), ADC1_CHANNEL_4_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_4, "MTMS" }, + { RTCIO_GPIO(5), ADC2_CHANNEL_0_GPIO_NUM, ADC_UNIT_2, ADC_CHANNEL_0, "MTDI" }, +}; + +/** + * @brief GPIO to RTC IO map (for internal use only) + */ +const gpio_t _gpio_rtcio_map[] = { + RTCIO_GPIO(0), /* GPIO0 */ + RTCIO_GPIO(1), /* GPIO1 */ + RTCIO_GPIO(2), /* GPIO2 */ + RTCIO_GPIO(3), /* GPIO3 */ + RTCIO_GPIO(4), /* GPIO4 */ + RTCIO_GPIO(5), /* GPIO5 */ + RTCIO_NA, /* GPIO6 */ + RTCIO_NA, /* GPIO7 */ + RTCIO_NA, /* GPIO8 */ + RTCIO_NA, /* GPIO9 */ + RTCIO_NA, /* GPIO10 */ + RTCIO_NA, /* GPIO11 */ + RTCIO_NA, /* GPIO12 */ + RTCIO_NA, /* GPIO13 */ + RTCIO_NA, /* GPIO14 */ + RTCIO_NA, /* GPIO15 */ + RTCIO_NA, /* GPIO16 */ + RTCIO_NA, /* GPIO17 */ + RTCIO_NA, /* GPIO18 */ + RTCIO_NA, /* GPIO19 */ + RTCIO_NA, /* GPIO20 */ + RTCIO_NA, /* GPIO21 */ +}; + +_Static_assert(ARRAY_SIZE(_gpio_rtcio_map) == SOC_GPIO_PIN_COUNT, + "size of _gpio_rtcio_map does not match SOC_GPIO_PIN_COUNT"); diff --git a/cpu/esp32/periph/gpio.c b/cpu/esp32/periph/gpio.c index 2baf9327b4..c7163de41e 100644 --- a/cpu/esp32/periph/gpio.c +++ b/cpu/esp32/periph/gpio.c @@ -96,6 +96,14 @@ static bool _gpio_pin_pd[GPIO_PIN_NUMOF] = { }; #define GPIO_OUT_XOR(b) if (b < 32) { GPIO.out ^= BIT(b); } else { GPIO.out1.val ^= BIT(b-32); } #define GPIO_OUT_GET(b) (b < 32) ? (GPIO.out >> b) & 1 : (GPIO.out1.val >> (b-32)) & 1 +#elif defined(CPU_FAM_ESP32C3) + +#define GPIO_IN_GET(b) GPIO.in.val & BIT(b) +#define GPIO_OUT_SET(b) GPIO.out_w1ts.val = BIT(b) +#define GPIO_OUT_CLR(b) GPIO.out_w1tc.val = BIT(b) +#define GPIO_OUT_XOR(b) GPIO.out.val ^= BIT(b) +#define GPIO_OUT_GET(b) (GPIO.out.val >> b) & 1 + #else #error "Platform implementation is missing" #endif diff --git a/cpu/esp32/periph/gpio_arch_esp32c3.c b/cpu/esp32/periph/gpio_arch_esp32c3.c new file mode 100644 index 0000000000..7e1e2ca6c8 --- /dev/null +++ b/cpu/esp32/periph/gpio_arch_esp32c3.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2022 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_esp32 + * @ingroup drivers_periph_gpio + * @{ + * + * @file + * @brief Architecture-specific GPIO definitions for ESP32-C3 variant (family) + * + * @author Gunar Schorcht + * @} + */ + +#include "gpio_arch.h" +#include "soc/io_mux_reg.h" + +#if !IS_USED(MODULE_ESP_IDF_GPIO_HAL) + +/* GPIO to IOMUX register mapping (see Technical Reference, Section 5.13.2 Register Summary) + https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf */ + +const uint32_t _gpio_to_iomux_reg[GPIO_PIN_NUMOF] = +{ + PERIPHS_IO_MUX_XTAL_32K_P_U, /* GPIO0 used for XTAL_32K_P */ + PERIPHS_IO_MUX_XTAL_32K_N_U, /* GPIO1 used for XTAL_32K_N*/ + PERIPHS_IO_MUX_GPIO2_U, /* GPIO2 */ + PERIPHS_IO_MUX_GPIO3_U, /* GPIO3 */ + PERIPHS_IO_MUX_MTMS_U, /* GPIO4 */ + PERIPHS_IO_MUX_MTDI_U, /* GPIO5 */ + PERIPHS_IO_MUX_MTCK_U, /* GPIO6 */ + PERIPHS_IO_MUX_MTDO_U, /* GPIO7 */ + PERIPHS_IO_MUX_GPIO8_U, /* GPIO8 */ + PERIPHS_IO_MUX_GPIO9_U, /* GPIO9 */ + PERIPHS_IO_MUX_GPIO10_U, /* GPIO10 */ + PERIPHS_IO_MUX_VDD_SPI_U, /* GPIO11 */ + PERIPHS_IO_MUX_SPIHD_U, /* GPIO12 */ + PERIPHS_IO_MUX_SPIWP_U, /* GPIO13 */ + PERIPHS_IO_MUX_SPICS0_U, /* GPIO14 */ + PERIPHS_IO_MUX_SPICLK_U, /* GPIO15 */ + PERIPHS_IO_MUX_SPID_U, /* GPIO16 */ + PERIPHS_IO_MUX_SPIQ_U, /* GPIO17 */ + PERIPHS_IO_MUX_GPIO18_U, /* GPIO18 */ + PERIPHS_IO_MUX_GPIO19_U, /* GPIO19 */ + PERIPHS_IO_MUX_U0RXD_U, /* GPIO20 */ + PERIPHS_IO_MUX_U0TXD_U, /* GPIO21 */ +}; + +#endif /* !IS_USED(MODULE_ESP_IDF_GPIO_HAL) */ + +/* Table of the usage type of each GPIO pin */ +gpio_pin_usage_t _gpio_pin_usage[GPIO_PIN_NUMOF] = { +#if MODULE_ESP_RTC_TIMER_32K + _NOT_EXIST, /* GPIO0 is used for external 32K crystal */ + _NOT_EXIST, /* GPIO1 is used for external 32K crystal */ +#else + _GPIO, /* GPIO0 */ + _GPIO, /* GPIO1 */ +#endif + _GPIO, /* GPIO2 */ + _GPIO, /* GPIO3 */ + _GPIO, /* GPIO4 */ + _GPIO, /* GPIO5 */ + _GPIO, /* GPIO6 */ + _GPIO, /* GPIO7 */ + _GPIO, /* GPIO8 */ + _GPIO, /* GPIO9 */ + _GPIO, /* GPIO10 */ + _NOT_EXIST, /* GPIO11 is used as SPI VDD */ +#if defined(CONFIG_FLASHMODE_QIO) || defined(CONFIG_FLASHMODE_QOUT) + /* in qio and qout mode these pins are used for Flash */ + _SPIF, /* GPIO12 is used as direct I/O SPI HD for Flash */ + _SPIF, /* GPIO13 is used as direct I/O SPI WP for Flash */ +#else + /* otherwise these pins can be used as GPIO */ + _GPIO, /* GPIO12 */ + _GPIO, /* GPIO13 */ +#endif + _SPIF, /* GPIO14 is used as direct I/O SPI CS0 for Flash */ + _SPIF, /* GPIO15 is used as direct I/O SPI CLK for Flash */ + _SPIF, /* GPIO16 is used as direct I/O SPI MISO for Flash */ + _SPIF, /* GPIO17 is used as direct I/O SPI MOSI for Flash */ + _GPIO, /* GPIO18 could be used for builtin USB2JTAG bridge */ + _GPIO, /* GPIO19 could be used for builtin USB2JTAG bridge */ + _UART, /* GPIO20 is used as direct I/O UART0 RxD */ + _UART, /* GPIO21 is used as direct I/O UART0 TxD */ +}; diff --git a/cpu/esp32/periph/spi.c b/cpu/esp32/periph/spi.c index 382bd5d4aa..9707251832 100644 --- a/cpu/esp32/periph/spi.c +++ b/cpu/esp32/periph/spi.c @@ -253,7 +253,7 @@ void IRAM_ATTR spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t cl if (apb_clk / 5 < clk) { LOG_TAG_ERROR("spi", "APB clock rate (%"PRIu32" Hz) has to be at " - "least 5 times SPI clock rate (%"PRIu32" Hz)\n", + "least 5 times SPI clock rate (%d Hz)\n", apb_clk, clk); assert(false); } @@ -267,7 +267,7 @@ void IRAM_ATTR spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t cl _spi[bus].timing.timing_miso_delay = 0; _spi[bus].timing.timing_dummy = 0; - DEBUG("%s bus %d: SPI clock frequency: clk=%"PRIu32" eff=%d " + DEBUG("%s bus %d: SPI clock frequency: clk=%d eff=%d " "reg=%08"PRIx32"\n", __func__, bus, clk, _clk, clk_reg); } diff --git a/cpu/esp32/periph/timer.c b/cpu/esp32/periph/timer.c index 47e0d2369e..cb6e1a303c 100644 --- a/cpu/esp32/periph/timer.c +++ b/cpu/esp32/periph/timer.c @@ -72,6 +72,16 @@ * TMG1 is left disabled. TMG1 is only enabled when more than one * timer device is needed. * + * --- + * ESP32-C3 hast only two 54 bit hardware timers: + * two timer groups TMG0 and TMG1 with 1 timer each + * + * TMG0, timer 0 is used for system time in us and is therefore not + * available as low level timer. Timers have only one channel. Timer devices + * are mapped to hardware timer as following: + * + * 0 -> TMG1 timer 0 + * * PLEASE NOTE: Don't use ETS timer functions ets_timer_* in and this hardware * timer implementation together! */ @@ -81,6 +91,11 @@ #define HW_TIMER_CORRECTION (RTC_PLL_320M / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) #define HW_TIMER_DELTA_MIN (MAX(HW_TIMER_CORRECTION << 1, 5)) +#elif defined(CPU_FAM_ESP32C3) + +#define HW_TIMER_CORRECTION 10 +#define HW_TIMER_DELTA_MIN (MAX(HW_TIMER_CORRECTION << 1, 5)) + #else #error "MCU implementation needed" #endif @@ -128,6 +143,14 @@ static const struct _hw_timer_desc_t _timers_desc[] = .int_mask = BIT(TIMER_1), .int_src = ETS_TG1_T1_LEVEL_INTR_SOURCE, } +#elif defined(CPU_FAM_ESP32C3) + { + .module = PERIPH_TIMG1_MODULE, + .group = TIMER_GROUP_1, + .index = TIMER_0, + .int_mask = BIT(TIMER_0), + .int_src = ETS_TG1_T0_LEVEL_INTR_SOURCE + }, #else #error "MCU implementation needed" #endif diff --git a/cpu/esp_common/periph/i2c_sw.c b/cpu/esp_common/periph/i2c_sw.c index 9057dbadff..6d202002cb 100644 --- a/cpu/esp_common/periph/i2c_sw.c +++ b/cpu/esp_common/periph/i2c_sw.c @@ -59,8 +59,15 @@ #define I2C_CLOCK_STRETCH 200 /* gpio access macros */ +#if defined(CPU_FAM_ESP32) #define GPIO_SET(lo, hi, b) if (b < 32) { GPIO.lo = BIT(b); } else { GPIO.hi.val = BIT(b-32); } #define GPIO_GET(lo, hi, b) ((b < 32) ? GPIO.lo & BIT(b) : GPIO.hi.val & BIT(b-32)) +#elif defined(CPU_FAM_ESP32C3) +#define GPIO_SET(lo, hi, b) GPIO.lo.val = BIT(b) +#define GPIO_GET(lo, hi, b) GPIO.lo.val & BIT(b) +#else +#error "Platform implementation is missing" +#endif #else /* MCU_ESP8266 */ @@ -110,6 +117,8 @@ static _i2c_bus_t _i2c_bus[I2C_NUMOF] = {}; #if defined(CPU_FAM_ESP32) #define I2C_CLK_CAL 62 /* clock calibration offset */ +#elif defined(CPU_FAM_ESP32C3) +#define I2C_CLK_CAL 32 /* clock calibration offset */ #elif defined(MCU_ESP8266) #define I2C_CLK_CAL 47 /* clock calibration offset */ #else