Merge branch 'feature/spi_bringup_esp32s3' into 'master'

spi: bringup on esp32s3

See merge request espressif/esp-idf!10107
This commit is contained in:
Michael (XIAO Xufeng) 2020-10-27 00:51:42 +08:00
commit 9a394e1aa0
26 changed files with 675 additions and 343 deletions

View File

@ -50,6 +50,11 @@ if(${target} STREQUAL "esp32s2")
list(APPEND includes "esp32s2/include") list(APPEND includes "esp32s2/include")
endif() endif()
if(${target} STREQUAL "esp32s3")
list(APPEND srcs "spi_slave_hd.c"
)
endif()
idf_component_register(SRCS "${srcs}" idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS ${includes} INCLUDE_DIRS ${includes}
PRIV_INCLUDE_DIRS "include/driver" PRIV_INCLUDE_DIRS "include/driver"

View File

@ -150,6 +150,14 @@ bool spicommon_dma_chan_in_use(int dma_chan);
*/ */
bool spicommon_dma_chan_free(int dma_chan); bool spicommon_dma_chan_free(int dma_chan);
/**
* @brief Connect SPI and DMA peripherals
*
* @param host SPI peripheral
* @param dma_chan DMA channel
*/
void spicommon_connect_spi_and_dma(spi_host_device_t host, int dma_chan);
/** /**
* @brief Connect a SPI peripheral to GPIO pins * @brief Connect a SPI peripheral to GPIO pins
* *

View File

@ -22,6 +22,7 @@
#include "esp_log.h" #include "esp_log.h"
#include "esp_err.h" #include "esp_err.h"
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/soc_caps.h"
#include "soc/dport_reg.h" #include "soc/dport_reg.h"
#include "soc/lldesc.h" #include "soc/lldesc.h"
#include "driver/gpio.h" #include "driver/gpio.h"
@ -32,6 +33,15 @@
#include "hal/spi_hal.h" #include "hal/spi_hal.h"
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros.
#if SOC_GDMA_SUPPORTED
#include "hal/gdma_ll.h"
#define spi_dma_set_rx_channel_priority(gdma_chan, priority) gdma_ll_rx_set_priority(&GDMA, gdma_chan, priority);
#define spi_dma_set_tx_channel_priority(gdma_chan, priority) gdma_ll_tx_set_priority(&GDMA, gdma_chan, priority);
#define spi_dma_connect_rx_channel_to_periph(gdma_chan, periph_id) gdma_ll_rx_connect_to_periph(&GDMA, gdma_chan, periph_id);
#define spi_dma_connect_tx_channel_to_periph(gdma_chan, periph_id) gdma_ll_tx_connect_to_periph(&GDMA, gdma_chan, periph_id);
#endif
static const char *SPI_TAG = "spi"; static const char *SPI_TAG = "spi";
@ -114,7 +124,6 @@ bool spicommon_periph_free(spi_host_device_t host)
return ret; return ret;
} }
int spicommon_irqsource_for_host(spi_host_device_t host) int spicommon_irqsource_for_host(spi_host_device_t host)
{ {
return spi_periph_signal[host].irq; return spi_periph_signal[host].irq;
@ -143,7 +152,7 @@ static inline uint32_t get_dma_periph(int dma_chan)
#endif #endif
} }
bool spicommon_dma_chan_claim (int dma_chan) bool spicommon_dma_chan_claim(int dma_chan)
{ {
bool ret = false; bool ret = false;
assert(dma_chan >= 1 && dma_chan <= SOC_SPI_DMA_CHAN_NUM); assert(dma_chan >= 1 && dma_chan <= SOC_SPI_DMA_CHAN_NUM);
@ -163,6 +172,8 @@ bool spicommon_dma_chan_claim (int dma_chan)
} else if (dma_chan==2) { } else if (dma_chan==2) {
periph_module_enable(PERIPH_SPI3_DMA_MODULE); periph_module_enable(PERIPH_SPI3_DMA_MODULE);
} }
#elif SOC_GDMA_SUPPORTED
periph_module_enable(PERIPH_GDMA_MODULE);
#endif #endif
portEXIT_CRITICAL(&spi_dma_spinlock); portEXIT_CRITICAL(&spi_dma_spinlock);
@ -171,7 +182,7 @@ bool spicommon_dma_chan_claim (int dma_chan)
bool spicommon_dma_chan_in_use(int dma_chan) bool spicommon_dma_chan_in_use(int dma_chan)
{ {
assert(dma_chan==1 || dma_chan == 2); assert(dma_chan ==1 || dma_chan == 2);
return spi_dma_chan_enabled & DMA_CHANNEL_ENABLED(dma_chan); return spi_dma_chan_enabled & DMA_CHANNEL_ENABLED(dma_chan);
} }
@ -193,12 +204,39 @@ bool spicommon_dma_chan_free(int dma_chan)
} else if (dma_chan==2) { } else if (dma_chan==2) {
periph_module_disable(PERIPH_SPI3_DMA_MODULE); periph_module_disable(PERIPH_SPI3_DMA_MODULE);
} }
#elif SOC_GDMA_SUPPORTED
periph_module_disable(PERIPH_GDMA_MODULE);
#endif #endif
portEXIT_CRITICAL(&spi_dma_spinlock); portEXIT_CRITICAL(&spi_dma_spinlock);
return true; return true;
} }
void spicommon_connect_spi_and_dma(spi_host_device_t host, int dma_chan)
{
#if CONFIG_IDF_TARGET_ESP32
DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_chan, (host * 2));
#elif CONFIG_IDF_TARGET_ESP32S2
//On ESP32S2, each SPI controller has its own DMA channel. So there is no need to connect them.
#elif SOC_GDMA_SUPPORTED
int gdma_chan, periph_id;
if (dma_chan == 1) {
gdma_chan = SOC_GDMA_SPI2_DMA_CHANNEL;
periph_id = GDMA_LL_TRIG_SRC_SPI2;
} else if (dma_chan == 2) {
gdma_chan = SOC_GDMA_SPI3_DMA_CHANNEL;
periph_id = GDMA_LL_TRIG_SRC_SPI3;
} else {
abort();
}
spi_dma_connect_rx_channel_to_periph(gdma_chan, periph_id);
spi_dma_connect_tx_channel_to_periph(gdma_chan, periph_id);
spi_dma_set_rx_channel_priority(gdma_chan, 1);
spi_dma_set_tx_channel_priority(gdma_chan, 1);
#endif
}
static bool bus_uses_iomux_pins(spi_host_device_t host, const spi_bus_config_t* bus_config) static bool bus_uses_iomux_pins(spi_host_device_t host, const spi_bus_config_t* bus_config)
{ {
if (bus_config->sclk_io_num>=0 && if (bus_config->sclk_io_num>=0 &&
@ -222,7 +260,7 @@ it should be able to be initialized.
*/ */
esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_config_t *bus_config, int dma_chan, uint32_t flags, uint32_t* flags_o) esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_config_t *bus_config, int dma_chan, uint32_t flags, uint32_t* flags_o)
{ {
uint32_t temp_flag=0; uint32_t temp_flag = 0;
bool miso_need_output; bool miso_need_output;
bool mosi_need_output; bool mosi_need_output;
@ -378,11 +416,6 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
} }
} }
//Select DMA channel.
#if CONFIG_IDF_TARGET_ESP32
DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_chan, (host * 2));
#endif
if (flags_o) *flags_o = temp_flag; if (flags_o) *flags_o = temp_flag;
return ESP_OK; return ESP_OK;
} }
@ -481,11 +514,13 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t *
SPI_CHECK(spi_chan_claimed, "host_id already in use", ESP_ERR_INVALID_STATE); SPI_CHECK(spi_chan_claimed, "host_id already in use", ESP_ERR_INVALID_STATE);
if (dma_chan != 0) { if (dma_chan != 0) {
bool dma_chan_claimed=spicommon_dma_chan_claim(dma_chan); bool dma_chan_claimed = spicommon_dma_chan_claim(dma_chan);
if (!dma_chan_claimed) { if (!dma_chan_claimed) {
spicommon_periph_free(host_id); spicommon_periph_free(host_id);
SPI_CHECK(false, "dma channel already in use", ESP_ERR_INVALID_STATE); SPI_CHECK(false, "dma channel already in use", ESP_ERR_INVALID_STATE);
} }
spicommon_connect_spi_and_dma(host_id, dma_chan);
} }
//clean and initialize the context //clean and initialize the context

View File

@ -693,6 +693,8 @@ static SPI_MASTER_ISR_ATTR esp_err_t check_trans_valid(spi_device_handle_t handl
SPI_CHECK(!((trans_desc->flags & (SPI_TRANS_MODE_DIO|SPI_TRANS_MODE_QIO)) && !is_half_duplex), "incompatible iface params", ESP_ERR_INVALID_ARG); SPI_CHECK(!((trans_desc->flags & (SPI_TRANS_MODE_DIO|SPI_TRANS_MODE_QIO)) && !is_half_duplex), "incompatible iface params", ESP_ERR_INVALID_ARG);
#ifdef CONFIG_IDF_TARGET_ESP32 #ifdef CONFIG_IDF_TARGET_ESP32
SPI_CHECK(!is_half_duplex || bus_attr->dma_chan == 0 || !rx_enabled || !tx_enabled, "SPI half duplex mode does not support using DMA with both MOSI and MISO phases.", ESP_ERR_INVALID_ARG ); SPI_CHECK(!is_half_duplex || bus_attr->dma_chan == 0 || !rx_enabled || !tx_enabled, "SPI half duplex mode does not support using DMA with both MOSI and MISO phases.", ESP_ERR_INVALID_ARG );
#elif CONFIG_IDF_TARGET_ESP32S3
SPI_CHECK(!is_half_duplex || !tx_enabled || !rx_enabled, "SPI half duplex mode is not supported when both MOSI and MISO phases are enabled.", ESP_ERR_INVALID_ARG);
#endif #endif
//MOSI phase is skipped only when both tx_buffer and SPI_TRANS_USE_TXDATA are not set. //MOSI phase is skipped only when both tx_buffer and SPI_TRANS_USE_TXDATA are not set.
SPI_CHECK(trans_desc->length != 0 || !tx_enabled, "trans tx_buffer should be NULL and SPI_TRANS_USE_TXDATA should be cleared to skip MOSI phase.", ESP_ERR_INVALID_ARG); SPI_CHECK(trans_desc->length != 0 || !tx_enabled, "trans tx_buffer should be NULL and SPI_TRANS_USE_TXDATA should be cleared to skip MOSI phase.", ESP_ERR_INVALID_ARG);

View File

@ -137,6 +137,8 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
spicommon_periph_free( host ); spicommon_periph_free( host );
SPI_CHECK(dma_chan_claimed, "dma channel already in use", ESP_ERR_INVALID_STATE); SPI_CHECK(dma_chan_claimed, "dma channel already in use", ESP_ERR_INVALID_STATE);
} }
spicommon_connect_spi_and_dma(host, dma_chan);
} }
spihost[host] = malloc(sizeof(spi_slave_t)); spihost[host] = malloc(sizeof(spi_slave_t));

View File

@ -77,6 +77,8 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b
spicommon_periph_free(host_id); spicommon_periph_free(host_id);
SPIHD_CHECK(dma_chan_claimed, "dma channel already in use", ESP_ERR_INVALID_STATE); SPIHD_CHECK(dma_chan_claimed, "dma channel already in use", ESP_ERR_INVALID_STATE);
} }
spicommon_connect_spi_and_dma(host_id, config->dma_chan);
} }
spi_slave_hd_slot_t* host = malloc(sizeof(spi_slave_hd_slot_t)); spi_slave_hd_slot_t* host = malloc(sizeof(spi_slave_hd_slot_t));

View File

@ -49,7 +49,7 @@
#define ESP_SPI_SLAVE_TV (12.5*3.5) #define ESP_SPI_SLAVE_TV (12.5*3.5)
#define WIRE_DELAY 12.5 #define WIRE_DELAY 12.5
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#define TEST_SPI_HOST FSPI_HOST #define TEST_SPI_HOST FSPI_HOST
#define TEST_SLAVE_HOST HSPI_HOST #define TEST_SLAVE_HOST HSPI_HOST
@ -58,6 +58,7 @@
#define PIN_NUM_MOSI FSPI_IOMUX_PIN_NUM_MOSI #define PIN_NUM_MOSI FSPI_IOMUX_PIN_NUM_MOSI
#define PIN_NUM_CLK FSPI_IOMUX_PIN_NUM_CLK #define PIN_NUM_CLK FSPI_IOMUX_PIN_NUM_CLK
#define PIN_NUM_CS FSPI_IOMUX_PIN_NUM_CS #define PIN_NUM_CS FSPI_IOMUX_PIN_NUM_CS
#define PIN_NUM_WP FSPI_IOMUX_PIN_NUM_WP #define PIN_NUM_WP FSPI_IOMUX_PIN_NUM_WP
#define PIN_NUM_HD FSPI_IOMUX_PIN_NUM_HD #define PIN_NUM_HD FSPI_IOMUX_PIN_NUM_HD

View File

@ -3,8 +3,6 @@
#include "esp_log.h" #include "esp_log.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
int test_freq_default[]=TEST_FREQ_DEFAULT(); int test_freq_default[]=TEST_FREQ_DEFAULT();
const char MASTER_TAG[] = "test_master"; const char MASTER_TAG[] = "test_master";
@ -207,5 +205,3 @@ void spitest_gpio_output_sel(uint32_t gpio_num, int func, uint32_t signal_idx)
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], func); PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], func);
GPIO.func_out_sel_cfg[gpio_num].func_sel=signal_idx; GPIO.func_out_sel_cfg[gpio_num].func_sel=signal_idx;
} }
#endif

View File

@ -18,7 +18,7 @@
#define TEST_BUS_PIN_NUM_WP VSPI_IOMUX_PIN_NUM_WP #define TEST_BUS_PIN_NUM_WP VSPI_IOMUX_PIN_NUM_WP
#define TEST_BUS_PIN_NUM_HD VSPI_IOMUX_PIN_NUM_HD #define TEST_BUS_PIN_NUM_HD VSPI_IOMUX_PIN_NUM_HD
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#define TEST_BUS_PIN_NUM_MISO FSPI_IOMUX_PIN_NUM_MISO #define TEST_BUS_PIN_NUM_MISO FSPI_IOMUX_PIN_NUM_MISO
#define TEST_BUS_PIN_NUM_MOSI FSPI_IOMUX_PIN_NUM_MOSI #define TEST_BUS_PIN_NUM_MOSI FSPI_IOMUX_PIN_NUM_MOSI
#define TEST_BUS_PIN_NUM_CLK FSPI_IOMUX_PIN_NUM_CLK #define TEST_BUS_PIN_NUM_CLK FSPI_IOMUX_PIN_NUM_CLK
@ -256,9 +256,9 @@ static void test_bus_lock(bool test_flash)
} }
ESP_LOGI(TAG, "Start testing..."); ESP_LOGI(TAG, "Start testing...");
xTaskCreate( spi_task1, "task1", 2048, &context1, 0, &task1 ); xTaskCreate( spi_task1, "task1", 4096, &context1, 0, &task1 );
xTaskCreate( spi_task2, "task2", 2048, &context2, 0, &task2 ); xTaskCreate( spi_task2, "task2", 4096, &context2, 0, &task2 );
xTaskCreate( spi_task3, "task3", 2048, &context3, 0, &task3 ); xTaskCreate( spi_task3, "task3", 4096, &context3, 0, &task3 );
if (test_flash) { if (test_flash) {
xTaskCreate( spi_task4, "task4", 2048, &context4, 0, &task4 ); xTaskCreate( spi_task4, "task4", 2048, &context4, 0, &task4 );
} else { } else {

View File

@ -26,8 +26,6 @@
#include "soc/soc_memory_layout.h" #include "soc/soc_memory_layout.h"
#include "driver/spi_common_internal.h" #include "driver/spi_common_internal.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
const static char TAG[] = "test_spi"; const static char TAG[] = "test_spi";
static void check_spi_pre_n_for(int clk, int pre, int n) static void check_spi_pre_n_for(int clk, int pre, int n)
@ -757,7 +755,7 @@ void test_cmd_addr(spi_slave_task_context_t *slave_context, bool lsb_first)
int addr_bits = int addr_bits =
#ifdef CONFIG_IDF_TARGET_ESP32 #ifdef CONFIG_IDF_TARGET_ESP32
56-8*i; 56-8*i;
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
//ESP32S2 only supportes up to 32 bits address //ESP32S2 only supportes up to 32 bits address
28-4*i; 28-4*i;
#endif #endif
@ -957,6 +955,8 @@ TEST_CASE("SPI master variable dummy test", "[spi]")
#define GET_US_BY_CCOUNT(t) ((double)t/CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) #define GET_US_BY_CCOUNT(t) ((double)t/CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ)
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2
#define GET_US_BY_CCOUNT(t) ((double)t/CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ) #define GET_US_BY_CCOUNT(t) ((double)t/CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ)
#elif CONFIG_IDF_TARGET_ESP32S3
#define GET_US_BY_CCOUNT(t) ((double)t/CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ)
#endif #endif
static void speed_setup(spi_device_handle_t* spi, bool use_dma) static void speed_setup(spi_device_handle_t* spi, bool use_dma)
@ -1095,5 +1095,3 @@ TEST_CASE("spi_speed","[spi]")
master_free_device_bus(spi); master_free_device_bus(spi);
} }
#endif #endif
#endif

View File

@ -6,8 +6,6 @@
#include "test/test_common_spi.h" #include "test/test_common_spi.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
#ifndef MIN #ifndef MIN
#define MIN(a, b)((a) > (b)? (b): (a)) #define MIN(a, b)((a) > (b)? (b): (a))
#endif #endif
@ -224,7 +222,7 @@ static void local_test_loop(const void* arg1, void* arg2)
//TODO: esp32s2 has better timing performance //TODO: esp32s2 has better timing performance
static spitest_param_set_t timing_pgroup[] = { static spitest_param_set_t timing_pgroup[] = {
//signals are not fed to peripherals through iomux if the functions are not selected to iomux //signals are not fed to peripherals through iomux if the functions are not selected to iomux
#if !DISABLED_FOR_TARGETS(ESP32S2) #if !DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
{ .pset_name = "FULL_DUP, MASTER IOMUX", { .pset_name = "FULL_DUP, MASTER IOMUX",
.freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC, .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
.master_limit = SPI_MASTER_FREQ_13M, .master_limit = SPI_MASTER_FREQ_13M,
@ -251,7 +249,7 @@ static spitest_param_set_t timing_pgroup[] = {
.slave_tv_ns = TV_INT_CONNECT_GPIO, .slave_tv_ns = TV_INT_CONNECT_GPIO,
}, },
//signals are not fed to peripherals through iomux if the functions are not selected to iomux //signals are not fed to peripherals through iomux if the functions are not selected to iomux
#if !DISABLED_FOR_TARGETS(ESP32S2) #if !DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
{ .pset_name = "MISO_DUP, MASTER IOMUX", { .pset_name = "MISO_DUP, MASTER IOMUX",
.freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC, .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
.master_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC, .master_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
@ -278,7 +276,7 @@ static spitest_param_set_t timing_pgroup[] = {
.slave_tv_ns = TV_INT_CONNECT_GPIO, .slave_tv_ns = TV_INT_CONNECT_GPIO,
}, },
//signals are not fed to peripherals through iomux if the functions are not selected to iomux //signals are not fed to peripherals through iomux if the functions are not selected to iomux
#if !DISABLED_FOR_TARGETS(ESP32S2) #if !DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
{ .pset_name = "MOSI_DUP, MASTER IOMUX", { .pset_name = "MOSI_DUP, MASTER IOMUX",
.freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC, .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
//.freq_limit = ESP_SPI_SLAVE_MAX_READ_FREQ, //ESP_SPI_SLAVE_MAX_FREQ_SYNC, //.freq_limit = ESP_SPI_SLAVE_MAX_READ_FREQ, //ESP_SPI_SLAVE_MAX_FREQ_SYNC,
@ -615,7 +613,7 @@ TEST_CASE("Slave receive correct data", "[spi]")
} }
} }
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2) #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
//These tests are ESP32 only due to lack of runners //These tests are ESP32 only due to lack of runners
/******************************************************************************** /********************************************************************************
* Test By Master & Slave (2 boards) * Test By Master & Slave (2 boards)
@ -1166,5 +1164,3 @@ spitest_param_set_t mode_conf[] = {
TEST_SPI_MASTER_SLAVE(MODE, mode_conf, "") TEST_SPI_MASTER_SLAVE(MODE, mode_conf, "")
#endif #endif
#endif

View File

@ -12,15 +12,13 @@
#include "test/test_common_spi.h" #include "test/test_common_spi.h"
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
#ifndef CONFIG_SPIRAM #ifndef CONFIG_SPIRAM
//This test should be removed once the timing test is merged. //This test should be removed once the timing test is merged.
#define MASTER_SEND {0x93, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0xaa, 0xcc, 0xff, 0xee, 0x55, 0x77, 0x88, 0x43} #define MASTER_SEND {0x93, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0xaa, 0xcc, 0xff, 0xee, 0x55, 0x77, 0x88, 0x43}
#define SLAVE_SEND { 0xaa, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x13, 0x57, 0x9b, 0xdf, 0x24, 0x68, 0xac, 0xe0 } #define SLAVE_SEND { 0xaa, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x13, 0x57, 0x9b, 0xdf, 0x24, 0x68, 0xac, 0xe0 }
static inline void int_connect( uint32_t gpio, uint32_t sigo, uint32_t sigi ) static inline void int_connect( uint32_t gpio, uint32_t sigo, uint32_t sigi )
{ {
esp_rom_gpio_connect_out_signal( gpio, sigo, false, false ); esp_rom_gpio_connect_out_signal( gpio, sigo, false, false );
@ -92,7 +90,7 @@ TEST_CASE("test slave send unaligned","[spi]")
//do internal connection //do internal connection
int_connect( PIN_NUM_MOSI, spi_periph_signal[TEST_SPI_HOST].spid_out, spi_periph_signal[TEST_SLAVE_HOST].spiq_in ); int_connect( PIN_NUM_MOSI, spi_periph_signal[TEST_SPI_HOST].spid_out, spi_periph_signal[TEST_SLAVE_HOST].spiq_in );
int_connect( PIN_NUM_MISO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out, spi_periph_signal[TEST_SPI_HOST].spid_in ); int_connect( PIN_NUM_MISO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out, spi_periph_signal[TEST_SPI_HOST].spid_in );
int_connect( PIN_NUM_CS, spi_periph_signal[TEST_SPI_HOST].spics_out[0], spi_periph_signal[TEST_SLAVE_HOST].spics_in ); int_connect( PIN_NUM_CS, spi_periph_signal[TEST_SPI_HOST].spics_out[0], spi_periph_signal[TEST_SLAVE_HOST].spics_in );
int_connect( PIN_NUM_CLK, spi_periph_signal[TEST_SPI_HOST].spiclk_out, spi_periph_signal[TEST_SLAVE_HOST].spiclk_in ); int_connect( PIN_NUM_CLK, spi_periph_signal[TEST_SPI_HOST].spiclk_out, spi_periph_signal[TEST_SLAVE_HOST].spiclk_in );
@ -104,6 +102,7 @@ TEST_CASE("test slave send unaligned","[spi]")
slave_t.length=8*32; slave_t.length=8*32;
slave_t.tx_buffer=slave_txbuf+i; slave_t.tx_buffer=slave_txbuf+i;
slave_t.rx_buffer=slave_rxbuf; slave_t.rx_buffer=slave_rxbuf;
TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_t, portMAX_DELAY)); TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_t, portMAX_DELAY));
//send //send
@ -127,7 +126,6 @@ TEST_CASE("test slave send unaligned","[spi]")
TEST_ASSERT_EQUAL_HEX8_ARRAY( t.tx_buffer, slave_t.rx_buffer, t.length/8 ); TEST_ASSERT_EQUAL_HEX8_ARRAY( t.tx_buffer, slave_t.rx_buffer, t.length/8 );
TEST_ASSERT_EQUAL_HEX8_ARRAY( slave_t.tx_buffer, t.rx_buffer, t.length/8 ); TEST_ASSERT_EQUAL_HEX8_ARRAY( slave_t.tx_buffer, t.rx_buffer, t.length/8 );
TEST_ASSERT_EQUAL( t.length, slave_t.trans_len ); TEST_ASSERT_EQUAL( t.length, slave_t.trans_len );
//clean //clean
@ -144,5 +142,3 @@ TEST_CASE("test slave send unaligned","[spi]")
} }
#endif // !CONFIG_SPIRAM #endif // !CONFIG_SPIRAM
#endif

View File

@ -13,12 +13,10 @@
#if SOC_SPI_SUPPORT_SLAVE_HD_VER2 #if SOC_SPI_SUPPORT_SLAVE_HD_VER2
#include "driver/spi_slave_hd.h" #include "driver/spi_slave_hd.h"
#include "esp_rom_gpio.h"
#include "unity.h" #include "unity.h"
#include "test/test_common_spi.h" #include "test/test_common_spi.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
#define TEST_DMA_MAX_SIZE 14000 #define TEST_DMA_MAX_SIZE 14000
#define TEST_BUFFER_SIZE 256 ///< buffer size of each wrdma buffer in fifo mode #define TEST_BUFFER_SIZE 256 ///< buffer size of each wrdma buffer in fifo mode
#define TEST_SEG_SIZE 25 #define TEST_SEG_SIZE 25
@ -72,6 +70,21 @@ static uint32_t get_hd_flags(void)
} }
} }
void config_single_board_test_pin(void)
{
esp_rom_gpio_connect_out_signal(PIN_NUM_MOSI, spi_periph_signal[TEST_SPI_HOST].spid_out, 0, 0);
esp_rom_gpio_connect_in_signal(PIN_NUM_MOSI, spi_periph_signal[TEST_SLAVE_HOST].spid_in, 0);
esp_rom_gpio_connect_out_signal(PIN_NUM_MISO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out, 0, 0);
esp_rom_gpio_connect_in_signal(PIN_NUM_MISO, spi_periph_signal[TEST_SPI_HOST].spiq_in, 0);
esp_rom_gpio_connect_out_signal(PIN_NUM_CS, spi_periph_signal[TEST_SPI_HOST].spics_out[0], 0, 0);
esp_rom_gpio_connect_in_signal(PIN_NUM_CS, spi_periph_signal[TEST_SLAVE_HOST].spics_in, 0);
esp_rom_gpio_connect_out_signal(PIN_NUM_CLK, spi_periph_signal[TEST_SPI_HOST].spiclk_out, 0, 0);
esp_rom_gpio_connect_in_signal(PIN_NUM_CLK, spi_periph_signal[TEST_SLAVE_HOST].spiclk_in, 0);
}
static void init_master_hd(spi_device_handle_t* spi, const spitest_param_set_t* config, int freq) static void init_master_hd(spi_device_handle_t* spi, const spitest_param_set_t* config, int freq)
{ {
spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG(); spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
@ -196,10 +209,8 @@ static void test_hd_start(spi_device_handle_t *spi, int freq, const spitest_para
}; };
init_slave_hd(cfg->mode, &callback); init_slave_hd(cfg->mode, &callback);
spitest_gpio_output_sel(PIN_NUM_MOSI, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out); //when test with single board via same set of mosi, miso, clk and cs pins.
spitest_gpio_output_sel(PIN_NUM_MISO, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out); config_single_board_test_pin();
spitest_gpio_output_sel(PIN_NUM_CS, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spics_out[0]);
spitest_gpio_output_sel(PIN_NUM_CLK, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiclk_out);
wait_wrbuf_sig(ctx, 0); wait_wrbuf_sig(ctx, 0);
wait_rdbuf_sig(ctx, 0); wait_rdbuf_sig(ctx, 0);
@ -232,7 +243,7 @@ static void test_hd_start(spi_device_handle_t *spi, int freq, const spitest_para
} }
#define REG_REGION_SIZE 4*18 #define REG_REGION_SIZE SOC_SPI_MAXIMUM_BUFFER_SIZE
void check_no_signal(testhd_context_t* context) void check_no_signal(testhd_context_t* context)
{ {
@ -358,8 +369,8 @@ static void test_hd_loop(const void* arg1, void* arg2)
wait_rdbuf_sig(context, portMAX_DELAY); wait_rdbuf_sig(context, portMAX_DELAY);
ESP_LOGI("mem", "pos: %d, len: %d", pos, len); ESP_LOGI("mem", "pos: %d, len: %d", pos, len);
//ESP_LOG_BUFFER_HEX("recv_buffer", recv_buffer, len); // ESP_LOG_BUFFER_HEX("recv_buffer", recv_buffer, len);
//ESP_LOG_BUFFER_HEX("mem", &mem_ptr[pos], len); // ESP_LOG_BUFFER_HEX("mem", &mem_ptr[pos], len);
TEST_ASSERT_EQUAL_HEX8_ARRAY(&mem_ptr[pos], recv_buffer, len); TEST_ASSERT_EQUAL_HEX8_ARRAY(&mem_ptr[pos], recv_buffer, len);
} }
@ -490,10 +501,8 @@ TEST_CASE("test spi slave hd continuous mode, master too long", "[spi][spi_slv_h
//no callback needed //no callback needed
init_slave_hd(cfg->mode, NULL); init_slave_hd(cfg->mode, NULL);
spitest_gpio_output_sel(PIN_NUM_MOSI, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out); //Use GPIO matrix to connect signal of master and slave via same set of pins on one board.
spitest_gpio_output_sel(PIN_NUM_MISO, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out); config_single_board_test_pin();
spitest_gpio_output_sel(PIN_NUM_CS, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spics_out[0]);
spitest_gpio_output_sel(PIN_NUM_CLK, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiclk_out);
const int send_buf_size = 1024; const int send_buf_size = 1024;
@ -575,5 +584,3 @@ TEST_CASE("test spi slave hd continuous mode, master too long", "[spi][spi_slv_h
} }
#endif //SOC_SPI_SUPPORT_SLAVE_HD_VER2 #endif //SOC_SPI_SUPPORT_SLAVE_HD_VER2
#endif

View File

@ -0,0 +1,38 @@
// Copyright 2010-2020 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.
#pragma once
// NOTE: From the view of master
#define CMD_HD_WRBUF_REG 0x01
#define CMD_HD_RDBUF_REG 0x02
#define CMD_HD_WRDMA_REG 0x03
#define CMD_HD_RDDMA_REG 0x04
#define CMD_HD_ONEBIT_MODE 0x00
#define CMD_HD_DOUT_MODE 0x10
#define CMD_HD_QOUT_MODE 0x20
#define CMD_HD_DIO_MODE 0x50
#define CMD_HD_QIO_MODE 0xA0
#define CMD_HD_SEG_END_REG 0x05
#define CMD_HD_EN_QPI_REG 0x06
#define CMD_HD_WR_END_REG 0x07
#define CMD_HD_INT0_REG 0x08
#define CMD_HD_INT1_REG 0x09
#define CMD_HD_INT2_REG 0x0A
#define CMD_HD_EX_QPI_REG 0xDD
#define SPI_SLAVE_HD_BUFFER_SIZE 64

View File

@ -64,6 +64,7 @@ if(NOT BOOTLOADER_BUILD)
if(${target} STREQUAL "esp32s3") if(${target} STREQUAL "esp32s3")
list(APPEND srcs list(APPEND srcs
"spi_flash_hal_gpspi.c" "spi_flash_hal_gpspi.c"
"spi_slave_hd_hal.c"
"esp32s3/brownout_hal.c" "esp32s3/brownout_hal.c"
"esp32s3/systimer_hal.c" "esp32s3/systimer_hal.c"
"esp32s3/touch_sensor_hal.c") "esp32s3/touch_sensor_hal.c")

View File

@ -121,11 +121,21 @@ static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
} }
/** /**
* Trigger start of user-defined transaction. * Trigger start of user-defined transaction for master.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
*/ */
static inline void spi_ll_user_start(spi_dev_t *hw) static inline void spi_ll_master_user_start(spi_dev_t *hw)
{
hw->cmd.usr = 1;
}
/**
* Trigger start of user-defined transaction for slave.
*
* @param hw Beginning address of the peripheral registers.
*/
static inline void spi_ll_slave_user_start(spi_dev_t *hw)
{ {
hw->cmd.usr = 1; hw->cmd.usr = 1;
} }

View File

@ -166,11 +166,21 @@ static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
} }
/** /**
* Trigger start of user-defined transaction. * Trigger start of user-defined transaction for master.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
*/ */
static inline void spi_ll_user_start(spi_dev_t *hw) static inline void spi_ll_master_user_start(spi_dev_t *hw)
{
hw->cmd.usr = 1;
}
/**
* Trigger start of user-defined transaction for slave.
*
* @param hw Beginning address of the peripheral registers.
*/
static inline void spi_ll_slave_user_start(spi_dev_t *hw)
{ {
hw->cmd.usr = 1; hw->cmd.usr = 1;
} }

File diff suppressed because it is too large Load Diff

View File

@ -17,31 +17,17 @@
#include "hal/spi_hal.h" #include "hal/spi_hal.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros.
#if SOC_GDMA_SUPPORTED #if SOC_GDMA_SUPPORTED
#include "soc/gdma_struct.h" #include "soc/gdma_struct.h"
#include "hal/gdma_ll.h" #include "hal/gdma_ll.h"
#define spi_dma_ll_rx_reset(dev) gdma_ll_rx_reset_channel(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL)
#define spi_dma_ll_tx_reset(dev) gdma_ll_tx_reset_channel(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL);
#define spi_dma_ll_rx_enable_burst_data(dev, enable) gdma_ll_rx_enable_data_burst(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable); #define spi_dma_ll_rx_enable_burst_data(dev, enable) gdma_ll_rx_enable_data_burst(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable);
#define spi_dma_ll_tx_enable_burst_data(dev, enable) gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable); #define spi_dma_ll_tx_enable_burst_data(dev, enable) gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable);
#define spi_dma_ll_rx_enable_burst_desc(dev, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable); #define spi_dma_ll_rx_enable_burst_desc(dev, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable);
#define spi_dma_ll_tx_enable_burst_desc(dev, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable); #define spi_dma_ll_tx_enable_burst_desc(dev, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable);
#define spi_dma_set_rx_channel_priority(dev, priority) gdma_ll_rx_set_priority(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, priority);
#define spi_dma_set_tx_channel_priority(dev, priority) gdma_ll_tx_set_priority(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, priority);
#define spi_dma_enable_out_auto_wrback(dev, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable); #define spi_dma_enable_out_auto_wrback(dev, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable);
#define spi_dma_set_out_eof_generation(dev, enable) gdma_ll_tx_set_eof_mode(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable); #define spi_dma_set_out_eof_generation(dev, enable) gdma_ll_tx_set_eof_mode(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable);
#define spi_dma_connect_rx_channel_to_periph(dev, periph_id) gdma_ll_rx_connect_to_periph(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, periph_id);
#define spi_dma_connect_tx_channel_to_periph(dev, periph_id) gdma_ll_tx_connect_to_periph(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, periph_id);
#define spi_dma_ll_rx_start(dev, addr) do {\
gdma_ll_rx_set_desc_addr(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, (uint32_t)addr);\
gdma_ll_rx_start(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL);\
} while (0)
#define spi_dma_ll_tx_start(dev, addr) do {\
gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, (uint32_t)addr);\
gdma_ll_tx_start(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL);\
} while (0)
#endif #endif
static const char SPI_HAL_TAG[] = "spi_hal"; static const char SPI_HAL_TAG[] = "spi_hal";

View File

@ -18,22 +18,13 @@
#include "hal/spi_hal.h" #include "hal/spi_hal.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros.
#if SOC_GDMA_SUPPORTED #if SOC_GDMA_SUPPORTED
#include "soc/gdma_struct.h" #include "soc/gdma_struct.h"
#include "hal/gdma_ll.h" #include "hal/gdma_ll.h"
#define spi_dma_ll_rx_reset(dev) gdma_ll_rx_reset_channel(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL) #define spi_dma_ll_rx_reset(dev) gdma_ll_rx_reset_channel(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL)
#define spi_dma_ll_tx_reset(dev) gdma_ll_tx_reset_channel(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL); #define spi_dma_ll_tx_reset(dev) gdma_ll_tx_reset_channel(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL);
#define spi_dma_ll_rx_enable_burst_data(dev, enable) gdma_ll_rx_enable_data_burst(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable);
#define spi_dma_ll_tx_enable_burst_data(dev, enable) gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable);
#define spi_dma_ll_rx_enable_burst_desc(dev, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable);
#define spi_dma_ll_tx_enable_burst_desc(dev, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable);
#define spi_dma_set_rx_channel_priority(dev, priority) gdma_ll_rx_set_priority(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, priority);
#define spi_dma_set_tx_channel_priority(dev, priority) gdma_ll_tx_set_priority(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, priority);
#define spi_dma_enable_out_auto_wrback(dev, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable);
#define spi_dma_set_out_eof_generation(dev, enable) gdma_ll_tx_set_eof_mode(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, enable);
#define spi_dma_connect_rx_channel_to_periph(dev, periph_id) gdma_ll_rx_connect_to_periph(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, periph_id);
#define spi_dma_connect_tx_channel_to_periph(dev, periph_id) gdma_ll_tx_connect_to_periph(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, periph_id);
#define spi_dma_ll_rx_start(dev, addr) do {\ #define spi_dma_ll_rx_start(dev, addr) do {\
gdma_ll_rx_set_desc_addr(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, (uint32_t)addr);\ gdma_ll_rx_set_desc_addr(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, (uint32_t)addr);\
gdma_ll_rx_start(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL);\ gdma_ll_rx_start(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL);\
@ -42,7 +33,6 @@
gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, (uint32_t)addr);\ gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL, (uint32_t)addr);\
gdma_ll_tx_start(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL);\ gdma_ll_tx_start(&GDMA, SOC_GDMA_SPI2_DMA_CHANNEL);\
} while (0) } while (0)
#endif #endif
void spi_hal_setup_device(spi_hal_context_t *hal, const spi_hal_dev_config_t *dev) void spi_hal_setup_device(spi_hal_context_t *hal, const spi_hal_dev_config_t *dev)
@ -196,7 +186,7 @@ void spi_hal_prepare_data(spi_hal_context_t *hal, const spi_hal_dev_config_t *de
void spi_hal_user_start(const spi_hal_context_t *hal) void spi_hal_user_start(const spi_hal_context_t *hal)
{ {
spi_ll_user_start(hal->hw); spi_ll_master_user_start(hal->hw);
} }
bool spi_hal_usr_is_done(const spi_hal_context_t *hal) bool spi_hal_usr_is_done(const spi_hal_context_t *hal)

View File

@ -2,31 +2,17 @@
#include "hal/spi_ll.h" #include "hal/spi_ll.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros.
#if SOC_GDMA_SUPPORTED #if SOC_GDMA_SUPPORTED
#include "soc/gdma_struct.h" #include "soc/gdma_struct.h"
#include "hal/gdma_ll.h" #include "hal/gdma_ll.h"
#define spi_dma_ll_rx_reset(dev) gdma_ll_rx_reset_channel(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL)
#define spi_dma_ll_tx_reset(dev) gdma_ll_tx_reset_channel(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL);
#define spi_dma_ll_rx_enable_burst_data(dev, enable) gdma_ll_rx_enable_data_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable); #define spi_dma_ll_rx_enable_burst_data(dev, enable) gdma_ll_rx_enable_data_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_ll_tx_enable_burst_data(dev, enable) gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable); #define spi_dma_ll_tx_enable_burst_data(dev, enable) gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_ll_rx_enable_burst_desc(dev, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable); #define spi_dma_ll_rx_enable_burst_desc(dev, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_ll_tx_enable_burst_desc(dev, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable); #define spi_dma_ll_tx_enable_burst_desc(dev, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_set_rx_channel_priority(dev, priority) gdma_ll_rx_set_priority(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, priority);
#define spi_dma_set_tx_channel_priority(dev, priority) gdma_ll_tx_set_priority(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, priority);
#define spi_dma_enable_out_auto_wrback(dev, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable); #define spi_dma_enable_out_auto_wrback(dev, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_set_out_eof_generation(dev, enable) gdma_ll_tx_set_eof_mode(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable); #define spi_dma_set_out_eof_generation(dev, enable) gdma_ll_tx_set_eof_mode(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_connect_rx_channel_to_periph(dev, periph_id) gdma_ll_rx_connect_to_periph(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, periph_id);
#define spi_dma_connect_tx_channel_to_periph(dev, periph_id) gdma_ll_tx_connect_to_periph(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, periph_id);
#define spi_dma_ll_rx_start(dev, addr) do {\
gdma_ll_rx_set_desc_addr(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, (uint32_t)addr);\
gdma_ll_rx_start(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL);\
} while (0)
#define spi_dma_ll_tx_start(dev, addr) do {\
gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, (uint32_t)addr);\
gdma_ll_tx_start(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL);\
} while (0)
#endif #endif
static void s_spi_slave_hal_dma_init_config(const spi_slave_hal_context_t *hal) static void s_spi_slave_hal_dma_init_config(const spi_slave_hal_context_t *hal)

View File

@ -2,22 +2,13 @@
#include "hal/spi_ll.h" #include "hal/spi_ll.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros.
#if SOC_GDMA_SUPPORTED #if SOC_GDMA_SUPPORTED
#include "soc/gdma_struct.h" #include "soc/gdma_struct.h"
#include "hal/gdma_ll.h" #include "hal/gdma_ll.h"
#define spi_dma_ll_rx_reset(dev) gdma_ll_rx_reset_channel(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL) #define spi_dma_ll_rx_reset(dev) gdma_ll_rx_reset_channel(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL)
#define spi_dma_ll_tx_reset(dev) gdma_ll_tx_reset_channel(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL); #define spi_dma_ll_tx_reset(dev) gdma_ll_tx_reset_channel(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL);
#define spi_dma_ll_rx_enable_burst_data(dev, enable) gdma_ll_rx_enable_data_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_ll_tx_enable_burst_data(dev, enable) gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_ll_rx_enable_burst_desc(dev, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_ll_tx_enable_burst_desc(dev, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_set_rx_channel_priority(dev, priority) gdma_ll_rx_set_priority(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, priority);
#define spi_dma_set_tx_channel_priority(dev, priority) gdma_ll_tx_set_priority(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, priority);
#define spi_dma_enable_out_auto_wrback(dev, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_set_out_eof_generation(dev, enable) gdma_ll_tx_set_eof_mode(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_connect_rx_channel_to_periph(dev, periph_id) gdma_ll_rx_connect_to_periph(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, periph_id);
#define spi_dma_connect_tx_channel_to_periph(dev, periph_id) gdma_ll_tx_connect_to_periph(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, periph_id);
#define spi_dma_ll_rx_start(dev, addr) do {\ #define spi_dma_ll_rx_start(dev, addr) do {\
gdma_ll_rx_set_desc_addr(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, (uint32_t)addr);\ gdma_ll_rx_set_desc_addr(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, (uint32_t)addr);\
gdma_ll_rx_start(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL);\ gdma_ll_rx_start(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL);\
@ -26,7 +17,6 @@
gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, (uint32_t)addr);\ gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, (uint32_t)addr);\
gdma_ll_tx_start(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL);\ gdma_ll_tx_start(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL);\
} while (0) } while (0)
#endif #endif
bool spi_slave_hal_usr_is_done(spi_slave_hal_context_t* hal) bool spi_slave_hal_usr_is_done(spi_slave_hal_context_t* hal)
@ -37,7 +27,7 @@ bool spi_slave_hal_usr_is_done(spi_slave_hal_context_t* hal)
void spi_slave_hal_user_start(const spi_slave_hal_context_t *hal) void spi_slave_hal_user_start(const spi_slave_hal_context_t *hal)
{ {
spi_ll_clear_int_stat(hal->hw); //clear int bit spi_ll_clear_int_stat(hal->hw); //clear int bit
spi_ll_user_start(hal->hw); spi_ll_slave_user_start(hal->hw);
} }
void spi_slave_hal_prepare_data(const spi_slave_hal_context_t *hal) void spi_slave_hal_prepare_data(const spi_slave_hal_context_t *hal)
@ -74,6 +64,8 @@ void spi_slave_hal_prepare_data(const spi_slave_hal_context_t *hal)
spi_ll_slave_reset(hal->hw); spi_ll_slave_reset(hal->hw);
spi_ll_write_buffer(hal->hw, hal->tx_buffer, hal->bitlen); spi_ll_write_buffer(hal->hw, hal->tx_buffer, hal->bitlen);
} }
spi_ll_cpu_fifo_reset(hal->hw);
} }
spi_ll_slave_set_rx_bitlen(hal->hw, hal->bitlen); spi_ll_slave_set_rx_bitlen(hal->hw, hal->bitlen);

View File

@ -24,6 +24,7 @@
#include "hal/spi_slave_hd_hal.h" #include "hal/spi_slave_hd_hal.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros.
#if SOC_GDMA_SUPPORTED #if SOC_GDMA_SUPPORTED
#include "soc/gdma_struct.h" #include "soc/gdma_struct.h"
#include "hal/gdma_ll.h" #include "hal/gdma_ll.h"
@ -34,12 +35,8 @@
#define spi_dma_ll_tx_enable_burst_data(dev, enable) gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable); #define spi_dma_ll_tx_enable_burst_data(dev, enable) gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_ll_rx_enable_burst_desc(dev, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable); #define spi_dma_ll_rx_enable_burst_desc(dev, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_ll_tx_enable_burst_desc(dev, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable); #define spi_dma_ll_tx_enable_burst_desc(dev, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_set_rx_channel_priority(dev, priority) gdma_ll_rx_set_priority(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, priority);
#define spi_dma_set_tx_channel_priority(dev, priority) gdma_ll_tx_set_priority(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, priority);
#define spi_dma_enable_out_auto_wrback(dev, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable); #define spi_dma_enable_out_auto_wrback(dev, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_set_out_eof_generation(dev, enable) gdma_ll_tx_set_eof_mode(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable); #define spi_dma_set_out_eof_generation(dev, enable) gdma_ll_tx_set_eof_mode(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, enable);
#define spi_dma_connect_rx_channel_to_periph(dev, periph_id) gdma_ll_rx_connect_to_periph(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, periph_id);
#define spi_dma_connect_tx_channel_to_periph(dev, periph_id) gdma_ll_tx_connect_to_periph(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, periph_id);
#define spi_dma_ll_rx_start(dev, addr) do {\ #define spi_dma_ll_rx_start(dev, addr) do {\
gdma_ll_rx_set_desc_addr(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, (uint32_t)addr);\ gdma_ll_rx_set_desc_addr(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, (uint32_t)addr);\
gdma_ll_rx_start(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL);\ gdma_ll_rx_start(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL);\
@ -48,7 +45,6 @@
gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, (uint32_t)addr);\ gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL, (uint32_t)addr);\
gdma_ll_tx_start(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL);\ gdma_ll_tx_start(&GDMA, SOC_GDMA_SPI3_DMA_CHANNEL);\
} while (0) } while (0)
#endif #endif
static void s_spi_slave_hd_hal_dma_init_config(const spi_slave_hd_hal_context_t *hal) static void s_spi_slave_hd_hal_dma_init_config(const spi_slave_hd_hal_context_t *hal)
@ -110,10 +106,13 @@ void spi_slave_hd_hal_rxdma(spi_slave_hd_hal_context_t *hal, uint8_t *out_buf, s
{ {
lldesc_setup_link(hal->dmadesc_rx, out_buf, len, true); lldesc_setup_link(hal->dmadesc_rx, out_buf, len, true);
spi_ll_dma_fifo_reset(hal->dev);
spi_dma_ll_rx_reset(hal->dma_in); spi_dma_ll_rx_reset(hal->dma_in);
spi_ll_slave_reset(hal->dev);
spi_ll_infifo_full_clr(hal->dev); spi_ll_infifo_full_clr(hal->dev);
spi_ll_clear_intr(hal->dev, SPI_LL_INTR_WR_DONE); spi_ll_clear_intr(hal->dev, SPI_LL_INTR_WR_DONE);
spi_ll_slave_set_rx_bitlen(hal->dev, len * 8);
spi_ll_dma_rx_enable(hal->dev, 1); spi_ll_dma_rx_enable(hal->dev, 1);
spi_dma_ll_rx_start(hal->dma_in, &hal->dmadesc_rx[0]); spi_dma_ll_rx_start(hal->dma_in, &hal->dmadesc_rx[0]);
} }
@ -122,7 +121,9 @@ void spi_slave_hd_hal_txdma(spi_slave_hd_hal_context_t *hal, uint8_t *data, size
{ {
lldesc_setup_link(hal->dmadesc_tx, data, len, false); lldesc_setup_link(hal->dmadesc_tx, data, len, false);
spi_ll_dma_fifo_reset(hal->dev);
spi_dma_ll_tx_reset(hal->dma_out); spi_dma_ll_tx_reset(hal->dma_out);
spi_ll_slave_reset(hal->dev);
spi_ll_outfifo_empty_clr(hal->dev); spi_ll_outfifo_empty_clr(hal->dev);
spi_ll_clear_intr(hal->dev, SPI_LL_INTR_CMD8); spi_ll_clear_intr(hal->dev, SPI_LL_INTR_CMD8);

View File

@ -315,6 +315,8 @@ typedef volatile struct {
uint32_t date; /*register version.*/ uint32_t date; /*register version.*/
} gdma_dev_t; } gdma_dev_t;
_Static_assert(sizeof(gdma_dev_t) == 0x244, "incorrect size of gdma_dev_t.");
extern gdma_dev_t GDMA; extern gdma_dev_t GDMA;
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -18,12 +18,13 @@
#define SOC_SPI_DMA_CHAN_NUM 3 #define SOC_SPI_DMA_CHAN_NUM 3
#define SOC_SPI_PERIPH_CS_NUM(i) 3 #define SOC_SPI_PERIPH_CS_NUM(i) 3
#define SOC_SPI_MAXIMUM_BUFFER_SIZE 72 #define SOC_SPI_MAXIMUM_BUFFER_SIZE 64
#define SOC_SPI_SUPPORT_DDRCLK 1 #define SOC_SPI_SUPPORT_DDRCLK 1
#define SOC_SPI_SLAVE_SUPPORT_SEG_TRANS 1 #define SOC_SPI_SLAVE_SUPPORT_SEG_TRANS 1
#define SOC_SPI_SUPPORT_CD_SIG 1 #define SOC_SPI_SUPPORT_CD_SIG 1
#define SOC_SPI_SUPPORT_CONTINUOUS_TRANS 1 #define SOC_SPI_SUPPORT_CONTINUOUS_TRANS 1
#define SOC_SPI_SUPPORT_SLAVE_HD_VER2 1
// Peripheral supports DIO, DOUT, QIO, or QOUT // Peripheral supports DIO, DOUT, QIO, or QOUT
#define SOC_SPI_PERIPH_SUPPORT_MULTILINE_MODE(spi_dev) (!((void*)spi_dev == (void*)&GPSPI3)) #define SOC_SPI_PERIPH_SUPPORT_MULTILINE_MODE(spi_dev) (!((void*)spi_dev == (void*)&GPSPI3))

View File

@ -341,7 +341,7 @@ typedef volatile struct {
uint32_t reserved_8c; uint32_t reserved_8c;
uint32_t reserved_90; uint32_t reserved_90;
uint32_t reserved_94; uint32_t reserved_94;
uint32_t data_buf[18]; /*data buffer*/ uint32_t data_buf[16]; /*data buffer*/
uint32_t reserved_d8; uint32_t reserved_d8;
uint32_t reserved_dc; uint32_t reserved_dc;
union { union {