spi: multichip support

move hardcoded numbers, etc. into soc files.
create headers for shared types which needs to be documented.

(MINOR CHANGE)
This commit is contained in:
Michael (XIAO Xufeng) 2019-06-13 14:12:54 +08:00
parent b395279196
commit 9b13a04abf
15 changed files with 105 additions and 64 deletions

View File

@ -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
@ -90,23 +91,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
*/
#if CONFIG_IDF_TARGET_ESP32
typedef enum {
SPI_HOST=0, ///< SPI1, SPI
HSPI_HOST=1, ///< SPI2, HSPI
VSPI_HOST=2 ///< SPI3, VSPI
} spi_host_device_t;
#elif CONFIG_IDF_TARGET_ESP32S2BETA
typedef enum {
SPI_HOST=0, ///< SPI1, SPI
FSPI_HOST=1, ///< SPI2, FSPI
HSPI_HOST=2, ///< SPI3, HSPI
VSPI_HOST=3 ///< SPI4, VSPI
} spi_host_device_t;
#endif
/**
* @brief This is a configuration structure for a SPI bus.
*
@ -207,7 +191,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.
@ -215,6 +199,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
*
@ -228,7 +215,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.
@ -236,7 +223,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.
@ -334,6 +321,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
*/

View File

@ -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
@ -54,14 +54,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;
@ -101,15 +100,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)) ) {
@ -118,7 +127,7 @@ bool spicommon_dma_chan_claim (int dma_chan)
ret = true;
}
#if CONFIG_IDF_TARGET_ESP32
periph_module_enable( PERIPH_SPI_DMA_MODULE );
periph_module_enable(get_dma_periph(dma_chan));
#elif CONFIG_IDF_TARGET_ESP32S2BETA
if (dma_chan==1) {
periph_module_enable(PERIPH_SPI2_DMA_MODULE);
@ -149,7 +158,7 @@ bool spicommon_dma_chan_free(int dma_chan)
#if CONFIG_IDF_TARGET_ESP32
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));
}
#elif CONFIG_IDF_TARGET_ESP32S2BETA
if (dma_chan==1) {
@ -237,7 +246,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
@ -249,7 +258,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);
}
@ -260,7 +269,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
if (bus_config->mosi_io_num >= 0) {
gpio_iomux_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in);
#if CONFIG_IDF_TARGET_ESP32
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);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
gpio_iomux_out(bus_config->mosi_io_num, spi_periph_signal[host].func, false);
#endif
@ -268,7 +277,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
if (bus_config->miso_io_num >= 0) {
gpio_iomux_in(bus_config->miso_io_num, spi_periph_signal[host].spiq_in);
#if CONFIG_IDF_TARGET_ESP32
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);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
gpio_iomux_out(bus_config->miso_io_num, spi_periph_signal[host].func, false);
#endif
@ -276,7 +285,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
if (bus_config->quadwp_io_num >= 0) {
gpio_iomux_in(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in);
#if CONFIG_IDF_TARGET_ESP32
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);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
gpio_iomux_out(bus_config->quadwp_io_num, spi_periph_signal[host].func, false);
#endif
@ -284,7 +293,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
if (bus_config->quadhd_io_num >= 0) {
gpio_iomux_in(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in);
#if CONFIG_IDF_TARGET_ESP32
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);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
gpio_iomux_out(bus_config->quadhd_io_num, spi_periph_signal[host].func, false);
#endif
@ -292,12 +301,12 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
if (bus_config->sclk_io_num >= 0) {
gpio_iomux_in(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in);
#if CONFIG_IDF_TARGET_ESP32
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);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
gpio_iomux_out(bus_config->sclk_io_num, spi_periph_signal[host].func, false);
#endif
}
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);
@ -430,7 +439,7 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num,
//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);
#if CONFIG_IDF_TARGET_ESP32
gpio_iomux_out(cs_io_num, FUNC_SPI, false);
gpio_iomux_out(cs_io_num, spi_periph_signal[host].func, false);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
gpio_iomux_out(cs_io_num, spi_periph_signal[host].func, false);
#endif

View File

@ -207,7 +207,7 @@ struct spi_device_t {
bool waiting; //the device is waiting for the exclusive control of the bus
};
static spi_host_t *spihost[SPI_PERIPH_NUM];
static spi_host_t *spihost[SOC_SPI_PERIPH_NUM];
static const char *SPI_TAG = "spi_master";
@ -281,7 +281,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);
@ -407,13 +407,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);
@ -445,7 +447,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;

View File

@ -73,13 +73,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)
@ -150,7 +150,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",

View File

@ -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};

View File

@ -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_PERIPH_NUM 3
@ -41,4 +44,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_ */

View File

@ -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,8 +42,8 @@ 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,
.hw = &SPI1,
.func = SPI_FUNC_NUM
.func = FUNC_SPI,
.hw = &SPI1
}, {
.spiclk_out = HSPICLK_OUT_IDX,
.spiclk_in = HSPICLK_IN_IDX,
@ -64,8 +66,8 @@ 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,
.hw = &SPI2,
.func = HSPI_FUNC_NUM
.func = FUNC_SPI,
.hw = &SPI2
}, {
.spiclk_out = VSPICLK_OUT_IDX,
.spiclk_in = VSPICLK_IN_IDX,
@ -88,7 +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,
.hw = &SPI3,
.func = VSPI_FUNC_NUM
.func = FUNC_SPI,
.hw = &SPI3
}
};

View File

@ -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

View File

@ -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>

View File

@ -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.

View 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

View File

@ -16,7 +16,7 @@
#include <stdint.h>
#include "soc/soc.h"
#include "soc/periph_defs.h"
#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"
@ -68,11 +68,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
const int func;
} spi_signal_conn_t;
extern const spi_signal_conn_t spi_periph_signal[SPI_PERIPH_NUM];
extern const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM];
#ifdef __cplusplus
}

View File

@ -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

View File

@ -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 \

View File

@ -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