|
|
|
@@ -26,6 +26,7 @@
|
|
|
|
|
#include "esp_clk_tree.h"
|
|
|
|
|
#include "esp_timer.h"
|
|
|
|
|
#include "esp_log.h"
|
|
|
|
|
#include "esp_cache.h"
|
|
|
|
|
#include "test_utils.h"
|
|
|
|
|
#include "test_spi_utils.h"
|
|
|
|
|
#include "spi_performance.h"
|
|
|
|
@@ -775,24 +776,27 @@ TEST_CASE("SPI Master DMA test, TX and RX in different regions", "[spi]")
|
|
|
|
|
//connect MOSI to two devices breaks the output, fix it.
|
|
|
|
|
spitest_gpio_output_sel(buscfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
|
|
|
|
|
|
|
|
|
|
#define TEST_REGION_SIZE 2
|
|
|
|
|
#define TEST_REGION_SIZE 3
|
|
|
|
|
static spi_transaction_t trans[TEST_REGION_SIZE];
|
|
|
|
|
int x;
|
|
|
|
|
memset(trans, 0, sizeof(trans));
|
|
|
|
|
|
|
|
|
|
trans[0].length = 320 * 8,
|
|
|
|
|
trans[0].tx_buffer = data_malloc + 2;
|
|
|
|
|
trans[0].length = 320 * 8;
|
|
|
|
|
trans[0].tx_buffer = data_malloc + 2;
|
|
|
|
|
trans[0].rx_buffer = data_dram;
|
|
|
|
|
|
|
|
|
|
trans[1].length = 4 * 8,
|
|
|
|
|
trans[1].flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA;
|
|
|
|
|
trans[1].length = 4 * 8;
|
|
|
|
|
trans[1].flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA;
|
|
|
|
|
uint32_t *ptr = (uint32_t *)trans[1].rx_data;
|
|
|
|
|
*ptr = 0x54545454;
|
|
|
|
|
ptr = (uint32_t *)trans[1].tx_data;
|
|
|
|
|
*ptr = 0xbc124960;
|
|
|
|
|
|
|
|
|
|
trans[2].length = 64 * 8;
|
|
|
|
|
trans[2].tx_buffer = data_drom;
|
|
|
|
|
trans[2].rx_buffer = data_malloc;
|
|
|
|
|
|
|
|
|
|
//Queue all transactions.
|
|
|
|
|
for (x = 0; x < TEST_REGION_SIZE; x++) {
|
|
|
|
|
for (int x = 0; x < TEST_REGION_SIZE; x++) {
|
|
|
|
|
ESP_LOGI(TAG, "transmitting %d...", x);
|
|
|
|
|
ret = spi_device_transmit(spi, &trans[x]);
|
|
|
|
|
TEST_ASSERT(ret == ESP_OK);
|
|
|
|
@@ -1969,3 +1973,95 @@ TEST_CASE("test_spi_master_auto_sleep_retention", "[spi]")
|
|
|
|
|
}
|
|
|
|
|
#endif //CONFIG_PM_ENABLE
|
|
|
|
|
#endif //SOC_LIGHT_SLEEP_SUPPORTED
|
|
|
|
|
|
|
|
|
|
#if CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE
|
|
|
|
|
#define TEST_EDMA_PSRAM_TRANS_NUM 5
|
|
|
|
|
#define TEST_EDMA_TRANS_LEN 20480 //Use PSRAM need a 16/32/64 aligned buffer len
|
|
|
|
|
#define TEST_EDMA_BUFFER_SZ (TEST_EDMA_PSRAM_TRANS_NUM * TEST_EDMA_TRANS_LEN)
|
|
|
|
|
|
|
|
|
|
void test_spi_psram_trans(spi_device_handle_t dev_handle, void *tx, void *rx)
|
|
|
|
|
{
|
|
|
|
|
spi_transaction_t trans_cfg = {
|
|
|
|
|
.length = TEST_EDMA_TRANS_LEN * 8,
|
|
|
|
|
.flags = SPI_TRANS_DMA_USE_PSRAM,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (uint8_t cnt = 0; cnt < TEST_EDMA_PSRAM_TRANS_NUM; cnt ++) {
|
|
|
|
|
trans_cfg.tx_buffer = tx + TEST_EDMA_TRANS_LEN * cnt;
|
|
|
|
|
trans_cfg.rx_buffer = rx + TEST_EDMA_TRANS_LEN * cnt;
|
|
|
|
|
|
|
|
|
|
// To use psram, hardware will pass data through MSPI and GDMA to GPSPI, which need some time
|
|
|
|
|
// GPSPI bandwidth(speed * line_num) should always no more than PSRAM bandwidth
|
|
|
|
|
trans_cfg.override_freq_hz = (CONFIG_SPIRAM_SPEED / 4) * 1000 * 1000;
|
|
|
|
|
printf("%d TX %p RX %p len %d @%ld kHz\n", cnt, trans_cfg.tx_buffer, trans_cfg.rx_buffer, TEST_EDMA_TRANS_LEN, trans_cfg.override_freq_hz / 1000);
|
|
|
|
|
TEST_ESP_OK(spi_device_transmit(dev_handle, &trans_cfg));
|
|
|
|
|
TEST_ASSERT(!(trans_cfg.flags & (SPI_TRANS_DMA_RX_FAIL | SPI_TRANS_DMA_TX_FAIL)));
|
|
|
|
|
spitest_cmp_or_dump(trans_cfg.tx_buffer, trans_cfg.rx_buffer, TEST_EDMA_TRANS_LEN);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("SPI_Master: PSRAM buffer transaction via EDMA", "[spi]")
|
|
|
|
|
{
|
|
|
|
|
spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
|
|
|
|
buscfg.miso_io_num = buscfg.mosi_io_num; // set spi "self-loopback"
|
|
|
|
|
buscfg.max_transfer_sz = TEST_EDMA_BUFFER_SZ;
|
|
|
|
|
TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
|
|
|
|
|
|
|
|
|
|
spi_device_handle_t dev_handle;
|
|
|
|
|
spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
|
|
|
|
|
devcfg.clock_speed_hz = 80 * 1000 * 1000; // Test error case on highest freq first
|
|
|
|
|
TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &dev_handle));
|
|
|
|
|
int real_freq_khz;
|
|
|
|
|
spi_device_get_actual_freq(dev_handle, &real_freq_khz);
|
|
|
|
|
|
|
|
|
|
uint32_t cache_width = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
|
|
|
|
|
uint8_t *internal_1 = heap_caps_aligned_calloc(cache_width, 1, TEST_EDMA_BUFFER_SZ, MALLOC_CAP_INTERNAL);
|
|
|
|
|
uint8_t *external_1 = heap_caps_aligned_calloc(cache_width, 1, TEST_EDMA_BUFFER_SZ, MALLOC_CAP_SPIRAM);
|
|
|
|
|
uint8_t *external_2 = heap_caps_aligned_calloc(cache_width, 1, TEST_EDMA_BUFFER_SZ, MALLOC_CAP_SPIRAM);
|
|
|
|
|
test_fill_random_to_buffers_dualboard(1001, internal_1, external_2, TEST_EDMA_BUFFER_SZ);
|
|
|
|
|
|
|
|
|
|
printf("Test error case: High freq @%d kHz\n", real_freq_khz);
|
|
|
|
|
spi_transaction_t trans_cfg = {
|
|
|
|
|
.length = TEST_EDMA_TRANS_LEN * 8,
|
|
|
|
|
.tx_buffer = external_2,
|
|
|
|
|
.rx_buffer = external_1,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < 2; i++) {
|
|
|
|
|
trans_cfg.flags = i ? SPI_TRANS_DMA_USE_PSRAM : 0;
|
|
|
|
|
uint32_t before = esp_get_free_heap_size();
|
|
|
|
|
spi_device_polling_start(dev_handle, &trans_cfg, portMAX_DELAY);
|
|
|
|
|
uint32_t after = esp_get_free_heap_size();
|
|
|
|
|
printf("\n==== %s ====\n", i ? "EDMA" : "Auto Malloc");
|
|
|
|
|
printf("before: %ld, after: %ld, diff: %ld\n", before, after, after - before);
|
|
|
|
|
spi_device_polling_end(dev_handle, portMAX_DELAY);
|
|
|
|
|
printf("RX fail: %d, TX fail: %d\n", !!(trans_cfg.flags & SPI_TRANS_DMA_RX_FAIL), !!(trans_cfg.flags & SPI_TRANS_DMA_TX_FAIL));
|
|
|
|
|
TEST_ASSERT(i ? (before - after) < TEST_EDMA_TRANS_LEN : (before - after) > 2 * TEST_EDMA_TRANS_LEN);
|
|
|
|
|
TEST_ASSERT((!!i) == !!(trans_cfg.flags & (SPI_TRANS_DMA_RX_FAIL | SPI_TRANS_DMA_TX_FAIL)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("\nTest unaligned tx psram buffer\n");
|
|
|
|
|
trans_cfg.tx_buffer ++;
|
|
|
|
|
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, spi_device_transmit(dev_handle, &trans_cfg));
|
|
|
|
|
|
|
|
|
|
printf("\nTest trans: internal -> psram\n");
|
|
|
|
|
memset(external_1, 0, TEST_EDMA_BUFFER_SZ);
|
|
|
|
|
TEST_ESP_OK(esp_cache_msync((void *)external_1, TEST_EDMA_BUFFER_SZ, ESP_CACHE_MSYNC_FLAG_DIR_C2M));
|
|
|
|
|
test_spi_psram_trans(dev_handle, internal_1, external_1);
|
|
|
|
|
|
|
|
|
|
printf("\nTest trans: psram -> psram\n");
|
|
|
|
|
memset(external_2, 0, TEST_EDMA_BUFFER_SZ);
|
|
|
|
|
TEST_ESP_OK(esp_cache_msync((void *)external_2, TEST_EDMA_BUFFER_SZ, ESP_CACHE_MSYNC_FLAG_DIR_C2M));
|
|
|
|
|
test_spi_psram_trans(dev_handle, external_1, external_2);
|
|
|
|
|
|
|
|
|
|
printf("\nTest trans: psram -> internal\n");
|
|
|
|
|
memset(internal_1, 0, TEST_EDMA_BUFFER_SZ);
|
|
|
|
|
test_spi_psram_trans(dev_handle, external_2, internal_1);
|
|
|
|
|
|
|
|
|
|
free(internal_1);
|
|
|
|
|
free(external_1);
|
|
|
|
|
free(external_2);
|
|
|
|
|
spi_bus_remove_device(dev_handle);
|
|
|
|
|
spi_bus_free(TEST_SPI_HOST);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|