diff --git a/Documentation/platforms/risc-v/esp32c3/boards/esp32c3-generic/index.rst b/Documentation/platforms/risc-v/esp32c3/boards/esp32c3-generic/index.rst index 95826e181ba..dc505e2acb9 100644 --- a/Documentation/platforms/risc-v/esp32c3/boards/esp32c3-generic/index.rst +++ b/Documentation/platforms/risc-v/esp32c3/boards/esp32c3-generic/index.rst @@ -150,6 +150,17 @@ You can set an alarm, check its progress and receive a notification after it exp Alarm 0 is active with 10 seconds to expiration nsh> alarm_daemon: alarm 0 received +spi +-------- + +This configuration enables the support for the SPI driver. +You can test it by connecting MOSI and MISO pins which are GPIO7 and GPIO2 +by default to each other and running the ``spi`` example:: + + nsh> spi exch -b 2 "AB" + Sending: AB + Received: AB + spiflash -------- diff --git a/Documentation/platforms/risc-v/esp32c3/index.rst b/Documentation/platforms/risc-v/esp32c3/index.rst index 25ec59852c6..16daf38f8d8 100644 --- a/Documentation/platforms/risc-v/esp32c3/index.rst +++ b/Documentation/platforms/risc-v/esp32c3/index.rst @@ -159,7 +159,7 @@ RNG No RSA No RTC Yes SHA No -SPI No +SPI Yes SPIFLASH Yes Timers Yes Touch No diff --git a/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/index.rst b/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/index.rst index af7f93a0f69..ba479f1768f 100644 --- a/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/index.rst +++ b/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/index.rst @@ -185,6 +185,17 @@ You can set an alarm, check its progress and receive a notification after it exp Alarm 0 is active with 10 seconds to expiration nsh> alarm_daemon: alarm 0 received +spi +-------- + +This configuration enables the support for the SPI driver. +You can test it by connecting MOSI and MISO pins which are GPIO7 and GPIO2 +by default to each other and running the ``spi`` example:: + + nsh> spi exch -b 2 "AB" + Sending: AB + Received: AB + spiflash -------- diff --git a/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitm/index.rst b/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitm/index.rst index 6887ad70454..7cfd47a6b96 100644 --- a/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitm/index.rst +++ b/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitm/index.rst @@ -185,6 +185,17 @@ You can set an alarm, check its progress and receive a notification after it exp Alarm 0 is active with 10 seconds to expiration nsh> alarm_daemon: alarm 0 received +spi +-------- + +This configuration enables the support for the SPI driver. +You can test it by connecting MOSI and MISO pins which are GPIO7 and GPIO2 +by default to each other and running the ``spi`` example:: + + nsh> spi exch -b 2 "AB" + Sending: AB + Received: AB + spiflash -------- diff --git a/Documentation/platforms/risc-v/esp32c6/index.rst b/Documentation/platforms/risc-v/esp32c6/index.rst index 1d61a6d8afa..44091ee528f 100644 --- a/Documentation/platforms/risc-v/esp32c6/index.rst +++ b/Documentation/platforms/risc-v/esp32c6/index.rst @@ -158,7 +158,7 @@ RTC Yes SD/MMC No SDIO No SHA No -SPI No +SPI Yes SPIFLASH Yes Timers Yes UART Yes diff --git a/Documentation/platforms/risc-v/esp32h2/boards/esp32h2-devkit/index.rst b/Documentation/platforms/risc-v/esp32h2/boards/esp32h2-devkit/index.rst index 8d53ec0b58d..56f181408c2 100644 --- a/Documentation/platforms/risc-v/esp32h2/boards/esp32h2-devkit/index.rst +++ b/Documentation/platforms/risc-v/esp32h2/boards/esp32h2-devkit/index.rst @@ -184,6 +184,17 @@ You can set an alarm, check its progress and receive a notification after it exp Alarm 0 is active with 10 seconds to expiration nsh> alarm_daemon: alarm 0 received +spi +-------- + +This configuration enables the support for the SPI driver. +You can test it by connecting MOSI and MISO pins which are GPIO7 and GPIO2 +by default to each other and running the ``spi`` example:: + + nsh> spi exch -b 2 "AB" + Sending: AB + Received: AB + spiflash -------- diff --git a/Documentation/platforms/risc-v/esp32h2/index.rst b/Documentation/platforms/risc-v/esp32h2/index.rst index 9e261976250..b8533cf6e2e 100644 --- a/Documentation/platforms/risc-v/esp32h2/index.rst +++ b/Documentation/platforms/risc-v/esp32h2/index.rst @@ -158,7 +158,7 @@ RTC Yes SD/MMC No SDIO No SHA No -SPI No +SPI Yes SPIFLASH Yes Timers Yes UART Yes diff --git a/arch/risc-v/src/common/espressif/Kconfig b/arch/risc-v/src/common/espressif/Kconfig index 35a1e1014de..bb6ffc22251 100644 --- a/arch/risc-v/src/common/espressif/Kconfig +++ b/arch/risc-v/src/common/espressif/Kconfig @@ -314,6 +314,16 @@ config ESPRESSIF_LEDC select PWM select ARCH_HAVE_PWM_MULTICHAN +config ESPRESSIF_SPI + bool + default n + +config ESPRESSIF_SPI2 + bool "SPI 2" + default n + select ESPRESSIF_SPI + select SPI + config ESPRESSIF_SPIFLASH bool "SPI Flash" default n @@ -841,6 +851,57 @@ config ESPRESSIF_TWAI_TEST_MODE endmenu #ESPRESSIF_TWAI +menu "SPI configuration" + depends on ESPRESSIF_SPI + +config ESPRESSIF_SPI_SWCS + bool "SPI software CS" + default n + ---help--- + Use SPI software CS. + +config ESPRESSIF_SPI_UDCS + bool "User defined CS" + default n + depends on ESPRESSIF_SPI_SWCS + ---help--- + Use user-defined CS. + +if ESPRESSIF_SPI2 + +config ESPRESSIF_SPI2_CSPIN + int "SPI2 CS Pin" + default 10 + range 0 21 + +config ESPRESSIF_SPI2_CLKPIN + int "SPI2 CLK Pin" + default 6 + range 0 21 + +config ESPRESSIF_SPI2_MOSIPIN + int "SPI2 MOSI Pin" + default 7 + range 0 21 + +config ESPRESSIF_SPI2_MISOPIN + int "SPI2 MISO Pin" + default 2 + range 0 21 + +endif # ESPRESSIF_SPI2 + +config ESPRESSIF_SPI_TEST_MODE + bool "SPI driver loopback test mode (for testing only)" + default n + depends on SYSTEM_SPITOOL + ---help--- + This enables a loopback test mode that attaches the transmitter + to the receiver internally, being able to test the SPI + peripheral without any external connection. + +endmenu # SPI configuration + menu "SPI Flash Configuration" choice ESPRESSIF_FLASH_MODE diff --git a/arch/risc-v/src/common/espressif/Make.defs b/arch/risc-v/src/common/espressif/Make.defs index ccb05252c9f..1c1b418a507 100644 --- a/arch/risc-v/src/common/espressif/Make.defs +++ b/arch/risc-v/src/common/espressif/Make.defs @@ -84,6 +84,10 @@ ifeq ($(CONFIG_ESP_RMT),y) endif endif +ifeq ($(CONFIG_ESPRESSIF_SPI),y) + CHIP_CSRCS += esp_spi.c +endif + ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y) CHIP_CSRCS += esp_spiflash.c ifeq ($(CONFIG_ESPRESSIF_MTD),y) @@ -107,7 +111,7 @@ endif ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty ifndef ESP_HAL_3RDPARTY_VERSION - ESP_HAL_3RDPARTY_VERSION = 6c58b9c8d29fc2faa8cb6273a169340b80229df5 + ESP_HAL_3RDPARTY_VERSION = 9bc2c73838d497b7742f37e9b5099d6c49081fce endif ifndef ESP_HAL_3RDPARTY_URL diff --git a/arch/risc-v/src/common/espressif/esp_spi.c b/arch/risc-v/src/common/espressif/esp_spi.c new file mode 100644 index 00000000000..dd14fd0334f --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_spi.c @@ -0,0 +1,951 @@ +/**************************************************************************** + * arch/risc-v/src/common/espressif/esp_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_ESPRESSIF_SPI + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "esp_spi.h" +#include "esp_irq.h" +#include "esp_gpio.h" + +#include "riscv_internal.h" + +#include "hal/spi_hal.h" +#include "hal/spi_types.h" +#include "hal/spi_hal.h" +#include "esp_clk_tree.h" +#include "hal/clk_tree_hal.h" +#include "periph_ctrl.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if CONFIG_ESPRESSIF_SPI_TEST_MODE +# define MOSI_PIN_ATTR (OUTPUT_FUNCTION_2 | INPUT_FUNCTION_2 | PULLUP) +# define MISO_PIN_ATTR (OUTPUT_FUNCTION_2 | INPUT_FUNCTION_2 | PULLUP) +#else +# define MOSI_PIN_ATTR (OUTPUT_FUNCTION_2) +# define MISO_PIN_ATTR (INPUT_FUNCTION_2 | PULLUP) +#endif + +#define SPI2_IOMUX_MISOPIN 2 +#define SPI2_IOMUX_MOSIPIN 7 +#define SPI2_IOMUX_CLKPIN 6 +#define SPI2_IOMUX_CSPIN 10 + +/* Check if Chip-Select pin will be controlled via software */ + +#ifdef CONFIG_ESPRESSIF_SPI_SWCS +# define SPI_HAVE_SWCS TRUE +#else +# define SPI_HAVE_SWCS FALSE +#endif + +/* Verify whether SPI has been assigned IOMUX pins. + * Otherwise, SPI signals will be routed via GPIO Matrix. + */ + +#define SPI_IS_CS_IOMUX (CONFIG_ESPRESSIF_SPI2_CSPIN == SPI2_IOMUX_CSPIN) +#define SPI_IS_CLK_IOMUX (CONFIG_ESPRESSIF_SPI2_CLKPIN == SPI2_IOMUX_CLKPIN) +#define SPI_IS_MOSI_IOMUX (CONFIG_ESPRESSIF_SPI2_MOSIPIN == SPI2_IOMUX_MOSIPIN) +#define SPI_IS_MISO_IOMUX (CONFIG_ESPRESSIF_SPI2_MISOPIN == SPI2_IOMUX_MISOPIN) + +#define SPI_VIA_IOMUX (SPI_IS_CS_IOMUX || SPI_HAVE_SWCS) && \ + (SPI_IS_CLK_IOMUX) && \ + (SPI_IS_MOSI_IOMUX) && \ + (SPI_IS_MISO_IOMUX) + +/* 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) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* SPI Device hardware configuration */ + +struct esp_spi_config_s +{ + uint32_t width; /* SPI default width */ + 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 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 esp_spi_priv_s +{ + /* Externally visible part of the SPI interface */ + + struct spi_dev_s spi_dev; + + /* Port configuration */ + + const struct esp_spi_config_s *config; + int refs; /* Reference count */ + mutex_t lock; /* Held while chip is selected for mutual exclusion */ + uint8_t nbits; /* Actual SPI send/receive bits once transmission */ + uint8_t id; /* ID number of SPI interface */ + uint8_t module; /* Module ID of SPI interface */ + spi_hal_context_t *ctx; /* Context struct of common layer */ + spi_hal_config_t *cfg; + spi_hal_dev_config_t *dev_cfg; /* Device configuration struct of common layer */ + spi_hal_timing_param_t *timing_param; /* Timing struct of common layer */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int esp_spi_lock(struct spi_dev_s *dev, bool lock); +#ifndef CONFIG_ESPRESSIF_SPI_UDCS +static void esp_spi_select(struct spi_dev_s *dev, + uint32_t devid, bool selected); +#endif +static uint32_t esp_spi_setfrequency(struct spi_dev_s *dev, + uint32_t frequency); +static void esp_spi_setmode(struct spi_dev_s *dev, + enum spi_mode_e mode); +static void esp_spi_setbits(struct spi_dev_s *dev, int nbits); +#ifdef CONFIG_SPI_HWFEATURES +static int esp_spi_hwfeatures(struct spi_dev_s *dev, + spi_hwfeatures_t features); +#endif +static uint32_t esp_spi_send(struct spi_dev_s *dev, uint32_t wd); +static void esp_spi_exchange(struct spi_dev_s *dev, + const void *txbuffer, + void *rxbuffer, size_t nwords); +static void esp_spi_poll_exchange(struct esp_spi_priv_s *priv, + const void *txbuffer, + void *rxbuffer, + size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void esp_spi_sndblock(struct spi_dev_s *dev, + const void *txbuffer, + size_t nwords); +static void esp_spi_recvblock(struct spi_dev_s *dev, + void *rxbuffer, + size_t nwords); +#endif +#ifdef CONFIG_SPI_TRIGGER +static int esp_spi_trigger(struct spi_dev_s *dev); +#endif +static void esp_spi_init(struct spi_dev_s *dev); +static void esp_spi_deinit(struct spi_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_SPI2 + +spi_hal_config_t cfg = +{ + 0 +}; + +spi_hal_context_t ctx = +{ + 0 +}; + +spi_hal_dev_config_t dev_cfg = +{ + .mode = SPI_DEFAULT_MODE, + .cs_setup = 0, + .cs_hold = 0, + .cs_pin_id = 0, + .timing_conf = + { + 0 + }, + { + 0 + } +}; + +spi_hal_timing_param_t timing_param = +{ + .no_compensate = 0, + .half_duplex = 0, + .input_delay_ns = 0, +#ifdef SPI_VIA_IOMUX + .use_gpio = 0, +#else + .use_gpio = 1, +#endif + .duty_cycle = 0, + .clk_src_hz = 0, + .expected_freq = 0, +}; + +static const struct esp_spi_config_s esp_spi2_config = +{ + .width = SPI_DEFAULT_WIDTH, + .cs_pin = CONFIG_ESPRESSIF_SPI2_CSPIN, + .mosi_pin = CONFIG_ESPRESSIF_SPI2_MOSIPIN, + .miso_pin = CONFIG_ESPRESSIF_SPI2_MISOPIN, + .clk_pin = CONFIG_ESPRESSIF_SPI2_CLKPIN, + .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 esp_spi2_ops = +{ + .lock = esp_spi_lock, +#ifdef CONFIG_ESPRESSIF_SPI_UDCS + .select = esp_spi2_select, +#else + .select = esp_spi_select, +#endif + .setfrequency = esp_spi_setfrequency, + .setmode = esp_spi_setmode, + .setbits = esp_spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = esp_spi_hwfeatures, +#endif + .status = esp_spi2_status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = esp_spi2_cmddata, +#endif + .send = esp_spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = esp_spi_exchange, +#else + .sndblock = esp_spi_sndblock, + .recvblock = esp_spi_recvblock, +#endif +#ifdef CONFIG_SPI_TRIGGER + .trigger = esp_spi_trigger, +#endif + .registercallback = NULL, +}; + +static struct esp_spi_priv_s esp_spi2_priv = +{ + .spi_dev = + { + .ops = &esp_spi2_ops + }, + .config = &esp_spi2_config, + .refs = 0, + .lock = NXMUTEX_INITIALIZER, + .id = SPI2_HOST, + .module = PERIPH_SPI2_MODULE, + .nbits = 0, + .cfg = &cfg, + .dev_cfg = &dev_cfg, + .ctx = &ctx, + .timing_param = &timing_param, +}; +#endif /* CONFIG_ESPRESSIF_SPI2 */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_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 esp_spi_lock(struct spi_dev_s *dev, bool lock) +{ + int ret; + struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)dev; + + if (lock) + { + ret = nxmutex_lock(&priv->lock); + } + else + { + ret = nxmutex_unlock(&priv->lock); + } + + return ret; +} + +/**************************************************************************** + * Name: esp_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 ESPRESSIF_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_ESPRESSIF_SPI_UDCS +static void esp_spi_select(struct spi_dev_s *dev, + uint32_t devid, bool selected) +{ +#if SPI_HAVE_SWCS + struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)dev; + bool value = selected ? false : true; + + esp_gpiowrite(priv->config->cs_pin, value); +#endif + + spiinfo("devid: %08" PRIx32 " CS: %s\n", + devid, selected ? "select" : "free"); +} +#endif + +/**************************************************************************** + * Name: esp_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 esp_spi_setfrequency(struct spi_dev_s *dev, + uint32_t frequency) +{ + struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)dev; + + if (priv->timing_param->clk_src_hz == frequency) + { + /* Requested frequency is the same as the current frequency. */ + + return priv->timing_param->clk_src_hz; + } + + spi_hal_cal_clock_conf(priv->timing_param, + NULL, + &(priv->dev_cfg->timing_conf)); + + priv->timing_param->expected_freq = frequency; + spiinfo("frequency=%" PRIu32 ", actual=%" PRIu32 "\n", + priv->timing_param->expected_freq, + priv->timing_param->clk_src_hz); + + return priv->timing_param->clk_src_hz; +} + +/**************************************************************************** + * Name: esp_spi_setmode + * + * Description: + * Set the SPI mode. + * + * Input Parameters: + * dev - Device-specific state data + * mode - The requested SPI mode + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp_spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode) +{ + struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)dev; + + spiinfo("mode=%d\n", mode); + + /* Has the mode changed? */ + + if (mode != priv->dev_cfg->mode) + { + if (mode > SPIDEV_MODE3 || mode < SPIDEV_MODE0) + { + spierr("Invalid mode: %d\n", mode); + DEBUGPANIC(); + return; + } + else + { + spi_ll_master_set_mode(priv->ctx->hw, mode); + } + + priv->dev_cfg->mode = mode; + } +} + +/**************************************************************************** + * Name: esp_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 esp_spi_setbits(struct spi_dev_s *dev, int nbits) +{ + struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)dev; + + spiinfo("nbits=%d\n", nbits); + + priv->nbits = nbits; +} + +/**************************************************************************** + * Name: esp_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 esp_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: esp_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 esp_spi_poll_send(struct esp_spi_priv_s *priv, uint32_t wd) +{ + uint32_t val; + spi_hal_trans_config_t trans = + { + 0 + }; + + spi_hal_setup_device(priv->ctx, priv->dev_cfg); + + trans.tx_bitlen = priv->nbits; + trans.rx_bitlen = priv->nbits; + trans.rcv_buffer = (uint8_t *)&val; + trans.send_buffer = (uint8_t *)&wd; + trans.cs_keep_active = priv->dev_cfg->cs_hold; + trans.line_mode.data_lines = 2; + trans.line_mode.addr_lines = 1; + trans.line_mode.cmd_lines = 1; + priv->ctx->trans_config = trans; + + spi_ll_set_mosi_bitlen(priv->ctx->hw, priv->nbits); + spi_hal_prepare_data(priv->ctx, priv->dev_cfg, &trans); + spi_hal_user_start(priv->ctx); + + while (!spi_hal_usr_is_done(priv->ctx)); + spi_hal_fetch_result(priv->ctx); + + spiinfo("send=0x%" PRIx32 " and recv=0x%" PRIx32 "\n", wd, val); + + return val; +} + +/**************************************************************************** + * Name: esp_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 esp_spi_send(struct spi_dev_s *dev, uint32_t wd) +{ + struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)dev; + + return esp_spi_poll_send(priv, wd); +} + +/**************************************************************************** + * Name: esp_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 esp_spi_poll_exchange(struct esp_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; + uint8_t *tp = (uint8_t *)txbuffer; + uint8_t *rp = (uint8_t *)rxbuffer; + spi_hal_trans_config_t trans = + { + 0 + }; + + spi_hal_setup_device(priv->ctx, priv->dev_cfg); + + trans.cs_keep_active = priv->dev_cfg->cs_hold; + trans.line_mode.data_lines = 2; + trans.line_mode.addr_lines = 1; + trans.line_mode.cmd_lines = 1; + + while (bytes_remaining != 0) + { + 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). + */ + + trans.tx_bitlen = transfer_size * 8; + trans.rx_bitlen = transfer_size * 8; + trans.rcv_buffer = (uint8_t *)rp; + trans.send_buffer = (uint8_t *)tp; + priv->ctx->trans_config = trans; + + spi_hal_prepare_data(priv->ctx, priv->dev_cfg, &trans); + spi_ll_set_mosi_bitlen(priv->ctx->hw, (transfer_size * 8)); + spi_hal_user_start(priv->ctx); + + while (!spi_hal_usr_is_done(priv->ctx)); + + if (rp != NULL) + { + spi_hal_fetch_result(priv->ctx); + } + + bytes_remaining -= transfer_size; + tp += transfer_size; + rp += transfer_size; + } +} + +/**************************************************************************** + * Name: esp_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 esp_spi_exchange(struct spi_dev_s *dev, + const void *txbuffer, + void *rxbuffer, + size_t nwords) +{ + struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)dev; + + esp_spi_poll_exchange(priv, txbuffer, rxbuffer, nwords); +} + +#ifndef CONFIG_SPI_EXCHANGE + +/**************************************************************************** + * Name: esp_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 esp_spi_sndblock(struct spi_dev_s *dev, + const void *txbuffer, + size_t nwords) +{ + spiinfo("txbuffer=%p nwords=%d\n", txbuffer, nwords); + + esp_spi_exchange(dev, txbuffer, NULL, nwords); +} + +/**************************************************************************** + * Name: esp_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 esp_spi_recvblock(struct spi_dev_s *dev, + void *rxbuffer, + size_t nwords) +{ + spiinfo("rxbuffer=%p nwords=%d\n", rxbuffer, nwords); + + esp_spi_exchange(dev, NULL, rxbuffer, nwords); +} +#endif + +/**************************************************************************** + * Name: esp_spi_trigger + * + * Description: + * Trigger a previously configured DMA transfer. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * -OK - Trigger was fired + * -ENOSYS - Trigger not fired due to lack of DMA or low level support + * -EIO - Trigger not fired because not previously primed + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_TRIGGER +static int esp_spi_trigger(struct spi_dev_s *dev) +{ + return -ENOSYS; +} +#endif + +/**************************************************************************** + * Name: esp_spi_init + * + * Description: + * Initialize SPI hardware interface. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp_spi_init(struct spi_dev_s *dev) +{ + struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)dev; + const struct esp_spi_config_s *config = priv->config; + uint32_t regval; + + esp_gpiowrite(config->cs_pin, true); + esp_gpiowrite(config->mosi_pin, true); + esp_gpiowrite(config->miso_pin, true); + esp_gpiowrite(config->clk_pin, true); + +#if SPI_HAVE_SWCS + esp_configgpio(config->cs_pin, OUTPUT_FUNCTION_2); + esp_gpio_matrix_out(config->cs_pin, SIG_GPIO_OUT_IDX, 0, 0); +#endif + +#if SPI_VIA_IOMUX +#if !SPI_HAVE_SWCS + esp_configgpio(config->cs_pin, OUTPUT_FUNCTION_3); + esp_gpio_matrix_out(config->cs_pin, SIG_GPIO_OUT_IDX, 0, 0); +#endif + esp_configgpio(config->mosi_pin, OUTPUT_FUNCTION_3); + esp_gpio_matrix_out(config->mosi_pin, SIG_GPIO_OUT_IDX, 0, 0); + + esp_configgpio(config->miso_pin, INPUT_FUNCTION_3 | PULLUP); + esp_gpio_matrix_out(config->miso_pin, SIG_GPIO_OUT_IDX, 0, 0); + + esp_configgpio(config->clk_pin, OUTPUT_FUNCTION_3); + esp_gpio_matrix_out(config->clk_pin, SIG_GPIO_OUT_IDX, 0, 0); +#else +#if !SPI_HAVE_SWCS + esp_configgpio(config->cs_pin, OUTPUT_FUNCTION_2); + esp_gpio_matrix_out(config->cs_pin, config->cs_outsig, 0, 0); +#endif + esp_configgpio(config->mosi_pin, MOSI_PIN_ATTR); + esp_gpio_matrix_out(config->mosi_pin, config->mosi_outsig, 0, 0); + + esp_configgpio(config->miso_pin, MISO_PIN_ATTR); + esp_gpio_matrix_in(config->miso_pin, config->miso_insig, 0); + + esp_configgpio(config->clk_pin, OUTPUT_FUNCTION_2); + esp_gpio_matrix_out(config->clk_pin, config->clk_outsig, 0, 0); +#endif + + periph_module_enable(priv->module); + + spi_hal_init(priv->ctx, priv->id, priv->cfg); + + priv->dev_cfg->timing_conf.clock_source = SPI_CLK_SRC_DEFAULT; + + esp_spi_setfrequency(dev, priv->timing_param->expected_freq); + esp_spi_setbits(dev, config->width); + esp_spi_setmode(dev, priv->dev_cfg->mode); + + spi_hal_setup_device(priv->ctx, priv->dev_cfg); +} + +/**************************************************************************** + * Name: esp_spi_deinit + * + * Description: + * Deinitialize SPI hardware interface. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void esp_spi_deinit(struct spi_dev_s *dev) +{ + struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)dev; + + periph_module_disable(priv->module); + spi_hal_deinit(priv->ctx); + + priv->nbits = 0; +} + +/**************************************************************************** + * Name: esp_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 *esp_spibus_initialize(int port) +{ + struct spi_dev_s *spi_dev; + struct esp_spi_priv_s *priv; + + switch (port) + { +#ifdef CONFIG_ESPRESSIF_SPI2 + case ESPRESSIF_SPI2: + priv = &esp_spi2_priv; + break; +#endif + default: + return NULL; + } + + spi_dev = (struct spi_dev_s *)priv; + + nxmutex_lock(&priv->lock); + if (priv->refs != 0) + { + priv->refs++; + nxmutex_unlock(&priv->lock); + return spi_dev; + } + + esp_spi_init(spi_dev); + priv->refs++; + + nxmutex_unlock(&priv->lock); + return spi_dev; +} + +/**************************************************************************** + * Name: esp_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 esp_spibus_uninitialize(struct spi_dev_s *dev) +{ + struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)dev; + + DEBUGASSERT(dev); + + if (priv->refs == 0) + { + return ERROR; + } + + nxmutex_lock(&priv->lock); + if (--priv->refs != 0) + { + nxmutex_unlock(&priv->lock); + return OK; + } + + esp_spi_deinit(dev); + nxmutex_unlock(&priv->lock); + + return OK; +} + +#endif /* CONFIG_ESPRESSIF_SPI */ diff --git a/arch/risc-v/src/common/espressif/esp_spi.h b/arch/risc-v/src/common/espressif/esp_spi.h new file mode 100644 index 00000000000..d5651415188 --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_spi.h @@ -0,0 +1,137 @@ +/**************************************************************************** + * arch/risc-v/src/common/espressif/esp_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_RISCV_SRC_COMMON_ESPRESSIF_ESP_SPI_H +#define __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_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_ESPRESSIF_SPI + +#include + +#ifdef CONFIG_ESPRESSIF_SPI2 +# define ESPRESSIF_SPI2 2 +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_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 *esp_spibus_initialize(int port); + +/**************************************************************************** + * Name: esp_spi[2]_select and esp_spi[2]_status + * + * Description: + * The external functions, esp_spi[2]_select, + * esp_spi[2]_status, and esp_spi[2]_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 esp_spibus_initialize()) are provided + * by common ESP32-S3 logic. To use this common SPI logic on your board: + * + * 1. Provide logic in esp_board_initialize() to configure SPI chip + * select pins. + * 2. Provide esp_spi[2]_select() and esp_spi[2]_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 esp_spi[2]_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 esp_spibus_initialize() in your low level + * application initialization logic. + * 5. The handle returned by esp_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_ESPRESSIF_SPI2 +void esp_spi2_select(struct spi_dev_s *dev, uint32_t devid, + bool selected); +uint8_t esp_spi2_status(struct spi_dev_s *dev, uint32_t devid); +int esp_spi2_cmddata(struct spi_dev_s *dev, + uint32_t devid, + bool cmd); +#endif + +/**************************************************************************** + * Name: esp_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 esp_spibus_uninitialize(struct spi_dev_s *dev); + +#endif /* CONFIG_ESPRESSIF_SPI */ + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_SPI_H */ diff --git a/arch/risc-v/src/esp32c3/hal_esp32c3.mk b/arch/risc-v/src/esp32c3/hal_esp32c3.mk index 876e8bd6f5d..68ea1ebcb0d 100644 --- a/arch/risc-v/src/esp32c3/hal_esp32c3.mk +++ b/arch/risc-v/src/esp32c3/hal_esp32c3.mk @@ -23,6 +23,7 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)$(CHIP_SERIES)$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)driver$(DELIM)twai$(DELIM)include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)driver$(DELIM)spi$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)private_include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)include @@ -124,6 +125,8 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)mpu_hal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)mmu_hal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)rmt_hal.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)spi_hal.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)spi_hal_iram.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)twai_hal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)twai_hal_iram.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)uart_hal.c @@ -135,6 +138,7 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)log$(DELIM)log.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)log$(DELIM)log_noos.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)riscv$(DELIM)interrupt.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)lldesc.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)gpio_periph.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)ledc_periph.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)rmt_periph.c diff --git a/arch/risc-v/src/esp32c6/hal_esp32c6.mk b/arch/risc-v/src/esp32c6/hal_esp32c6.mk index d66e16acb35..915faf55e42 100644 --- a/arch/risc-v/src/esp32c6/hal_esp32c6.mk +++ b/arch/risc-v/src/esp32c6/hal_esp32c6.mk @@ -23,6 +23,7 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)$(CHIP_SERIES)$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)driver$(DELIM)twai$(DELIM)include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)driver$(DELIM)spi$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)private_include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)include @@ -124,6 +125,8 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)ledc_hal_iram.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)lp_timer_hal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)rmt_hal.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)spi_hal.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)spi_hal_iram.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)timer_hal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)timer_hal_iram.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)twai_hal_iram.c @@ -140,6 +143,7 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)log$(DELIM)log.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)log$(DELIM)log_noos.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)riscv$(DELIM)interrupt.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)lldesc.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)gpio_periph.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)ledc_periph.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)rmt_periph.c diff --git a/arch/risc-v/src/esp32h2/hal_esp32h2.mk b/arch/risc-v/src/esp32h2/hal_esp32h2.mk index 12190c1e718..52749fa2ca8 100644 --- a/arch/risc-v/src/esp32h2/hal_esp32h2.mk +++ b/arch/risc-v/src/esp32h2/hal_esp32h2.mk @@ -52,6 +52,7 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/compone INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include/spi_flash INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/driver/twai/include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/driver/spi/include ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y) INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/bootloader_support/include @@ -110,6 +111,8 @@ CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/ledc_hal.c CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/ledc_hal_iram.c CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/lp_timer_hal.c CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/rmt_hal.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/spi_hal.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/spi_hal_iram.c CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/timer_hal.c CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/timer_hal_iram.c CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/mpu_hal.c @@ -123,6 +126,7 @@ CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/$(CHIP_SERIES)/modem_ CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/log/log.c CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/log/log_noos.c CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/riscv/interrupt.c +CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/lldesc.c CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/gpio_periph.c CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/ledc_periph.c CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/rmt_periph.c diff --git a/boards/risc-v/esp32c3/common/include/esp_board_spidev.h b/boards/risc-v/esp32c3/common/include/esp_board_spidev.h new file mode 100644 index 00000000000..70abc41609a --- /dev/null +++ b/boards/risc-v/esp32c3/common/include/esp_board_spidev.h @@ -0,0 +1,78 @@ +/**************************************************************************** + * boards/risc-v/esp32c3/common/include/esp_board_spidev.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_RISC_V_ESP32C3_COMMON_INCLUDE_ESP_BOARD_SPIDEV_H +#define __BOARDS_RISC_V_ESP32C3_COMMON_INCLUDE_ESP_BOARD_SPIDEV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: board_spidev_initialize + * + * Description: + * Initialize SPI driver and register the /dev/spi device. + * + * Input Parameters: + * bus - The SPI bus number, used to build the device path as /dev/spiN + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_DRIVER +int board_spidev_initialize(int bus); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_RISC_V_ESP32C3_COMMON_INCLUDE_ESP_BOARD_SPIDEV_H */ diff --git a/boards/risc-v/esp32c3/common/src/Make.defs b/boards/risc-v/esp32c3/common/src/Make.defs index ab73484da08..67892bf2ba1 100644 --- a/boards/risc-v/esp32c3/common/src/Make.defs +++ b/boards/risc-v/esp32c3/common/src/Make.defs @@ -28,6 +28,14 @@ ifeq ($(CONFIG_ESP_RMT),y) CSRCS += esp_board_rmt.c endif +ifeq ($(CONFIG_ESPRESSIF_SPI),y) + CSRCS += esp_board_spi.c +endif + +ifeq ($(CONFIG_SPI_DRIVER),y) + CSRCS += esp_board_spidev.c +endif + ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y) CSRCS += esp_board_spiflash.c endif diff --git a/boards/risc-v/esp32c3/common/src/esp_board_spi.c b/boards/risc-v/esp32c3/common/src/esp_board_spi.c new file mode 100644 index 00000000000..e9a996a8b2b --- /dev/null +++ b/boards/risc-v/esp32c3/common/src/esp_board_spi.c @@ -0,0 +1,83 @@ +/**************************************************************************** + * boards/risc-v/esp32c3/common/src/esp_board_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 + +#include +#include +#include + +#include + +#include "espressif/esp_gpio.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_spi2_status + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_SPI2 + +uint8_t esp_spi2_status(struct spi_dev_s *dev, uint32_t devid) +{ + uint8_t status = 0; + + return status; +} + +#endif + +/**************************************************************************** + * Name: esp_spi2_cmddata + ****************************************************************************/ + +#if defined(CONFIG_ESPRESSIF_SPI2) && defined(CONFIG_SPI_CMDDATA) + +int esp_spi2_cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ + if (devid == SPIDEV_DISPLAY(0)) + { + /* This is the Data/Command control pad which determines whether the + * data bits are data or a command. + */ + + esp_gpiowrite(CONFIG_ESPRESSIF_SPI2_MISOPIN, !cmd); + + return OK; + } + + spiinfo("devid: %" PRIu32 " CMD: %s\n", devid, cmd ? "command" : + "data"); + + return -ENODEV; +} + +#endif diff --git a/boards/risc-v/esp32c3/common/src/esp_board_spidev.c b/boards/risc-v/esp32c3/common/src/esp_board_spidev.c new file mode 100644 index 00000000000..01a47105e2f --- /dev/null +++ b/boards/risc-v/esp32c3/common/src/esp_board_spidev.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * boards/risc-v/esp32c3/common/src/esp_board_spidev.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 "espressif/esp_spi.h" + +#include "esp_board_spidev.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_spidev_initialize + * + * Description: + * Initialize SPI driver and register the /dev/spi device. + * + * Input Parameters: + * port - The SPI bus number, used to build the device path as /dev/spiN + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int board_spidev_initialize(int port) +{ + int ret; + struct spi_dev_s *spi; + + syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); + + /* Initialize SPI device */ + + spi = esp_spibus_initialize(port); + if (spi == NULL) + { + syslog(LOG_ERR, "Failed to initialize SPI%d.\n", port); + return -ENODEV; + } + + ret = spi_register(spi, port); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to register /dev/spi%d: %d\n", port, ret); + + esp_spibus_uninitialize(spi); + } + + return ret; +} diff --git a/boards/risc-v/esp32c3/esp32c3-generic/configs/spi/defconfig b/boards/risc-v/esp32c3/esp32c3-generic/configs/spi/defconfig new file mode 100644 index 00000000000..7c56fef6de5 --- /dev/null +++ b/boards/risc-v/esp32c3/esp32c3-generic/configs/spi/defconfig @@ -0,0 +1,49 @@ +# +# 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="esp32c3" +CONFIG_ARCH_CHIP_ESP32C3_GENERIC=y +CONFIG_ARCH_INTERRUPTSTACK=1536 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_LOOPSPERMSEC=15000 +CONFIG_BUILTIN=y +CONFIG_DEV_ZERO=y +CONFIG_ESPRESSIF_SPI2=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_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_SPITOOL_MINBUS=2 +CONFIG_START_DAY=29 +CONFIG_START_MONTH=11 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_DUMPSTACK=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_SPITOOL=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y diff --git a/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c b/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c index 6d9d2d3c60f..420476536eb 100644 --- a/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c +++ b/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c @@ -65,6 +65,11 @@ # include "esp_board_rmt.h" #endif +#ifdef CONFIG_ESPRESSIF_SPI +# include "espressif/esp_spi.h" +# include "esp_board_spidev.h" +#endif + #ifdef CONFIG_ESPRESSIF_WIFI_BT_COEXIST # include "esp_coexist_internal.h" #endif @@ -176,6 +181,14 @@ int esp_bringup(void) #endif #endif +#if defined(CONFIG_ESPRESSIF_SPI) && defined(CONFIG_SPI_DRIVER) + ret = board_spidev_initialize(ESPRESSIF_SPI2); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to init spidev 2: %d\n", ret); + } +#endif + #ifdef CONFIG_ESPRESSIF_SPIFLASH ret = board_spiflash_init(); if (ret) diff --git a/boards/risc-v/esp32c6/common/include/esp_board_spidev.h b/boards/risc-v/esp32c6/common/include/esp_board_spidev.h new file mode 100644 index 00000000000..f4659bc5ca8 --- /dev/null +++ b/boards/risc-v/esp32c6/common/include/esp_board_spidev.h @@ -0,0 +1,78 @@ +/**************************************************************************** + * boards/risc-v/esp32c6/common/include/esp_board_spidev.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_RISC_V_ESP32C6_COMMON_INCLUDE_ESP_BOARD_SPIDEV_H +#define __BOARDS_RISC_V_ESP32C6_COMMON_INCLUDE_ESP_BOARD_SPIDEV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: board_spidev_initialize + * + * Description: + * Initialize SPI driver and register the /dev/spi device. + * + * Input Parameters: + * bus - The SPI bus number, used to build the device path as /dev/spiN + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_DRIVER +int board_spidev_initialize(int bus); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_RISC_V_ESP32C6_COMMON_INCLUDE_ESP_BOARD_SPIDEV_H */ diff --git a/boards/risc-v/esp32c6/common/src/Make.defs b/boards/risc-v/esp32c6/common/src/Make.defs index 36a1c1ce041..d3240f9ad55 100644 --- a/boards/risc-v/esp32c6/common/src/Make.defs +++ b/boards/risc-v/esp32c6/common/src/Make.defs @@ -28,6 +28,14 @@ ifeq ($(CONFIG_ESP_RMT),y) CSRCS += esp_board_rmt.c endif +ifeq ($(CONFIG_ESPRESSIF_SPI),y) + CSRCS += esp_board_spi.c +endif + +ifeq ($(CONFIG_SPI_DRIVER),y) + CSRCS += esp_board_spidev.c +endif + ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y) CSRCS += esp_board_spiflash.c endif diff --git a/boards/risc-v/esp32c6/common/src/esp_board_spi.c b/boards/risc-v/esp32c6/common/src/esp_board_spi.c new file mode 100644 index 00000000000..0ddc61022c4 --- /dev/null +++ b/boards/risc-v/esp32c6/common/src/esp_board_spi.c @@ -0,0 +1,83 @@ +/**************************************************************************** + * boards/risc-v/esp32c6/common/src/esp_board_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 + +#include +#include +#include + +#include + +#include "espressif/esp_gpio.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_spi2_status + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_SPI2 + +uint8_t esp_spi2_status(struct spi_dev_s *dev, uint32_t devid) +{ + uint8_t status = 0; + + return status; +} + +#endif + +/**************************************************************************** + * Name: esp_spi2_cmddata + ****************************************************************************/ + +#if defined(CONFIG_ESPRESSIF_SPI2) && defined(CONFIG_SPI_CMDDATA) + +int esp_spi2_cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ + if (devid == SPIDEV_DISPLAY(0)) + { + /* This is the Data/Command control pad which determines whether the + * data bits are data or a command. + */ + + esp_gpiowrite(CONFIG_ESPRESSIF_SPI2_MISOPIN, !cmd); + + return OK; + } + + spiinfo("devid: %" PRIu32 " CMD: %s\n", devid, cmd ? "command" : + "data"); + + return -ENODEV; +} + +#endif diff --git a/boards/risc-v/esp32c6/common/src/esp_board_spidev.c b/boards/risc-v/esp32c6/common/src/esp_board_spidev.c new file mode 100644 index 00000000000..040936c7fbe --- /dev/null +++ b/boards/risc-v/esp32c6/common/src/esp_board_spidev.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * boards/risc-v/esp32c6/common/src/esp_board_spidev.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 "espressif/esp_spi.h" + +#include "esp_board_spidev.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_spidev_initialize + * + * Description: + * Initialize SPI driver and register the /dev/spi device. + * + * Input Parameters: + * port - The SPI bus number, used to build the device path as /dev/spiN + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int board_spidev_initialize(int port) +{ + int ret; + struct spi_dev_s *spi; + + syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); + + /* Initialize SPI device */ + + spi = esp_spibus_initialize(port); + if (spi == NULL) + { + syslog(LOG_ERR, "Failed to initialize SPI%d.\n", port); + return -ENODEV; + } + + ret = spi_register(spi, port); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to register /dev/spi%d: %d\n", port, ret); + + esp_spibus_uninitialize(spi); + } + + return ret; +} diff --git a/boards/risc-v/esp32c6/esp32c6-devkitc/configs/spi/defconfig b/boards/risc-v/esp32c6/esp32c6-devkitc/configs/spi/defconfig new file mode 100644 index 00000000000..658610b7691 --- /dev/null +++ b/boards/risc-v/esp32c6/esp32c6-devkitc/configs/spi/defconfig @@ -0,0 +1,51 @@ +# +# 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="esp32c6-devkitc" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32C6_DEVKITC=y +CONFIG_ARCH_CHIP="esp32c6" +CONFIG_ARCH_CHIP_ESP32C6=y +CONFIG_ARCH_CHIP_ESP32C6WROOM1=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_LOOPSPERMSEC=15000 +CONFIG_BUILTIN=y +CONFIG_DEV_ZERO=y +CONFIG_ESPRESSIF_ESP32C6=y +CONFIG_ESPRESSIF_SPI2=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_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_SPITOOL_MINBUS=2 +CONFIG_START_DAY=29 +CONFIG_START_MONTH=11 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_DUMPSTACK=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_SPITOOL=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y diff --git a/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c b/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c index f353dda0ff7..9b115fbd8fa 100644 --- a/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c +++ b/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c @@ -65,6 +65,11 @@ # include "esp_board_rmt.h" #endif +#ifdef CONFIG_ESPRESSIF_SPI +# include "espressif/esp_spi.h" +# include "esp_board_spidev.h" +#endif + #ifdef CONFIG_ESPRESSIF_WIFI_BT_COEXIST # include "esp_coexist_internal.h" #endif @@ -200,6 +205,14 @@ int esp_bringup(void) } #endif +#if defined(CONFIG_ESPRESSIF_SPI) && defined(CONFIG_SPI_DRIVER) + ret = board_spidev_initialize(ESPRESSIF_SPI2); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to init spidev 2: %d\n", ret); + } +#endif + #ifdef CONFIG_ESPRESSIF_SPIFLASH ret = board_spiflash_init(); if (ret) diff --git a/boards/risc-v/esp32c6/esp32c6-devkitm/configs/spi/defconfig b/boards/risc-v/esp32c6/esp32c6-devkitm/configs/spi/defconfig new file mode 100644 index 00000000000..727609b169f --- /dev/null +++ b/boards/risc-v/esp32c6/esp32c6-devkitm/configs/spi/defconfig @@ -0,0 +1,51 @@ +# +# 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="esp32c6-devkitm" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32C6_DEVKITM=y +CONFIG_ARCH_CHIP="esp32c6" +CONFIG_ARCH_CHIP_ESP32C6=y +CONFIG_ARCH_CHIP_ESP32C6MINI1=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_LOOPSPERMSEC=15000 +CONFIG_BUILTIN=y +CONFIG_DEV_ZERO=y +CONFIG_ESPRESSIF_ESP32C6=y +CONFIG_ESPRESSIF_SPI2=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_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_SPITOOL_MINBUS=2 +CONFIG_START_DAY=29 +CONFIG_START_MONTH=11 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_DUMPSTACK=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_SPITOOL=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y diff --git a/boards/risc-v/esp32c6/esp32c6-devkitm/src/esp32c6_bringup.c b/boards/risc-v/esp32c6/esp32c6-devkitm/src/esp32c6_bringup.c index 03737dfe443..2ffccd2ccbd 100644 --- a/boards/risc-v/esp32c6/esp32c6-devkitm/src/esp32c6_bringup.c +++ b/boards/risc-v/esp32c6/esp32c6-devkitm/src/esp32c6_bringup.c @@ -65,6 +65,11 @@ # include "esp_board_rmt.h" #endif +#ifdef CONFIG_ESPRESSIF_SPI +# include "espressif/esp_spi.h" +# include "esp_board_spidev.h" +#endif + #ifdef CONFIG_ESPRESSIF_WIFI_BT_COEXIST # include "esp_coexist_internal.h" #endif @@ -200,6 +205,14 @@ int esp_bringup(void) } #endif +#if defined(CONFIG_ESPRESSIF_SPI) && defined(CONFIG_SPI_DRIVER) + ret = board_spidev_initialize(ESPRESSIF_SPI2); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to init spidev 2: %d\n", ret); + } +#endif + #ifdef CONFIG_ESPRESSIF_SPIFLASH ret = board_spiflash_init(); if (ret) diff --git a/boards/risc-v/esp32h2/common/include/esp_board_spidev.h b/boards/risc-v/esp32h2/common/include/esp_board_spidev.h new file mode 100644 index 00000000000..fdd586b0af1 --- /dev/null +++ b/boards/risc-v/esp32h2/common/include/esp_board_spidev.h @@ -0,0 +1,78 @@ +/**************************************************************************** + * boards/risc-v/esp32h2/common/include/esp_board_spidev.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_RISC_V_ESP32H2_COMMON_INCLUDE_ESP_BOARD_SPIDEV_H +#define __BOARDS_RISC_V_ESP32H2_COMMON_INCLUDE_ESP_BOARD_SPIDEV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: board_spidev_initialize + * + * Description: + * Initialize SPI driver and register the /dev/spi device. + * + * Input Parameters: + * bus - The SPI bus number, used to build the device path as /dev/spiN + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_DRIVER +int board_spidev_initialize(int bus); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_RISC_V_ESP32H2_COMMON_INCLUDE_ESP_BOARD_SPIDEV_H */ diff --git a/boards/risc-v/esp32h2/common/src/Make.defs b/boards/risc-v/esp32h2/common/src/Make.defs index 55f4960451a..a8a80f29985 100644 --- a/boards/risc-v/esp32h2/common/src/Make.defs +++ b/boards/risc-v/esp32h2/common/src/Make.defs @@ -28,6 +28,14 @@ ifeq ($(CONFIG_ESP_RMT),y) CSRCS += esp_board_rmt.c endif +ifeq ($(CONFIG_ESPRESSIF_SPI),y) + CSRCS += esp_board_spi.c +endif + +ifeq ($(CONFIG_SPI_DRIVER),y) + CSRCS += esp_board_spidev.c +endif + ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y) CSRCS += esp_board_spiflash.c endif diff --git a/boards/risc-v/esp32h2/common/src/esp_board_spi.c b/boards/risc-v/esp32h2/common/src/esp_board_spi.c new file mode 100644 index 00000000000..daca0d87f74 --- /dev/null +++ b/boards/risc-v/esp32h2/common/src/esp_board_spi.c @@ -0,0 +1,83 @@ +/**************************************************************************** + * boards/risc-v/esp32h2/common/src/esp_board_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 + +#include +#include +#include + +#include + +#include "espressif/esp_gpio.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_spi2_status + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_SPI2 + +uint8_t esp_spi2_status(struct spi_dev_s *dev, uint32_t devid) +{ + uint8_t status = 0; + + return status; +} + +#endif + +/**************************************************************************** + * Name: esp_spi2_cmddata + ****************************************************************************/ + +#if defined(CONFIG_ESPRESSIF_SPI2) && defined(CONFIG_SPI_CMDDATA) + +int esp_spi2_cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ + if (devid == SPIDEV_DISPLAY(0)) + { + /* This is the Data/Command control pad which determines whether the + * data bits are data or a command. + */ + + esp_gpiowrite(CONFIG_ESPRESSIF_SPI2_MISOPIN, !cmd); + + return OK; + } + + spiinfo("devid: %" PRIu32 " CMD: %s\n", devid, cmd ? "command" : + "data"); + + return -ENODEV; +} + +#endif diff --git a/boards/risc-v/esp32h2/common/src/esp_board_spidev.c b/boards/risc-v/esp32h2/common/src/esp_board_spidev.c new file mode 100644 index 00000000000..8e2e9bdb9a9 --- /dev/null +++ b/boards/risc-v/esp32h2/common/src/esp_board_spidev.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * boards/risc-v/esp32h2/common/src/esp_board_spidev.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 "espressif/esp_spi.h" + +#include "esp_board_spidev.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_spidev_initialize + * + * Description: + * Initialize SPI driver and register the /dev/spi device. + * + * Input Parameters: + * port - The SPI bus number, used to build the device path as /dev/spiN + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int board_spidev_initialize(int port) +{ + int ret; + struct spi_dev_s *spi; + + syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); + + /* Initialize SPI device */ + + spi = esp_spibus_initialize(port); + if (spi == NULL) + { + syslog(LOG_ERR, "Failed to initialize SPI%d.\n", port); + return -ENODEV; + } + + ret = spi_register(spi, port); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to register /dev/spi%d: %d\n", port, ret); + + esp_spibus_uninitialize(spi); + } + + return ret; +} diff --git a/boards/risc-v/esp32h2/esp32h2-devkit/configs/spi/defconfig b/boards/risc-v/esp32h2/esp32h2-devkit/configs/spi/defconfig new file mode 100644 index 00000000000..31c16f302f1 --- /dev/null +++ b/boards/risc-v/esp32h2/esp32h2-devkit/configs/spi/defconfig @@ -0,0 +1,50 @@ +# +# 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="esp32h2-devkit" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32H2_DEVKIT=y +CONFIG_ARCH_CHIP="esp32h2" +CONFIG_ARCH_CHIP_ESP32H2=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_LOOPSPERMSEC=15000 +CONFIG_BUILTIN=y +CONFIG_DEV_ZERO=y +CONFIG_ESPRESSIF_ESP32H2=y +CONFIG_ESPRESSIF_SPI2=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_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_SPITOOL_MINBUS=2 +CONFIG_START_DAY=29 +CONFIG_START_MONTH=11 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_DUMPSTACK=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_SPITOOL=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y diff --git a/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c b/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c index 481d6d1340e..0213f5ef4f6 100644 --- a/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c +++ b/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c @@ -65,6 +65,11 @@ # include "esp_board_rmt.h" #endif +#ifdef CONFIG_ESPRESSIF_SPI +# include "espressif/esp_spi.h" +# include "esp_board_spidev.h" +#endif + #include "esp32h2-devkit.h" /**************************************************************************** @@ -192,6 +197,14 @@ int esp_bringup(void) } #endif +#if defined(CONFIG_ESPRESSIF_SPI) && defined(CONFIG_SPI_DRIVER) + ret = board_spidev_initialize(ESPRESSIF_SPI2); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to init spidev 2: %d\n", ret); + } +#endif + #ifdef CONFIG_ESPRESSIF_SPIFLASH ret = board_spiflash_init(); if (ret)