mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feat/psram_support_hspi' into 'master'
esp32: support to use hspi to output clock for 4M psram See merge request idf/esp-idf!3377
This commit is contained in:
commit
621e316725
@ -1522,6 +1522,20 @@ UT_012_03:
|
||||
- UT_T1_1
|
||||
- 8Mpsram
|
||||
|
||||
UT_012_04:
|
||||
<<: *unit_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
- 8Mpsram
|
||||
|
||||
UT_012_05:
|
||||
<<: *unit_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
- 8Mpsram
|
||||
|
||||
UT_601_01:
|
||||
<<: *unit_test_template
|
||||
tags:
|
||||
|
@ -96,9 +96,32 @@ typedef struct {
|
||||
* Call this if your driver wants to manage a SPI peripheral.
|
||||
*
|
||||
* @param host Peripheral to claim
|
||||
* @param source The caller indentification string.
|
||||
*
|
||||
* @return True if peripheral is claimed successfully; false if peripheral already is claimed.
|
||||
*/
|
||||
bool spicommon_periph_claim(spi_host_device_t host);
|
||||
bool spicommon_periph_claim(spi_host_device_t host, const char* source);
|
||||
|
||||
// The macro is to keep the back-compatibility of IDF v3.2 and before
|
||||
// In this way we can call spicommon_periph_claim with two arguments, or the host with the source set to the calling function name
|
||||
// When two arguments (host, func) are given, __spicommon_periph_claim2 is called
|
||||
// or if only one arguments (host) is given, __spicommon_periph_claim1 is called
|
||||
#define spicommon_periph_claim(host...) __spicommon_periph_claim(host, 2, 1)
|
||||
#define __spicommon_periph_claim(host, source, n, ...) __spicommon_periph_claim ## n(host, source)
|
||||
#define __spicommon_periph_claim1(host, _) ({ \
|
||||
char* warning_str = "calling spicommon_periph_claim without source string is deprecated.";\
|
||||
spicommon_periph_claim(host, __FUNCTION__); })
|
||||
|
||||
#define __spicommon_periph_claim2(host, func) spicommon_periph_claim(host, func)
|
||||
|
||||
/**
|
||||
* @brief Check whether the spi periph is in use.
|
||||
*
|
||||
* @param host Peripheral to check.
|
||||
*
|
||||
* @return True if in use, otherwise false.
|
||||
*/
|
||||
bool spicommon_periph_in_use(spi_host_device_t host);
|
||||
|
||||
/**
|
||||
* @brief Return the SPI peripheral so another driver can claim it.
|
||||
@ -119,6 +142,15 @@ bool spicommon_periph_free(spi_host_device_t host);
|
||||
*/
|
||||
bool spicommon_dma_chan_claim(int dma_chan);
|
||||
|
||||
/**
|
||||
* @brief Check whether the spi DMA channel is in use.
|
||||
*
|
||||
* @param dma_chan DMA channel to check.
|
||||
*
|
||||
* @return True if in use, otherwise false.
|
||||
*/
|
||||
bool spicommon_dma_chan_in_use(int dma_chan);
|
||||
|
||||
/**
|
||||
* @brief Return the SPI DMA channel so other driver can claim it, or just to power down DMA.
|
||||
*
|
||||
|
@ -52,19 +52,30 @@ typedef struct spi_device_t spi_device_t;
|
||||
|
||||
//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 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;
|
||||
|
||||
|
||||
//Returns true if this peripheral is successfully claimed, false if otherwise.
|
||||
bool spicommon_periph_claim(spi_host_device_t host)
|
||||
bool spicommon_periph_claim(spi_host_device_t host, const char* source)
|
||||
{
|
||||
bool false_var = false;
|
||||
bool ret = atomic_compare_exchange_strong(&spi_periph_claimed[host], &false_var, true);
|
||||
if (ret) periph_module_enable(spi_periph_signal[host].module);
|
||||
if (ret) {
|
||||
spi_claiming_func[host] = source;
|
||||
periph_module_enable(spi_periph_signal[host].module);
|
||||
} else {
|
||||
ESP_EARLY_LOGE(SPI_TAG, "SPI%d already claimed by %s.", host+1, spi_claiming_func[host]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool spicommon_periph_in_use(spi_host_device_t host)
|
||||
{
|
||||
return atomic_load(&spi_periph_claimed[host]);
|
||||
}
|
||||
|
||||
//Returns true if this peripheral is successfully freed, false if otherwise.
|
||||
bool spicommon_periph_free(spi_host_device_t host)
|
||||
{
|
||||
@ -102,6 +113,12 @@ bool spicommon_dma_chan_claim (int dma_chan)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool spicommon_dma_chan_in_use(int dma_chan)
|
||||
{
|
||||
assert(dma_chan==1 || dma_chan == 2);
|
||||
return spi_dma_chan_enabled & DMA_CHANNEL_ENABLED(dma_chan);
|
||||
}
|
||||
|
||||
bool spicommon_dma_chan_free(int dma_chan)
|
||||
{
|
||||
assert( dma_chan == 1 || dma_chan == 2 );
|
||||
@ -190,7 +207,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
||||
if (use_iomux) {
|
||||
//All SPI iomux pin selections resolve to 1, so we put that here instead of trying to figure
|
||||
//out which FUNC_GPIOx_xSPIxx to grab; they all are defined to 1 anyway.
|
||||
ESP_LOGD(SPI_TAG, "SPI%d use iomux pins.", host );
|
||||
ESP_LOGD(SPI_TAG, "SPI%d use iomux pins.", host+1);
|
||||
if (bus_config->mosi_io_num >= 0) {
|
||||
gpio_iomux_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in);
|
||||
gpio_iomux_out(bus_config->mosi_io_num, FUNC_SPI, false);
|
||||
@ -214,7 +231,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
||||
temp_flag |= SPICOMMON_BUSFLAG_NATIVE_PINS;
|
||||
} else {
|
||||
//Use GPIO matrix
|
||||
ESP_LOGD(SPI_TAG, "SPI%d use gpio matrix.", host );
|
||||
ESP_LOGD(SPI_TAG, "SPI%d use gpio matrix.", host+1);
|
||||
if (bus_config->mosi_io_num >= 0) {
|
||||
if (mosi_output || (temp_flag&SPICOMMON_BUSFLAG_DUAL)) {
|
||||
gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT_OUTPUT);
|
||||
|
@ -234,7 +234,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
|
||||
SPI_CHECK(host>=SPI_HOST && host<=VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
|
||||
SPI_CHECK( dma_chan >= 0 && dma_chan <= 2, "invalid dma channel", ESP_ERR_INVALID_ARG );
|
||||
|
||||
spi_chan_claimed=spicommon_periph_claim(host);
|
||||
spi_chan_claimed=spicommon_periph_claim(host, "spi master");
|
||||
SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
|
||||
|
||||
if ( dma_chan != 0 ) {
|
||||
@ -498,7 +498,7 @@ Specify ``SPI_DEVICE_NO_DUMMY`` to ignore this checking. Then you can output dat
|
||||
spihost[host]->hw->ctrl2.mosi_delay_mode = 0;
|
||||
spihost[host]->hw->ctrl2.mosi_delay_num = 0;
|
||||
*handle=dev;
|
||||
ESP_LOGD(SPI_TAG, "SPI%d: New device added to CS%d, effective clock: %dkHz", host, freecs, dev->clk_cfg.eff_clk/1000);
|
||||
ESP_LOGD(SPI_TAG, "SPI%d: New device added to CS%d, effective clock: %dkHz", host+1, freecs, dev->clk_cfg.eff_clk/1000);
|
||||
return ESP_OK;
|
||||
|
||||
nomem:
|
||||
|
@ -110,7 +110,7 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
|
||||
SPI_CHECK(VALID_HOST(host), "invalid host", ESP_ERR_INVALID_ARG);
|
||||
SPI_CHECK( dma_chan >= 0 && dma_chan <= 2, "invalid dma channel", ESP_ERR_INVALID_ARG );
|
||||
|
||||
spi_chan_claimed=spicommon_periph_claim(host);
|
||||
spi_chan_claimed=spicommon_periph_claim(host, "spi slave");
|
||||
SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
|
||||
|
||||
if ( dma_chan != 0 ) {
|
||||
|
@ -98,8 +98,9 @@ choice SPIRAM_SPEED
|
||||
2. Flash SPI running at 80Mhz and RAM SPI running at 40Mhz
|
||||
3. Flash SPI running at 80Mhz and RAM SPI running at 80Mhz
|
||||
|
||||
Note: If the third mode(80Mhz+80Mhz) is enabled, the VSPI port will be occupied by the system.
|
||||
Application code should never touch VSPI hardware in this case. The option to select
|
||||
Note: If the third mode(80Mhz+80Mhz) is enabled for SPI RAM of type 32MBit, one of the HSPI/VSPI host will
|
||||
be occupied by the system. Which SPI host to use can be selected by the config item SPIRAM_OCCUPY_SPI_HOST.
|
||||
Application code should never touch HSPI/VSPI hardware in this case. The option to select
|
||||
80MHz will only be visible if the flash SPI speed is also 80MHz. (ESPTOOLPY_FLASHFREQ_80M is true)
|
||||
|
||||
config SPIRAM_SPEED_40M
|
||||
@ -213,6 +214,20 @@ config SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
in PSRAM instead of internal memory, and placed most of variables of lwip,net802.11,pp,bluedroid library
|
||||
to external memory defaultly.
|
||||
|
||||
choice SPIRAM_OCCUPY_SPI_HOST
|
||||
prompt "SPI host to use for 32MBit PSRAM"
|
||||
default SPIRAM_OCCUPY_VSPI_HOST
|
||||
depends on SPIRAM_SPEED_80M
|
||||
help
|
||||
When both flash and PSRAM is working under 80MHz, and the PSRAM is of type 32MBit, one of the HSPI/VSPI
|
||||
host will be used to output the clock. Select which one to use here.
|
||||
|
||||
config SPIRAM_OCCUPY_HSPI_HOST
|
||||
bool "HSPI host (SPI2)"
|
||||
config SPIRAM_OCCUPY_VSPI_HOST
|
||||
bool "VSPI host (SPI3)"
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
|
||||
config MEMMAP_TRACEMEM
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "xtensa/core-macros.h"
|
||||
#include "bootloader_clock.h"
|
||||
#include "driver/spi_common.h"
|
||||
|
||||
/* Number of cycles to wait from the 32k XTAL oscillator to consider it running.
|
||||
* Larger values increase startup delay. Smaller values may cause false positive
|
||||
@ -292,11 +293,16 @@ void esp_perip_clk_init(void)
|
||||
DPORT_SPI_DMA_CLK_EN;
|
||||
|
||||
#if CONFIG_SPIRAM_SPEED_80M
|
||||
//80MHz SPIRAM uses SPI3 as well; it's initialized before this is called. Because it is used in
|
||||
//80MHz SPIRAM uses SPI2/SPI3 as well; it's initialized before this is called. Because it is used in
|
||||
//a weird mode where clock to the peripheral is disabled but reset is also disabled, it 'hangs'
|
||||
//in a state where it outputs a continuous 80MHz signal. Mask its bit here because we should
|
||||
//not modify that state, regardless of what we calculated earlier.
|
||||
if (!spicommon_periph_in_use(HSPI_HOST)) {
|
||||
common_perip_clk &= ~DPORT_SPI2_CLK_EN;
|
||||
}
|
||||
if (!spicommon_periph_in_use(VSPI_HOST)) {
|
||||
common_perip_clk &= ~DPORT_SPI3_CLK_EN;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock,
|
||||
|
@ -98,6 +98,27 @@ typedef enum {
|
||||
#define _SPI_80M_CLK_DIV 1
|
||||
#define _SPI_40M_CLK_DIV 2
|
||||
|
||||
//For 4MB PSRAM, we need one more SPI host, select which one to use by kconfig
|
||||
#ifdef CONFIG_SPIRAM_OCCUPY_HSPI_HOST
|
||||
#define PSRAM_SPI_MODULE PERIPH_HSPI_MODULE
|
||||
#define PSRAM_SPI_HOST HSPI_HOST
|
||||
#define PSRAM_CLK_SIGNAL HSPICLK_OUT_IDX
|
||||
#define PSRAM_SPI_NUM PSRAM_SPI_2
|
||||
#define PSRAM_SPICLKEN DPORT_SPI2_CLK_EN
|
||||
#elif defined CONFIG_SPIRAM_OCCUPY_VSPI_HOST
|
||||
#define PSRAM_SPI_MODULE PERIPH_VSPI_MODULE
|
||||
#define PSRAM_SPI_HOST VSPI_HOST
|
||||
#define PSRAM_CLK_SIGNAL VSPICLK_OUT_IDX
|
||||
#define PSRAM_SPI_NUM PSRAM_SPI_3
|
||||
#define PSRAM_SPICLKEN DPORT_SPI3_CLK_EN
|
||||
#else //set to SPI avoid HSPI and VSPI being used
|
||||
#define PSRAM_SPI_MODULE PERIPH_SPI_MODULE
|
||||
#define PSRAM_SPI_HOST SPI_HOST
|
||||
#define PSRAM_CLK_SIGNAL SPICLK_OUT_IDX
|
||||
#define PSRAM_SPI_NUM PSRAM_SPI_1
|
||||
#define PSRAM_SPICLKEN DPORT_SPI01_CLK_EN
|
||||
#endif
|
||||
|
||||
static const char* TAG = "psram";
|
||||
typedef enum {
|
||||
PSRAM_SPI_1 = 0x1,
|
||||
@ -621,27 +642,27 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
|
||||
} else if (PSRAM_IS_32MBIT_VER0(s_psram_id)) {
|
||||
s_clk_mode = PSRAM_CLK_MODE_DCLK;
|
||||
if (mode == PSRAM_CACHE_F80M_S80M) {
|
||||
/* note: If the third mode(80Mhz+80Mhz) is enabled for 32MBit 1V8 psram, VSPI port will be
|
||||
occupied by the system.
|
||||
Application code should never touch VSPI hardware in this case. We try to stop applications
|
||||
/* note: If the third mode(80Mhz+80Mhz) is enabled for 32MBit 1V8 psram, one of HSPI/VSPI port will be
|
||||
occupied by the system (according to kconfig).
|
||||
Application code should never touch HSPI/VSPI hardware in this case. We try to stop applications
|
||||
from doing this using the drivers by claiming the port for ourselves */
|
||||
periph_module_enable(PERIPH_VSPI_MODULE);
|
||||
bool r=spicommon_periph_claim(VSPI_HOST);
|
||||
periph_module_enable(PSRAM_SPI_MODULE);
|
||||
bool r=spicommon_periph_claim(PSRAM_SPI_HOST, "psram");
|
||||
if (!r) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
gpio_matrix_out(PSRAM_CLK_IO, VSPICLK_OUT_IDX, 0, 0);
|
||||
gpio_matrix_out(PSRAM_CLK_IO, PSRAM_CLK_SIGNAL, 0, 0);
|
||||
//use spi3 clock,but use spi1 data/cs wires
|
||||
//We get a solid 80MHz clock from SPI3 by setting it up, starting a transaction, waiting until it
|
||||
//is in progress, then cutting the clock (but not the reset!) to that peripheral.
|
||||
WRITE_PERI_REG(SPI_ADDR_REG(PSRAM_SPI_3), 32 << 24);
|
||||
WRITE_PERI_REG(SPI_CLOCK_REG(PSRAM_SPI_3), SPI_CLK_EQU_SYSCLK_M); //SET 80M AND CLEAR OTHERS
|
||||
SET_PERI_REG_MASK(SPI_CMD_REG(PSRAM_SPI_3), SPI_FLASH_READ_M);
|
||||
WRITE_PERI_REG(SPI_ADDR_REG(PSRAM_SPI_NUM), 32 << 24);
|
||||
WRITE_PERI_REG(SPI_CLOCK_REG(PSRAM_SPI_NUM), SPI_CLK_EQU_SYSCLK_M); //SET 80M AND CLEAR OTHERS
|
||||
SET_PERI_REG_MASK(SPI_CMD_REG(PSRAM_SPI_NUM), SPI_FLASH_READ_M);
|
||||
uint32_t spi_status;
|
||||
while (1) {
|
||||
spi_status = READ_PERI_REG(SPI_EXT2_REG(PSRAM_SPI_3));
|
||||
spi_status = READ_PERI_REG(SPI_EXT2_REG(PSRAM_SPI_NUM));
|
||||
if (spi_status != 0 && spi_status != 1) {
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, PSRAM_SPICLKEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,38 @@
|
||||
set(COMPONENT_SRCDIRS ".")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ". ${CMAKE_CURRENT_BINARY_DIR}")
|
||||
if (CONFIG_TEST_ESP32_SUBTEST_ONLY)
|
||||
set(COMPONENT_SRCDIRS "psram_4m")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
|
||||
set(COMPONENT_REQUIRES unity nvs_flash ulp)
|
||||
register_component()
|
||||
|
||||
register_component()
|
||||
else()
|
||||
set(COMPONENT_SRCDIRS ". psram_4m")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ". ${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test_tjpgd_logo.h"
|
||||
set(COMPONENT_REQUIRES unity nvs_flash ulp)
|
||||
|
||||
register_component()
|
||||
|
||||
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test_tjpgd_logo.h"
|
||||
COMMAND xxd -i "logo.jpg" "${CMAKE_CURRENT_BINARY_DIR}/test_tjpgd_logo.h"
|
||||
WORKING_DIRECTORY ${COMPONENT_PATH}
|
||||
DEPENDS "${CMAKE_CURRENT_LIST_DIR}/logo.jpg")
|
||||
|
||||
# Calculate MD5 value of header file esp_wifi_os_adapter.h
|
||||
execute_process(COMMAND md5sum ${IDF_PATH}/components/esp32/include/esp_wifi_os_adapter.h
|
||||
# Calculate MD5 value of header file esp_wifi_os_adapter.h
|
||||
execute_process(COMMAND md5sum ${IDF_PATH}/components/esp32/include/esp_wifi_os_adapter.h
|
||||
COMMAND cut -c 1-7
|
||||
OUTPUT_VARIABLE WIFI_OS_ADAPTER_MD5
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
# Calculate MD5 value of header file esp_wifi_crypto_types.h
|
||||
execute_process(COMMAND md5sum ${IDF_PATH}/components/esp32/include/esp_wifi_crypto_types.h
|
||||
# Calculate MD5 value of header file esp_wifi_crypto_types.h
|
||||
execute_process(COMMAND md5sum ${IDF_PATH}/components/esp32/include/esp_wifi_crypto_types.h
|
||||
COMMAND cut -c 1-7
|
||||
OUTPUT_VARIABLE WIFI_CRYPTO_MD5
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
add_definitions(-DWIFI_OS_ADAPTER_MD5=\"${WIFI_OS_ADAPTER_MD5}\")
|
||||
add_definitions(-DWIFI_CRYPTO_MD5=\"${WIFI_CRYPTO_MD5}\")
|
||||
add_definitions(-DWIFI_OS_ADAPTER_MD5=\"${WIFI_OS_ADAPTER_MD5}\")
|
||||
add_definitions(-DWIFI_CRYPTO_MD5=\"${WIFI_CRYPTO_MD5}\")
|
||||
|
||||
add_custom_target(esp32_test_logo DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/test_tjpgd_logo.h")
|
||||
add_custom_target(esp32_test_logo DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/test_tjpgd_logo.h")
|
||||
|
||||
add_dependencies(${COMPONENT_NAME} esp32_test_logo)
|
||||
add_dependencies(${COMPONENT_NAME} esp32_test_logo)
|
||||
endif()
|
@ -6,7 +6,11 @@ COMPONENT_EXTRA_CLEAN := test_tjpgd_logo.h
|
||||
|
||||
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
|
||||
|
||||
COMPONENT_SRCDIRS := . test_vectors
|
||||
ifdef CONFIG_TEST_ESP32_SUBTEST_ONLY
|
||||
COMPONENT_SRCDIRS := psram_4m
|
||||
else
|
||||
COMPONENT_SRCDIRS := . test_vectors psram_4m
|
||||
endif
|
||||
|
||||
# Calculate MD5 value of header file esp_wifi_os_adapter.h
|
||||
WIFI_OS_ADAPTER_MD5_VAL=\"$(shell md5sum $(IDF_PATH)/components/esp32/include/esp_wifi_os_adapter.h | cut -c 1-7)\"
|
||||
|
69
components/esp32/test/psram_4m/test_4mpsram.c
Normal file
69
components/esp32/test/psram_4m/test_4mpsram.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include "esp_heap_caps.h"
|
||||
#include "unity.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/spi_common.h"
|
||||
|
||||
static const char TAG[] = "test_psram";
|
||||
|
||||
static void test_psram_content()
|
||||
{
|
||||
const int test_size = 2048;
|
||||
uint32_t *test_area = heap_caps_malloc(test_size, MALLOC_CAP_SPIRAM);
|
||||
|
||||
size_t p;
|
||||
size_t s=test_size;
|
||||
int errct=0;
|
||||
int initial_err=-1;
|
||||
for (p=0; p<(s/sizeof(int)); p+=4) {
|
||||
test_area[p]=p^0xAAAAAAAA;
|
||||
}
|
||||
for (p=0; p<(s/sizeof(int)); p+=4) {
|
||||
if (test_area[p]!=(p^0xAAAAAAAA)) {
|
||||
errct++;
|
||||
if (errct==1) initial_err=p*4;
|
||||
}
|
||||
}
|
||||
if (errct) {
|
||||
ESP_LOGE(TAG, "SPI SRAM memory test fail. %d/%d writes failed, first @ %p\n", errct, s/32, initial_err+test_area);
|
||||
TEST_FAIL();
|
||||
} else {
|
||||
ESP_LOGI(TAG, "SPI SRAM memory test OK");
|
||||
}
|
||||
|
||||
free(test_area);
|
||||
}
|
||||
|
||||
// NOTE: this unit test rely on the config that PSRAM of 8MB is used only when CONFIG_SPIRAM_BNKSWITCH_ENABLE is set
|
||||
TEST_CASE("can use spi when not being used by psram", "[esp32]")
|
||||
{
|
||||
spi_host_device_t host;
|
||||
#if !CONFIG_SPIRAM_SUPPORT || !CONFIG_SPIRAM_SPEED_80M || CONFIG_SPIRAM_BANKSWITCH_ENABLE
|
||||
//currently all 8M psram don't need more SPI peripherals
|
||||
host = -1;
|
||||
#elif CONFIG_SPIRAM_OCCUPY_HSPI_HOST
|
||||
host = HSPI_HOST;
|
||||
#elif CONFIG_SPIRAM_OCCUPY_VSPI_HOST
|
||||
host = VSPI_HOST;
|
||||
#endif
|
||||
|
||||
bool claim_hspi = spicommon_periph_claim(HSPI_HOST, "ut-hspi");
|
||||
if (claim_hspi) ESP_LOGI(TAG, "HSPI claimed.");
|
||||
|
||||
bool claim_vspi = spicommon_periph_claim(VSPI_HOST, "ut-vspi");
|
||||
if (claim_vspi) ESP_LOGI(TAG, "VSPI claimed.");
|
||||
|
||||
if (host == HSPI_HOST) {
|
||||
TEST_ASSERT(claim_hspi==false);
|
||||
TEST_ASSERT(claim_vspi==true);
|
||||
} else if (host == VSPI_HOST) {
|
||||
TEST_ASSERT(claim_vspi==false);
|
||||
TEST_ASSERT(claim_hspi==true);
|
||||
} else {
|
||||
TEST_ASSERT(claim_hspi==true);
|
||||
TEST_ASSERT(claim_vspi==true);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPIRAM_SUPPORT
|
||||
test_psram_content();
|
||||
#endif
|
||||
}
|
@ -47,7 +47,7 @@ ESP-IDF fully supports integrating external memory use into your applications. E
|
||||
* Initialize RAM, add it to the capability allocator and add memory to the pool of RAM that can be returned by ``malloc()``. This allows
|
||||
any application to use the external RAM without having to rewrite the code to use ``heap_caps_malloc``.
|
||||
* Initialize RAM, use a region start from 0x3F800000 for storing zero initialized data(BSS segment) of lwip,net802.11,pp,bluedroid library
|
||||
by enabling :ref: `CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY` in menuconfig,this way can save some internal memory,because the BSS segment
|
||||
by enabling :ref: `CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY` in menuconfig, this way can save some internal memory,because the BSS segment
|
||||
originally stored in internal memory,and the rest of external RAM can be add the capability allocator and add memory to the pool of RAM as above way
|
||||
|
||||
All these options can be selected from the menuconfig menu.
|
||||
@ -75,6 +75,7 @@ The use of external RAM has a few restrictions:
|
||||
them is defined by linkfile, the :ref:`CONFIG_SPIRAM_IGNORE_NOTFOUND` can't handle this situation,if you want to enable :ref:
|
||||
`CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY` the :ref:`CONFIG_SPIRAM_IGNORE_NOTFOUND` will be disabled, and if initialize SPIRAM failed,the system
|
||||
will invoke abort.
|
||||
* External RAM of 4MBit (test up to know) has to be used with one of HSPI/VSPI occupied under 80MHz. Select which SPI host to be used by :ref:`CONFIG_SPIRAM_OCCUPY_SPI_HOST`.
|
||||
|
||||
Because there are a fair few situations that have a specific need for internal memory, but it is also possible to use malloc() to exhaust
|
||||
internal memory, there is a pool reserved specifically for requests that cannot be resolved from external memory; allocating task
|
||||
|
@ -13,3 +13,14 @@ config UNITY_FREERTOS_STACK_SIZE
|
||||
default 8192
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Test options"
|
||||
|
||||
config TEST_ESP32_SUBTEST_ONLY
|
||||
bool "Test only 4M PSRAM cases for esp32 component"
|
||||
depends on SPIRAM_SUPPORT
|
||||
default n
|
||||
help
|
||||
If this option is enabled, only 4M PSRAM cases are compiled. Otherwise all cases are included.
|
||||
|
||||
endmenu
|
||||
|
6
tools/unit-test-app/configs/psram_hspi
Normal file
6
tools/unit-test-app/configs/psram_hspi
Normal file
@ -0,0 +1,6 @@
|
||||
TEST_COMPONENTS=esp32
|
||||
CONFIG_TEST_ESP32_SUBTEST_ONLY=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
||||
CONFIG_SPIRAM_SUPPORT=y
|
||||
CONFIG_SPIRAM_SPEED_80M=y
|
||||
CONFIG_SPIRAM_OCCUPY_HSPI_HOST=y
|
6
tools/unit-test-app/configs/psram_vspi
Normal file
6
tools/unit-test-app/configs/psram_vspi
Normal file
@ -0,0 +1,6 @@
|
||||
TEST_COMPONENTS=esp32
|
||||
CONFIG_TEST_ESP32_SUBTEST_ONLY=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
||||
CONFIG_SPIRAM_SUPPORT=y
|
||||
CONFIG_SPIRAM_SPEED_80M=y
|
||||
CONFIG_SPIRAM_OCCUPY_VSPI_HOST=y
|
Loading…
x
Reference in New Issue
Block a user