mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/spi_driver_support_multi_chip' into 'master'
spi: multichip support See merge request idf/esp-idf!5234
This commit is contained in:
commit
90008e3fd6
@ -21,6 +21,7 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp32/rom/lldesc.h"
|
||||
#include "soc/spi_periph.h"
|
||||
#include "hal/spi_types.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -61,15 +62,6 @@ extern "C"
|
||||
*/
|
||||
#define SPI_SWAP_DATA_RX(data, len) (__builtin_bswap32(data)>>(32-len))
|
||||
|
||||
/**
|
||||
* @brief Enum with the three SPI peripherals that are software-accessible in it
|
||||
*/
|
||||
typedef enum {
|
||||
SPI_HOST=0, ///< SPI1, SPI
|
||||
HSPI_HOST=1, ///< SPI2, HSPI
|
||||
VSPI_HOST=2 ///< SPI3, VSPI
|
||||
} spi_host_device_t;
|
||||
|
||||
/**
|
||||
* @brief This is a configuration structure for a SPI bus.
|
||||
*
|
||||
@ -167,7 +159,7 @@ bool spicommon_dma_chan_free(int dma_chan);
|
||||
|
||||
#define SPICOMMON_BUSFLAG_SLAVE 0 ///< Initialize I/O in slave mode
|
||||
#define SPICOMMON_BUSFLAG_MASTER (1<<0) ///< Initialize I/O in master mode
|
||||
#define SPICOMMON_BUSFLAG_NATIVE_PINS (1<<1) ///< Check using iomux pins. Or indicates the pins are configured through the IO mux rather than GPIO matrix.
|
||||
#define SPICOMMON_BUSFLAG_IOMUX_PINS (1<<1) ///< Check using iomux pins. Or indicates the pins are configured through the IO mux rather than GPIO matrix.
|
||||
#define SPICOMMON_BUSFLAG_SCLK (1<<2) ///< Check existing of SCLK pin. Or indicates CLK line initialized.
|
||||
#define SPICOMMON_BUSFLAG_MISO (1<<3) ///< Check existing of MISO pin. Or indicates MISO line initialized.
|
||||
#define SPICOMMON_BUSFLAG_MOSI (1<<4) ///< Check existing of MOSI pin. Or indicates CLK line initialized.
|
||||
@ -175,6 +167,9 @@ bool spicommon_dma_chan_free(int dma_chan);
|
||||
#define SPICOMMON_BUSFLAG_WPHD (1<<6) ///< Check existing of WP and HD pins. Or indicates WP & HD pins initialized.
|
||||
#define SPICOMMON_BUSFLAG_QUAD (SPICOMMON_BUSFLAG_DUAL|SPICOMMON_BUSFLAG_WPHD) ///< Check existing of MOSI/MISO/WP/HD pins as output. Or indicates bus able to work under QIO mode.
|
||||
|
||||
#define SPICOMMON_BUSFLAG_NATIVE_PINS SPICOMMON_BUSFLAG_IOMUX_PINS
|
||||
|
||||
|
||||
/**
|
||||
* @brief Connect a SPI peripheral to GPIO pins
|
||||
*
|
||||
@ -188,7 +183,7 @@ bool spicommon_dma_chan_free(int dma_chan);
|
||||
* @param flags Combination of SPICOMMON_BUSFLAG_* flags, set to ensure the pins set are capable with some functions:
|
||||
* - ``SPICOMMON_BUSFLAG_MASTER``: Initialize I/O in master mode
|
||||
* - ``SPICOMMON_BUSFLAG_SLAVE``: Initialize I/O in slave mode
|
||||
* - ``SPICOMMON_BUSFLAG_NATIVE_PINS``: Pins set should match the iomux pins of the controller.
|
||||
* - ``SPICOMMON_BUSFLAG_IOMUX_PINS``: Pins set should match the iomux pins of the controller.
|
||||
* - ``SPICOMMON_BUSFLAG_SCLK``, ``SPICOMMON_BUSFLAG_MISO``, ``SPICOMMON_BUSFLAG_MOSI``:
|
||||
* Make sure SCLK/MISO/MOSI is/are set to a valid GPIO. Also check output capability according to the mode.
|
||||
* - ``SPICOMMON_BUSFLAG_DUAL``: Make sure both MISO and MOSI are output capable so that DIO mode is capable.
|
||||
@ -196,7 +191,7 @@ bool spicommon_dma_chan_free(int dma_chan);
|
||||
* - ``SPICOMMON_BUSFLAG_QUAD``: Combination of ``SPICOMMON_BUSFLAG_DUAL`` and ``SPICOMMON_BUSFLAG_WPHD``.
|
||||
* @param[out] flags_o A SPICOMMON_BUSFLAG_* flag combination of bus abilities will be written to this address.
|
||||
* Leave to NULL if not needed.
|
||||
* - ``SPICOMMON_BUSFLAG_NATIVE_PINS``: The bus is connected to iomux pins.
|
||||
* - ``SPICOMMON_BUSFLAG_IOMUX_PINS``: The bus is connected to iomux pins.
|
||||
* - ``SPICOMMON_BUSFLAG_SCLK``, ``SPICOMMON_BUSFLAG_MISO``, ``SPICOMMON_BUSFLAG_MOSI``: The bus has
|
||||
* CLK/MISO/MOSI connected.
|
||||
* - ``SPICOMMON_BUSFLAG_DUAL``: The bus is capable with DIO mode.
|
||||
@ -294,6 +289,15 @@ spi_dev_t *spicommon_hw_for_host(spi_host_device_t host);
|
||||
*/
|
||||
int spicommon_irqsource_for_host(spi_host_device_t host);
|
||||
|
||||
/**
|
||||
* @brief Get the IRQ source for a specific SPI DMA
|
||||
*
|
||||
* @param host The SPI host
|
||||
*
|
||||
* @return The hosts IRQ source
|
||||
*/
|
||||
int spicommon_irqdma_source_for_host(spi_host_device_t host);
|
||||
|
||||
/**
|
||||
* Callback, to be called when a DMA engine reset is completed
|
||||
*/
|
||||
|
@ -1,9 +1,9 @@
|
||||
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed 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
|
||||
@ -49,14 +49,13 @@ static const char *SPI_TAG = "spi";
|
||||
|
||||
typedef struct spi_device_t spi_device_t;
|
||||
|
||||
#define FUNC_SPI 1 //all pins of HSPI and VSPI shares this function number
|
||||
#define FUNC_GPIO PIN_FUNC_GPIO
|
||||
|
||||
|
||||
#define DMA_CHANNEL_ENABLED(dma_chan) (BIT(dma_chan-1))
|
||||
|
||||
//Periph 1 is 'claimed' by SPI flash code.
|
||||
static atomic_bool spi_periph_claimed[3] = { ATOMIC_VAR_INIT(true), ATOMIC_VAR_INIT(false), ATOMIC_VAR_INIT(false)};
|
||||
static atomic_bool spi_periph_claimed[SOC_SPI_PERIPH_NUM] = { ATOMIC_VAR_INIT(true), ATOMIC_VAR_INIT(false), ATOMIC_VAR_INIT(false),
|
||||
};
|
||||
static const char* spi_claiming_func[3] = {NULL, NULL, NULL};
|
||||
static uint8_t spi_dma_chan_enabled = 0;
|
||||
static portMUX_TYPE spi_dma_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
@ -96,15 +95,25 @@ int spicommon_irqsource_for_host(spi_host_device_t host)
|
||||
return spi_periph_signal[host].irq;
|
||||
}
|
||||
|
||||
int spicommon_irqdma_source_for_host(spi_host_device_t host)
|
||||
{
|
||||
return spi_periph_signal[host].irq_dma;
|
||||
}
|
||||
|
||||
spi_dev_t *spicommon_hw_for_host(spi_host_device_t host)
|
||||
{
|
||||
return spi_periph_signal[host].hw;
|
||||
}
|
||||
|
||||
static inline uint32_t get_dma_periph(int dma_chan)
|
||||
{
|
||||
return PERIPH_SPI_DMA_MODULE;
|
||||
}
|
||||
|
||||
bool spicommon_dma_chan_claim (int dma_chan)
|
||||
{
|
||||
bool ret = false;
|
||||
assert( dma_chan == 1 || dma_chan == 2 );
|
||||
assert(dma_chan >= 1 && dma_chan <= SOC_SPI_DMA_CHAN_NUM);
|
||||
|
||||
portENTER_CRITICAL(&spi_dma_spinlock);
|
||||
if ( !(spi_dma_chan_enabled & DMA_CHANNEL_ENABLED(dma_chan)) ) {
|
||||
@ -112,7 +121,7 @@ bool spicommon_dma_chan_claim (int dma_chan)
|
||||
spi_dma_chan_enabled |= DMA_CHANNEL_ENABLED(dma_chan);
|
||||
ret = true;
|
||||
}
|
||||
periph_module_enable( PERIPH_SPI_DMA_MODULE );
|
||||
periph_module_enable(get_dma_periph(dma_chan));
|
||||
portEXIT_CRITICAL(&spi_dma_spinlock);
|
||||
|
||||
return ret;
|
||||
@ -133,7 +142,7 @@ bool spicommon_dma_chan_free(int dma_chan)
|
||||
spi_dma_chan_enabled &= ~DMA_CHANNEL_ENABLED(dma_chan);
|
||||
if ( spi_dma_chan_enabled == 0 ) {
|
||||
//disable the DMA only when all the channels are freed.
|
||||
periph_module_disable( PERIPH_SPI_DMA_MODULE );
|
||||
periph_module_disable(get_dma_periph(dma_chan));
|
||||
}
|
||||
portEXIT_CRITICAL(&spi_dma_spinlock);
|
||||
|
||||
@ -212,7 +221,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
||||
|
||||
//check if the selected pins correspond to the iomux pins of the peripheral
|
||||
bool use_iomux = bus_uses_iomux_pins(host, bus_config);
|
||||
if (use_iomux) temp_flag |= SPICOMMON_BUSFLAG_NATIVE_PINS;
|
||||
if (use_iomux) temp_flag |= SPICOMMON_BUSFLAG_IOMUX_PINS;
|
||||
|
||||
uint32_t missing_flag = flags & ~temp_flag;
|
||||
missing_flag &= ~SPICOMMON_BUSFLAG_MASTER;//don't check this flag
|
||||
@ -224,7 +233,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
||||
if (missing_flag & SPICOMMON_BUSFLAG_MISO) ESP_LOGE(SPI_TAG, "miso pin required.");
|
||||
if (missing_flag & SPICOMMON_BUSFLAG_DUAL) ESP_LOGE(SPI_TAG, "not both mosi and miso output capable");
|
||||
if (missing_flag & SPICOMMON_BUSFLAG_WPHD) ESP_LOGE(SPI_TAG, "both wp and hd required.");
|
||||
if (missing_flag & SPICOMMON_BUSFLAG_NATIVE_PINS) ESP_LOGE(SPI_TAG, "not using iomux pins");
|
||||
if (missing_flag & SPICOMMON_BUSFLAG_IOMUX_PINS) ESP_LOGE(SPI_TAG, "not using iomux pins");
|
||||
SPI_CHECK(missing_flag == 0, "not all required capabilities satisfied.", ESP_ERR_INVALID_ARG);
|
||||
}
|
||||
|
||||
@ -234,25 +243,25 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
||||
ESP_LOGD(SPI_TAG, "SPI%d use iomux pins.", host+1);
|
||||
if (bus_config->mosi_io_num >= 0) {
|
||||
gpio_iomux_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in);
|
||||
gpio_iomux_out(bus_config->mosi_io_num, FUNC_SPI, false);
|
||||
gpio_iomux_out(bus_config->mosi_io_num, spi_periph_signal[host].func, false);
|
||||
}
|
||||
if (bus_config->miso_io_num >= 0) {
|
||||
gpio_iomux_in(bus_config->miso_io_num, spi_periph_signal[host].spiq_in);
|
||||
gpio_iomux_out(bus_config->miso_io_num, FUNC_SPI, false);
|
||||
gpio_iomux_out(bus_config->miso_io_num, spi_periph_signal[host].func, false);
|
||||
}
|
||||
if (bus_config->quadwp_io_num >= 0) {
|
||||
gpio_iomux_in(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in);
|
||||
gpio_iomux_out(bus_config->quadwp_io_num, FUNC_SPI, false);
|
||||
gpio_iomux_out(bus_config->quadwp_io_num, spi_periph_signal[host].func, false);
|
||||
}
|
||||
if (bus_config->quadhd_io_num >= 0) {
|
||||
gpio_iomux_in(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in);
|
||||
gpio_iomux_out(bus_config->quadhd_io_num, FUNC_SPI, false);
|
||||
gpio_iomux_out(bus_config->quadhd_io_num, spi_periph_signal[host].func, false);
|
||||
}
|
||||
if (bus_config->sclk_io_num >= 0) {
|
||||
gpio_iomux_in(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in);
|
||||
gpio_iomux_out(bus_config->sclk_io_num, FUNC_SPI, false);
|
||||
gpio_iomux_out(bus_config->sclk_io_num, spi_periph_signal[host].func, false);
|
||||
}
|
||||
temp_flag |= SPICOMMON_BUSFLAG_NATIVE_PINS;
|
||||
temp_flag |= SPICOMMON_BUSFLAG_IOMUX_PINS;
|
||||
} else {
|
||||
//Use GPIO matrix
|
||||
ESP_LOGD(SPI_TAG, "SPI%d use gpio matrix.", host+1);
|
||||
@ -354,7 +363,7 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num,
|
||||
if (!force_gpio_matrix && cs_io_num == spi_periph_signal[host].spics0_iomux_pin && cs_num == 0) {
|
||||
//The cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define.
|
||||
gpio_iomux_in(cs_io_num, spi_periph_signal[host].spics_in);
|
||||
gpio_iomux_out(cs_io_num, FUNC_SPI, false);
|
||||
gpio_iomux_out(cs_io_num, spi_periph_signal[host].func, false);
|
||||
} else {
|
||||
//Use GPIO matrix
|
||||
if (GPIO_IS_VALID_OUTPUT_GPIO(cs_io_num)) {
|
||||
|
@ -199,7 +199,7 @@ struct spi_device_t {
|
||||
bool waiting; //the device is waiting for the exclusive control of the bus
|
||||
};
|
||||
|
||||
static spi_host_t *spihost[3];
|
||||
static spi_host_t *spihost[SOC_SPI_PERIPH_NUM];
|
||||
|
||||
|
||||
static const char *SPI_TAG = "spi_master";
|
||||
@ -263,7 +263,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
|
||||
int dma_desc_ct=0;
|
||||
spihost[host]->dma_chan=dma_chan;
|
||||
if (dma_chan == 0) {
|
||||
spihost[host]->max_transfer_sz = 64;
|
||||
spihost[host]->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE;
|
||||
} else {
|
||||
//See how many dma descriptors we need and allocate them
|
||||
dma_desc_ct=lldesc_get_required_num(bus_config->max_transfer_sz);
|
||||
@ -389,13 +389,15 @@ esp_err_t spi_bus_add_device(spi_host_device_t host, const spi_device_interface_
|
||||
int freq;
|
||||
spi_hal_context_t *hal = &spihost[host]->hal;
|
||||
hal->half_duplex = dev_config->flags & SPI_DEVICE_HALFDUPLEX ? 1 : 0;
|
||||
#ifdef SOC_SPI_SUPPORT_AS_CS
|
||||
hal->as_cs = dev_config->flags & SPI_DEVICE_CLK_AS_CS ? 1 : 0;
|
||||
#endif
|
||||
hal->positive_cs = dev_config->flags & SPI_DEVICE_POSITIVE_CS ? 1 : 0;
|
||||
hal->no_compensate = dev_config->flags & SPI_DEVICE_NO_DUMMY ? 1 : 0;
|
||||
|
||||
spi_hal_timing_conf_t temp_timing_conf;
|
||||
esp_err_t ret = spi_hal_get_clock_conf(hal, dev_config->clock_speed_hz, duty_cycle,
|
||||
!(spihost[host]->flags & SPICOMMON_BUSFLAG_NATIVE_PINS),
|
||||
!(spihost[host]->flags & SPICOMMON_BUSFLAG_IOMUX_PINS),
|
||||
dev_config->input_delay_ns, &freq,
|
||||
&temp_timing_conf);
|
||||
|
||||
@ -427,7 +429,7 @@ esp_err_t spi_bus_add_device(spi_host_device_t host, const spi_device_interface_
|
||||
|
||||
//Set CS pin, CS options
|
||||
if (dev_config->spics_io_num >= 0) {
|
||||
spicommon_cs_initialize(host, dev_config->spics_io_num, freecs, !(spihost[host]->flags&SPICOMMON_BUSFLAG_NATIVE_PINS));
|
||||
spicommon_cs_initialize(host, dev_config->spics_io_num, freecs, !(spihost[host]->flags&SPICOMMON_BUSFLAG_IOMUX_PINS));
|
||||
}
|
||||
|
||||
*handle=dev;
|
||||
|
@ -72,13 +72,13 @@ typedef struct {
|
||||
#endif
|
||||
} spi_slave_t;
|
||||
|
||||
static spi_slave_t *spihost[3];
|
||||
static spi_slave_t *spihost[SOC_SPI_PERIPH_NUM];
|
||||
|
||||
static void IRAM_ATTR spi_intr(void *arg);
|
||||
|
||||
static inline bool bus_is_iomux(spi_slave_t *host)
|
||||
{
|
||||
return host->flags&SPICOMMON_BUSFLAG_NATIVE_PINS;
|
||||
return host->flags&SPICOMMON_BUSFLAG_IOMUX_PINS;
|
||||
}
|
||||
|
||||
static void freeze_cs(spi_slave_t *host)
|
||||
@ -149,7 +149,7 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
|
||||
spihost[host]->max_transfer_sz = dma_desc_ct * SPI_MAX_DMA_LEN;
|
||||
} else {
|
||||
//We're limited to non-DMA transfers: the SPI work registers can hold 64 bytes at most.
|
||||
spihost[host]->max_transfer_sz = 16 * 4;
|
||||
spihost[host]->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE;
|
||||
}
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "spi_slave",
|
||||
|
@ -329,7 +329,7 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
|
||||
uint32_t flags_expected;
|
||||
|
||||
ESP_LOGI(TAG, "test 6 iomux output pins...");
|
||||
flags_expected = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_NATIVE_PINS | SPICOMMON_BUSFLAG_QUAD;
|
||||
flags_expected = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_IOMUX_PINS | SPICOMMON_BUSFLAG_QUAD;
|
||||
cfg = (spi_bus_config_t){.mosi_io_num = HSPI_IOMUX_PIN_NUM_MOSI, .miso_io_num = HSPI_IOMUX_PIN_NUM_MISO, .sclk_io_num = HSPI_IOMUX_PIN_NUM_CLK, .quadhd_io_num = HSPI_IOMUX_PIN_NUM_HD, .quadwp_io_num = HSPI_IOMUX_PIN_NUM_WP,
|
||||
.max_transfer_sz = 8, .flags = flags_expected};
|
||||
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, 0, flags_expected|SPICOMMON_BUSFLAG_MASTER, &flags_o));
|
||||
@ -338,7 +338,7 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
|
||||
TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
|
||||
|
||||
ESP_LOGI(TAG, "test 4 iomux output pins...");
|
||||
flags_expected = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_NATIVE_PINS | SPICOMMON_BUSFLAG_DUAL;
|
||||
flags_expected = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_IOMUX_PINS | SPICOMMON_BUSFLAG_DUAL;
|
||||
cfg = (spi_bus_config_t){.mosi_io_num = HSPI_IOMUX_PIN_NUM_MOSI, .miso_io_num = HSPI_IOMUX_PIN_NUM_MISO, .sclk_io_num = HSPI_IOMUX_PIN_NUM_CLK, .quadhd_io_num = -1, .quadwp_io_num = -1,
|
||||
.max_transfer_sz = 8, .flags = flags_expected};
|
||||
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, 0, flags_expected|SPICOMMON_BUSFLAG_MASTER, &flags_o));
|
||||
@ -396,7 +396,7 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
|
||||
TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
|
||||
|
||||
ESP_LOGI(TAG, "check native flag for 6 output pins...");
|
||||
flags_expected = SPICOMMON_BUSFLAG_NATIVE_PINS;
|
||||
flags_expected = SPICOMMON_BUSFLAG_IOMUX_PINS;
|
||||
//swap MOSI and MISO
|
||||
cfg = (spi_bus_config_t){.mosi_io_num = HSPI_IOMUX_PIN_NUM_MISO, .miso_io_num = HSPI_IOMUX_PIN_NUM_MOSI, .sclk_io_num = HSPI_IOMUX_PIN_NUM_CLK, .quadhd_io_num = HSPI_IOMUX_PIN_NUM_HD, .quadwp_io_num = HSPI_IOMUX_PIN_NUM_WP,
|
||||
.max_transfer_sz = 8, .flags = flags_expected};
|
||||
@ -404,7 +404,7 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, 0, flags_expected|SPICOMMON_BUSFLAG_SLAVE, &flags_o));
|
||||
|
||||
ESP_LOGI(TAG, "check native flag for 4 output pins...");
|
||||
flags_expected = SPICOMMON_BUSFLAG_NATIVE_PINS;
|
||||
flags_expected = SPICOMMON_BUSFLAG_IOMUX_PINS;
|
||||
//swap MOSI and MISO
|
||||
cfg = (spi_bus_config_t){.mosi_io_num = HSPI_IOMUX_PIN_NUM_MISO, .miso_io_num = HSPI_IOMUX_PIN_NUM_MOSI, .sclk_io_num = HSPI_IOMUX_PIN_NUM_CLK, .quadhd_io_num = -1, .quadwp_io_num = -1,
|
||||
.max_transfer_sz = 8, .flags = flags_expected};
|
||||
|
@ -12,8 +12,11 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _SOC_SPI_PINS_H_
|
||||
#define _SOC_SPI_PINS_H_
|
||||
#ifndef _SOC_SPI_CAPS_H_
|
||||
#define _SOC_SPI_CAPS_H_
|
||||
|
||||
#define SOC_SPI_PERIPH_NUM 3
|
||||
#define SOC_SPI_DMA_CHAN_NUM 2
|
||||
|
||||
#define SPI_IOMUX_PIN_NUM_MISO 7
|
||||
#define SPI_IOMUX_PIN_NUM_MOSI 8
|
||||
@ -44,4 +47,8 @@
|
||||
#define VSPI_IOMUX_PIN_NUM_WP 22
|
||||
#define VSPI_IOMUX_PIN_NUM_HD 21
|
||||
|
||||
#endif /* _SOC_SPI_PINS_H_ */
|
||||
#define SOC_SPI_MAXIMUM_BUFFER_SIZE 64
|
||||
|
||||
#define SOC_SPI_SUPPORT_AS_CS 1 //Support to toggle the CS while the clock toggles
|
||||
|
||||
#endif /* _SOC_SPI_CAPS_H_ */
|
@ -14,6 +14,8 @@
|
||||
|
||||
#include "soc/spi_periph.h"
|
||||
|
||||
#define FUNC_SPI 1 //all pins of SPI1, HSPI and VSPI shares this function number
|
||||
|
||||
/*
|
||||
Bunch of constants for every SPI peripheral: GPIO signals, irqs, hw addr of registers etc
|
||||
*/
|
||||
@ -40,6 +42,7 @@ const spi_signal_conn_t spi_periph_signal[3] = {
|
||||
.irq = ETS_SPI1_INTR_SOURCE,
|
||||
.irq_dma = ETS_SPI1_DMA_INTR_SOURCE,
|
||||
.module = PERIPH_SPI_MODULE,
|
||||
.func = FUNC_SPI,
|
||||
.hw = &SPI1
|
||||
}, {
|
||||
.spiclk_out = HSPICLK_OUT_IDX,
|
||||
@ -63,6 +66,7 @@ const spi_signal_conn_t spi_periph_signal[3] = {
|
||||
.irq = ETS_SPI2_INTR_SOURCE,
|
||||
.irq_dma = ETS_SPI2_DMA_INTR_SOURCE,
|
||||
.module = PERIPH_HSPI_MODULE,
|
||||
.func = FUNC_SPI,
|
||||
.hw = &SPI2
|
||||
}, {
|
||||
.spiclk_out = VSPICLK_OUT_IDX,
|
||||
@ -86,6 +90,7 @@ const spi_signal_conn_t spi_periph_signal[3] = {
|
||||
.irq = ETS_SPI3_INTR_SOURCE,
|
||||
.irq_dma = ETS_SPI3_DMA_INTR_SOURCE,
|
||||
.module = PERIPH_VSPI_MODULE,
|
||||
.func = FUNC_SPI,
|
||||
.hw = &SPI3
|
||||
}
|
||||
};
|
@ -34,7 +34,7 @@
|
||||
// field comments.
|
||||
|
||||
#pragma once
|
||||
#include "spi_ll.h"
|
||||
#include "hal/spi_ll.h"
|
||||
#include <esp_err.h>
|
||||
#include "soc/lldesc.h"
|
||||
|
||||
@ -85,7 +85,9 @@ typedef struct {
|
||||
uint32_t rx_lsbfirst : 1; ///< Whether LSB is received first for RX data, device specific
|
||||
uint32_t dma_enabled : 1; ///< Whether the DMA is enabled, do not update after initialization
|
||||
uint32_t no_compensate : 1; ///< No need to add dummy to compensate the timing, device specific
|
||||
uint32_t as_cs : 1; ///< Whether the AS_CS feature is enabled, device specific
|
||||
#ifdef SOC_SPI_SUPPORT_AS_CS
|
||||
uint32_t as_cs : 1; ///< Whether to toggle the CS while the clock toggles, device specific
|
||||
#endif
|
||||
uint32_t positive_cs : 1; ///< Whether the postive CS feature is abled, device specific
|
||||
};//boolean configurations
|
||||
|
||||
|
@ -18,11 +18,11 @@
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The LL layer for SPI register operations
|
||||
// The LL layer for ESP32 SPI register operations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal_defs.h"
|
||||
#include "hal/hal_defs.h"
|
||||
#include "soc/spi_periph.h"
|
||||
#include "esp32/rom/lldesc.h"
|
||||
#include <string.h>
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "soc/lldesc.h"
|
||||
#include "soc/spi_struct.h"
|
||||
#include <esp_types.h>
|
||||
#include "soc/spi_caps.h"
|
||||
|
||||
/**
|
||||
* Context that should be maintained by both the driver and the HAL.
|
||||
|
18
components/soc/include/hal/spi_types.h
Normal file
18
components/soc/include/hal/spi_types.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "soc/spi_caps.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/**
|
||||
* @brief Enum with the three SPI peripherals that are software-accessible in it
|
||||
*/
|
||||
typedef enum {
|
||||
SPI1_HOST=0, ///< SPI1
|
||||
SPI2_HOST=1, ///< SPI2
|
||||
SPI3_HOST=2, ///< SPI3
|
||||
} spi_host_device_t;
|
||||
|
||||
//alias for different chips
|
||||
#define SPI_HOST SPI1_HOST
|
||||
#define HSPI_HOST SPI2_HOST
|
||||
#define VSPI_HOST SPI3_HOST
|
@ -17,7 +17,7 @@
|
||||
#include "soc/soc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
//include soc related (generated) definitions
|
||||
#include "soc/spi_pins.h"
|
||||
#include "soc/spi_caps.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/spi_struct.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
@ -52,10 +52,11 @@ typedef struct {
|
||||
const uint8_t irq; //irq source for interrupt mux
|
||||
const uint8_t irq_dma; //dma irq source for interrupt mux
|
||||
const periph_module_t module; //peripheral module, for enabling clock etc
|
||||
const int func; //function number for IOMUX
|
||||
spi_dev_t *hw; //Pointer to the hardware registers
|
||||
} spi_signal_conn_t;
|
||||
|
||||
extern const spi_signal_conn_t spi_periph_signal[3];
|
||||
extern const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -21,7 +21,9 @@ void spi_hal_setup_device(const spi_hal_context_t *hal)
|
||||
{
|
||||
//Configure clock settings
|
||||
spi_dev_t *hw = hal->hw;
|
||||
#ifdef SOC_SPI_SUPPORT_AS_CS
|
||||
spi_ll_master_set_cksel(hw, hal->cs_pin_id, hal->as_cs);
|
||||
#endif
|
||||
spi_ll_master_set_pos_cs(hw, hal->cs_pin_id, hal->positive_cs);
|
||||
spi_ll_master_set_clock_by_reg(hw, &hal->timing_conf->clock_reg);
|
||||
//Configure bit order
|
||||
|
@ -87,6 +87,7 @@ INPUT = \
|
||||
../../components/driver/include/driver/touch_pad.h \
|
||||
../../components/driver/include/driver/uart.h \
|
||||
../../components/esp_adc_cal/include/esp_adc_cal.h \
|
||||
../../components/soc/include/hal/spi_types.h \
|
||||
../../components/soc/esp32/include/soc/adc_channel.h \
|
||||
../../components/soc/esp32/include/soc/dac_channel.h \
|
||||
../../components/soc/esp32/include/soc/touch_channel.h \
|
||||
|
@ -538,6 +538,7 @@ Display graphics on the 320x240 LCD of WROVER-Kits: :example:`peripherals/spi_ma
|
||||
API Reference - SPI Common
|
||||
--------------------------
|
||||
|
||||
.. include:: /_build/inc/spi_types.inc
|
||||
.. include:: /_build/inc/spi_common.inc
|
||||
|
||||
|
||||
|
@ -109,8 +109,8 @@ void app_main()
|
||||
ret=spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg, 1);
|
||||
assert(ret==ESP_OK);
|
||||
|
||||
char sendbuf[129]="";
|
||||
char recvbuf[129]="";
|
||||
WORD_ALIGNED_ATTR char sendbuf[129]="";
|
||||
WORD_ALIGNED_ATTR char recvbuf[129]="";
|
||||
memset(recvbuf, 0, 33);
|
||||
spi_slave_transaction_t t;
|
||||
memset(&t, 0, sizeof(t));
|
||||
|
Loading…
Reference in New Issue
Block a user