spi: support esp32s2

pull/2405/merge
Michael (XIAO Xufeng) 2020-01-21 18:35:24 +08:00
rodzic 9d41829e09
commit 7026087dc0
13 zmienionych plików z 74 dodań i 153 usunięć

Wyświetl plik

@ -110,8 +110,6 @@ static uint32_t get_clk_en_mask(periph_module_t periph)
return DPORT_SPI2_CLK_EN;
case PERIPH_HSPI_MODULE:
return DPORT_SPI3_CLK_EN;
case PERIPH_VSPI_MODULE:
return DPORT_SPI4_CLK_EN;
case PERIPH_SPI2_DMA_MODULE:
return DPORT_SPI2_DMA_CLK_EN;
case PERIPH_SPI3_DMA_MODULE:
@ -212,8 +210,6 @@ static uint32_t get_rst_en_mask(periph_module_t periph, bool enable)
return DPORT_SPI2_RST;
case PERIPH_HSPI_MODULE:
return DPORT_SPI3_RST;
case PERIPH_VSPI_MODULE:
return DPORT_SPI4_RST;
case PERIPH_SPI2_DMA_MODULE:
return DPORT_SPI2_DMA_RST;
case PERIPH_SPI3_DMA_MODULE:
@ -289,13 +285,9 @@ static uint32_t get_clk_en_reg(periph_module_t periph)
#if CONFIG_IDF_TARGET_ESP32
if (periph == PERIPH_AES_MODULE || periph == PERIPH_SHA_MODULE || periph == PERIPH_RSA_MODULE) {
return DPORT_PERI_CLK_EN_REG;
}
#elif CONFIG_IDF_TARGET_ESP32S2
if(periph == PERIPH_SPI_SHARED_DMA_MODULE) {
return DPORT_PERIP_CLK_EN1_REG;
}
} else
#endif
else {
{
return is_wifi_clk_peripheral(periph) ? DPORT_WIFI_CLK_EN_REG : DPORT_PERIP_CLK_EN_REG;
}
}
@ -305,13 +297,9 @@ static uint32_t get_rst_en_reg(periph_module_t periph)
#if CONFIG_IDF_TARGET_ESP32
if (periph == PERIPH_AES_MODULE || periph == PERIPH_SHA_MODULE || periph == PERIPH_RSA_MODULE) {
return DPORT_PERI_RST_EN_REG;
}
#elif CONFIG_IDF_TARGET_ESP32S2
if(periph == PERIPH_SPI_SHARED_DMA_MODULE){
return DPORT_PERIP_CLK_EN1_REG;
}
} else
#endif
else {
{
return is_wifi_clk_peripheral(periph) ? DPORT_CORE_RST_EN_REG : DPORT_PERIP_RST_EN_REG;
}
}

Wyświetl plik

@ -109,7 +109,8 @@ static bool card_missing(int slot)
/// Check if slot number is within bounds
static bool is_valid_slot(int slot)
{
return slot == VSPI_HOST || slot == HSPI_HOST;
//SPI1 is not supported yet
return slot == SPI2_HOST || slot == SPI3_HOST;
}
static spi_device_handle_t spi_handle(int slot)

Wyświetl plik

@ -110,8 +110,6 @@ static inline uint32_t get_dma_periph(int dma_chan)
return PERIPH_SPI2_DMA_MODULE;
} else if (dma_chan==2) {
return PERIPH_SPI3_DMA_MODULE;
} else if (dma_chan==3) {
return PERIPH_SPI_SHARED_DMA_MODULE;
} else {
abort();
return -1;
@ -140,8 +138,6 @@ bool spicommon_dma_chan_claim (int dma_chan)
periph_module_enable(PERIPH_SPI2_DMA_MODULE);
} else if (dma_chan==2) {
periph_module_enable(PERIPH_SPI3_DMA_MODULE);
} else if (dma_chan==3) {
periph_module_enable(PERIPH_SPI_SHARED_DMA_MODULE);
}
#endif
portEXIT_CRITICAL(&spi_dma_spinlock);
@ -172,8 +168,6 @@ bool spicommon_dma_chan_free(int dma_chan)
periph_module_disable(PERIPH_SPI2_DMA_MODULE);
} else if (dma_chan==2) {
periph_module_disable(PERIPH_SPI3_DMA_MODULE);
} else if (dma_chan==3) {
periph_module_disable(PERIPH_SPI_SHARED_DMA_MODULE);
}
#endif
portEXIT_CRITICAL(&spi_dma_spinlock);

Wyświetl plik

@ -209,6 +209,11 @@ static const char *SPI_TAG = "spi_master";
static void spi_intr(void *arg);
static inline bool is_valid_host(spi_host_device_t host)
{
return host >= SPI1_HOST && host <= SPI3_HOST;
}
esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus_config, int dma_chan)
{
bool spi_chan_claimed, dma_chan_claimed;
@ -217,7 +222,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
/* ToDo: remove this when we have flash operations cooperating with this */
SPI_CHECK(host!=SPI_HOST, "SPI1 is not supported", ESP_ERR_NOT_SUPPORTED);
SPI_CHECK(host>=SPI_HOST && host<=VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
SPI_CHECK(is_valid_host(host), "invalid host", ESP_ERR_INVALID_ARG);
#ifdef CONFIG_IDF_TARGET_ESP32
SPI_CHECK( dma_chan >= 0 && dma_chan <= 2, "invalid dma channel", ESP_ERR_INVALID_ARG );
#elif CONFIG_IDF_TARGET_ESP32S2
@ -321,7 +326,7 @@ cleanup:
esp_err_t spi_bus_free(spi_host_device_t host)
{
int x;
SPI_CHECK(host>=SPI_HOST && host<=VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
SPI_CHECK(is_valid_host(host), "invalid host", ESP_ERR_INVALID_ARG);
SPI_CHECK(spihost[host]!=NULL, "host not in use", ESP_ERR_INVALID_STATE);
for (x=0; x<NO_CS; x++) {
SPI_CHECK(atomic_load(&spihost[host]->device[x])==NULL, "not all CSses freed", ESP_ERR_INVALID_STATE);
@ -370,7 +375,7 @@ esp_err_t spi_bus_add_device(spi_host_device_t host, const spi_device_interface_
int freecs;
int duty_cycle;
SPI_CHECK(host>=SPI_HOST && host<=VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
SPI_CHECK(is_valid_host(host), "invalid host", ESP_ERR_INVALID_ARG);
SPI_CHECK(spihost[host]!=NULL, "host not initialized", ESP_ERR_INVALID_STATE);
SPI_CHECK(dev_config->spics_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(dev_config->spics_io_num), "spics pin invalid", ESP_ERR_INVALID_ARG);
SPI_CHECK(dev_config->clock_speed_hz > 0, "invalid sclk speed", ESP_ERR_INVALID_ARG);

Wyświetl plik

@ -41,7 +41,7 @@ static const char *SPI_TAG = "spi_slave";
return (ret_val); \
}
#define VALID_HOST(x) (x>SPI_HOST && x<=VSPI_HOST)
#define VALID_HOST(x) (x > SPI1_HOST && x <= SPI3_HOST)
#ifdef CONFIG_SPI_SLAVE_ISR_IN_IRAM
#define SPI_SLAVE_ISR_ATTR IRAM_ATTR

Wyświetl plik

@ -752,7 +752,13 @@ void test_cmd_addr(spi_slave_task_context_t *slave_context, bool lsb_first)
vTaskDelay(50);
//prepare master tx data
int cmd_bits = (i+1)*2;
int addr_bits = 56-8*i;
int addr_bits =
#ifdef CONFIG_IDF_TARGET_ESP32
56-8*i;
#elif CONFIG_IDF_TARGET_ESP32S2
//ESP32S2 only supportes up to 32 bits address
28-4*i;
#endif
int round_up = (cmd_bits+addr_bits+7)/8*8;
addr_bits = round_up - cmd_bits;

Wyświetl plik

@ -97,22 +97,19 @@ static inline void spi_ll_master_init(spi_dev_t *hw)
*/
static inline void spi_ll_slave_init(spi_dev_t *hw)
{
//it's stupid, but if something goes wrong, try to uncomment it
//hw->slave.slave_mode = 1;
//Configure slave
hw->clock.val = 0;
hw->user.val = 0;
hw->ctrl.val = 0;
hw->user.doutdin = 1; //we only support full duplex
hw->user.sio = 0;
hw->user.tx_start_bit = 7;
hw->slave.slave_mode = 1;
hw->dma_conf.val |= SPI_LL_RST_MASK;
hw->dma_out_link.start = 0;
hw->dma_in_link.start = 0;
hw->dma_conf.val &= ~SPI_LL_RST_MASK;
hw->slave.sync_reset = 1;
hw->slave.sync_reset = 0;
hw->slave.soft_reset = 1;
hw->slave.soft_reset = 0;
//use all 64 bytes of the buffer
hw->user.usr_miso_highpart = 0;
hw->user.usr_mosi_highpart = 0;
@ -136,7 +133,7 @@ static inline void spi_ll_reset_dma(spi_dev_t *hw)
hw->dma_out_link.start = 0;
hw->dma_in_link.start = 0;
hw->dma_conf.val &= ~SPI_LL_RST_MASK;
hw->dma_conf.out_data_burst_en = 1;
hw->dma_conf.out_data_burst_en = 0;
hw->dma_conf.indscr_burst_en = 1;
hw->dma_conf.outdscr_burst_en = 1;
hw->dma_in_link.dma_rx_ena = 0;
@ -151,8 +148,6 @@ static inline void spi_ll_reset_dma(spi_dev_t *hw)
*/
static inline void spi_ll_rxdma_start(spi_dev_t *hw, lldesc_t *addr)
{
//if something breaks, uncomment this line
//hw->dma_in_link.restart = 1;
hw->dma_in_link.addr = (int) addr & 0xFFFFF;
hw->dma_in_link.start = 1;
}
@ -165,8 +160,6 @@ static inline void spi_ll_rxdma_start(spi_dev_t *hw, lldesc_t *addr)
*/
static inline void spi_ll_txdma_start(spi_dev_t *hw, lldesc_t *addr)
{
//if something breaks, uncomment this line
hw->dma_out_link.restart = 1;
hw->dma_out_link.addr = (int) addr & 0xFFFFF;
hw->dma_out_link.start = 1;
}
@ -249,7 +242,7 @@ static inline uint32_t spi_ll_get_running_cmd(spi_dev_t *hw)
*/
static inline void spi_ll_disable_int(spi_dev_t *hw)
{
hw->slave.trans_inten = 0;
hw->slave.int_trans_done_en = 0;
}
/**
@ -280,7 +273,7 @@ static inline void spi_ll_set_int_stat(spi_dev_t *hw)
*/
static inline void spi_ll_enable_int(spi_dev_t *hw)
{
hw->slave.trans_inten = 1;
hw->slave.int_trans_done_en = 1;
}
/**
@ -295,17 +288,15 @@ static inline void spi_ll_slave_set_int_type(spi_dev_t *hw, spi_ll_slave_intr_ty
case SPI_LL_INT_TYPE_SEG:
hw->dma_int_ena.in_suc_eof = 1;
hw->dma_int_ena.out_total_eof = 1;
hw->slave.trans_inten = 0;
hw->slave.int_trans_done_en = 0;
break;
default:
hw->dma_int_ena.in_suc_eof = 0;
hw->dma_int_ena.out_total_eof = 0;
hw->slave.trans_inten = 1;
hw->slave.int_trans_done_en = 1;
}
}
/*------------------------------------------------------------------------------
* Configs: mode
*----------------------------------------------------------------------------*/
@ -383,28 +374,24 @@ static inline void spi_ll_slave_set_mode(spi_dev_t *hw, const int mode, bool dma
hw->misc.ck_idle_edge = 0;
hw->user.rsck_i_edge = 0;
hw->user.tsck_i_edge = 0;
hw->ctrl1.rsck_data_out = 0;
hw->ctrl1.clk_mode_13 = 0;
} else if (mode == 1) {
hw->misc.ck_idle_edge = 0;
hw->user.rsck_i_edge = 1;
hw->user.tsck_i_edge = 1;
hw->ctrl1.rsck_data_out = 0;
hw->ctrl1.clk_mode_13 = 1;
} else if (mode == 2) {
hw->misc.ck_idle_edge = 1;
hw->user.rsck_i_edge = 1;
hw->user.tsck_i_edge = 1;
hw->ctrl1.rsck_data_out = 0;
hw->ctrl1.clk_mode_13 = 0;
} else if (mode == 3) {
hw->misc.ck_idle_edge = 1;
hw->user.rsck_i_edge = 0;
hw->user.tsck_i_edge = 0;
hw->ctrl1.rsck_data_out = 0;
hw->ctrl1.clk_mode_13 = 1;
}
//hw->ctrl1.rsck_data_out = 1;
hw->ctrl1.rsck_data_out = 0;
}
/**
@ -439,31 +426,34 @@ static inline void spi_ll_set_sio_mode(spi_dev_t *hw, int sio_mode)
*/
static inline void spi_ll_master_set_io_mode(spi_dev_t *hw, spi_ll_io_mode_t io_mode)
{
hw->ctrl.val &= ~(SPI_FREAD_DUAL | SPI_FREAD_QUAD | SPI_FREAD_DIO | SPI_FREAD_QIO);
hw->user.val &= ~(SPI_FWRITE_DUAL | SPI_FWRITE_QUAD | SPI_FWRITE_DIO | SPI_FWRITE_QIO);
switch (io_mode) {
case SPI_LL_IO_MODE_DIO:
// hw->ctrl.fread_dio = 1;
// hw->user.fwrite_dio = 1;
break;
case SPI_LL_IO_MODE_DUAL:
hw->ctrl.fread_dual = 1;
hw->user.fwrite_dual = 1;
break;
case SPI_LL_IO_MODE_QIO:
// hw->ctrl.fread_qio = 1;
// hw->user.fwrite_qio = 1;
break;
case SPI_LL_IO_MODE_QUAD:
hw->ctrl.fread_quad = 1;
hw->user.fwrite_quad = 1;
break;
default:
break;
};
// if (io_mode != SPI_LL_IO_MODE_NORMAL) {
// hw->ctrl.fastrd_mode = 1;
// }
if (io_mode == SPI_LL_IO_MODE_DIO || io_mode == SPI_LL_IO_MODE_DUAL) {
hw->ctrl.fcmd_dual= (io_mode == SPI_LL_IO_MODE_DIO) ? 1 : 0;
hw->ctrl.faddr_dual= (io_mode == SPI_LL_IO_MODE_DIO) ? 1 : 0;
hw->ctrl.fread_dual=1;
hw->user.fwrite_dual=1;
hw->ctrl.fcmd_quad = 0;
hw->ctrl.faddr_quad = 0;
hw->ctrl.fread_quad = 0;
hw->user.fwrite_quad = 0;
} else if (io_mode == SPI_LL_IO_MODE_QIO || io_mode == SPI_LL_IO_MODE_QUAD) {
hw->ctrl.fcmd_quad = (io_mode == SPI_LL_IO_MODE_QIO) ? 1 : 0;
hw->ctrl.faddr_quad = (io_mode == SPI_LL_IO_MODE_QIO) ? 1 : 0;
hw->ctrl.fread_quad=1;
hw->user.fwrite_quad=1;
hw->ctrl.fcmd_dual = 0;
hw->ctrl.faddr_dual = 0;
hw->ctrl.fread_dual = 0;
hw->user.fwrite_dual = 0;
} else {
hw->ctrl.fcmd_dual = 0;
hw->ctrl.faddr_dual = 0;
hw->ctrl.fread_dual = 0;
hw->user.fwrite_dual = 0;
hw->ctrl.fcmd_quad = 0;
hw->ctrl.faddr_quad = 0;
hw->ctrl.fread_quad = 0;
hw->user.fwrite_quad = 0;
}
}
/**
@ -722,7 +712,7 @@ static inline void spi_ll_set_mosi_bitlen(spi_dev_t *hw, size_t bitlen)
*/
static inline void spi_ll_slave_set_rx_bitlen(spi_dev_t *hw, size_t bitlen)
{
hw->slv_wrbuf_dlen.bit_len = bitlen - 1;
spi_ll_set_miso_bitlen(hw, bitlen);
}
/**
@ -733,7 +723,7 @@ static inline void spi_ll_slave_set_rx_bitlen(spi_dev_t *hw, size_t bitlen)
*/
static inline void spi_ll_slave_set_tx_bitlen(spi_dev_t *hw, size_t bitlen)
{
hw->slv_rdbuf_dlen.bit_len = bitlen - 1;
spi_ll_set_miso_bitlen(hw, bitlen);
}
/**
@ -785,27 +775,13 @@ static inline void spi_ll_set_address(spi_dev_t *hw, uint64_t addr, int addrlen,
* addr[0] -> addr[7]
* So swap the byte order to let the LSB sent first.
*/
addr = HAL_SWAP64(addr);
if (addrlen > 32) {
//The slv_wr_status register bits are sent first, then
//bits in addr register is sent.
hw->slv_wr_status = addr >> 32;
hw->addr = addr;
} else {
//otherwise only addr register is sent
hw->addr = addr >> 32;
}
addr = HAL_SWAP32(addr);
//otherwise only addr register is sent
hw->addr = addr;
} else {
// shift the address to MSB of addr (and maybe slv_wr_status) register.
if (addrlen > 32) {
// output address will be sent from MSB to LSB of slv_wr_status register, then comes the MSB to
// LSB of addr register.
hw->addr = addr << (64 - addrlen);
hw->slv_wr_status = addr >> (addrlen - 32);
} else {
// output address will be sent from MSB to LSB of addr register
hw->addr = addr << (32 - addrlen);
}
// shift the address to MSB of addr register.
// output address will be sent from MSB to LSB of addr register
hw->addr = addr << (32 - addrlen);
}
}
@ -863,8 +839,8 @@ static inline void spi_ll_enable_mosi(spi_dev_t *hw, int enable)
*/
static inline void spi_ll_slave_reset(spi_dev_t *hw)
{
hw->slave.sync_reset = 1;
hw->slave.sync_reset = 0;
hw->slave.soft_reset = 1;
hw->slave.soft_reset = 0;
}
/**
@ -876,7 +852,7 @@ static inline void spi_ll_slave_reset(spi_dev_t *hw)
*/
static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw)
{
return hw->slv_rd_byte.slv_rdata_bit * 8;
return hw->slv_rd_byte.data_bytelen * 8;
}

Wyświetl plik

@ -45,10 +45,8 @@ typedef enum {
PERIPH_SPI_MODULE, //SPI1
PERIPH_FSPI_MODULE, //SPI2
PERIPH_HSPI_MODULE, //SPI3
PERIPH_VSPI_MODULE, //SPI4
PERIPH_SPI2_DMA_MODULE,
PERIPH_SPI3_DMA_MODULE,
PERIPH_SPI_SHARED_DMA_MODULE, //this DMA is shared by SPI1 and SPI4
PERIPH_SDMMC_MODULE,
PERIPH_SDIO_SLAVE_MODULE,
PERIPH_CAN_MODULE,

Wyświetl plik

@ -1,40 +0,0 @@
// Copyright 2015-2018 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
// 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.
#ifndef _SOC_SPI_PINS_H_
#define _SOC_SPI_PINS_H_
#define SPI_PERIPH_NUM 3
#define SPI_FUNC_NUM 2
#define SPI_IOMUX_PIN_NUM_HD 27
#define SPI_IOMUX_PIN_NUM_CS 29
#define SPI_IOMUX_PIN_NUM_MOSI 32
#define SPI_IOMUX_PIN_NUM_CLK 30
#define SPI_IOMUX_PIN_NUM_MISO 31
#define SPI_IOMUX_PIN_NUM_WP 28
//TODO: add the next slot
#define FSPI_FUNC_NUM 0
#define FSPI_IOMUX_PIN_NUM_HD 9
#define FSPI_IOMUX_PIN_NUM_CS 10
#define FSPI_IOMUX_PIN_NUM_MOSI 11
#define FSPI_IOMUX_PIN_NUM_CLK 12
#define FSPI_IOMUX_PIN_NUM_MISO 13
#define FSPI_IOMUX_PIN_NUM_WP 14
//TODO: add the next slot
//HSPI and VSPI have no iomux pins
#endif

Wyświetl plik

@ -20,7 +20,7 @@
*/
const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = {
{
.spiclk_out = SPICLK_OUT_IDX,
.spiclk_out = SPICLK_OUT_MUX_IDX,
.spiclk_in = 0,/* SPI clock is not an input signal*/
.spid_out = SPID_OUT_IDX,
.spiq_out = SPIQ_OUT_IDX,
@ -39,13 +39,12 @@ const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = {
.spihd_iomux_pin = SPI_IOMUX_PIN_NUM_HD,
.spics0_iomux_pin = SPI_IOMUX_PIN_NUM_CS,
.irq = ETS_SPI1_INTR_SOURCE,
//TODO: SPI1 do not have DMA
/*.irq_dma = ETS_SPI1_DMA_INTR_SOURCE,*/
.irq_dma = -1,
.module = PERIPH_SPI_MODULE,
.hw = (spi_dev_t *) &SPIMEM1,
.func = SPI_FUNC_NUM,
}, {
.spiclk_out = FSPICLK_OUT_IDX,
.spiclk_out = FSPICLK_OUT_MUX_IDX,
.spiclk_in = FSPICLK_IN_IDX,
.spid_out = FSPID_OUT_IDX,
.spiq_out = FSPIQ_OUT_IDX,

Wyświetl plik

@ -38,5 +38,4 @@ typedef enum {
#define SPI_HOST SPI1_HOST
#define FSPI_HOST SPI2_HOST
#define HSPI_HOST SPI3_HOST
#define VSPI_HOST SPI4_HOST
#endif

Wyświetl plik

@ -59,9 +59,7 @@ typedef struct {
const uint8_t spics_out[3]; // /CS GPIO output mux signals
const uint8_t spics_in;
const uint8_t spidqs_out;
const uint8_t spidqs_in;
const uint8_t spicd_out;
const uint8_t spicd_in;
const uint8_t spiclk_iomux_pin; //IO pins of IO_MUX muxed signals
const uint8_t spid_iomux_pin;
const uint8_t spiq_iomux_pin;

Wyświetl plik

@ -227,11 +227,8 @@ static void setup_bus(spi_host_device_t host_id)
static void release_bus(int host_id)
{
#if CONFIG_IDF_TARGET_ESP32
if (host_id == HSPI_HOST || host_id == VSPI_HOST) {
#elif CONFIG_IDF_TARGET_ESP32S2
if (host_id == FSPI_HOST || host_id == HSPI_HOST || host_id == VSPI_HOST) {
#endif
//SPI1 bus can't be deinitialized
if (host_id == SPI2_HOST || host_id == SPI3_HOST) {
spi_bus_free(host_id);
}
}