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 4f74029fe8b..c4685a347b0 100644 --- a/Documentation/platforms/risc-v/esp32c3/boards/esp32c3-generic/index.rst +++ b/Documentation/platforms/risc-v/esp32c3/boards/esp32c3-generic/index.rst @@ -248,6 +248,10 @@ by default to each other and running the ``spi`` example:: Sending: AB Received: AB +If SPI peripherals are already in use you can also use bitbang driver which is a +software implemented SPI peripheral by enabling `CONFIG_ESPRESSIF_SPI_BITBANG` +option. + spiflash -------- 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 c809f71bd37..da2233c17b1 100644 --- a/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/index.rst +++ b/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/index.rst @@ -260,6 +260,10 @@ by default to each other and running the ``spi`` example:: Sending: AB Received: AB +If SPI peripherals are already in use you can also use bitbang driver which is a +software implemented SPI peripheral by enabling `CONFIG_ESPRESSIF_SPI_BITBANG` +option. + 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 1a71ac55664..700991a75b3 100644 --- a/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitm/index.rst +++ b/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitm/index.rst @@ -222,6 +222,10 @@ by default to each other and running the ``spi`` example:: Sending: AB Received: AB +If SPI peripherals are already in use you can also use bitbang driver which is a +software implemented SPI peripheral by enabling `CONFIG_ESPRESSIF_SPI_BITBANG` +option. + spiflash -------- 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 cafb97bcd7c..604b87e81a2 100644 --- a/Documentation/platforms/risc-v/esp32h2/boards/esp32h2-devkit/index.rst +++ b/Documentation/platforms/risc-v/esp32h2/boards/esp32h2-devkit/index.rst @@ -221,6 +221,10 @@ by default to each other and running the ``spi`` example:: Sending: AB Received: AB +If SPI peripherals are already in use you can also use bitbang driver which is a +software implemented SPI peripheral by enabling `CONFIG_ESPRESSIF_SPI_BITBANG` +option. + spiflash -------- diff --git a/arch/risc-v/src/common/espressif/Kconfig b/arch/risc-v/src/common/espressif/Kconfig index a1d067b1118..c8d55964bf3 100644 --- a/arch/risc-v/src/common/espressif/Kconfig +++ b/arch/risc-v/src/common/espressif/Kconfig @@ -354,11 +354,26 @@ config ESPRESSIF_SPI bool default n +config ESPRESSIF_SPI_PERIPH + bool + depends on ESPRESSIF_SPI2 + default n + config ESPRESSIF_SPI2 bool "SPI 2" default n select ESPRESSIF_SPI select SPI + select ESPRESSIF_SPI_PERIPH + +config ESPRESSIF_SPI_BITBANG + bool "SPI Bitbang" + default n + select ESPRESSIF_SPI + select SPI + select SPI_BITBANG + ---help--- + Software implemented SPI peripheral with GPIOs. Suggested to use if SPI peripheral is already in use. config ESPRESSIF_SPIFLASH bool "SPI Flash" @@ -1167,6 +1182,7 @@ menu "SPI configuration" config ESPRESSIF_SPI_SWCS bool "SPI software CS" + depends on ESPRESSIF_SPI_PERIPH default n ---help--- Use SPI software CS. @@ -1175,6 +1191,7 @@ config ESPRESSIF_SPI_UDCS bool "User defined CS" default n depends on ESPRESSIF_SPI_SWCS + depends on ESPRESSIF_SPI_PERIPH ---help--- Use user-defined CS. @@ -1245,10 +1262,53 @@ config ESPRESSIF_SPI2_MISOPIN endif # ESPRESSIF_SPI2 +if 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 + +endif # ESPRESSIF_SPI_BITBANG + config ESPRESSIF_SPI_TEST_MODE bool "SPI driver loopback test mode (for testing only)" default n depends on SYSTEM_SPITOOL + depends on ESPRESSIF_SPI_PERIPH ---help--- This enables a loopback test mode that attaches the transmitter to the receiver internally, being able to test the SPI diff --git a/arch/risc-v/src/common/espressif/Make.defs b/arch/risc-v/src/common/espressif/Make.defs index 8e0791cc395..c608fdfda31 100644 --- a/arch/risc-v/src/common/espressif/Make.defs +++ b/arch/risc-v/src/common/espressif/Make.defs @@ -108,10 +108,15 @@ ifeq ($(CONFIG_ESPRESSIF_I2C),y) endif ifeq ($(CONFIG_ESPRESSIF_SPI),y) - CHIP_CSRCS += esp_spi.c + ifeq ($(CONFIG_ESPRESSIF_SPI_PERIPH),y) + CHIP_CSRCS += esp_spi.c + endif ifeq ($(CONFIG_SPI_SLAVE),y) CHIP_CSRCS += esp_spi_slave.c endif + ifeq ($(CONFIG_ESPRESSIF_SPI_BITBANG),y) + CHIP_CSRCS += esp_spi_bitbang.c + endif endif ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y) diff --git a/arch/risc-v/src/common/espressif/esp_spi.c b/arch/risc-v/src/common/espressif/esp_spi.c index 5113c30deae..0884c19c2a4 100644 --- a/arch/risc-v/src/common/espressif/esp_spi.c +++ b/arch/risc-v/src/common/espressif/esp_spi.c @@ -24,7 +24,7 @@ #include -#ifdef CONFIG_ESPRESSIF_SPI +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH #include #include @@ -1283,4 +1283,4 @@ int esp_spibus_uninitialize(struct spi_dev_s *dev) return OK; } -#endif /* CONFIG_ESPRESSIF_SPI */ +#endif /* CONFIG_ESPRESSIF_SPI_PERIPH */ diff --git a/arch/risc-v/src/common/espressif/esp_spi.h b/arch/risc-v/src/common/espressif/esp_spi.h index 5979f7e2dcc..9d53befe64f 100644 --- a/arch/risc-v/src/common/espressif/esp_spi.h +++ b/arch/risc-v/src/common/espressif/esp_spi.h @@ -42,13 +42,11 @@ extern "C" #define EXTERN extern #endif -#ifdef CONFIG_ESPRESSIF_SPI +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH #include -#ifdef CONFIG_ESPRESSIF_SPI2 -# define ESPRESSIF_SPI2 2 -#endif +#define ESPRESSIF_SPI2 2 /**************************************************************************** * Public Function Prototypes @@ -159,7 +157,7 @@ struct spi_slave_ctrlr_s *esp_spislave_ctrlr_initialize(int port); int esp_spislave_ctrlr_uninitialize(struct spi_slave_ctrlr_s *ctrlr); -#endif /* CONFIG_ESPRESSIF_SPI */ +#endif /* CONFIG_ESPRESSIF_SPI_PERIPH */ #ifdef __cplusplus } diff --git a/arch/risc-v/src/common/espressif/esp_spi_bitbang.c b/arch/risc-v/src/common/espressif/esp_spi_bitbang.c new file mode 100644 index 00000000000..45928d9d189 --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_spi_bitbang.c @@ -0,0 +1,251 @@ +/**************************************************************************** + * arch/risc-v/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 "riscv_internal.h" +#include "espressif/esp_gpio.h" +#include "soc/gpio_sig_map.h" +#include "esp_spi_bitbang.h" +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#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 */ + + esp_gpiowrite(CONFIG_ESPRESSIF_SPI_BITBANG_CSPIN, true); + esp_gpiowrite(CONFIG_ESPRESSIF_SPI_BITBANG_MOSIPIN, true); + esp_gpiowrite(CONFIG_ESPRESSIF_SPI_BITBANG_CLKPIN, true); + +#if CONFIG_ESPRESSIF_SPI_SWCS + esp_configgpio(CONFIG_ESPRESSIF_SPI_BITBANG_CSPIN, OUTPUT_FUNCTION_1); + esp_gpio_matrix_out(CONFIG_ESPRESSIF_SPI_BITBANG_CSPIN, SIG_GPIO_OUT_IDX, + 0, 0); +#endif + esp_configgpio(CONFIG_ESPRESSIF_SPI_BITBANG_MOSIPIN, OUTPUT_FUNCTION_1); + esp_gpio_matrix_out(CONFIG_ESPRESSIF_SPI_BITBANG_MOSIPIN, SIG_GPIO_OUT_IDX, + 0, 0); + + esp_configgpio(CONFIG_ESPRESSIF_SPI_BITBANG_MISOPIN, + INPUT_FUNCTION_1 | PULLUP); + esp_gpio_matrix_out(CONFIG_ESPRESSIF_SPI_BITBANG_MISOPIN, SIG_GPIO_OUT_IDX, + 0, 0); + + esp_configgpio(CONFIG_ESPRESSIF_SPI_BITBANG_CLKPIN, OUTPUT_FUNCTION_1); + esp_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/risc-v/src/common/espressif/esp_spi_bitbang.h b/arch/risc-v/src/common/espressif/esp_spi_bitbang.h new file mode 100644 index 00000000000..3afa6b3cc17 --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_spi_bitbang.h @@ -0,0 +1,116 @@ +/**************************************************************************** + * arch/risc-v/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_RISCV_SRC_COMMON_ESPRESSIF_ESP_SPI_BITBANG_H +#define __ARCH_RISCV_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 +#include "espressif/esp_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Macros needed to include/nuttx/spi/spi_bitbang.c. */ + +#define SPI_SETSCK esp_gpiowrite(CONFIG_ESPRESSIF_SPI_BITBANG_CLKPIN, true) +#define SPI_CLRSCK esp_gpiowrite(CONFIG_ESPRESSIF_SPI_BITBANG_CLKPIN, false) +#define SPI_SETMOSI esp_gpiowrite(CONFIG_ESPRESSIF_SPI_BITBANG_MOSIPIN, true) +#define SPI_CLRMOSI esp_gpiowrite(CONFIG_ESPRESSIF_SPI_BITBANG_MOSIPIN, \ + false) +#define SPI_GETMISO esp_gpioread(CONFIG_ESPRESSIF_SPI_BITBANG_MISOPIN) +#define SPI_SETCS esp_gpiowrite(CONFIG_ESPRESSIF_SPI_BITBANG_CSPIN, true) +#define SPI_CLRCS esp_gpiowrite(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 3 + +/**************************************************************************** + * 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_RISCV_SRC_COMMON_ESPRESSIF_ESP_SPI_BITBANG_H */ diff --git a/boards/risc-v/esp32c3/common/src/esp_board_spidev.c b/boards/risc-v/esp32c3/common/src/esp_board_spidev.c index 01a47105e2f..dec6739bc2f 100644 --- a/boards/risc-v/esp32c3/common/src/esp_board_spidev.c +++ b/boards/risc-v/esp32c3/common/src/esp_board_spidev.c @@ -30,16 +30,65 @@ #include +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH #include "espressif/esp_spi.h" +#endif +#ifdef CONFIG_ESPRESSIF_SPI_BITBANG +#include "espressif/esp_spi_bitbang.h" +#endif #include "esp_board_spidev.h" /**************************************************************************** - * Public Functions + * Private Functions ****************************************************************************/ /**************************************************************************** - * Name: board_spidev_initialize + * 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. @@ -53,9 +102,10 @@ * ****************************************************************************/ -int board_spidev_initialize(int port) +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH +static int spi_driver_init(int port) { - int ret; + int ret = OK; struct spi_dev_s *spi; syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); @@ -63,6 +113,7 @@ int board_spidev_initialize(int port) /* Initialize SPI device */ spi = esp_spibus_initialize(port); + if (spi == NULL) { syslog(LOG_ERR, "Failed to initialize SPI%d.\n", port); @@ -73,9 +124,68 @@ int board_spidev_initialize(int port) if (ret < 0) { syslog(LOG_ERR, "Failed to register /dev/spi%d: %d\n", port, ret); - esp_spibus_uninitialize(spi); } return ret; } +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_spidev_initialize + * + * Description: + * Configure the SPI drivers. + * + * 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 = OK; + + switch (port) + { +#ifdef CONFIG_ESPRESSIF_SPI2 + case ESPRESSIF_SPI2: + { + ret = spi_driver_init(ESPRESSIF_SPI2); + if (ret != OK) + { + return ret; + } + break; + } +#endif + +#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/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c b/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c index 134427f3b00..46149ee1f8d 100644 --- a/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c +++ b/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c @@ -70,6 +70,9 @@ #ifdef CONFIG_ESPRESSIF_SPI # include "espressif/esp_spi.h" # include "esp_board_spidev.h" +# ifdef CONFIG_ESPRESSIF_SPI_BITBANG +# include "espressif/esp_spi_bitbang.h" +# endif #endif #ifdef CONFIG_ESPRESSIF_TEMP @@ -197,12 +200,22 @@ int esp_bringup(void) #endif #if defined(CONFIG_ESPRESSIF_SPI) && defined(CONFIG_SPI_DRIVER) +# ifdef CONFIG_ESPRESSIF_SPI2 ret = board_spidev_initialize(ESPRESSIF_SPI2); if (ret < 0) { syslog(LOG_ERR, "ERROR: Failed to init spidev 2: %d\n", ret); } -#endif +# endif /* CONFIG_ESPRESSIF_SPI2 */ + +# 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_ESPRESSIF_SPI && CONFIG_SPI_DRIVER*/ #ifdef CONFIG_ESPRESSIF_SPIFLASH ret = board_spiflash_init(); diff --git a/boards/risc-v/esp32c6/common/src/esp_board_spidev.c b/boards/risc-v/esp32c6/common/src/esp_board_spidev.c index 040936c7fbe..17c6700977b 100644 --- a/boards/risc-v/esp32c6/common/src/esp_board_spidev.c +++ b/boards/risc-v/esp32c6/common/src/esp_board_spidev.c @@ -30,16 +30,65 @@ #include +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH #include "espressif/esp_spi.h" +#endif +#ifdef CONFIG_ESPRESSIF_SPI_BITBANG +#include "espressif/esp_spi_bitbang.h" +#endif #include "esp_board_spidev.h" /**************************************************************************** - * Public Functions + * Private Functions ****************************************************************************/ /**************************************************************************** - * Name: board_spidev_initialize + * 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. @@ -53,9 +102,10 @@ * ****************************************************************************/ -int board_spidev_initialize(int port) +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH +static int spi_driver_init(int port) { - int ret; + int ret = OK; struct spi_dev_s *spi; syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); @@ -63,6 +113,7 @@ int board_spidev_initialize(int port) /* Initialize SPI device */ spi = esp_spibus_initialize(port); + if (spi == NULL) { syslog(LOG_ERR, "Failed to initialize SPI%d.\n", port); @@ -73,9 +124,68 @@ int board_spidev_initialize(int port) if (ret < 0) { syslog(LOG_ERR, "Failed to register /dev/spi%d: %d\n", port, ret); - esp_spibus_uninitialize(spi); } return ret; } +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_spidev_initialize + * + * Description: + * Configure the SPI drivers. + * + * 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 = OK; + + switch (port) + { +#ifdef CONFIG_ESPRESSIF_SPI2 + case ESPRESSIF_SPI2: + { + ret = spi_driver_init(ESPRESSIF_SPI2); + if (ret != OK) + { + return ret; + } + break; + } +#endif + +#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/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c b/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c index fc7c9fde7da..de3d8775c65 100644 --- a/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c +++ b/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c @@ -70,6 +70,9 @@ #ifdef CONFIG_ESPRESSIF_SPI # include "espressif/esp_spi.h" # include "esp_board_spidev.h" +# ifdef CONFIG_ESPRESSIF_SPI_BITBANG +# include "espressif/esp_spi_bitbang.h" +# endif #endif #ifdef CONFIG_ESPRESSIF_TEMP @@ -225,12 +228,22 @@ int esp_bringup(void) #endif #if defined(CONFIG_ESPRESSIF_SPI) && defined(CONFIG_SPI_DRIVER) +# ifdef CONFIG_ESPRESSIF_SPI2 ret = board_spidev_initialize(ESPRESSIF_SPI2); if (ret < 0) { syslog(LOG_ERR, "ERROR: Failed to init spidev 2: %d\n", ret); } -#endif +# endif /* CONFIG_ESPRESSIF_SPI2 */ + +# 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_ESPRESSIF_SPI && CONFIG_SPI_DRIVER*/ #ifdef CONFIG_ESPRESSIF_SPIFLASH ret = board_spiflash_init(); 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 630da38c59f..512127c8a6d 100644 --- a/boards/risc-v/esp32c6/esp32c6-devkitm/src/esp32c6_bringup.c +++ b/boards/risc-v/esp32c6/esp32c6-devkitm/src/esp32c6_bringup.c @@ -70,6 +70,9 @@ #ifdef CONFIG_ESPRESSIF_SPI # include "espressif/esp_spi.h" # include "esp_board_spidev.h" +# ifdef CONFIG_ESPRESSIF_SPI_BITBANG +# include "espressif/esp_spi_bitbang.h" +# endif #endif #ifdef CONFIG_ESPRESSIF_TEMP @@ -221,12 +224,22 @@ int esp_bringup(void) #endif #if defined(CONFIG_ESPRESSIF_SPI) && defined(CONFIG_SPI_DRIVER) +# ifdef CONFIG_ESPRESSIF_SPI2 ret = board_spidev_initialize(ESPRESSIF_SPI2); if (ret < 0) { syslog(LOG_ERR, "ERROR: Failed to init spidev 2: %d\n", ret); } -#endif +# endif /* CONFIG_ESPRESSIF_SPI2 */ + +# 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_ESPRESSIF_SPI && CONFIG_SPI_DRIVER*/ #ifdef CONFIG_ESPRESSIF_SPIFLASH ret = board_spiflash_init(); diff --git a/boards/risc-v/esp32h2/common/src/esp_board_spidev.c b/boards/risc-v/esp32h2/common/src/esp_board_spidev.c index 8e2e9bdb9a9..0f6396d5bf6 100644 --- a/boards/risc-v/esp32h2/common/src/esp_board_spidev.c +++ b/boards/risc-v/esp32h2/common/src/esp_board_spidev.c @@ -30,16 +30,65 @@ #include +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH #include "espressif/esp_spi.h" +#endif +#ifdef CONFIG_ESPRESSIF_SPI_BITBANG +#include "espressif/esp_spi_bitbang.h" +#endif #include "esp_board_spidev.h" /**************************************************************************** - * Public Functions + * Private Functions ****************************************************************************/ /**************************************************************************** - * Name: board_spidev_initialize + * 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. @@ -53,9 +102,10 @@ * ****************************************************************************/ -int board_spidev_initialize(int port) +#ifdef CONFIG_ESPRESSIF_SPI_PERIPH +static int spi_driver_init(int port) { - int ret; + int ret = OK; struct spi_dev_s *spi; syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); @@ -63,6 +113,7 @@ int board_spidev_initialize(int port) /* Initialize SPI device */ spi = esp_spibus_initialize(port); + if (spi == NULL) { syslog(LOG_ERR, "Failed to initialize SPI%d.\n", port); @@ -73,9 +124,68 @@ int board_spidev_initialize(int port) if (ret < 0) { syslog(LOG_ERR, "Failed to register /dev/spi%d: %d\n", port, ret); - esp_spibus_uninitialize(spi); } return ret; } +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_spidev_initialize + * + * Description: + * Configure the SPI drivers. + * + * 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 = OK; + + switch (port) + { +#ifdef CONFIG_ESPRESSIF_SPI2 + case ESPRESSIF_SPI2: + { + ret = spi_driver_init(ESPRESSIF_SPI2); + if (ret != OK) + { + return ret; + } + break; + } +#endif + +#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/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c b/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c index f6afd1f4d6c..85d2156264a 100644 --- a/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c +++ b/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c @@ -70,6 +70,9 @@ #ifdef CONFIG_ESPRESSIF_SPI # include "espressif/esp_spi.h" # include "esp_board_spidev.h" +# ifdef CONFIG_ESPRESSIF_SPI_BITBANG +# include "espressif/esp_spi_bitbang.h" +# endif #endif #ifdef CONFIG_SPI_SLAVE_DRIVER @@ -213,12 +216,22 @@ int esp_bringup(void) #endif #if defined(CONFIG_ESPRESSIF_SPI) && defined(CONFIG_SPI_DRIVER) +# ifdef CONFIG_ESPRESSIF_SPI2 ret = board_spidev_initialize(ESPRESSIF_SPI2); if (ret < 0) { syslog(LOG_ERR, "ERROR: Failed to init spidev 2: %d\n", ret); } -#endif +# endif /* CONFIG_ESPRESSIF_SPI2 */ + +# 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_ESPRESSIF_SPI && CONFIG_SPI_DRIVER*/ #ifdef CONFIG_ESPRESSIF_SPIFLASH ret = board_spiflash_init();