mirror of
https://github.com/espressif/esp-idf.git
synced 2025-11-02 21:48:13 +00:00
feat(driver_spi): update p4 eco5 spi support on real chip
This commit is contained in:
@@ -614,7 +614,8 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
||||
}
|
||||
//set flags for DUAL mode according to output-capability of MOSI and MISO pins.
|
||||
if ((bus_config->mosi_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->mosi_io_num)) &&
|
||||
(bus_config->miso_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->miso_io_num))) {
|
||||
(bus_config->miso_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->miso_io_num)) &&
|
||||
(bus_config->miso_io_num != bus_config->mosi_io_num)) {
|
||||
temp_flag |= SPICOMMON_BUSFLAG_DUAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -633,9 +633,7 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle)
|
||||
|
||||
esp_err_t spi_device_get_actual_freq(spi_device_handle_t handle, int* freq_khz)
|
||||
{
|
||||
if ((spi_device_t *)handle == NULL || freq_khz == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
SPI_CHECK(handle && freq_khz, "invalid arg", ESP_ERR_INVALID_ARG);
|
||||
|
||||
*freq_khz = handle->hal_dev.timing_conf.real_freq / 1000;
|
||||
return ESP_OK;
|
||||
|
||||
@@ -104,20 +104,26 @@ static inline bool SPI_SLAVE_ISR_ATTR bus_is_iomux(spi_slave_t *host)
|
||||
return host->flags & SPICOMMON_BUSFLAG_IOMUX_PINS;
|
||||
}
|
||||
|
||||
static void SPI_SLAVE_ISR_ATTR freeze_cs(spi_slave_t *host)
|
||||
static inline void SPI_SLAVE_ISR_ATTR freeze_cs(spi_slave_t *host)
|
||||
{
|
||||
#if SPI_LL_SLAVE_NEEDS_CS_WORKAROUND
|
||||
// This workaround only for ESP32 due to old hardware design, see MR !3207
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, host->cs_in_signal, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Use this function instead of cs_initial to avoid overwrite the output config
|
||||
// This is used in test by internal gpio matrix connections
|
||||
static inline void SPI_SLAVE_ISR_ATTR restore_cs(spi_slave_t *host)
|
||||
{
|
||||
#if SPI_LL_SLAVE_NEEDS_CS_WORKAROUND
|
||||
// This workaround only for ESP32 due to old hardware design, see MR !3207
|
||||
if (host->cs_iomux) {
|
||||
gpio_ll_set_input_signal_from(GPIO_HAL_GET_HW(GPIO_PORT_0), host->cs_in_signal, false);
|
||||
} else {
|
||||
esp_rom_gpio_connect_in_signal(host->cfg.spics_io_num, host->cs_in_signal, false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (SOC_CPU_CORES_NUM > 1) && (!CONFIG_FREERTOS_UNICORE)
|
||||
@@ -640,21 +646,13 @@ static void SPI_SLAVE_ISR_ATTR s_spi_slave_dma_prepare_data(spi_dma_ctx_t *dma_c
|
||||
|
||||
spi_dma_reset(dma_ctx->rx_dma_chan);
|
||||
spi_slave_hal_hw_prepare_rx(hal->hw);
|
||||
spi_dma_start(dma_ctx->rx_dma_chan, dma_ctx->dmadesc_rx);
|
||||
}
|
||||
if (hal->tx_buffer) {
|
||||
spicommon_dma_desc_setup_link(dma_ctx->dmadesc_tx, hal->tx_buffer, (hal->bitlen + 7) / 8, false);
|
||||
|
||||
spi_dma_reset(dma_ctx->tx_dma_chan);
|
||||
spi_slave_hal_hw_prepare_tx(hal->hw);
|
||||
}
|
||||
}
|
||||
|
||||
static void SPI_SLAVE_ISR_ATTR s_spi_slave_start_dma(spi_dma_ctx_t *dma_ctx, spi_slave_hal_context_t *hal)
|
||||
{
|
||||
if (hal->rx_buffer) {
|
||||
spi_dma_start(dma_ctx->rx_dma_chan, dma_ctx->dmadesc_rx);
|
||||
}
|
||||
if (hal->tx_buffer) {
|
||||
spi_dma_start(dma_ctx->tx_dma_chan, dma_ctx->dmadesc_tx);
|
||||
}
|
||||
}
|
||||
@@ -784,10 +782,7 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg)
|
||||
|
||||
//The slave rx dma get disturbed by unexpected transaction. Only connect the CS and start DMA when slave is ready.
|
||||
if (use_dma) {
|
||||
// Note: order of restore_cs and s_spi_slave_start_dma is important
|
||||
// restore_cs also bring potential glitch, should happen before start DMA
|
||||
restore_cs(host);
|
||||
s_spi_slave_start_dma(host->dma_ctx, hal);
|
||||
}
|
||||
|
||||
//Kick off transfer
|
||||
|
||||
@@ -1855,6 +1855,7 @@ TEST_CASE("test_spi_master_sleep_retention", "[spi]")
|
||||
spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
|
||||
buscfg.flags |= SPICOMMON_BUSFLAG_GPIO_PINS;
|
||||
buscfg.flags |= SPICOMMON_BUSFLAG_SLP_ALLOW_PD;
|
||||
buscfg.miso_io_num = buscfg.mosi_io_num; // set spi "self-loop"
|
||||
uint8_t send[16] = "hello spi x\n";
|
||||
uint8_t recv[16];
|
||||
spi_transaction_t trans_cfg = {
|
||||
@@ -1871,8 +1872,6 @@ TEST_CASE("test_spi_master_sleep_retention", "[spi]")
|
||||
#endif
|
||||
printf("Retention on GPSPI%d with dma: %d\n", periph + 1, use_dma);
|
||||
TEST_ESP_OK(spi_bus_initialize(periph, &buscfg, use_dma));
|
||||
// set spi "self-loop" after bus initialized
|
||||
spitest_gpio_output_sel(buscfg.miso_io_num, FUNC_GPIO, spi_periph_signal[periph].spid_out);
|
||||
TEST_ESP_OK(spi_bus_add_device(periph, &devcfg, &dev_handle));
|
||||
|
||||
for (uint8_t cnt = 0; cnt < 3; cnt ++) {
|
||||
@@ -1927,9 +1926,8 @@ TEST_CASE("test_spi_master_auto_sleep_retention", "[spi]")
|
||||
spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
||||
buscfg.flags = (allow_pd) ? SPICOMMON_BUSFLAG_SLP_ALLOW_PD : 0;
|
||||
buscfg.flags |= SPICOMMON_BUSFLAG_GPIO_PINS;
|
||||
buscfg.miso_io_num = buscfg.mosi_io_num; // set spi "self-loop"
|
||||
TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_DISABLED));
|
||||
// set spi "self-loop" after bus initialized
|
||||
spitest_gpio_output_sel(buscfg.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
|
||||
|
||||
spi_device_handle_t dev_handle;
|
||||
spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
|
||||
|
||||
@@ -44,6 +44,9 @@ extern "C" {
|
||||
#define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words
|
||||
#define SPI_LL_MOSI_FREE_LEVEL 0 //Default level after bus initialized
|
||||
|
||||
// CS_WORKAROUND: SPI slave with using DMA, the rx dma suffers from unexpected transactions
|
||||
// before slave is ready, need disconnect CS before and after each transaction
|
||||
#define SPI_LL_SLAVE_NEEDS_CS_WORKAROUND 1
|
||||
#define SPI_LL_SLAVE_NEEDS_RESET_WORKAROUND 1
|
||||
#define SPI_LL_SUPPORT_TIME_TUNING 1
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <stdlib.h> //for abs()
|
||||
#include <string.h>
|
||||
#include "hal/config.h"
|
||||
#include "esp_types.h"
|
||||
#include "soc/spi_periph.h"
|
||||
#include "soc/spi_struct.h"
|
||||
@@ -262,6 +263,10 @@ static inline void spi_ll_master_init(spi_dev_t *hw)
|
||||
hw->slave.val = 0;
|
||||
hw->user.val = 0;
|
||||
|
||||
//Disable unused error_end condition
|
||||
hw->user1.mst_wfull_err_end_en = 0;
|
||||
hw->user2.mst_rempty_err_end_en = 0;
|
||||
|
||||
hw->dma_conf.val = 0;
|
||||
hw->dma_conf.slv_tx_seg_trans_clr_en = 1;
|
||||
hw->dma_conf.slv_rx_seg_trans_clr_en = 1;
|
||||
@@ -763,13 +768,16 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Set the standard clock mode for master.
|
||||
* This config take effect only when SPI_CLK (pre-div before periph) div >=2
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param enable_std True for std timing, False for half cycle delay sampling.
|
||||
*/
|
||||
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
|
||||
{
|
||||
//This is not supported
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||
hw->clock.clk_edge_sel = (sample_point == SPI_SAMPLING_POINT_PHASE_1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -777,7 +785,11 @@ static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_
|
||||
*/
|
||||
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
|
||||
{
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -627,7 +627,15 @@ typedef union {
|
||||
* In the master mode it is pre-divider of spi_clk. Can be configured in CONF state.
|
||||
*/
|
||||
uint32_t clkdiv_pre:4;
|
||||
uint32_t reserved_22:9;
|
||||
uint32_t reserved_22:8;
|
||||
/** clk_edge_sel : R/W; bitpos: [30]; default: 0;
|
||||
* Configures use standard clock sampling edge or delay the sampling edge by half a
|
||||
* cycle in master transfer.
|
||||
* 0: clock sampling edge is delayed by half a cycle.
|
||||
* 1: clock sampling edge is standard.
|
||||
* Can be configured in CONF state.
|
||||
*/
|
||||
uint32_t clk_edge_sel:1;
|
||||
/** clk_equ_sysclk : R/W; bitpos: [31]; default: 1;
|
||||
* In the master mode 1: spi_clk is equal to system 0: spi_clk is divided from system
|
||||
* clock. Can be configured in CONF state.
|
||||
@@ -975,7 +983,7 @@ typedef union {
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** date : R/W; bitpos: [27:0]; default: 35680770;
|
||||
/** date : R/W; bitpos: [27:0]; default: 37761424;
|
||||
* SPI register version.
|
||||
*/
|
||||
uint32_t date:28;
|
||||
|
||||
Reference in New Issue
Block a user