esp32[s2|s3]: Add SPI bitbang support

This commit is contained in:
Eren Terzioglu
2024-10-10 15:44:35 +03:00
committed by Xiang Xiao
parent 243a2adcaf
commit 3f77e97b03
11 changed files with 912 additions and 50 deletions
+59
View File
@@ -40,6 +40,22 @@ config ESPRESSIF_I2C_BITBANG
---help--- ---help---
Software implemented I2C peripheral with GPIOs. Suggested to use if I2C peripherals are already in use. 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 config ESPRESSIF_SPIFLASH
bool "SPI Flash" bool "SPI Flash"
depends on ARCH_CHIP_ESP32S2 depends on ARCH_CHIP_ESP32S2
@@ -104,6 +120,49 @@ config ESPRESSIF_I2C_BITBANG_SDAPIN
endmenu # I2C bitbang configuration 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 config ESPRESSIF_HAVE_OTA_PARTITION
bool bool
default n default n
@@ -44,6 +44,10 @@ ifeq ($(CONFIG_ESPRESSIF_I2C_BITBANG),y)
CHIP_CSRCS += esp_i2c_bitbang.c CHIP_CSRCS += esp_i2c_bitbang.c
endif endif
ifeq ($(CONFIG_ESPRESSIF_SPI_BITBANG),y)
CHIP_CSRCS += esp_spi_bitbang.c
endif
ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y) ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y)
CHIP_CSRCS += esp_spiflash.c CHIP_CSRCS += esp_spiflash.c
ifeq ($(CONFIG_ESPRESSIF_MTD),y) ifeq ($(CONFIG_ESPRESSIF_MTD),y)
@@ -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 <nuttx/config.h>
#ifdef CONFIG_ESPRESSIF_SPI_BITBANG
#include <sys/param.h>
#include <sys/types.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/mutex.h>
#include <nuttx/kmalloc.h>
#include <nuttx/spi/spi.h>
#include <nuttx/spi/spi_bitbang.h>
#include "esp_spi_bitbang.h"
#include <nuttx/spi/spi_bitbang.c>
#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 */
@@ -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 <nuttx/config.h>
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
#ifdef CONFIG_ESPRESSIF_SPI_BITBANG
#include <nuttx/spi/spi.h>
#include <nuttx/spi/spi_bitbang.h>
#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 */
+2
View File
@@ -610,6 +610,7 @@ config ESP32_SPI2
select ESP32_SPI select ESP32_SPI
select ESP32_GPIO_IRQ select ESP32_GPIO_IRQ
select SPI select SPI
select ESPRESSIF_SPI_PERIPH
config ESP32_SPI3 config ESP32_SPI3
bool "SPI 3" bool "SPI 3"
@@ -617,6 +618,7 @@ config ESP32_SPI3
select ESP32_SPI select ESP32_SPI
select ESP32_GPIO_IRQ select ESP32_GPIO_IRQ
select SPI select SPI
select ESPRESSIF_SPI_PERIPH
config ESP32_SPIRAM config ESP32_SPIRAM
bool "SPI RAM" bool "SPI RAM"
+2
View File
@@ -353,12 +353,14 @@ config ESP32S2_SPI2
default n default n
select ESP32S2_SPI select ESP32S2_SPI
select SPI select SPI
select ESPRESSIF_SPI_PERIPH
config ESP32S2_SPI3 config ESP32S2_SPI3
bool "SPI 3" bool "SPI 3"
default n default n
select ESP32S2_SPI select ESP32S2_SPI
select SPI select SPI
select ESPRESSIF_SPI_PERIPH
config ESP32S2_SPIRAM config ESP32S2_SPIRAM
bool "SPI RAM Support" bool "SPI RAM Support"
+2
View File
@@ -615,6 +615,7 @@ config ESP32S3_SPI2
select ESP32S3_SPI select ESP32S3_SPI
select SPI select SPI
select ESP32S3_GPIO_IRQ if SPI_SLAVE select ESP32S3_GPIO_IRQ if SPI_SLAVE
select ESPRESSIF_SPI_PERIPH
config ESP32S3_SPI3 config ESP32S3_SPI3
bool "SPI 3" bool "SPI 3"
@@ -622,6 +623,7 @@ config ESP32S3_SPI3
select ESP32S3_SPI select ESP32S3_SPI
select SPI select SPI
select ESP32S3_GPIO_IRQ if SPI_SLAVE select ESP32S3_GPIO_IRQ if SPI_SLAVE
select ESPRESSIF_SPI_PERIPH
config ESP32S3_DMA config ESP32S3_DMA
bool "General DMA (GDMA)" bool "General DMA (GDMA)"
@@ -30,7 +30,105 @@
#include <nuttx/spi/spi_transfer.h> #include <nuttx/spi/spi_transfer.h>
#ifdef CONFIG_ESPRESSIF_SPI_PERIPH
#include "esp32_spi.h" #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 * Public Functions
@@ -40,32 +138,64 @@
* Name: board_spidev_initialize * Name: board_spidev_initialize
* *
* Description: * 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 board_spidev_initialize(int port)
{ {
int ret; int ret = OK;
struct spi_dev_s *spi;
spiinfo("Initializing /dev/spi%d...\n", port); switch (port)
/* Initialize SPI device */
spi = esp32_spibus_initialize(port);
if (spi == NULL)
{ {
spierr("Failed to initialize SPI%d.\n", port); #ifdef CONFIG_ESP32_SPI2
return -ENODEV; case ESP32_SPI2:
} {
ret = spi_driver_init(ESP32_SPI2);
if (ret != OK)
{
return ret;
}
break;
}
#endif
ret = spi_register(spi, port); #ifdef CONFIG_ESP32_SPI3
if (ret < 0) case ESP32_SPI3:
{ {
spierr("Failed to register /dev/spi%d: %d\n", port, ret); 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; return ret;
@@ -30,10 +30,108 @@
#include <nuttx/spi/spi_transfer.h> #include <nuttx/spi/spi_transfer.h>
#ifdef CONFIG_ESPRESSIF_SPI_PERIPH
#include "esp32s2_spi.h" #include "esp32s2_spi.h"
#endif
#ifdef CONFIG_ESPRESSIF_SPI_BITBANG
#include "espressif/esp_spi_bitbang.h"
#endif
#include "esp32s2_board_spidev.h" #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 * Public Functions
****************************************************************************/ ****************************************************************************/
@@ -55,26 +153,51 @@
int board_spidev_initialize(int port) int board_spidev_initialize(int port)
{ {
int ret; int ret = OK;
struct spi_dev_s *spi;
syslog(LOG_INFO, "Initializing /dev/spi%d...\n", port); switch (port)
/* Initialize SPI device */
spi = esp32s2_spibus_initialize(port);
if (spi == NULL)
{ {
syslog(LOG_ERR, "Failed to initialize SPI%d.\n", port); #ifdef CONFIG_ESP32S2_SPI2
return -ENODEV; case ESP32S2_SPI2:
} {
ret = spi_driver_init(ESP32S2_SPI2);
if (ret != OK)
{
return ret;
}
break;
}
#endif
ret = spi_register(spi, port); #ifdef CONFIG_ESP32S2_SPI3
if (ret < 0) case ESP32S2_SPI3:
{ {
syslog(LOG_ERR, "Failed to register /dev/spi%d: %d\n", port, ret); 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; return ret;
@@ -30,7 +30,105 @@
#include <nuttx/spi/spi_transfer.h> #include <nuttx/spi/spi_transfer.h>
#ifdef CONFIG_ESPRESSIF_SPI_PERIPH
#include "esp32s3_spi.h" #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 * Public Functions
@@ -53,26 +151,51 @@
int board_spidev_initialize(int port) int board_spidev_initialize(int port)
{ {
int ret; int ret = OK;
struct spi_dev_s *spi;
spiinfo("Initializing /dev/spi%d...\n", port); switch (port)
/* Initialize SPI device */
spi = esp32s3_spibus_initialize(port);
if (spi == NULL)
{ {
spierr("Failed to initialize SPI%d.\n", port); #ifdef CONFIG_ESP32S3_SPI2
return -ENODEV; case ESP32S3_SPI2:
} {
ret = spi_driver_init(ESP32S3_SPI2);
if (ret != OK)
{
return ret;
}
break;
}
#endif
ret = spi_register(spi, port); #ifdef CONFIG_ESP32S3_SPI3
if (ret < 0) case ESP32S3_SPI3:
{ {
spierr("Failed to register /dev/spi%d: %d\n", port, ret); 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; return ret;
@@ -107,6 +107,9 @@
#ifdef CONFIG_ESP32S3_SPI #ifdef CONFIG_ESP32S3_SPI
#include "esp32s3_spi.h" #include "esp32s3_spi.h"
#include "esp32s3_board_spidev.h" #include "esp32s3_board_spidev.h"
# ifdef CONFIG_ESPRESSIF_SPI_BITBANG
# include "espressif/esp_spi_bitbang.h"
# endif
#endif #endif
#ifdef CONFIG_ESP32S3_SDMMC #ifdef CONFIG_ESP32S3_SDMMC
@@ -179,7 +182,15 @@ int esp32s3_bringup(void)
syslog(LOG_ERR, "ERROR: Failed to init spidev 3: %d\n", ret); syslog(LOG_ERR, "ERROR: Failed to init spidev 3: %d\n", ret);
} }
#endif #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) #if defined(CONFIG_ESP32S3_EFUSE)
ret = esp32s3_efuse_initialize("/dev/efuse"); ret = esp32s3_efuse_initialize("/dev/efuse");