diff --git a/arch/xtensa/src/common/espressif/Kconfig b/arch/xtensa/src/common/espressif/Kconfig index 51f44bf83f1..65444840a91 100644 --- a/arch/xtensa/src/common/espressif/Kconfig +++ b/arch/xtensa/src/common/espressif/Kconfig @@ -40,6 +40,22 @@ config ESPRESSIF_I2C_BITBANG ---help--- Software implemented I2C peripheral with GPIOs. Suggested to use if I2C peripherals are already in use. +config ESPRESSIF_SPI_PERIPH + bool + depends on (ESP32S3_SPI2 || ESP32S3_SPI3) || (ESP32_SPI2 || ESP32_SPI3) || (ESP32S2_SPI2 || ESP32S2_SPI3) + default n + +config ESPRESSIF_SPI_BITBANG + bool "SPI Bitbang" + default n + select ESP32_SPI if ARCH_CHIP_ESP32 + select ESP32S2_SPI if ARCH_CHIP_ESP32S2 + select ESP32S3_SPI if ARCH_CHIP_ESP32S3 + select SPI + select SPI_BITBANG + ---help--- + Software implemented SPI peripheral with GPIOs. Suggested to use if SPI peripherals are already in use. + config ESPRESSIF_SPIFLASH bool "SPI Flash" depends on ARCH_CHIP_ESP32S2 @@ -104,6 +120,49 @@ config ESPRESSIF_I2C_BITBANG_SDAPIN endmenu # I2C bitbang configuration +menu "SPI bitbang configuration" + depends on ESPRESSIF_SPI_BITBANG + +config ESPRESSIF_SPI_BITBANG_CSPIN + int "SPI Bitbang CS Pin" + default 0 + range 0 21 + +config ESPRESSIF_SPI_BITBANG_CLKPIN + int "SPI Bitbang CLK Pin" + default 1 + range 0 21 + +config ESPRESSIF_SPI_BITBANG_MOSIPIN + int "SPI Bitbang MOSI Pin" + default 2 + range 0 21 + +config ESPRESSIF_SPI_BITBANG_MISOPIN + int "SPI Bitbang MISO Pin" + default 3 + range 0 21 + +choice ESPRESSIF_SPI_BITBANG_MODE + prompt "SPI Bitbang mode" + default ESPRESSIF_SPI_BITBANG_MODE0 + +config ESPRESSIF_SPI_BITBANG_MODE0 + bool "SPI MODE0" + +config ESPRESSIF_SPI_BITBANG_MODE1 + bool "SPI MODE1" + +config ESPRESSIF_SPI_BITBANG_MODE2 + bool "SPI MODE2" + +config ESPRESSIF_SPI_BITBANG_MODE3 + bool "SPI MODE3" + +endchoice # ESPRESSIF_SPI_BITBANG_MODE + +endmenu # SPI bitbang configuration + config ESPRESSIF_HAVE_OTA_PARTITION bool default n diff --git a/arch/xtensa/src/common/espressif/Make.defs b/arch/xtensa/src/common/espressif/Make.defs index de328a5cf60..5bea53d5215 100644 --- a/arch/xtensa/src/common/espressif/Make.defs +++ b/arch/xtensa/src/common/espressif/Make.defs @@ -44,6 +44,10 @@ ifeq ($(CONFIG_ESPRESSIF_I2C_BITBANG),y) CHIP_CSRCS += esp_i2c_bitbang.c endif +ifeq ($(CONFIG_ESPRESSIF_SPI_BITBANG),y) +CHIP_CSRCS += esp_spi_bitbang.c +endif + ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y) CHIP_CSRCS += esp_spiflash.c ifeq ($(CONFIG_ESPRESSIF_MTD),y) diff --git a/arch/xtensa/src/common/espressif/esp_spi_bitbang.c b/arch/xtensa/src/common/espressif/esp_spi_bitbang.c new file mode 100644 index 00000000000..25133e649ba --- /dev/null +++ b/arch/xtensa/src/common/espressif/esp_spi_bitbang.c @@ -0,0 +1,273 @@ +/**************************************************************************** + * arch/xtensa/src/common/espressif/esp_spi_bitbang.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_BITBANG +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "esp_spi_bitbang.h" +#include + +#if defined(CONFIG_ARCH_CHIP_ESP32S3) +#include "esp32s3_gpio.h" +#include "hardware/esp32s3_gpio_sigmap.h" +#elif defined(CONFIG_ARCH_CHIP_ESP32S2) +#include "esp32s2_gpio.h" +#include "esp32s2_gpio_sigmap.h" +#else +#include "esp32_gpio.h" +#include "esp32_gpio_sigmap.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_ESP32S3) +#define CONFIG_GPIO(pin, attr) esp32s3_configgpio(pin, attr) +#define GPIO_MATRIX_OUT(pin, idx, inv, en_inv) esp32s3_gpio_matrix_out(pin, \ + idx, inv, en_inv) +#elif defined(CONFIG_ARCH_CHIP_ESP32S2) +#define CONFIG_GPIO(pin, attr) esp32s2_configgpio(pin, attr) +#define GPIO_MATRIX_OUT(pin, idx, inv, en_inv) esp32s2_gpio_matrix_out(pin, \ + idx, inv, en_inv) +#else +#define CONFIG_GPIO(pin, attr) esp32_configgpio(pin, attr) +#define GPIO_MATRIX_OUT(pin, idx, inv, en_inv) esp32_gpio_matrix_out(pin, \ + idx, inv, en_inv) +#endif + +#if defined(CONFIG_ESPRESSIF_SPI_BITBANG_MODE0) +#undef SPI_BITBANG_DISABLEMODE0 +#define SPI_BITBANG_DISABLEMODE1 1 +#define SPI_BITBANG_DISABLEMODE2 1 +#define SPI_BITBANG_DISABLEMODE3 1 +#elif defined(CONFIG_ESPRESSIF_SPI_BITBANG_MODE1) +#undef SPI_BITBANG_DISABLEMODE1 +#define SPI_BITBANG_DISABLEMODE0 1 +#define SPI_BITBANG_DISABLEMODE2 1 +#define SPI_BITBANG_DISABLEMODE3 1 +#elif defined(CONFIG_ESPRESSIF_SPI_BITBANG_MODE2) +#undef SPI_BITBANG_DISABLEMODE2 +#define SPI_BITBANG_DISABLEMODE0 1 +#define SPI_BITBANG_DISABLEMODE1 1 +#define SPI_BITBANG_DISABLEMODE3 1 +#else +#undef SPI_BITBANG_DISABLEMODE3 +#define SPI_BITBANG_DISABLEMODE0 1 +#define SPI_BITBANG_DISABLEMODE1 1 +#define SPI_BITBANG_DISABLEMODE2 1 +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Lower-half SPI */ + +static void spi_select(struct spi_bitbang_s *priv, uint32_t devid, + bool selected); +static uint8_t spi_status(struct spi_bitbang_s *priv, uint32_t devid); +#ifdef CONFIG_SPI_CMDDATA +static int spi_cmddata(struct spi_bitbang_s *priv, uint32_t devid, + bool cmd); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct spi_bitbang_ops_s esp_spi_bitbang_ops = +{ + .select = spi_select, + .status = spi_status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = spi_cmddata, +#endif + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .exchange = spi_exchange, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_select + * + * Description: + * Select or de-selected the SPI device specified by 'devid' + * + * Input Parameters: + * priv - An instance of the bit-bang driver structure + * devid - The device to select or de-select + * selected - True:select false:de-select + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_select(struct spi_bitbang_s *priv, uint32_t devid, + bool selected) +{ + if (selected) + { + SPI_CLRCS; + } + else + { + SPI_SETCS; + } +} + +/**************************************************************************** + * Name: spi_status + * + * Description: + * Return status of the SPI device specified by 'devid' + * + * Input Parameters: + * priv - An instance of the bit-bang driver structure + * devid - The device to select or de-select + * + * Returned Value: + * An 8-bit, bit-encoded status byte + * + ****************************************************************************/ + +static uint8_t spi_status(struct spi_bitbang_s *priv, uint32_t devid) +{ + if (devid == SPIDEV_MMCSD(0)) + { + return SPI_STATUS_PRESENT; + } + + return 0; +} + +/**************************************************************************** + * Name: spi_cmddata + * + * Description: + * If there were was a CMD/DATA line, this function would manage it + * + * Input Parameters: + * priv - An instance of the bit-bang driver structure + * devid - The device to use + * cmd - True=MCD false=DATA + * + * Returned Value: + * OK + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CMDDATA +static int spi_cmddata(struct spi_bitbang_s *priv, uint32_t devid, + bool cmd) +{ + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_spi_bitbang_init + * + * Description: + * Initialize the SPI bit-bang driver + * + * Input Parameters: + * None + * + * Returned Value: + * A non-NULL reference to the SPI driver on success + * + ****************************************************************************/ + +struct spi_dev_s *esp_spi_bitbang_init(void) +{ + /* Configure the SPI bit-bang pins */ + + GPIO_WRITE(CONFIG_ESPRESSIF_SPI_BITBANG_CSPIN, true); + GPIO_WRITE(CONFIG_ESPRESSIF_SPI_BITBANG_MOSIPIN, true); + GPIO_WRITE(CONFIG_ESPRESSIF_SPI_BITBANG_CLKPIN, true); + +#if CONFIG_ESPRESSIF_SPI_SWCS + CONFIG_GPIO(CONFIG_ESPRESSIF_SPI_BITBANG_CSPIN, OUTPUT_FUNCTION_1); + GPIO_MATRIX_OUT(CONFIG_ESPRESSIF_SPI_BITBANG_CSPIN, SIG_GPIO_OUT_IDX, + 0, 0); +#endif + CONFIG_GPIO(CONFIG_ESPRESSIF_SPI_BITBANG_MOSIPIN, OUTPUT_FUNCTION_1); + GPIO_MATRIX_OUT(CONFIG_ESPRESSIF_SPI_BITBANG_MOSIPIN, SIG_GPIO_OUT_IDX, + 0, 0); + + CONFIG_GPIO(CONFIG_ESPRESSIF_SPI_BITBANG_MISOPIN, + INPUT_FUNCTION_1 | PULLUP); + GPIO_MATRIX_OUT(CONFIG_ESPRESSIF_SPI_BITBANG_MISOPIN, SIG_GPIO_OUT_IDX, + 0, 0); + + CONFIG_GPIO(CONFIG_ESPRESSIF_SPI_BITBANG_CLKPIN, OUTPUT_FUNCTION_1); + GPIO_MATRIX_OUT(CONFIG_ESPRESSIF_SPI_BITBANG_CLKPIN, SIG_GPIO_OUT_IDX, + 0, 0); + + /* Create the SPI driver instance */ + + return spi_create_bitbang(&esp_spi_bitbang_ops, NULL); +} + +/**************************************************************************** + * Name: esp_spi_bitbang_uninitialize + * + * Description: + * Destroy an instance of the SPI bit-bang driver. + * + * Input Parameters: + * dev - device instance, target driver to destroy. + * + ****************************************************************************/ + +void esp_spi_bitbang_uninitialize(struct spi_dev_s *dev) +{ + spi_destroy_bitbang(dev); +} + +#endif /* CONFIG_ESPRESSIF_SPI_BITBANG */ diff --git a/arch/xtensa/src/common/espressif/esp_spi_bitbang.h b/arch/xtensa/src/common/espressif/esp_spi_bitbang.h new file mode 100644 index 00000000000..b01a12bc759 --- /dev/null +++ b/arch/xtensa/src/common/espressif/esp_spi_bitbang.h @@ -0,0 +1,133 @@ +/**************************************************************************** + * arch/xtensa/src/common/espressif/esp_spi_bitbang.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_COMMON_ESPRESSIF_ESP_SPI_BITBANG_H +#define __ARCH_XTENSA_SRC_COMMON_ESPRESSIF_ESP_SPI_BITBANG_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_BITBANG + +#include +#include +#if defined(CONFIG_ARCH_CHIP_ESP32S3) +#include "esp32s3_gpio.h" +#elif defined(CONFIG_ARCH_CHIP_ESP32S2) +#include "esp32s2_gpio.h" +#else +#include "esp32_gpio.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_ESP32S3) +#define GPIO_WRITE(pin, value) esp32s3_gpiowrite(pin, value) +#define GPIO_READ(pin) esp32s3_gpioread(pin) +#elif defined(CONFIG_ARCH_CHIP_ESP32S2) +#define GPIO_WRITE(pin, value) esp32s2_gpiowrite(pin, value) +#define GPIO_READ(pin) esp32s2_gpioread(pin) +#else +#define GPIO_WRITE(pin, value) esp32_gpiowrite(pin, value) +#define GPIO_READ(pin) esp3_gpioread(pin) +#endif + +/* Macros needed to include/nuttx/spi/spi_bitbang.c. */ + +#define SPI_SETSCK GPIO_WRITE(CONFIG_ESPRESSIF_SPI_BITBANG_CLKPIN, true) +#define SPI_CLRSCK GPIO_WRITE(CONFIG_ESPRESSIF_SPI_BITBANG_CLKPIN, false) +#define SPI_SETMOSI GPIO_WRITE(CONFIG_ESPRESSIF_SPI_BITBANG_MOSIPIN, true) +#define SPI_CLRMOSI GPIO_WRITE(CONFIG_ESPRESSIF_SPI_BITBANG_MOSIPIN, \ + false) +#define SPI_GETMISO GPIO_READ(CONFIG_ESPRESSIF_SPI_BITBANG_MISOPIN) +#define SPI_SETCS GPIO_WRITE(CONFIG_ESPRESSIF_SPI_BITBANG_CSPIN, true) +#define SPI_CLRCS GPIO_WRITE(CONFIG_ESPRESSIF_SPI_BITBANG_CSPIN, false) + +/* Calibration value for timing loop */ + +#define SPI_BITBANG_LOOPSPERMSEC CONFIG_BOARD_LOOPSPERMSEC + +/* SPI_PERBIT_NSEC is the minimum time to transfer one bit. This determines + * the maximum frequency and is also used to calculate delays to achieve + * other SPI frequencies. + */ + +#define SPI_PERBIT_NSEC 100 + +#define ESPRESSIF_SPI_BITBANG 4 + +/**************************************************************************** + * Name: esp_spi_bitbang_init + * + * Description: + * Initialize the SPI bit-bang driver + * + * Input Parameters: + * None + * + * Returned Value: + * A non-NULL reference to the SPI driver on success + * + ****************************************************************************/ + +struct spi_dev_s *esp_spi_bitbang_init(void); + +/**************************************************************************** + * Name: esp_spi_bitbang_uninitialize + * + * Description: + * Destroy an instance of the SPI bit-bang driver. + * + * Input Parameters: + * dev - device instance, target driver to destroy. + * + ****************************************************************************/ + +void esp_spi_bitbang_uninitialize(struct spi_dev_s *dev); + +#endif /* CONFIG_ESPRESSIF_SPI_BITBANG */ + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_XTENSA_SRC_COMMON_ESPRESSIF_ESP_SPI_BITBANG_H */ diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig index 68c7a68ace9..4667553af47 100644 --- a/arch/xtensa/src/esp32/Kconfig +++ b/arch/xtensa/src/esp32/Kconfig @@ -610,6 +610,7 @@ config ESP32_SPI2 select ESP32_SPI select ESP32_GPIO_IRQ select SPI + select ESPRESSIF_SPI_PERIPH config ESP32_SPI3 bool "SPI 3" @@ -617,6 +618,7 @@ config ESP32_SPI3 select ESP32_SPI select ESP32_GPIO_IRQ select SPI + select ESPRESSIF_SPI_PERIPH config ESP32_SPIRAM bool "SPI RAM" diff --git a/arch/xtensa/src/esp32s2/Kconfig b/arch/xtensa/src/esp32s2/Kconfig index a6a257d3a74..895eeb49566 100644 --- a/arch/xtensa/src/esp32s2/Kconfig +++ b/arch/xtensa/src/esp32s2/Kconfig @@ -353,12 +353,14 @@ config ESP32S2_SPI2 default n select ESP32S2_SPI select SPI + select ESPRESSIF_SPI_PERIPH config ESP32S2_SPI3 bool "SPI 3" default n select ESP32S2_SPI select SPI + select ESPRESSIF_SPI_PERIPH config ESP32S2_SPIRAM bool "SPI RAM Support" diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig index 18b888c5dae..44b7913436b 100644 --- a/arch/xtensa/src/esp32s3/Kconfig +++ b/arch/xtensa/src/esp32s3/Kconfig @@ -615,6 +615,7 @@ config ESP32S3_SPI2 select ESP32S3_SPI select SPI select ESP32S3_GPIO_IRQ if SPI_SLAVE + select ESPRESSIF_SPI_PERIPH config ESP32S3_SPI3 bool "SPI 3" @@ -622,6 +623,7 @@ config ESP32S3_SPI3 select ESP32S3_SPI select SPI select ESP32S3_GPIO_IRQ if SPI_SLAVE + select ESPRESSIF_SPI_PERIPH config ESP32S3_DMA bool "General DMA (GDMA)" diff --git a/boards/xtensa/esp32/common/src/esp32_board_spidev.c b/boards/xtensa/esp32/common/src/esp32_board_spidev.c index 0d7a5c2f94f..2eaedad6dc7 100644 --- a/boards/xtensa/esp32/common/src/esp32_board_spidev.c +++ b/boards/xtensa/esp32/common/src/esp32_board_spidev.c @@ -30,7 +30,105 @@ #include +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH #include "esp32_spi.h" +#endif + +#ifdef CONFIG_ESPRESSIF_SPI_BITBANG +#include "espressif/esp_spi_bitbang.h" +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_bitbang_driver_init + * + * Description: + * Initialize SPI bitbang 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. + * + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_SPI_BITBANG +static int spi_bitbang_driver_init(int port) +{ + int ret; + struct spi_dev_s *spi; + + syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); + + /* Initialize SPI device */ + + spi = esp_spi_bitbang_init(); + + 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_spi_bitbang_uninitialize(spi); + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: spi_driver_init + * + * 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. + * + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH +static int spi_driver_init(int port) +{ + int ret = OK; + struct spi_dev_s *spi; + + syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); + + /* Initialize SPI device */ + + spi = esp32_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); + esp32_spibus_uninitialize(spi); + } + + return ret; +} +#endif /**************************************************************************** * Public Functions @@ -40,32 +138,64 @@ * Name: board_spidev_initialize * * Description: - * Initialize and register SPI driver for the specified SPI port. + * 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; + int ret = OK; - spiinfo("Initializing /dev/spi%d...\n", port); - - /* Initialize SPI device */ - - spi = esp32_spibus_initialize(port); - if (spi == NULL) + switch (port) { - spierr("Failed to initialize SPI%d.\n", port); - return -ENODEV; - } +#ifdef CONFIG_ESP32_SPI2 + case ESP32_SPI2: + { + ret = spi_driver_init(ESP32_SPI2); + if (ret != OK) + { + return ret; + } + break; + } +#endif - ret = spi_register(spi, port); - if (ret < 0) - { - spierr("Failed to register /dev/spi%d: %d\n", port, ret); +#ifdef CONFIG_ESP32_SPI3 + case ESP32_SPI3: + { + ret = spi_driver_init(ESP32_SPI3); + if (ret != OK) + { + return ret; + } + break; + } +#endif - esp32_spibus_uninitialize(spi); +#ifdef CONFIG_ESPRESSIF_SPI_BITBANG + case ESPRESSIF_SPI_BITBANG: + { + ret = spi_bitbang_driver_init(ESPRESSIF_SPI_BITBANG); + if (ret != OK) + { + return ret; + } + break; + } +#endif + + default: + { + wderr("ERROR: unsupported SPI %d\n", port); + return ERROR; + } } return ret; diff --git a/boards/xtensa/esp32s2/common/src/esp32s2_board_spidev.c b/boards/xtensa/esp32s2/common/src/esp32s2_board_spidev.c index 5bec3c86b26..b1af0e06c98 100644 --- a/boards/xtensa/esp32s2/common/src/esp32s2_board_spidev.c +++ b/boards/xtensa/esp32s2/common/src/esp32s2_board_spidev.c @@ -30,10 +30,108 @@ #include +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH #include "esp32s2_spi.h" +#endif + +#ifdef CONFIG_ESPRESSIF_SPI_BITBANG +#include "espressif/esp_spi_bitbang.h" +#endif #include "esp32s2_board_spidev.h" +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_bitbang_driver_init + * + * Description: + * Initialize SPI bitbang 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. + * + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_SPI_BITBANG +static int spi_bitbang_driver_init(int port) +{ + int ret; + struct spi_dev_s *spi; + + syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); + + /* Initialize SPI device */ + + spi = esp_spi_bitbang_init(); + + 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_spi_bitbang_uninitialize(spi); + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: spi_driver_init + * + * 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. + * + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH +static int spi_driver_init(int port) +{ + int ret = OK; + struct spi_dev_s *spi; + + syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); + + /* Initialize SPI device */ + + spi = esp32s2_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); + esp32s2_spibus_uninitialize(spi); + } + + return ret; +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -55,26 +153,51 @@ int board_spidev_initialize(int port) { - int ret; - struct spi_dev_s *spi; + int ret = OK; - syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); - - /* Initialize SPI device */ - - spi = esp32s2_spibus_initialize(port); - if (spi == NULL) + switch (port) { - syslog(LOG_ERR, "Failed to initialize SPI%d.\n", port); - return -ENODEV; - } +#ifdef CONFIG_ESP32S2_SPI2 + case ESP32S2_SPI2: + { + ret = spi_driver_init(ESP32S2_SPI2); + if (ret != OK) + { + return ret; + } + break; + } +#endif - ret = spi_register(spi, port); - if (ret < 0) - { - syslog(LOG_ERR, "Failed to register /dev/spi%d: %d\n", port, ret); +#ifdef CONFIG_ESP32S2_SPI3 + case ESP32S2_SPI3: + { + ret = spi_driver_init(ESP32S2_SPI3); + if (ret != OK) + { + return ret; + } + break; + } +#endif - esp32s2_spibus_uninitialize(spi); +#ifdef CONFIG_ESPRESSIF_SPI_BITBANG + case ESPRESSIF_SPI_BITBANG: + { + ret = spi_bitbang_driver_init(ESPRESSIF_SPI_BITBANG); + if (ret != OK) + { + return ret; + } + break; + } +#endif + + default: + { + wderr("ERROR: unsupported SPI %d\n", port); + return ERROR; + } } return ret; diff --git a/boards/xtensa/esp32s3/common/src/esp32s3_board_spidev.c b/boards/xtensa/esp32s3/common/src/esp32s3_board_spidev.c index c5d391e9be4..9511492f65e 100644 --- a/boards/xtensa/esp32s3/common/src/esp32s3_board_spidev.c +++ b/boards/xtensa/esp32s3/common/src/esp32s3_board_spidev.c @@ -30,7 +30,105 @@ #include +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH #include "esp32s3_spi.h" +#endif + +#ifdef CONFIG_ESPRESSIF_SPI_BITBANG +#include "espressif/esp_spi_bitbang.h" +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_bitbang_driver_init + * + * Description: + * Initialize SPI bitbang 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. + * + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_SPI_BITBANG +static int spi_bitbang_driver_init(int port) +{ + int ret; + struct spi_dev_s *spi; + + syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); + + /* Initialize SPI device */ + + spi = esp_spi_bitbang_init(); + + 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_spi_bitbang_uninitialize(spi); + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: spi_driver_init + * + * 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. + * + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH +static int spi_driver_init(int port) +{ + int ret = OK; + struct spi_dev_s *spi; + + syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); + + /* Initialize SPI device */ + + spi = esp32s3_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); + esp32s3_spibus_uninitialize(spi); + } + + return ret; +} +#endif /**************************************************************************** * Public Functions @@ -53,26 +151,51 @@ int board_spidev_initialize(int port) { - int ret; - struct spi_dev_s *spi; + int ret = OK; - spiinfo("Initializing /dev/spi%d...\n", port); - - /* Initialize SPI device */ - - spi = esp32s3_spibus_initialize(port); - if (spi == NULL) + switch (port) { - spierr("Failed to initialize SPI%d.\n", port); - return -ENODEV; - } +#ifdef CONFIG_ESP32S3_SPI2 + case ESP32S3_SPI2: + { + ret = spi_driver_init(ESP32S3_SPI2); + if (ret != OK) + { + return ret; + } + break; + } +#endif - ret = spi_register(spi, port); - if (ret < 0) - { - spierr("Failed to register /dev/spi%d: %d\n", port, ret); +#ifdef CONFIG_ESP32S3_SPI3 + case ESP32S3_SPI3: + { + ret = spi_driver_init(ESP32S3_SPI3); + if (ret != OK) + { + return ret; + } + break; + } +#endif - esp32s3_spibus_uninitialize(spi); +#ifdef CONFIG_ESPRESSIF_SPI_BITBANG + case ESPRESSIF_SPI_BITBANG: + { + ret = spi_bitbang_driver_init(ESPRESSIF_SPI_BITBANG); + if (ret != OK) + { + return ret; + } + break; + } +#endif + + default: + { + wderr("ERROR: unsupported SPI %d\n", port); + return ERROR; + } } return ret; diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3_bringup.c b/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3_bringup.c index 8718a875db1..e5afb34c696 100644 --- a/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3_bringup.c +++ b/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3_bringup.c @@ -107,6 +107,9 @@ #ifdef CONFIG_ESP32S3_SPI #include "esp32s3_spi.h" #include "esp32s3_board_spidev.h" +# ifdef CONFIG_ESPRESSIF_SPI_BITBANG +# include "espressif/esp_spi_bitbang.h" +# endif #endif #ifdef CONFIG_ESP32S3_SDMMC @@ -179,7 +182,15 @@ int esp32s3_bringup(void) syslog(LOG_ERR, "ERROR: Failed to init spidev 3: %d\n", ret); } #endif -#endif + + #ifdef CONFIG_ESPRESSIF_SPI_BITBANG + ret = board_spidev_initialize(ESPRESSIF_SPI_BITBANG); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to init spidev 3: %d\n", ret); + } + #endif /* CONFIG_ESPRESSIF_SPI_BITBANG */ +#endif /* CONFIG_ESP32S3_SPI && CONFIG_SPI_DRIVER*/ #if defined(CONFIG_ESP32S3_EFUSE) ret = esp32s3_efuse_initialize("/dev/efuse");