From 0b4ef1406d6182e9acaade94862e1f01a5ed955f Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Thu, 4 Aug 2022 15:16:13 -0300 Subject: [PATCH] xtensa/esp32s2: Add basic support to SPI --- arch/xtensa/src/esp32s2/Kconfig | 79 ++ arch/xtensa/src/esp32s2/Make.defs | 4 + arch/xtensa/src/esp32s2/esp32s2_spi.c | 1215 +++++++++++++++++ arch/xtensa/src/esp32s2/esp32s2_spi.h | 150 ++ .../src/esp32s2/hardware/esp32s2_pinmap.h | 54 + .../xtensa/src/esp32s2/hardware/esp32s2_soc.h | 2 + .../xtensa/src/esp32s2/hardware/esp32s2_spi.h | 136 +- 7 files changed, 1572 insertions(+), 68 deletions(-) create mode 100644 arch/xtensa/src/esp32s2/esp32s2_spi.c create mode 100644 arch/xtensa/src/esp32s2/esp32s2_spi.h create mode 100644 arch/xtensa/src/esp32s2/hardware/esp32s2_pinmap.h diff --git a/arch/xtensa/src/esp32s2/Kconfig b/arch/xtensa/src/esp32s2/Kconfig index 01c68a72b4..ff5a671adf 100644 --- a/arch/xtensa/src/esp32s2/Kconfig +++ b/arch/xtensa/src/esp32s2/Kconfig @@ -237,6 +237,10 @@ config ESP32S2_I2C bool default n +config ESP32S2_SPI + bool + default n + config ESP32S2_TIMER bool default n @@ -252,6 +256,18 @@ config ESP32S2_RNG ---help--- ESP32-S2 supports a RNG that passed on Dieharder test suite. +config ESP32S2_SPI2 + bool "SPI 2" + default n + select ESP32S2_SPI + select SPI + +config ESP32S2_SPI3 + bool "SPI 3" + default n + select ESP32S2_SPI + select SPI + config ESP32S2_SPIFLASH bool "SPI Flash" default n @@ -361,6 +377,69 @@ config ESP32S2_GPIO_IRQ ---help--- Enable support for interrupting GPIO pins. +menu "SPI configuration" + depends on ESP32S2_SPI + +config ESP32S2_SPI_SWCS + bool "SPI software CS" + default n + ---help--- + Use SPI software CS. + +config ESP32S2_SPI_UDCS + bool "User defined CS" + default n + depends on ESP32S2_SPI_SWCS + ---help--- + Use user-defined CS. + +if ESP32S2_SPI2 +config ESP32S2_SPI2_CSPIN + int "SPI2 CS Pin" + default 10 + range 0 48 + +config ESP32S2_SPI2_CLKPIN + int "SPI2 CLK Pin" + default 12 + range 0 48 + +config ESP32S2_SPI2_MOSIPIN + int "SPI2 MOSI Pin" + default 11 + range 0 48 + +config ESP32S2_SPI2_MISOPIN + int "SPI2 MISO Pin" + default 13 + range 0 48 + +endif # ESP32S2_SPI2 + +if ESP32S2_SPI3 +config ESP32S2_SPI3_CSPIN + int "SPI3 CS Pin" + default 10 + range 0 48 + +config ESP32S2_SPI3_CLKPIN + int "SPI3 CLK Pin" + default 12 + range 0 48 + +config ESP32S2_SPI3_MOSIPIN + int "SPI3 MOSI Pin" + default 11 + range 0 48 + +config ESP32S2_SPI3_MISOPIN + int "SPI3 MISO Pin" + default 13 + range 0 48 + +endif # ESP32S2_SPI3 +endmenu + menu "UART Configuration" depends on ESP32S2_UART diff --git a/arch/xtensa/src/esp32s2/Make.defs b/arch/xtensa/src/esp32s2/Make.defs index db87863817..6d79385633 100644 --- a/arch/xtensa/src/esp32s2/Make.defs +++ b/arch/xtensa/src/esp32s2/Make.defs @@ -49,6 +49,10 @@ ifeq ($(CONFIG_ESP32S2_I2C),y) CHIP_CSRCS += esp32s2_i2c.c endif +ifeq ($(CONFIG_ESP32S2_SPI),y) +CHIP_CSRCS += esp32s2_spi.c +endif + ifeq ($(CONFIG_ESP32S2_TIMER),y) CHIP_CSRCS += esp32s2_tim.c ifeq ($(CONFIG_TIMER),y) diff --git a/arch/xtensa/src/esp32s2/esp32s2_spi.c b/arch/xtensa/src/esp32s2/esp32s2_spi.c new file mode 100644 index 0000000000..d86f418846 --- /dev/null +++ b/arch/xtensa/src/esp32s2/esp32s2_spi.c @@ -0,0 +1,1215 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/esp32s2_spi.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 + +#ifdef CONFIG_ESP32S2_SPI + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "esp32s2_spi.h" +#include "esp32s2_irq.h" +#include "esp32s2_gpio.h" + +#include "xtensa.h" +#include "hardware/esp32s2_gpio_sigmap.h" +#include "hardware/esp32s2_pinmap.h" +#include "hardware/esp32s2_spi.h" +#include "hardware/esp32s2_soc.h" +#include "hardware/esp32s2_system.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Check if Chip-Select pin will be controlled via software */ + +#ifdef CONFIG_ESP32S2_SPI_SWCS +# define SPI_HAVE_SWCS 1 +#else +# define SPI_HAVE_SWCS 0 +#endif + +/* SPI default frequency (limited by clock divider) */ + +#define SPI_DEFAULT_FREQ (400000) + +/* SPI default width */ + +#define SPI_DEFAULT_WIDTH (8) + +/* SPI default mode */ + +#define SPI_DEFAULT_MODE (SPIDEV_MODE0) + +/* SPI Maximum buffer size in bytes */ + +#define SPI_MAX_BUF_SIZE (64) + +#ifndef MIN +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* SPI Device hardware configuration */ + +struct esp32s2_spi_config_s +{ + uint32_t clk_freq; /* SPI default clock frequency */ + uint32_t width; /* SPI default width */ + enum spi_mode_e mode; /* SPI default mode */ + + uint8_t id; /* ESP32-S2 SPI device ID: SPIx {2,3} */ + uint8_t cs_pin; /* GPIO configuration for CS */ + uint8_t mosi_pin; /* GPIO configuration for MOSI */ + uint8_t miso_pin; /* GPIO configuration for MISO */ + uint8_t clk_pin; /* GPIO configuration for CLK */ + uint32_t clk_bit; /* Clock enable bit */ + uint32_t rst_bit; /* SPI reset bit */ + uint32_t cs_insig; /* SPI CS input signal index */ + uint32_t cs_outsig; /* SPI CS output signal index */ + uint32_t mosi_insig; /* SPI MOSI input signal index */ + uint32_t mosi_outsig; /* SPI MOSI output signal index */ + uint32_t miso_insig; /* SPI MISO input signal index */ + uint32_t miso_outsig; /* SPI MISO output signal index */ + uint32_t clk_insig; /* SPI CLK input signal index */ + uint32_t clk_outsig; /* SPI CLK output signal index */ +}; + +struct esp32s2_spi_priv_s +{ + /* Externally visible part of the SPI interface */ + + struct spi_dev_s spi_dev; + + /* Port configuration */ + + const struct esp32s2_spi_config_s *config; + int refs; /* Reference count */ + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + enum spi_mode_e mode; /* Actual SPI hardware mode */ + uint8_t nbits; /* Actual SPI send/receive bits once transmission */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int esp32s2_spi_lock(struct spi_dev_s *dev, bool lock); +#ifndef CONFIG_ESP32S2_SPI_UDCS +static void esp32s2_spi_select(struct spi_dev_s *dev, + uint32_t devid, bool selected); +#endif +static uint32_t esp32s2_spi_setfrequency(struct spi_dev_s *dev, + uint32_t frequency); +static void esp32s2_spi_setmode(struct spi_dev_s *dev, + enum spi_mode_e mode); +static void esp32s2_spi_setbits(struct spi_dev_s *dev, int nbits); +#ifdef CONFIG_SPI_HWFEATURES +static int esp32s2_spi_hwfeatures(struct spi_dev_s *dev, + spi_hwfeatures_t features); +#endif +static uint32_t esp32s2_spi_send(struct spi_dev_s *dev, uint32_t wd); +static void esp32s2_spi_exchange(struct spi_dev_s *dev, + const void *txbuffer, + void *rxbuffer, size_t nwords); +static void esp32s2_spi_poll_exchange(struct esp32s2_spi_priv_s *priv, + const void *txbuffer, + void *rxbuffer, + size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void esp32s2_spi_sndblock(struct spi_dev_s *dev, + const void *txbuffer, + size_t nwords); +static void esp32s2_spi_recvblock(struct spi_dev_s *dev, + void *rxbuffer, + size_t nwords); +#endif +#ifdef CONFIG_SPI_TRIGGER +static int esp32s2_spi_trigger(struct spi_dev_s *dev); +#endif +static void esp32s2_spi_init(struct spi_dev_s *dev); +static void esp32s2_spi_deinit(struct spi_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_ESP32S2_SPI2 +static const struct esp32s2_spi_config_s esp32s2_spi2_config = +{ + .clk_freq = SPI_DEFAULT_FREQ, + .width = SPI_DEFAULT_WIDTH, + .id = 2, + .mode = SPI_DEFAULT_MODE, + .cs_pin = CONFIG_ESP32S2_SPI2_CSPIN, + .mosi_pin = CONFIG_ESP32S2_SPI2_MOSIPIN, + .miso_pin = CONFIG_ESP32S2_SPI2_MISOPIN, + .clk_pin = CONFIG_ESP32S2_SPI2_CLKPIN, + .clk_bit = SYSTEM_SPI2_CLK_EN, + .rst_bit = SYSTEM_SPI2_RST, + .cs_insig = FSPICS0_IN_IDX, + .cs_outsig = FSPICS0_OUT_IDX, + .mosi_insig = FSPID_IN_IDX, + .mosi_outsig = FSPID_OUT_IDX, + .miso_insig = FSPIQ_IN_IDX, + .miso_outsig = FSPIQ_OUT_IDX, + .clk_insig = FSPICLK_IN_IDX, + .clk_outsig = FSPICLK_OUT_IDX +}; + +static const struct spi_ops_s esp32s2_spi2_ops = +{ +#ifdef CONFIG_ESP32S2_SPI_UDCS + .select = esp32s2_spi2_select, +#else + .select = esp32s2_spi_select, +#endif + .setfrequency = esp32s2_spi_setfrequency, + .setmode = esp32s2_spi_setmode, + .setbits = esp32s2_spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = esp32s2_spi_hwfeatures, +#endif + .status = esp32s2_spi2_status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = esp32s2_spi2_cmddata, +#endif + .send = esp32s2_spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = esp32s2_spi_exchange, +#else + .sndblock = esp32s2_spi_sndblock, + .recvblock = esp32s2_spi_recvblock, +#endif +#ifdef CONFIG_SPI_TRIGGER + .trigger = esp32s2_spi_trigger, +#endif + .registercallback = NULL, +}; + +static struct esp32s2_spi_priv_s esp32s2_spi2_priv = +{ + .spi_dev = + { + .ops = &esp32s2_spi2_ops + }, + .config = &esp32s2_spi2_config, + .refs = 0, + .exclsem = SEM_INITIALIZER(0), + .frequency = 0, + .actual = 0, + .mode = 0, + .nbits = 0 +}; +#endif /* CONFIG_ESP32S2_SPI2 */ + +#ifdef CONFIG_ESP32S2_SPI3 +static const struct esp32s2_spi_config_s esp32s2_spi3_config = +{ + .clk_freq = SPI_DEFAULT_FREQ, + .width = SPI_DEFAULT_WIDTH, + .id = 3, + .mode = SPI_DEFAULT_MODE, + .cs_pin = CONFIG_ESP32S2_SPI3_CSPIN, + .mosi_pin = CONFIG_ESP32S2_SPI3_MOSIPIN, + .miso_pin = CONFIG_ESP32S2_SPI3_MISOPIN, + .clk_pin = CONFIG_ESP32S2_SPI3_CLKPIN, + .clk_bit = SYSTEM_SPI3_CLK_EN, + .rst_bit = SYSTEM_SPI3_RST, + .cs_insig = FSPICS0_IN_IDX, + .cs_outsig = FSPICS0_OUT_IDX, + .mosi_insig = FSPID_IN_IDX, + .mosi_outsig = FSPID_OUT_IDX, + .miso_insig = FSPIQ_IN_IDX, + .miso_outsig = FSPIQ_OUT_IDX, + .clk_insig = FSPICLK_IN_IDX, + .clk_outsig = FSPICLK_OUT_IDX +}; + +static const struct spi_ops_s esp32s2_spi3_ops = +{ +#ifdef CONFIG_ESP32S2_SPI_UDCS + .select = esp32s2_spi3_select, +#else + .select = esp32s2_spi_select, +#endif + .setfrequency = esp32s2_spi_setfrequency, + .setmode = esp32s2_spi_setmode, + .setbits = esp32s2_spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = esp32s2_spi_hwfeatures, +#endif + .status = esp32s2_spi3_status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = esp32s2_spi3_cmddata, +#endif + .send = esp32s2_spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = esp32s2_spi_exchange, +#else + .sndblock = esp32s2_spi_sndblock, + .recvblock = esp32s2_spi_recvblock, +#endif +#ifdef CONFIG_SPI_TRIGGER + .trigger = esp32s2_spi_trigger, +#endif + .registercallback = NULL, +}; + +static struct esp32s2_spi_priv_s esp32s2_spi3_priv = +{ + .spi_dev = + { + .ops = &esp32s2_spi3_ops + }, + .config = &esp32s2_spi3_config, + .refs = 0, + .exclsem = SEM_INITIALIZER(0), + .frequency = 0, + .actual = 0, + .mode = 0, + .nbits = 0 +}; +#endif /* CONFIG_ESP32S2_SPI3 */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s2_spi_set_regbits + * + * Description: + * Set the bits of the SPI register. + * + * Input Parameters: + * addr - Address of the register of interest + * bits - Bits to be set + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void esp32s2_spi_set_regbits(uint32_t addr, uint32_t bits) +{ + uint32_t tmp = getreg32(addr); + + putreg32(tmp | bits, addr); +} + +/**************************************************************************** + * Name: esp32s2_spi_clr_regbits + * + * Description: + * Clear the bits of the SPI register. + * + * Input Parameters: + * addr - Address of the register of interest + * bits - Bits to be cleared + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void esp32s2_spi_clr_regbits(uint32_t addr, uint32_t bits) +{ + uint32_t tmp = getreg32(addr); + + putreg32(tmp & ~bits, addr); +} + +/**************************************************************************** + * Name: esp32s2_spi_iomux + * + * Description: + * Check if the option SPI GPIO pins can use IOMUX directly + * + * Input Parameters: + * priv - Private SPI device structure + * + * Returned Value: + * True if can use IOMUX or false if can't. + * + ****************************************************************************/ + +static inline bool esp32s2_spi_iomux(struct esp32s2_spi_priv_s *priv) +{ + bool mapped = false; + const struct esp32s2_spi_config_s *cfg = priv->config; + + /* We only need to check SPI2, SPI3 doesn't support IOMUX */ + + if (cfg->id == 2) + { + if (cfg->mosi_pin == SPI2_IOMUX_MOSIPIN && +#ifndef CONFIG_ESP32S2_SPI_SWCS + cfg->cs_pin == SPI2_IOMUX_CSPIN && +#endif + cfg->miso_pin == SPI2_IOMUX_MISOPIN && + cfg->clk_pin == SPI2_IOMUX_CLKPIN) + { + mapped = true; + } + } + + return mapped; +} + +/**************************************************************************** + * Name: esp32s2_spi_lock + * + * Description: + * Lock or unlock the SPI device. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock SPI bus, false: unlock SPI bus + * + * Returned Value: + * The result of lock or unlock the SPI device. + * + ****************************************************************************/ + +static int esp32s2_spi_lock(struct spi_dev_s *dev, bool lock) +{ + int ret; + struct esp32s2_spi_priv_s *priv = (struct esp32s2_spi_priv_s *)dev; + + if (lock) + { + ret = nxsem_wait_uninterruptible(&priv->exclsem); + } + else + { + ret = nxsem_post(&priv->exclsem); + } + + return ret; +} + +/**************************************************************************** + * Name: esp32s2_spi_select + * + * Description: + * Enable/disable the SPI chip select. The implementation of this method + * must include handshaking: If a device is selected, it must hold off + * all other attempts to select the device until the device is deselected. + * + * If ESP32S2_SPI_SWCS is disabled, the driver will use hardware CS so that + * once transmission is started the hardware selects the device and when + * this transmission is done hardware deselects the device automatically. + * So, this function will do nothing. + * + * Input Parameters: + * dev - Device-specific state data + * devid - Identifies the device to select + * selected - true: slave selected, false: slave de-selected + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifndef CONFIG_ESP32S2_SPI_UDCS +static void esp32s2_spi_select(struct spi_dev_s *dev, + uint32_t devid, bool selected) +{ +#if SPI_HAVE_SWCS + struct esp32s2_spi_priv_s *priv = (struct esp32s2_spi_priv_s *)dev; + + esp32s2_gpiowrite(priv->config->cs_pin, !selected); +#endif + + spiinfo("devid: %08" PRIx32 " CS: %s\n", + devid, selected ? "select" : "free"); +} +#endif + +/**************************************************************************** + * Name: esp32s2_spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The requested SPI frequency + * + * Returned Value: + * Returns the current selected frequency. + * + ****************************************************************************/ + +static uint32_t esp32s2_spi_setfrequency(struct spi_dev_s *dev, + uint32_t frequency) +{ + uint32_t reg_val; + struct esp32s2_spi_priv_s *priv = (struct esp32s2_spi_priv_s *)dev; + const uint32_t duty_cycle = 128; + + if (priv->frequency == frequency) + { + /* Requested frequency is the same as the current frequency. */ + + return priv->actual; + } + + /* In HW, n, h and l fields range from 1 to 64, pre ranges from 1 to 8K. + * The value written to register is one lower than the used value. + */ + + if (frequency > ((APB_CLK_FREQ / 4) * 3)) + { + /* Using APB frequency directly will give us the best result here. */ + + reg_val = SPI_CLK_EQU_SYSCLK_M; + priv->actual = APB_CLK_FREQ; + } + else + { + /* For best duty cycle resolution, we want n to be as close to 32 as + * possible, but we also need a pre/n combo that gets us as close as + * possible to the intended frequency. To do this, we bruteforce n and + * calculate the best pre to go along with that. If there's a choice + * between pre/n combos that give the same result, use the one with the + * higher n. + */ + + int32_t pre; + int32_t n; + int32_t h; + int32_t l; + int32_t bestn = -1; + int32_t bestpre = -1; + int32_t besterr = 0; + int32_t errval; + + /* Start at n = 2. We need to be able to set h/l so we have at least + * one high and one low pulse. + */ + + for (n = 2; n <= 64; n++) + { + /* Effectively, this does: + * pre = round((APB_CLK_FREQ / n) / frequency) + */ + + pre = ((APB_CLK_FREQ / n) + (frequency / 2)) / frequency; + + if (pre <= 0) + { + pre = 1; + } + + if (pre > 16) + { + pre = 16; + } + + errval = abs(APB_CLK_FREQ / (pre * n) - frequency); + if (bestn == -1 || errval <= besterr) + { + besterr = errval; + bestn = n; + bestpre = pre; + } + } + + n = bestn; + pre = bestpre; + l = n; + + /* Effectively, this does: + * h = round((duty_cycle * n) / 256) + */ + + h = (duty_cycle * n + 127) / 256; + if (h <= 0) + { + h = 1; + } + + reg_val = ((l - 1) << SPI_CLKCNT_L_S) | + ((h - 1) << SPI_CLKCNT_H_S) | + ((n - 1) << SPI_CLKCNT_N_S) | + ((pre - 1) << SPI_CLKDIV_PRE_S); + + priv->actual = APB_CLK_FREQ / (n * pre); + } + + priv->frequency = frequency; + + putreg32(reg_val, SPI_CLOCK_REG(priv->config->id)); + + spiinfo("frequency=%" PRIu32 ", actual=%" PRIu32 "\n", + priv->frequency, priv->actual); + + return priv->actual; +} + +/**************************************************************************** + * Name: esp32s2_spi_setmode + * + * Description: + * Set the SPI mode. + * + * Input Parameters: + * dev - Device-specific state data + * mode - The requested SPI mode + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp32s2_spi_setmode(struct spi_dev_s *dev, + enum spi_mode_e mode) +{ + struct esp32s2_spi_priv_s *priv = (struct esp32s2_spi_priv_s *)dev; + + spiinfo("mode=%d\n", mode); + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + uint32_t ck_idle_edge; + uint32_t ck_out_edge; + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + ck_idle_edge = 0; + ck_out_edge = 0; + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + ck_idle_edge = 0; + ck_out_edge = 1; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + ck_idle_edge = 1; + ck_out_edge = 1; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + ck_idle_edge = 1; + ck_out_edge = 0; + break; + + default: + spierr("Invalid mode: %d\n", mode); + DEBUGPANIC(); + return; + } + + esp32s2_spi_clr_regbits(SPI_MISC_REG(priv->config->id), + SPI_CK_IDLE_EDGE_M); + esp32s2_spi_set_regbits(SPI_MISC_REG(priv->config->id), + VALUE_TO_FIELD(ck_idle_edge, + SPI_CK_IDLE_EDGE)); + + esp32s2_spi_clr_regbits(SPI_USER_REG(priv->config->id), + SPI_CK_OUT_EDGE_M); + esp32s2_spi_set_regbits(SPI_USER_REG(priv->config->id), + VALUE_TO_FIELD(ck_out_edge, SPI_CK_OUT_EDGE)); + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: esp32s2_spi_setbits + * + * Description: + * Set the number of bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits in an SPI word. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp32s2_spi_setbits(struct spi_dev_s *dev, int nbits) +{ + struct esp32s2_spi_priv_s *priv = (struct esp32s2_spi_priv_s *)dev; + + spiinfo("nbits=%d\n", nbits); + + priv->nbits = nbits; +} + +/**************************************************************************** + * Name: esp32s2_spi_hwfeatures + * + * Description: + * Set hardware-specific feature flags. + * + * Input Parameters: + * dev - Device-specific state data + * features - H/W feature flags + * + * Returned Value: + * Zero (OK) if the selected H/W features are enabled; A negated errno + * value if any H/W feature is not supportable. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_HWFEATURES +static int esp32s2_spi_hwfeatures(struct spi_dev_s *dev, + spi_hwfeatures_t features) +{ + /* Other H/W features are not supported */ + + return (features == 0) ? OK : -ENOSYS; +} +#endif + +/**************************************************************************** + * Name: esp32s2_spi_poll_send + * + * Description: + * Send one word on SPI by polling mode. + * + * Input Parameters: + * priv - SPI private state data + * wd - The word to send. The size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * Received value. + * + ****************************************************************************/ + +static uint32_t esp32s2_spi_poll_send(struct esp32s2_spi_priv_s *priv, + uint32_t wd) +{ + uint32_t val; + + const uintptr_t spi_miso_dlen_reg = SPI_MISO_DLEN_REG(priv->config->id); + const uintptr_t spi_mosi_dlen_reg = SPI_MOSI_DLEN_REG(priv->config->id); + const uintptr_t spi_w0_reg = SPI_W0_REG(priv->config->id); + const uintptr_t spi_cmd_reg = SPI_CMD_REG(priv->config->id); + + putreg32((priv->nbits - 1), spi_miso_dlen_reg); + putreg32((priv->nbits - 1), spi_mosi_dlen_reg); + + putreg32(wd, spi_w0_reg); + + esp32s2_spi_set_regbits(spi_cmd_reg, SPI_USR_M); + + while ((getreg32(spi_cmd_reg) & SPI_USR_M) != 0) + { + ; + } + + val = getreg32(spi_w0_reg); + + spiinfo("send=0x%" PRIx32 " and recv=0x%" PRIx32 "\n", wd, val); + + return val; +} + +/**************************************************************************** + * Name: esp32s2_spi_send + * + * Description: + * Send one word on SPI. + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. The size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * Received value. + * + ****************************************************************************/ + +static uint32_t esp32s2_spi_send(struct spi_dev_s *dev, uint32_t wd) +{ + struct esp32s2_spi_priv_s *priv = (struct esp32s2_spi_priv_s *)dev; + + return esp32s2_spi_poll_send(priv, wd); +} + +/**************************************************************************** + * Name: esp32s2_spi_poll_exchange + * + * Description: + * Exchange a block of data from SPI. + * + * Input Parameters: + * priv - SPI private state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to receive data + * nwords - The length of data that to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp32s2_spi_poll_exchange(struct esp32s2_spi_priv_s *priv, + const void *txbuffer, + void *rxbuffer, + size_t nwords) +{ + const uint32_t total_bytes = nwords * (priv->nbits / 8); + uintptr_t bytes_remaining = total_bytes; + const uint8_t *tp = (const uint8_t *)txbuffer; + uint8_t *rp = (uint8_t *)rxbuffer; + + while (bytes_remaining != 0) + { + /* Initialize data_buf_reg with the address of the first data buffer + * register (W0). + */ + + uintptr_t data_buf_reg = SPI_W0_REG(priv->config->id); + uint32_t transfer_size = MIN(SPI_MAX_BUF_SIZE, bytes_remaining); + + /* Write data words to data buffer registers. + * SPI peripheral contains 16 registers (W0 - W15). + */ + + for (int i = 0 ; i < transfer_size; i += sizeof(uintptr_t)) + { + uintptr_t w_wd = UINT32_MAX; + + if (tp != NULL) + { + memcpy(&w_wd, tp, sizeof(uintptr_t)); + + tp += sizeof(uintptr_t); + } + + putreg32(w_wd, data_buf_reg); + + spiinfo("send=0x%" PRIx32 " data_reg=0x%" PRIxPTR "\n", + w_wd, data_buf_reg); + + /* Update data_buf_reg to point to the next data buffer register. */ + + data_buf_reg += sizeof(uintptr_t); + } + + esp32s2_spi_set_regbits(SPI_USER_REG(priv->config->id), + SPI_USR_MOSI_M); + + if (rp == NULL) + { + esp32s2_spi_clr_regbits(SPI_USER_REG(priv->config->id), + SPI_USR_MISO_M); + } + else + { + esp32s2_spi_set_regbits(SPI_USER_REG(priv->config->id), + SPI_USR_MISO_M); + } + + putreg32((transfer_size * 8) - 1, + SPI_MOSI_DLEN_REG(priv->config->id)); + + putreg32((transfer_size * 8) - 1, + SPI_MISO_DLEN_REG(priv->config->id)); + + /* Trigger start of user-defined transaction for master. */ + + esp32s2_spi_set_regbits(SPI_CMD_REG(priv->config->id), SPI_USR_M); + + /* Wait for the user-defined transaction to finish. */ + + while ((getreg32(SPI_CMD_REG(priv->config->id)) & SPI_USR_M) != 0) + { + ; + } + + if (rp != NULL) + { + /* Set data_buf_reg with the address of the first data buffer + * register (W0). + */ + + data_buf_reg = SPI_W0_REG(priv->config->id); + + /* Read received data words from SPI data buffer registers. */ + + for (int i = 0 ; i < transfer_size; i += sizeof(uintptr_t)) + { + uintptr_t r_wd = getreg32(data_buf_reg); + + spiinfo("recv=0x%" PRIx32 " data_reg=0x%" PRIxPTR "\n", + r_wd, data_buf_reg); + + memcpy(rp, &r_wd, sizeof(uintptr_t)); + + rp += sizeof(uintptr_t); + + /* Update data_buf_reg to point to the next data buffer + * register. + */ + + data_buf_reg += sizeof(uintptr_t); + } + } + + bytes_remaining -= transfer_size; + } +} + +/**************************************************************************** + * Name: esp32s2_spi_exchange + * + * Description: + * Exchange a block of data from SPI. + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to receive data + * nwords - The length of data that to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp32s2_spi_exchange(struct spi_dev_s *dev, + const void *txbuffer, + void *rxbuffer, + size_t nwords) +{ + struct esp32s2_spi_priv_s *priv = (struct esp32s2_spi_priv_s *)dev; + + esp32s2_spi_poll_exchange(priv, txbuffer, rxbuffer, nwords); +} + +#ifndef CONFIG_SPI_EXCHANGE + +/**************************************************************************** + * Name: esp32s2_spi_sndblock + * + * Description: + * Send a block of data on SPI. + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * nwords - The length of data to send from the buffer in number of + * words. The wordsize is determined by the number of + * bits-per-word selected for the SPI interface. If nbits <= 8, + * the data is packed into uint8_t's; if nbits >8, the data is + * packed into uint16_t's + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp32s2_spi_sndblock(struct spi_dev_s *dev, + const void *txbuffer, + size_t nwords) +{ + spiinfo("txbuffer=%p nwords=%d\n", txbuffer, nwords); + + esp32s2_spi_exchange(dev, txbuffer, NULL, nwords); +} + +/**************************************************************************** + * Name: esp32s2_spi_recvblock + * + * Description: + * Receive a block of data from SPI. + * + * Input Parameters: + * dev - Device-specific state data + * rxbuffer - A pointer to the buffer in which to receive data + * nwords - The length of data that can be received in the buffer in + * number of words. The wordsize is determined by the number of + * bits-per-word selected for the SPI interface. If nbits <= 8, + * the data is packed into uint8_t's; if nbits >8, the data is + * packed into uint16_t's + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp32s2_spi_recvblock(struct spi_dev_s *dev, + void *rxbuffer, + size_t nwords) +{ + spiinfo("rxbuffer=%p nwords=%d\n", rxbuffer, nwords); + + esp32s2_spi_exchange(dev, NULL, rxbuffer, nwords); +} +#endif + +/**************************************************************************** + * Name: esp32s2_spi_init + * + * Description: + * Initialize ESP32-S2 SPI hardware interface. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp32s2_spi_init(struct spi_dev_s *dev) +{ + struct esp32s2_spi_priv_s *priv = (struct esp32s2_spi_priv_s *)dev; + const struct esp32s2_spi_config_s *config = priv->config; + uint32_t regval; + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + nxsem_init(&priv->exclsem, 0, 1); + + esp32s2_gpiowrite(config->cs_pin, true); + esp32s2_gpiowrite(config->mosi_pin, true); + esp32s2_gpiowrite(config->miso_pin, true); + esp32s2_gpiowrite(config->clk_pin, true); + +#if SPI_HAVE_SWCS + esp32s2_configgpio(config->cs_pin, OUTPUT_FUNCTION_1); + esp32s2_gpio_matrix_out(config->cs_pin, SIG_GPIO_OUT_IDX, 0, 0); +#endif + + /* SPI3 doesn't have IOMUX, if SPI3 is enabled use GPIO Matrix for both */ + + if (esp32s2_spi_iomux(priv)) + { +#if !SPI_HAVE_SWCS + esp32s2_configgpio(config->cs_pin, OUTPUT_FUNCTION_5); + esp32s2_gpio_matrix_out(config->cs_pin, SIG_GPIO_OUT_IDX, 0, 0); +#endif + esp32s2_configgpio(config->mosi_pin, OUTPUT_FUNCTION_5); + esp32s2_gpio_matrix_out(config->mosi_pin, SIG_GPIO_OUT_IDX, 0, 0); + + esp32s2_configgpio(config->miso_pin, INPUT_FUNCTION_5 | PULLUP); + esp32s2_gpio_matrix_out(config->miso_pin, SIG_GPIO_OUT_IDX, 0, 0); + + esp32s2_configgpio(config->clk_pin, OUTPUT_FUNCTION_5); + esp32s2_gpio_matrix_out(config->clk_pin, SIG_GPIO_OUT_IDX, 0, 0); + } + else + { +#if !SPI_HAVE_SWCS + esp32s2_configgpio(config->cs_pin, OUTPUT); + esp32s2_gpio_matrix_out(config->cs_pin, config->cs_outsig, 0, 0); +#endif + esp32s2_configgpio(config->mosi_pin, OUTPUT); + esp32s2_gpio_matrix_out(config->mosi_pin, config->mosi_outsig, 0, 0); + + esp32s2_configgpio(config->miso_pin, INPUT | PULLUP); + esp32s2_gpio_matrix_in(config->miso_pin, config->miso_insig, 0); + + esp32s2_configgpio(config->clk_pin, OUTPUT); + esp32s2_gpio_matrix_out(config->clk_pin, config->clk_outsig, 0, 0); + } + + modifyreg32(SYSTEM_PERIP_CLK_EN0_REG, 0, config->clk_bit); + modifyreg32(SYSTEM_PERIP_RST_EN0_REG, config->rst_bit, 0); + + regval = SPI_DOUTDIN_M | SPI_USR_MISO_M | SPI_USR_MOSI_M | SPI_CS_HOLD_M; + putreg32(regval, SPI_USER_REG(priv->config->id)); + putreg32(0, SPI_USER1_REG(priv->config->id)); + putreg32(0, SPI_SLAVE_REG(priv->config->id)); + putreg32(SPI_CS1_DIS_M | SPI_CS2_DIS_M, + SPI_MISC_REG(priv->config->id)); + +#if SPI_HAVE_SWCS + esp32s2_spi_set_regbits(SPI_MISC_REG(priv->config->id), SPI_CS0_DIS_M); +#endif + + putreg32(0, SPI_CTRL_REG(priv->config->id)); + putreg32(VALUE_TO_FIELD(0, SPI_CS_HOLD_TIME), + SPI_USER1_REG(priv->config->id)); + + esp32s2_spi_setfrequency(dev, config->clk_freq); + esp32s2_spi_setbits(dev, config->width); + esp32s2_spi_setmode(dev, config->mode); +} + +/**************************************************************************** + * Name: esp32s2_spi_deinit + * + * Description: + * Deinitialize ESP32-S2 SPI hardware interface. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp32s2_spi_deinit(struct spi_dev_s *dev) +{ + struct esp32s2_spi_priv_s *priv = (struct esp32s2_spi_priv_s *)dev; + + modifyreg32(SYSTEM_PERIP_RST_EN0_REG, 0, priv->config->rst_bit); + modifyreg32(SYSTEM_PERIP_CLK_EN0_REG, priv->config->clk_bit, 0); + + priv->frequency = 0; + priv->actual = 0; + priv->mode = SPIDEV_MODE0; + priv->nbits = 0; +} + +/**************************************************************************** + * Name: esp32s2_spibus_initialize + * + * Description: + * Initialize the selected SPI bus. + * + * Input Parameters: + * port - Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; NULL on failure. + * + ****************************************************************************/ + +struct spi_dev_s *esp32s2_spibus_initialize(int port) +{ + struct spi_dev_s *spi_dev; + struct esp32s2_spi_priv_s *priv; + irqstate_t flags; + + switch (port) + { +#ifdef CONFIG_ESP32S2_SPI2 + case ESP32S2_SPI2: + priv = &esp32s2_spi2_priv; + break; +#endif +#ifdef CONFIG_ESP32S2_SPI3 + case ESP32S2_SPI3: + priv = &esp32s2_spi3_priv; + break; +#endif + default: + return NULL; + } + + spi_dev = (struct spi_dev_s *)priv; + + flags = enter_critical_section(); + + esp32s2_spi_init(spi_dev); + + priv->refs++; + + leave_critical_section(flags); + + return spi_dev; +} + +/**************************************************************************** + * Name: esp32s2_spibus_uninitialize + * + * Description: + * Uninitialize an SPI bus. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) is returned on success. Otherwise -1 (ERROR). + * + ****************************************************************************/ + +int esp32s2_spibus_uninitialize(struct spi_dev_s *dev) +{ + irqstate_t flags; + struct esp32s2_spi_priv_s *priv = (struct esp32s2_spi_priv_s *)dev; + + DEBUGASSERT(dev); + + if (priv->refs == 0) + { + return ERROR; + } + + flags = enter_critical_section(); + + if (--priv->refs != 0) + { + leave_critical_section(flags); + return OK; + } + + leave_critical_section(flags); + + esp32s2_spi_deinit(dev); + + nxsem_destroy(&priv->exclsem); + + return OK; +} + +#endif /* CONFIG_ESP32S2_SPI */ diff --git a/arch/xtensa/src/esp32s2/esp32s2_spi.h b/arch/xtensa/src/esp32s2/esp32s2_spi.h new file mode 100644 index 0000000000..3f569b73c8 --- /dev/null +++ b/arch/xtensa/src/esp32s2/esp32s2_spi.h @@ -0,0 +1,150 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/esp32s2_spi.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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_SPI_H +#define __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_SPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#ifdef CONFIG_ESP32S2_SPI + +#include + +#ifdef CONFIG_ESP32S2_SPI2 +# define ESP32S2_SPI2 2 +#endif + +#ifdef CONFIG_ESP32S2_SPI3 +# define ESP32S2_SPI3 3 +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s2_spibus_initialize + * + * Description: + * Initialize the selected SPI bus. + * + * Input Parameters: + * port - Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s *esp32s2_spibus_initialize(int port); + +/**************************************************************************** + * Name: esp32s2_spi[2|3]_select and esp32s2_spi[2|3]_status + * + * Description: + * The external functions, esp32s2_spi[2|3]_select, + * esp32s2_spi[2|3]_status, and esp32s2_spi[2|3]_cmddata must be provided + * by board-specific logic. + * These are implementations of the select, status, and cmddata methods of + * the SPI interface defined by struct spi_ops_s (include/nuttx/spi/spi.h). + * All other methods (including esp32s2_spibus_initialize()) are provided + * by common ESP32-S2 logic. To use this common SPI logic on your board: + * + * 1. Provide logic in esp32s2_board_initialize() to configure SPI chip + * select pins. + * 2. Provide esp32s2_spi[2|3]_select() and esp32s2_spi[2|3]_status() + * functions in your board-specific logic. These functions will perform + * chip selection and status operations using GPIOs in the way your + * board is configured. + * 3. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration file, + * then provide esp32s2_spi[2|3]_cmddata() functions in your + * board-specific logic. These functions will perform cmd/data selection + * operations using GPIOs in the way your board is configured. + * 4. Add a call to esp32s2_spibus_initialize() in your low level + * application initialization logic. + * 5. The handle returned by esp32s2_spibus_initialize() may then be used + * to bind the SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32S2_SPI2 +void esp32s2_spi2_select(struct spi_dev_s *dev, uint32_t devid, + bool selected); +uint8_t esp32s2_spi2_status(struct spi_dev_s *dev, uint32_t devid); +int esp32s2_spi2_cmddata(struct spi_dev_s *dev, + uint32_t devid, + bool cmd); +#endif + +#ifdef CONFIG_ESP32S2_SPI3 +void esp32s2_spi3_select(struct spi_dev_s *dev, uint32_t devid, + bool selected); +uint8_t esp32s2_spi3_status(struct spi_dev_s *dev, uint32_t devid); +int esp32s2_spi3_cmddata(struct spi_dev_s *dev, + uint32_t devid, + bool cmd); +#endif + +/**************************************************************************** + * Name: esp32s2_spibus_uninitialize + * + * Description: + * Uninitialize an SPI bus. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) is returned on success. Otherwise -1 (ERROR). + * + ****************************************************************************/ + +int esp32s2_spibus_uninitialize(struct spi_dev_s *dev); + +#endif /* CONFIG_ESP32S2_SPI */ + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_SPI_H */ diff --git a/arch/xtensa/src/esp32s2/hardware/esp32s2_pinmap.h b/arch/xtensa/src/esp32s2/hardware/esp32s2_pinmap.h new file mode 100644 index 0000000000..4b7ecf609b --- /dev/null +++ b/arch/xtensa/src/esp32s2/hardware/esp32s2_pinmap.h @@ -0,0 +1,54 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/hardware/esp32s2_pinmap.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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_PINMAP_H +#define __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_PINMAP_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/** + * Peripheral' fixed mapped pins by IOMUX, these GPIO pins can have better + * speed performance. + */ + +/* UART0 */ + +/* UART1 */ + +/* SPI2 */ + +#define SPI2_IOMUX_MISOPIN (13) +#define SPI2_IOMUX_MOSIPIN (11) +#define SPI2_IOMUX_CLKPIN (12) +#define SPI2_IOMUX_CSPIN (10) +#define SPI2_IOMUX_WPPIN (14) +#define SPI2_IOMUX_HDPIN (9) + +/* SPI3 */ + +/* SPI3 have no iomux pins */ + +#endif /* __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_PINMAP_H */ diff --git a/arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h b/arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h index 9276d98d7a..8d7b945421 100644 --- a/arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h +++ b/arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h @@ -274,6 +274,8 @@ #define REG_SPI_MEM_BASE(i) (DR_REG_SPI0_BASE - (i) * 0x1000) #define REG_I2C_BASE(i) (DR_REG_I2C_EXT_BASE + (i) * 0x14000 ) +#define REG_SPI_BASE(i) (DR_REG_SPI2_BASE + (((i) > 3) ? ((((i) - 2) * 0x1000) + 0x10000) : (((i) - 2) * 0x1000))) + /* Registers Operation */ #define REG_UART_BASE( i ) (DR_REG_UART_BASE + (i) * 0x10000 ) diff --git a/arch/xtensa/src/esp32s2/hardware/esp32s2_spi.h b/arch/xtensa/src/esp32s2/hardware/esp32s2_spi.h index 1fa5538c47..5abb83e03b 100644 --- a/arch/xtensa/src/esp32s2/hardware/esp32s2_spi.h +++ b/arch/xtensa/src/esp32s2/hardware/esp32s2_spi.h @@ -33,7 +33,7 @@ /* SPI_CMD_REG register */ -#define SPI_CMD_REG (DR_REG_SPI_BASE + 0x0) +#define SPI_CMD_REG(i) (REG_SPI_BASE(i) + 0x0) /* SPI_USR : R/W; bitpos: [24]; default: 0; * User define command enable. An operation will be triggered when the bit @@ -57,7 +57,7 @@ /* SPI_ADDR_REG register */ -#define SPI_ADDR_REG (DR_REG_SPI_BASE + 0x4) +#define SPI_ADDR_REG(i) (REG_SPI_BASE(i) + 0x4) /* SPI_USR_ADDR_VALUE : R/W; bitpos: [31:0]; default: 0; * [31:8]:address to slave, [7:0]:Reserved. @@ -70,7 +70,7 @@ /* SPI_CTRL_REG register */ -#define SPI_CTRL_REG (DR_REG_SPI_BASE + 0x8) +#define SPI_CTRL_REG(i) (REG_SPI_BASE(i) + 0x8) /* SPI_WR_BIT_ORDER : R/W; bitpos: [26]; default: 0; * In command address write-data (MOSI) phases 1: LSB firs 0: MSB first @@ -225,7 +225,7 @@ /* SPI_CTRL1_REG register */ -#define SPI_CTRL1_REG (DR_REG_SPI_BASE + 0xc) +#define SPI_CTRL1_REG(i) (REG_SPI_BASE(i) + 0xc) /* SPI_CS_HOLD_DELAY : R/W; bitpos: [19:14]; default: 1; * SPI cs signal is delayed by spi clock cycles. @@ -280,7 +280,7 @@ /* SPI_CTRL2_REG register */ -#define SPI_CTRL2_REG (DR_REG_SPI_BASE + 0x10) +#define SPI_CTRL2_REG(i) (REG_SPI_BASE(i) + 0x10) /* SPI_CS_DELAY_NUM : R/W; bitpos: [30:29]; default: 0; * spi_cs signal is delayed by system clock cycles @@ -325,7 +325,7 @@ /* SPI_CLOCK_REG register */ -#define SPI_CLOCK_REG (DR_REG_SPI_BASE + 0x14) +#define SPI_CLOCK_REG(i) (REG_SPI_BASE(i) + 0x14) /* SPI_CLK_EQU_SYSCLK : R/W; bitpos: [31]; default: 1; * In the master mode 1: spi_clk is eqaul to system 0: spi_clk is divided @@ -378,7 +378,7 @@ /* SPI_USER_REG register */ -#define SPI_USER_REG (DR_REG_SPI_BASE + 0x18) +#define SPI_USER_REG(i) (REG_SPI_BASE(i) + 0x18) /* SPI_USR_COMMAND : R/W; bitpos: [31]; default: 1; * This bit enable the command phase of an operation. @@ -649,7 +649,7 @@ /* SPI_USER1_REG register */ -#define SPI_USER1_REG (DR_REG_SPI_BASE + 0x1c) +#define SPI_USER1_REG(i) (REG_SPI_BASE(i) + 0x1c) /* SPI_USR_ADDR_BITLEN : R/W; bitpos: [31:27]; default: 23; * The length in bits of address phase. The register value shall be @@ -673,7 +673,7 @@ /* SPI_USER2_REG register */ -#define SPI_USER2_REG (DR_REG_SPI_BASE + 0x20) +#define SPI_USER2_REG(i) (REG_SPI_BASE(i) + 0x20) /* SPI_USR_COMMAND_BITLEN : R/W; bitpos: [31:28]; default: 7; * The length in bits of command phase. The register value shall be @@ -696,7 +696,7 @@ /* SPI_MOSI_DLEN_REG register */ -#define SPI_MOSI_DLEN_REG (DR_REG_SPI_BASE + 0x24) +#define SPI_MOSI_DLEN_REG(i) (REG_SPI_BASE(i) + 0x24) /* SPI_USR_MOSI_DBITLEN : R/W; bitpos: [22:0]; default: 0; * The length in bits of write-data. The register value shall be (bit_num-1). @@ -709,7 +709,7 @@ /* SPI_MISO_DLEN_REG register */ -#define SPI_MISO_DLEN_REG (DR_REG_SPI_BASE + 0x28) +#define SPI_MISO_DLEN_REG(i) (REG_SPI_BASE(i) + 0x28) /* SPI_USR_MISO_DBITLEN : R/W; bitpos: [22:0]; default: 0; * The length in bits of read-data. The register value shall be (bit_num-1). @@ -722,7 +722,7 @@ /* SPI_SLV_WR_STATUS_REG register */ -#define SPI_SLV_WR_STATUS_REG (DR_REG_SPI_BASE + 0x2c) +#define SPI_SLV_WR_STATUS_REG(i) (REG_SPI_BASE(i) + 0x2c) /* SPI_OPI_MODE : R/W; bitpos: [1]; default: 0; * Just for master mode. 1: spi controller is in OPI mode (all in 8-b-m). 0: @@ -746,7 +746,7 @@ /* SPI_MISC_REG register */ -#define SPI_MISC_REG (DR_REG_SPI_BASE + 0x30) +#define SPI_MISC_REG(i) (REG_SPI_BASE(i) + 0x30) /* SPI_QUAD_DIN_PIN_SWAP : R/W; bitpos: [31]; default: 0; * 1: spi quad input swap enable 0: spi quad input swap disable @@ -917,7 +917,7 @@ /* SPI_SLAVE_REG register */ -#define SPI_SLAVE_REG (DR_REG_SPI_BASE + 0x34) +#define SPI_SLAVE_REG(i) (REG_SPI_BASE(i) + 0x34) /* SPI_SOFT_RESET : R/W; bitpos: [31]; default: 0; * Software reset enable, reset the spi clock line cs line and data lines. @@ -1031,7 +1031,7 @@ /* SPI_SLAVE1_REG register */ -#define SPI_SLAVE1_REG (DR_REG_SPI_BASE + 0x38) +#define SPI_SLAVE1_REG(i) (REG_SPI_BASE(i) + 0x38) /* SPI_SLV_LAST_ADDR : R/W; bitpos: [31:24]; default: 0; * In the slave mode it is the value of address. @@ -1083,7 +1083,7 @@ /* SPI_SLAVE2_REG register */ -#define SPI_SLAVE2_REG (DR_REG_SPI_BASE + 0x3c) +#define SPI_SLAVE2_REG(i) (REG_SPI_BASE(i) + 0x3c) /* SPI_SLV_RD_DMA_DONE : R/W; bitpos: [8]; default: 0; * The interrupt raw bit for the completion of Rd-DMA operation in the slave @@ -1097,7 +1097,7 @@ /* SPI_SLV_WRBUF_DLEN_REG register */ -#define SPI_SLV_WRBUF_DLEN_REG (DR_REG_SPI_BASE + 0x40) +#define SPI_SLV_WRBUF_DLEN_REG(i) (REG_SPI_BASE(i) + 0x40) /* SPI_CONF_BASE_BITLEN : R/W; bitpos: [31:25]; default: 108; * The basic spi_clk cycles of CONF state. The real cycle length of CONF @@ -1122,7 +1122,7 @@ /* SPI_SLV_RDBUF_DLEN_REG register */ -#define SPI_SLV_RDBUF_DLEN_REG (DR_REG_SPI_BASE + 0x44) +#define SPI_SLV_RDBUF_DLEN_REG(i) (REG_SPI_BASE(i) + 0x44) /* SPI_SEG_MAGIC_ERR : R/W; bitpos: [25]; default: 0; * 1: The recent magic value in CONF buffer is not right in master DMA @@ -1156,7 +1156,7 @@ /* SPI_SLV_RD_BYTE_REG register */ -#define SPI_SLV_RD_BYTE_REG (DR_REG_SPI_BASE + 0x48) +#define SPI_SLV_RD_BYTE_REG(i) (REG_SPI_BASE(i) + 0x48) /* SPI_USR_CONF : R/W; bitpos: [31]; default: 0; * 1: Enable the DMA CONF phase of current seg-trans operation, which means @@ -1230,7 +1230,7 @@ /* SPI_FSM_REG register */ -#define SPI_FSM_REG (DR_REG_SPI_BASE + 0x50) +#define SPI_FSM_REG(i) (REG_SPI_BASE(i) + 0x50) /* SPI_MST_DMA_RD_BYTELEN : R/W; bitpos: [31:12]; default: 0; * Define the master DMA read byte length in non seg-trans or seg-trans @@ -1255,7 +1255,7 @@ /* SPI_HOLD_REG register */ -#define SPI_HOLD_REG (DR_REG_SPI_BASE + 0x54) +#define SPI_HOLD_REG(i) (REG_SPI_BASE(i) + 0x54) /* SPI_DMA_SEG_TRANS_DONE : R/W; bitpos: [7]; default: 0; * 1: spi master DMA full-duplex/half-duplex seg-trans ends or slave @@ -1311,7 +1311,7 @@ /* SPI_DMA_CONF_REG register */ -#define SPI_DMA_CONF_REG (DR_REG_SPI_BASE + 0x58) +#define SPI_DMA_CONF_REG(i) (REG_SPI_BASE(i) + 0x58) /* SPI_EXT_MEM_BK_SIZE : R/W; bitpos: [27:26]; default: 0; * Select the external memory block size. @@ -1552,7 +1552,7 @@ /* SPI_DMA_OUT_LINK_REG register */ -#define SPI_DMA_OUT_LINK_REG (DR_REG_SPI_BASE + 0x5c) +#define SPI_DMA_OUT_LINK_REG(i) (REG_SPI_BASE(i) + 0x5c) /* SPI_DMA_TX_ENA : R/W; bitpos: [31]; default: 0; * spi dma write data status bit. @@ -1601,7 +1601,7 @@ /* SPI_DMA_IN_LINK_REG register */ -#define SPI_DMA_IN_LINK_REG (DR_REG_SPI_BASE + 0x60) +#define SPI_DMA_IN_LINK_REG(i) (REG_SPI_BASE(i) + 0x60) /* SPI_DMA_RX_ENA : R/W; bitpos: [31]; default: 0; * spi dma read data status bit. @@ -1660,7 +1660,7 @@ /* SPI_DMA_INT_ENA_REG register */ -#define SPI_DMA_INT_ENA_REG (DR_REG_SPI_BASE + 0x64) +#define SPI_DMA_INT_ENA_REG(i) (REG_SPI_BASE(i) + 0x64) /* SPI_OUT_TOTAL_EOF_INT_ENA : R/W; bitpos: [8]; default: 0; * The enable bit for sending all the packets to host done. @@ -1745,7 +1745,7 @@ /* SPI_DMA_INT_RAW_REG register */ -#define SPI_DMA_INT_RAW_REG (DR_REG_SPI_BASE + 0x68) +#define SPI_DMA_INT_RAW_REG(i) (REG_SPI_BASE(i) + 0x68) /* SPI_OUT_TOTAL_EOF_INT_RAW : RO; bitpos: [8]; default: 0; * The raw bit for sending all the packets to host done. @@ -1830,7 +1830,7 @@ /* SPI_DMA_INT_ST_REG register */ -#define SPI_DMA_INT_ST_REG (DR_REG_SPI_BASE + 0x6c) +#define SPI_DMA_INT_ST_REG(i) (REG_SPI_BASE(i) + 0x6c) /* SPI_OUT_TOTAL_EOF_INT_ST : RO; bitpos: [8]; default: 0; * The status bit for sending all the packets to host done. @@ -1915,7 +1915,7 @@ /* SPI_DMA_INT_CLR_REG register */ -#define SPI_DMA_INT_CLR_REG (DR_REG_SPI_BASE + 0x70) +#define SPI_DMA_INT_CLR_REG(i) (REG_SPI_BASE(i) + 0x70) /* SPI_OUT_TOTAL_EOF_INT_CLR : R/W; bitpos: [8]; default: 0; * The clear bit for sending all the packets to host done. @@ -2000,7 +2000,7 @@ /* SPI_IN_ERR_EOF_DES_ADDR_REG register */ -#define SPI_IN_ERR_EOF_DES_ADDR_REG (DR_REG_SPI_BASE + 0x74) +#define SPI_IN_ERR_EOF_DES_ADDR_REG(i) (REG_SPI_BASE(i) + 0x74) /* SPI_DMA_IN_ERR_EOF_DES_ADDR : RO; bitpos: [31:0]; default: 0; * The inlink descriptor address when spi dma produce receiving error. @@ -2013,7 +2013,7 @@ /* SPI_IN_SUC_EOF_DES_ADDR_REG register */ -#define SPI_IN_SUC_EOF_DES_ADDR_REG (DR_REG_SPI_BASE + 0x78) +#define SPI_IN_SUC_EOF_DES_ADDR_REG(i) (REG_SPI_BASE(i) + 0x78) /* SPI_DMA_IN_SUC_EOF_DES_ADDR : RO; bitpos: [31:0]; default: 0; * The last inlink descriptor address when spi dma produce from_suc_eof. @@ -2026,7 +2026,7 @@ /* SPI_INLINK_DSCR_REG register */ -#define SPI_INLINK_DSCR_REG (DR_REG_SPI_BASE + 0x7c) +#define SPI_INLINK_DSCR_REG(i) (REG_SPI_BASE(i) + 0x7c) /* SPI_DMA_INLINK_DSCR : RO; bitpos: [31:0]; default: 0; * The content of current in descriptor pointer. @@ -2039,7 +2039,7 @@ /* SPI_INLINK_DSCR_BF0_REG register */ -#define SPI_INLINK_DSCR_BF0_REG (DR_REG_SPI_BASE + 0x80) +#define SPI_INLINK_DSCR_BF0_REG(i) (REG_SPI_BASE(i) + 0x80) /* SPI_DMA_INLINK_DSCR_BF0 : RO; bitpos: [31:0]; default: 0; * The content of next in descriptor pointer. @@ -2052,7 +2052,7 @@ /* SPI_INLINK_DSCR_BF1_REG register */ -#define SPI_INLINK_DSCR_BF1_REG (DR_REG_SPI_BASE + 0x84) +#define SPI_INLINK_DSCR_BF1_REG(i) (REG_SPI_BASE(i) + 0x84) /* SPI_DMA_INLINK_DSCR_BF1 : RO; bitpos: [31:0]; default: 0; * The content of current in descriptor data buffer pointer. @@ -2065,7 +2065,7 @@ /* SPI_OUT_EOF_BFR_DES_ADDR_REG register */ -#define SPI_OUT_EOF_BFR_DES_ADDR_REG (DR_REG_SPI_BASE + 0x88) +#define SPI_OUT_EOF_BFR_DES_ADDR_REG(i) (REG_SPI_BASE(i) + 0x88) /* SPI_DMA_OUT_EOF_BFR_DES_ADDR : RO; bitpos: [31:0]; default: 0; * The address of buffer relative to the outlink descriptor that produce eof. @@ -2078,7 +2078,7 @@ /* SPI_OUT_EOF_DES_ADDR_REG register */ -#define SPI_OUT_EOF_DES_ADDR_REG (DR_REG_SPI_BASE + 0x8c) +#define SPI_OUT_EOF_DES_ADDR_REG(i) (REG_SPI_BASE(i) + 0x8c) /* SPI_DMA_OUT_EOF_DES_ADDR : RO; bitpos: [31:0]; default: 0; * The last outlink descriptor address when spi dma produce to_eof. @@ -2091,7 +2091,7 @@ /* SPI_OUTLINK_DSCR_REG register */ -#define SPI_OUTLINK_DSCR_REG (DR_REG_SPI_BASE + 0x90) +#define SPI_OUTLINK_DSCR_REG(i) (REG_SPI_BASE(i) + 0x90) /* SPI_DMA_OUTLINK_DSCR : RO; bitpos: [31:0]; default: 0; * The content of current out descriptor pointer. @@ -2104,7 +2104,7 @@ /* SPI_OUTLINK_DSCR_BF0_REG register */ -#define SPI_OUTLINK_DSCR_BF0_REG (DR_REG_SPI_BASE + 0x94) +#define SPI_OUTLINK_DSCR_BF0_REG(i) (REG_SPI_BASE(i) + 0x94) /* SPI_DMA_OUTLINK_DSCR_BF0 : RO; bitpos: [31:0]; default: 0; * The content of next out descriptor pointer. @@ -2117,7 +2117,7 @@ /* SPI_OUTLINK_DSCR_BF1_REG register */ -#define SPI_OUTLINK_DSCR_BF1_REG (DR_REG_SPI_BASE + 0x98) +#define SPI_OUTLINK_DSCR_BF1_REG(i) (REG_SPI_BASE(i) + 0x98) /* SPI_DMA_OUTLINK_DSCR_BF1 : RO; bitpos: [31:0]; default: 0; * The content of current out descriptor data buffer pointer. @@ -2130,7 +2130,7 @@ /* SPI_DMA_OUTSTATUS_REG register */ -#define SPI_DMA_OUTSTATUS_REG (DR_REG_SPI_BASE + 0x9c) +#define SPI_DMA_OUTSTATUS_REG(i) (REG_SPI_BASE(i) + 0x9c) /* SPI_DMA_OUTFIFO_EMPTY : RO; bitpos: [31]; default: 1; * SPI dma outfifo is empty. @@ -2188,7 +2188,7 @@ /* SPI_DMA_INSTATUS_REG register */ -#define SPI_DMA_INSTATUS_REG (DR_REG_SPI_BASE + 0xa0) +#define SPI_DMA_INSTATUS_REG(i) (REG_SPI_BASE(i) + 0xa0) /* SPI_DMA_INFIFO_EMPTY : RO; bitpos: [31]; default: 1; * SPI dma infifo is empty. @@ -2246,7 +2246,7 @@ /* SPI_W0_REG register */ -#define SPI_W0_REG (DR_REG_SPI_BASE + 0xa4) +#define SPI_W0_REG(i) (REG_SPI_BASE(i) + 0xa4) /* SPI_BUF0 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2259,7 +2259,7 @@ /* SPI_W1_REG register */ -#define SPI_W1_REG (DR_REG_SPI_BASE + 0xa8) +#define SPI_W1_REG(i) (REG_SPI_BASE(i) + 0xa8) /* SPI_BUF1 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2272,7 +2272,7 @@ /* SPI_W2_REG register */ -#define SPI_W2_REG (DR_REG_SPI_BASE + 0xac) +#define SPI_W2_REG(i) (REG_SPI_BASE(i) + 0xac) /* SPI_BUF2 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2285,7 +2285,7 @@ /* SPI_W3_REG register */ -#define SPI_W3_REG (DR_REG_SPI_BASE + 0xb0) +#define SPI_W3_REG(i) (REG_SPI_BASE(i) + 0xb0) /* SPI_BUF3 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2298,7 +2298,7 @@ /* SPI_W4_REG register */ -#define SPI_W4_REG (DR_REG_SPI_BASE + 0xb4) +#define SPI_W4_REG(i) (REG_SPI_BASE(i) + 0xb4) /* SPI_BUF4 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2311,7 +2311,7 @@ /* SPI_W5_REG register */ -#define SPI_W5_REG (DR_REG_SPI_BASE + 0xb8) +#define SPI_W5_REG(i) (REG_SPI_BASE(i) + 0xb8) /* SPI_BUF5 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2324,7 +2324,7 @@ /* SPI_W6_REG register */ -#define SPI_W6_REG (DR_REG_SPI_BASE + 0xbc) +#define SPI_W6_REG(i) (REG_SPI_BASE(i) + 0xbc) /* SPI_BUF6 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2337,7 +2337,7 @@ /* SPI_W7_REG register */ -#define SPI_W7_REG (DR_REG_SPI_BASE + 0xc0) +#define SPI_W7_REG(i) (REG_SPI_BASE(i) + 0xc0) /* SPI_BUF7 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2350,7 +2350,7 @@ /* SPI_W8_REG register */ -#define SPI_W8_REG (DR_REG_SPI_BASE + 0xc4) +#define SPI_W8_REG(i) (REG_SPI_BASE(i) + 0xc4) /* SPI_BUF8 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2363,7 +2363,7 @@ /* SPI_W9_REG register */ -#define SPI_W9_REG (DR_REG_SPI_BASE + 0xc8) +#define SPI_W9_REG(i) (REG_SPI_BASE(i) + 0xc8) /* SPI_BUF9 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2376,7 +2376,7 @@ /* SPI_W10_REG register */ -#define SPI_W10_REG (DR_REG_SPI_BASE + 0xcc) +#define SPI_W10_REG(i) (REG_SPI_BASE(i) + 0xcc) /* SPI_BUF10 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2389,7 +2389,7 @@ /* SPI_W11_REG register */ -#define SPI_W11_REG (DR_REG_SPI_BASE + 0xd0) +#define SPI_W11_REG(i) (REG_SPI_BASE(i) + 0xd0) /* SPI_BUF11 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2402,7 +2402,7 @@ /* SPI_W12_REG register */ -#define SPI_W12_REG (DR_REG_SPI_BASE + 0xd4) +#define SPI_W12_REG(i) (REG_SPI_BASE(i) + 0xd4) /* SPI_BUF12 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2415,7 +2415,7 @@ /* SPI_W13_REG register */ -#define SPI_W13_REG (DR_REG_SPI_BASE + 0xd8) +#define SPI_W13_REG(i) (REG_SPI_BASE(i) + 0xd8) /* SPI_BUF13 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2428,7 +2428,7 @@ /* SPI_W14_REG register */ -#define SPI_W14_REG (DR_REG_SPI_BASE + 0xdc) +#define SPI_W14_REG(i) (REG_SPI_BASE(i) + 0xdc) /* SPI_BUF14 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2441,7 +2441,7 @@ /* SPI_W15_REG register */ -#define SPI_W15_REG (DR_REG_SPI_BASE + 0xe0) +#define SPI_W15_REG(i) (REG_SPI_BASE(i) + 0xe0) /* SPI_BUF15 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2454,7 +2454,7 @@ /* SPI_W16_REG register */ -#define SPI_W16_REG (DR_REG_SPI_BASE + 0xe4) +#define SPI_W16_REG(i) (REG_SPI_BASE(i) + 0xe4) /* SPI_BUF16 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2467,7 +2467,7 @@ /* SPI_W17_REG register */ -#define SPI_W17_REG (DR_REG_SPI_BASE + 0xe8) +#define SPI_W17_REG(i) (REG_SPI_BASE(i) + 0xe8) /* SPI_BUF17 : R/W; bitpos: [31:0]; default: 0; * data buffer @@ -2480,7 +2480,7 @@ /* SPI_DIN_MODE_REG register */ -#define SPI_DIN_MODE_REG (DR_REG_SPI_BASE + 0xec) +#define SPI_DIN_MODE_REG(i) (REG_SPI_BASE(i) + 0xec) /* SPI_TIMING_CLK_ENA : R/W; bitpos: [24]; default: 0; * 1:enable hclk in spi_timing.v. 0: disable it. @@ -2597,7 +2597,7 @@ /* SPI_DIN_NUM_REG register */ -#define SPI_DIN_NUM_REG (DR_REG_SPI_BASE + 0xf0) +#define SPI_DIN_NUM_REG(i) (REG_SPI_BASE(i) + 0xf0) /* SPI_DIN7_NUM : R/W; bitpos: [15:14]; default: 0; * the input signals are delayed by system clock cycles, 0: delayed by 1 @@ -2681,7 +2681,7 @@ /* SPI_DOUT_MODE_REG register */ -#define SPI_DOUT_MODE_REG (DR_REG_SPI_BASE + 0xf4) +#define SPI_DOUT_MODE_REG(i) (REG_SPI_BASE(i) + 0xf4) /* SPI_DOUT7_MODE : R/W; bitpos: [23:21]; default: 0; * Configure the output signal delay mode. 0: without delayed, 1: with the @@ -2789,7 +2789,7 @@ /* SPI_DOUT_NUM_REG register */ -#define SPI_DOUT_NUM_REG (DR_REG_SPI_BASE + 0xf8) +#define SPI_DOUT_NUM_REG(i) (REG_SPI_BASE(i) + 0xf8) /* SPI_DOUT7_NUM : R/W; bitpos: [15:14]; default: 0; * the output signals are delayed by system clock cycles, 0: delayed by 1 @@ -2873,7 +2873,7 @@ /* SPI_LCD_CTRL_REG register */ -#define SPI_LCD_CTRL_REG (DR_REG_SPI_BASE + 0xfc) +#define SPI_LCD_CTRL_REG(i) (REG_SPI_BASE(i) + 0xfc) /* SPI_LCD_SRGB_MODE_EN : R/W; bitpos: [31]; default: 0; * 1: Enable LCD mode output vsync, hsync, de. 0: Disable. @@ -2913,7 +2913,7 @@ /* SPI_LCD_CTRL1_REG register */ -#define SPI_LCD_CTRL1_REG (DR_REG_SPI_BASE + 0x100) +#define SPI_LCD_CTRL1_REG(i) (REG_SPI_BASE(i) + 0x100) /* SPI_LCD_HT_WIDTH : R/W; bitpos: [31:20]; default: 0; * It is the horizontal total width of a frame. @@ -2944,7 +2944,7 @@ /* SPI_LCD_CTRL2_REG register */ -#define SPI_LCD_CTRL2_REG (DR_REG_SPI_BASE + 0x104) +#define SPI_LCD_CTRL2_REG(i) (REG_SPI_BASE(i) + 0x104) /* SPI_LCD_HSYNC_POSITION : R/W; bitpos: [31:24]; default: 0; * It is the position of spi_hsync_out active pulse in a line. @@ -3002,7 +3002,7 @@ /* SPI_LCD_D_MODE_REG register */ -#define SPI_LCD_D_MODE_REG (DR_REG_SPI_BASE + 0x108) +#define SPI_LCD_D_MODE_REG(i) (REG_SPI_BASE(i) + 0x108) /* SPI_D_VSYNC_MODE : R/W; bitpos: [14:12]; default: 0; * Configure the output spi_vsync delay mode. 0: without delayed, 1: with @@ -3071,7 +3071,7 @@ /* SPI_LCD_D_NUM_REG register */ -#define SPI_LCD_D_NUM_REG (DR_REG_SPI_BASE + 0x10c) +#define SPI_LCD_D_NUM_REG(i) (REG_SPI_BASE(i) + 0x10c) /* SPI_D_VSYNC_NUM : R/W; bitpos: [9:8]; default: 0; * the output spi_vsync is delayed by system clock cycles, 0: delayed by 1 @@ -3125,7 +3125,7 @@ /* SPI_REG_DATE_REG register */ -#define SPI_REG_DATE_REG (DR_REG_SPI_BASE + 0x3fc) +#define SPI_REG_DATE_REG(i) (REG_SPI_BASE(i) + 0x3fc) /* SPI_DATE : RW; bitpos: [27:0]; default: 26222993; * SPI register version.