Add support to PSRAM using SPIRAM interface

This commit is contained in:
Alan C. Assis 2020-10-07 12:42:48 -03:00 committed by Abdelatif Guettouche
parent d1225f3110
commit 232aa62f03
13 changed files with 4518 additions and 0 deletions

View File

@ -15,6 +15,8 @@ config ARCH_CHIP_ESP32
select XTENSA_HAVE_INTERRUPTS
select ARCH_HAVE_MULTICPU
select ARCH_HAVE_MODULE_TEXT
select ARCH_HAVE_SDRAM
select ARCH_HAVE_HEAP2
select ARCH_HAVE_RESET
select ARCH_TOOLCHAIN_GNU
---help---

View File

@ -131,6 +131,26 @@ config ESP32_SPI3
select ESP32_GPIO_IRQ
select SPI
config ESP32_SPIRAM
bool "SPI RAM Support"
default n
if ESP32_SPIRAM && SMP
choice
prompt "How does SPIRAM share cache?"
default ESP32_MEMMAP_SPIRAM_CACHE_EVENODD
help
Selects the cache mode to CPU access the external memory.
config ESP32_MEMMAP_SPIRAM_CACHE_EVENODD
bool "Pro CPU uses even 32 byte ranges, App uses odd ones"
config ESP32_MEMMAP_SPIRAM_CACHE_LOWHIGH
bool "Pro CPU uses low 2MB ranges, App uses high ones"
endchoice # CPU frequency
endif
config XTENSA_TIMER1
bool "Xtensa Timer 1"
default n
@ -497,6 +517,78 @@ config ESP32_SPIFLASH_DEBUG
endmenu # ESP32_SPIFLASH
menu "SPI RAM Config"
depends on ESP32_SPIRAM
choice ESP32_SPIRAM_TYPE
prompt "Type of SPI RAM chip in use"
default ESP32_SPIRAM_TYPE_AUTO
config ESP32_SPIRAM_TYPE_AUTO
bool "Auto-detect"
config ESP32_SPIRAM_TYPE_ESPPSRAM32
bool "ESP-PSRAM32 or IS25WP032"
config ESP32_SPIRAM_TYPE_ESPPSRAM64
bool "ESP-PSRAM64 or LY68L6400"
endchoice #ESP32_SPIRAM_TYPE
config ESP32_SPIRAM_SIZE
int
default -1 if ESP32_SPIRAM_TYPE_AUTO
default 4194304 if ESP32_SPIRAM_TYPE_ESPPSRAM32
default 8388608 if ESP32_SPIRAM_TYPE_ESPPSRAM64
default 0
choice ESP32_SPIRAM_SPEED
prompt "Set RAM clock speed"
default ESP32_SPIRAM_SPEED_40M
help
Select the speed for the SPI RAM chip.
config ESP32_SPIRAM_SPEED_40M
bool "40MHz clock speed"
config ESP32_SPIRAM_SPEED_80M
bool "80MHz clock speed"
endchoice # ESP32_SPIRAM_SPEED
config ESP32_SPIRAM_BOOT_INIT
bool "Initialize SPI RAM during startup"
default "y"
help
If this is enabled, the SPI RAM will be enabled during initial
boot. Unless you have specific requirements, you'll want to leave
this enabled so memory allocated during boot-up can also be
placed in SPI RAM.
config ESP32_SPIRAM_IGNORE_NOTFOUND
bool "Ignore PSRAM when not found"
default "n"
depends on ESP_SPIRAM_BOOT_INIT && !BOOT_SDRAM_DATA
help
Normally, if psram initialization is enabled during compile time
but not found at runtime, it is seen as an error making the CPU
panic. If this is enabled, booting will complete but no PSRAM
will be available.
config ESP32_SPIRAM_2T_MODE
bool "Enable SPI PSRAM 2T mode"
depends on ESP32_SPIRAM
default "n"
help
Enable this option to fix single bit errors inside 64Mbit PSRAM.
Some 64Mbit PSRAM chips have a hardware issue in the RAM which
causes bit errors at multiple fixed bit positions.
Note: If this option is enabled, the 64Mbit PSRAM chip will appear
to be 32Mbit in size.
Applications will not be affected unless the use the esp_himem
APIs, which are not supported in 2T mode.
endmenu #SPI RAM Config
menu "Ethernet configuration"
depends on ESP32_EMAC

View File

@ -114,6 +114,11 @@ ifeq ($(CONFIG_ESP32_SPIFLASH),y)
CHIP_CSRCS += esp32_spiflash.c
endif
ifeq ($(CONFIG_ESP32_SPIRAM),y)
CHIP_CSRCS += esp32_spiram.c
CHIP_CSRCS += esp32_psram.c
endif
ifeq ($(CONFIG_ESP32_EMAC),y)
CHIP_CSRCS += esp32_emac.c
endif

View File

@ -43,11 +43,16 @@
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/mm/mm.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "xtensa.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
@ -88,5 +93,10 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
#if CONFIG_MM_REGIONS > 1
void xtensa_add_region(void)
{
/* Check for any additional memory regions */
#if defined(CONFIG_HEAP2_BASE) && defined(CONFIG_HEAP2_SIZE)
umm_addregion((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE);
#endif
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,91 @@
/****************************************************************************
* arch/xtensa/src/esp32/esp32_psram.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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 __ARCH_XTENSA_SRC_ESP32_ESP32_PSRAM_H
#define __ARCH_XTENSA_SRC_ESP32_ESP32_PSRAM_H
/****************************************************************************
* Included Files
****************************************************************************/
typedef enum
{
PSRAM_CACHE_F80M_S40M = 0,
PSRAM_CACHE_F40M_S40M,
PSRAM_CACHE_F80M_S80M,
PSRAM_CACHE_MAX,
} psram_cache_mode_t;
typedef enum
{
PSRAM_SIZE_16MBITS = 0,
PSRAM_SIZE_32MBITS = 1,
PSRAM_SIZE_64MBITS = 2,
PSRAM_SIZE_MAX,
} psram_size_t;
/* See the TRM, chapter PID/MPU/MMU, header 'External RAM' for the
* definitions of these modes. Important is that NORMAL works with the app
* CPU cache disabled, but gives huge cache coherency issues when both app
* and pro CPU are enabled. LOWHIGH and EVENODD do not have these coherency
* issues but cannot be used when the app CPU cache is disabled.
*/
typedef enum
{
PSRAM_VADDR_MODE_NORMAL = 0, /* App and Pro CPU use their own flash cache
* for external RAM access
*/
PSRAM_VADDR_MODE_LOWHIGH, /* App and Pro CPU share external RAM caches:
* pro CPU has low 2M, app CPU has high 2M
*/
PSRAM_VADDR_MODE_EVENODD, /* App and Pro CPU share external RAM caches:
* pro CPU does even 32yte ranges, app does
* odd ones.
*/
} psram_vaddr_mode_t;
/* Description: Get PSRAM size
* return:
* - PSRAM_SIZE_MAX if psram not enabled or not valid
* - PSRAM size
*/
psram_size_t psram_get_size(void);
/* Description: PSRAM cache enable function
*
* Esp-idf uses this to initialize cache for psram, mapping it into the main
* memory address space.
*
* param:
* mode SPI mode to access psram in
* vaddrmode Mode the psram cache works in.
* return:
* OK on success
* EINVAL when VSPI peripheral is needed but cannot be
* claimed.
*/
int psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t
vaddrmode);
#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_HIMEM_H */

View File

@ -0,0 +1,385 @@
/****************************************************************************
* arch/xtensa/src/esp32/esp32_spiflash.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifdef CONFIG_ESP32_SPIRAM
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>
#include <debug.h>
#include <string.h>
#include <sys/param.h>
#include <nuttx/config.h>
#include "esp32_spiram.h"
#include "esp32_psram.h"
#include "xtensa.h"
#include "xtensa_attr.h"
#include "hardware/esp32_soc.h"
#include "hardware/esp32_dport.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef CONFIG_SMP
# define PSRAM_MODE PSRAM_VADDR_MODE_NORMAL
#else
#if CONFIG_ESP32_MEMMAP_SPIRAM_CACHE_EVENODD
# define PSRAM_MODE PSRAM_VADDR_MODE_EVENODD
#else
# define PSRAM_MODE PSRAM_VADDR_MODE_LOWHIGH
#endif
#endif
/****************************************************************************
* Private Data
****************************************************************************/
/* Let's to assume SPIFLASH SPEED == SPIRAM SPEED for now */
#if CONFIG_ESP32_SPIRAM_SPEED_40M
# define PSRAM_SPEED PSRAM_CACHE_F40M_S40M
#elif CONFIG_ESP32_SPIRAM_SPEED_80M
# define PSRAM_SPEED PSRAM_CACHE_F80M_S80M
#else
# error "FLASH speed can only be equal to or higher than SRAM speed while SRAM is enabled!"
#endif
#if defined(CONFIG_BOOT_SDRAM_DATA)
extern uint8_t _ext_ram_bss_start;
extern uint8_t _ext_ram_bss_end;
#endif
static bool spiram_inited = false;
/****************************************************************************
* Private Functions
****************************************************************************/
/* If no function in esp_himem.c is used, this function will be linked into
* the binary instead of the one in esp_himem.c, automatically making sure
* no memory is reserved if no himem function is used.
*/
size_t __attribute__((weak)) esp_himem_reserved_area_size(void)
{
return 0;
}
static int spiram_size_usable_for_malloc(void)
{
int s = esp_spiram_get_size();
if (s > 4 * 1024 * 1024)
{
s = 4 * 1024 * 1024; /* we can map at most 4MiB */
}
return s - esp_himem_reserved_area_size();
}
/****************************************************************************
* Public Functions
****************************************************************************/
void IRAM_ATTR esp_spiram_init_cache(void)
{
/* Enable external RAM in MMU */
cache_sram_mmu_set(0, 0, SOC_EXTRAM_DATA_LOW, 0, 32, 128);
/* Flush and enable icache for APP CPU */
#ifdef CONFIG_SMP
DPORT_CLEAR_PERI_REG_MASK(DPORT_APP_CACHE_CTRL1_REG,
DPORT_APP_CACHE_MASK_DRAM1);
cache_sram_mmu_set(1, 0, SOC_EXTRAM_DATA_LOW, 0, 32, 128);
#endif
}
esp_spiram_size_t esp_spiram_get_chip_size(void)
{
if (!spiram_inited)
{
merr("SPI RAM not initialized");
return ESP_SPIRAM_SIZE_INVALID;
}
psram_size_t psram_size = psram_get_size();
switch (psram_size)
{
case PSRAM_SIZE_16MBITS:
return ESP_SPIRAM_SIZE_16MBITS;
case PSRAM_SIZE_32MBITS:
return ESP_SPIRAM_SIZE_32MBITS;
case PSRAM_SIZE_64MBITS:
return ESP_SPIRAM_SIZE_64MBITS;
default:
return ESP_SPIRAM_SIZE_INVALID;
}
}
int esp_spiram_init(void)
{
int ret;
ret = psram_enable(PSRAM_SPEED, PSRAM_MODE);
if (ret != OK)
{
#ifdef CONFIG_ESP32_SPIRAM_IGNORE_NOTFOUND
merr("SPI RAM enabled but initialization failed.\
Bailing out.");
#endif
return ret;
}
/* note: this needs to be set before esp_spiram_get_chip_* /
* esp_spiram_get_size calls.
*/
spiram_inited = true;
#if (CONFIG_ESP32_SPIRAM_SIZE != -1)
if (esp_spiram_get_size() != CONFIG_ESP32_SPIRAM_SIZE)
{
merr("Expected %dKiB chip but found %dKiB chip.\
Bailing out..\n", CONFIG_ESP32_SPIRAM_SIZE / 1024,
esp_spiram_get_size() / 1024);
return -EINVAL;
}
#endif
minfo("Found %dMBit SPI RAM device\n",
(esp_spiram_get_size() * 8) / (1024 * 1024));
minfo("SPI RAM mode: %s\n",
PSRAM_SPEED == PSRAM_CACHE_F40M_S40M ? "flash 40m sram 40m" : \
PSRAM_SPEED == PSRAM_CACHE_F80M_S40M ? "flash 80m sram 40m" : \
PSRAM_SPEED == PSRAM_CACHE_F80M_S80M ? "flash 80m sram 80m" : \
"ERROR");
minfo("PSRAM initialized, cache is in %s mode.\n", \
(PSRAM_MODE == PSRAM_VADDR_MODE_EVENODD) ? "even/odd (2-core)": \
(PSRAM_MODE == PSRAM_VADDR_MODE_LOWHIGH) ? "low/high (2-core)": \
(PSRAM_MODE == PSRAM_VADDR_MODE_NORMAL) ? "normal (1-core)":"ERROR");
return OK;
}
#if 0
/* DMA is not supported yet */
static uint8_t *dma_heap;
int esp_spiram_reserve_dma_pool(size_t size)
{
minfo("Reserving pool of %dK of internal memory for DMA/internal\
allocations", size / 1024);
/* Pool may be allocated in multiple non-contiguous chunks, depending on
* available RAM
*/
while (size > 0)
{
size_t next_size = heap_caps_get_largest_free_block(MALLOC_CAP_DMA |
MALLOC_CAP_INTERNAL);
next_size = MIN(next_size, size);
minfo("Allocating block of size %d bytes", next_size);
dma_heap = heap_caps_malloc(next_size, MALLOC_CAP_DMA |
MALLOC_CAP_INTERNAL);
if (!dma_heap || next_size == 0)
{
return ESP_ERR_NO_MEM;
}
uint32_t caps[] =
{
0, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL,
MALLOC_CAP_8BIT | MALLOC_CAP_32BIT
};
int e = heap_caps_add_region_with_caps(caps, (intptr_t) dma_heap,
(intptr_t) dma_heap + next_size - 1);
if (e != ESP_OK)
{
return e;
}
size -= next_size;
}
return OK;
}
#endif
size_t esp_spiram_get_size(void)
{
psram_size_t size = esp_spiram_get_chip_size();
if (size == PSRAM_SIZE_16MBITS)
{
return 2 * 1024 * 1024;
}
if (size == PSRAM_SIZE_32MBITS)
{
return 4 * 1024 * 1024;
}
if (size == PSRAM_SIZE_64MBITS)
{
return 8 * 1024 * 1024;
}
return CONFIG_ESP32_SPIRAM_SIZE;
}
/* Before flushing the cache, if psram is enabled as a memory-mapped thing,
* we need to write back the data in the cache to the psram first, otherwise
* it will get lost. For now, we just read 64/128K of random PSRAM memory to
* do this. Note that this routine assumes some unique mapping for the first
* 2 banks of the PSRAM memory range, as well as the 2 banks after the 2 MiB
* mark.
*/
void IRAM_ATTR esp_spiram_writeback_cache(void)
{
int x;
uint32_t regval;
volatile int i = 0;
volatile uint8_t *psram = (volatile uint8_t *)SOC_EXTRAM_DATA_LOW;
int cache_was_disabled = 0;
if (!spiram_inited)
{
return;
}
/* We need cache enabled for this to work. Re-enable it if needed; make
* sure we disable it again on exit as well.
*/
regval = getreg32(DPORT_PRO_CACHE_CTRL_REG);
if ((regval & DPORT_PRO_CACHE_ENABLE) == 0)
{
cache_was_disabled |= (1 << 0);
regval = getreg32(DPORT_PRO_CACHE_CTRL_REG);
regval |= (1 << DPORT_PRO_CACHE_ENABLE_S);
putreg32(regval, DPORT_PRO_CACHE_CTRL_REG);
}
#ifdef CONFIG_SMP
regval = getreg32(DPORT_APP_CACHE_CTRL_REG);
if ((regval & DPORT_APP_CACHE_ENABLE) == 0)
{
cache_was_disabled |= (1 << 1);
regval = getreg32(DPORT_APP_CACHE_CTRL_REG);
regval |= 1 << DPORT_APP_CACHE_ENABLE_S;
putreg32(regval, DPORT_APP_CACHE_CTRL_REG);
}
#endif
#if (PSRAM_MODE != PSRAM_VADDR_MODE_LOWHIGH)
/* Single-core and even/odd mode only have 32K of cache evenly distributed
* over the address lines. We can clear the cache by just reading 64K
* worth of cache lines.
*/
for (x = 0; x < 1024 * 64; x += 32)
{
i += psram[x];
}
#else
/* Low/high psram cache mode uses one 32K cache for the lowest 2MiB of SPI
* flash and another 32K for the highest 2MiB. Clear this by reading from
* both regions. Note: this assumes the amount of external RAM is >2M.
* If it is 2M or less, what this code does is undefined. If we ever
* support external RAM chips of 2M or smaller, this may need adjusting.
*/
for (x = 0; x < 1024 * 64; x += 32)
{
i += psram[x];
i += psram[x + (1024 * 1024 * 2)];
}
#endif
if (cache_was_disabled & (1 << 0))
{
while (((getreg32(DPORT_PRO_DCACHE_DBUG0_REG) >>
(DPORT_PRO_CACHE_STATE_S)) &
(DPORT_PRO_CACHE_STATE)) != 1)
{
};
regval = getreg32(DPORT_PRO_CACHE_CTRL_REG);
regval &= ~(1 << DPORT_PRO_CACHE_ENABLE_S);
putreg32(regval, DPORT_PRO_CACHE_CTRL_REG);
}
#ifdef CONFIG_SMP
if (cache_was_disabled & (1 << 1))
{
while (((getreg32(DPORT_APP_DCACHE_DBUG0_REG) >>
(DPORT_APP_CACHE_STATE_S)) &
(DPORT_APP_CACHE_STATE)) != 1)
{
};
regval = getreg32(DPORT_APP_CACHE_CTRL_REG);
regval &= ~(1 << DPORT_APP_CACHE_ENABLE_S);
putreg32(regval, DPORT_APP_CACHE_CTRL_REG);
}
#endif
}
/* If SPI RAM(PSRAM) has been initialized
*
* Return:
* - true SPI RAM has been initialized successfully
* - false SPI RAM hasn't been initialized or initialized failed
*/
bool esp_spiram_is_initialized(void)
{
return spiram_inited;
}
#endif

View File

@ -0,0 +1,157 @@
/****************************************************************************
* arch/xtensa/src/esp32/esp32_spiram.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#ifndef __ARCH_XTENSA_SRC_ESP32_ESP32_SPIRAM_H
#define __ARCH_XTENSA_SRC_ESP32_ESP32_SPIRAM_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "xtensa_attr.h"
typedef enum
{
ESP_SPIRAM_SIZE_16MBITS = 0, /* SPI RAM size is 16 MBits */
ESP_SPIRAM_SIZE_32MBITS = 1, /* SPI RAM size is 32 MBits */
ESP_SPIRAM_SIZE_64MBITS = 2, /* SPI RAM size is 64 MBits */
ESP_SPIRAM_SIZE_INVALID, /* SPI RAM size is invalid */
} esp_spiram_size_t;
/* Description: get SPI RAM size
* return
* - ESP_SPIRAM_SIZE_INVALID if SPI RAM not enabled or not valid
* - SPI RAM size
*/
esp_spiram_size_t esp_spiram_get_chip_size(void);
/* Description: Initialize spiram interface/hardware. Normally called from
* cpu_start.c.
*
* return:
* OK on success
*/
int esp_spiram_init(void);
/* Description: Configure Cache/MMU for access to external SPI RAM.
*
* Normally this function is called from cpu_start, if
* CONFIG_ESP32_SPIRAM_BOOT_INIT option is enabled. Applications which need to
* enable SPI RAM at run time can disable CONFIG_ESP32_SPIRAM_BOOT_INIT, and
* call this function later.
*
* Attention this function must be called with flash cache disabled.
*/
void esp_spiram_init_cache(void);
/* Description: Memory test for SPI RAM. Should be called after SPI RAM is
* initialized and (in case of a dual-core system) the app CPU
* is online. This test overwrites the memory with crap, so do
* not call after e.g. the heap allocator has stored important
* stuff in SPI RAM.
*
* return:
* true on success, false on failed memory test
*/
bool esp_spiram_test(void);
/* Description Add the initialized SPI RAM to the heap allocator. */
int esp_spiram_add_to_heapalloc(void);
/* Description: Get the size of the attached SPI RAM chip selected in
* menuconfig
*
* return:
* Size in bytes, or 0 if no external RAM chip support compiled in.
*/
size_t esp_spiram_get_size(void);
/* Description: Force a writeback of the data in the SPI RAM cache. This is
* to be called whenever cache is disabled, because disabling cache on the
* ESP32 discards the data in the SPI RAM cache.
*
* This is meant for use from within the SPI flash code.
*/
void esp_spiram_writeback_cache(void);
/* Description: Reserve a pool of internal memory for specific DMA/internal
* allocations.
*
* param:
* size Size of reserved pool in bytes
*
* return:
* - ESP_OK on success
* - ESP_ERR_NO_MEM when no memory available for pool
*/
int esp_spiram_reserve_dma_pool(size_t size);
/* Description: If SPI RAM(PSRAM) has been initialized
*
* return:
* - true SPI RAM has been initialized successfully
* - false SPI RAM hasn't been initialized or initialized failed
*/
bool esp_spiram_is_initialized(void);
/* Description: Set Ext-SRAM-Cache mmu mapping.
*
* Note that this code lives in IRAM and has a bugfix in respect to the
* ROM version of this function (which erroneously refused a vaddr > 2MiB
*
* param:
* int cpu_no : CPU number, 0 for PRO cpu, 1 for APP cpu.
* int pod : process identifier. Range 0~7.
* unsigned int vaddr : virtual address in CPU address space.
* Can be IRam0, IRam1, IRom0 and DRom0 memory
* address.
* Should be aligned by psize.
*
* unsigned int paddr : physical address in Ext-SRAM.
* Should be aligned by psize.
* int psize : page size of flash, in kilobytes. Should be 32 here.
* int num : pages to be set.
*
* unsigned int: error status
* 0 : mmu set success
* 1 : vaddr or paddr is not aligned
* 2 : pid error
* 3 : psize error
* 4 : mmu table to be written is out of range
* 5 : vaddr is out of range
*/
unsigned int IRAM_ATTR
cache_sram_mmu_set(int cpu_no, int pid, unsigned int vaddr,
unsigned int paddr, int psize, int num);
#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_SPIRAM_H */

View File

@ -43,6 +43,7 @@
#include "esp32_clockconfig.h"
#include "esp32_region.h"
#include "esp32_start.h"
#include "esp32_spiram.h"
/****************************************************************************
* Public Data
@ -146,6 +147,18 @@ void IRAM_ATTR __start(void)
xtensa_early_serial_initialize();
#endif
#if defined(CONFIG_ESP32_SPIRAM_BOOT_INIT)
esp_spiram_init_cache();
if (esp_spiram_init() != OK)
{
# if defined(ESP32_SPIRAM_IGNORE_NOTFOUND)
mwarn("SPIRAM Initialization failed!\n");
# else
PANIC();
# endif
}
#endif
/* Initialize onboard resources */
esp32_board_initialize();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,64 @@
/****************************************************************************
* arch/xtensa/src/esp32/hardware/esp32_caps.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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 __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_CAPS_H
#define __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_CAPS_H
#define SOC_SPI_PERIPH_NUM 3
#define SOC_SPI_DMA_CHAN_NUM 2
#define SOC_SPI_PERIPH_CS_NUM(i) 3
#define SPI_FUNC_NUM 1
#define SPI_IOMUX_PIN_NUM_MISO 7
#define SPI_IOMUX_PIN_NUM_MOSI 8
#define SPI_IOMUX_PIN_NUM_CLK 6
#define SPI_IOMUX_PIN_NUM_CS 11
#define SPI_IOMUX_PIN_NUM_WP 10
#define SPI_IOMUX_PIN_NUM_HD 9
#define HSPI_FUNC_NUM 1
/* For D2WD and PICO-D4 chip */
#define SPI_D2WD_PIN_NUM_MISO 17
#define SPI_D2WD_PIN_NUM_MOSI 8
#define SPI_D2WD_PIN_NUM_CLK 6
#define SPI_D2WD_PIN_NUM_CS 16
#define SPI_D2WD_PIN_NUM_WP 7
#define SPI_D2WD_PIN_NUM_HD 11
#define HSPI_IOMUX_PIN_NUM_MISO 12
#define HSPI_IOMUX_PIN_NUM_MOSI 13
#define HSPI_IOMUX_PIN_NUM_CLK 14
#define HSPI_IOMUX_PIN_NUM_CS 15
#define HSPI_IOMUX_PIN_NUM_WP 2
#define HSPI_IOMUX_PIN_NUM_HD 4
#define VSPI_FUNC_NUM 1
#define VSPI_IOMUX_PIN_NUM_MISO 19
#define VSPI_IOMUX_PIN_NUM_MOSI 23
#define VSPI_IOMUX_PIN_NUM_CLK 18
#define VSPI_IOMUX_PIN_NUM_CS 5
#define VSPI_IOMUX_PIN_NUM_WP 22
#define VSPI_IOMUX_PIN_NUM_HD 21
#define SOC_SPI_MAXIMUM_BUFFER_SIZE 64
#endif /* __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_CAPS_H */

View File

@ -246,6 +246,30 @@
#define DR_REG_PWM3_BASE 0x3ff70000
#define PERIPHS_SPI_ENCRYPT_BASEADDR DR_REG_SPI_ENCRYPT_BASE
/* Overall memory map */
#define SOC_DROM_LOW 0x3f400000
#define SOC_DROM_HIGH 0x3f800000
#define SOC_DRAM_LOW 0x3ffae000
#define SOC_DRAM_HIGH 0x40000000
#define SOC_IROM_LOW 0x400d0000
#define SOC_IROM_HIGH 0x40400000
#define SOC_IROM_MASK_LOW 0x40000000
#define SOC_IROM_MASK_HIGH 0x40064f00
#define SOC_CACHE_PRO_LOW 0x40070000
#define SOC_CACHE_PRO_HIGH 0x40078000
#define SOC_CACHE_APP_LOW 0x40078000
#define SOC_CACHE_APP_HIGH 0x40080000
#define SOC_IRAM_LOW 0x40080000
#define SOC_IRAM_HIGH 0x400a0000
#define SOC_RTC_IRAM_LOW 0x400c0000
#define SOC_RTC_IRAM_HIGH 0x400c2000
#define SOC_RTC_DRAM_LOW 0x3ff80000
#define SOC_RTC_DRAM_HIGH 0x3ff82000
#define SOC_RTC_DATA_LOW 0x50000000
#define SOC_RTC_DATA_HIGH 0x50002000
#define SOC_EXTRAM_DATA_LOW 0x3f800000
#define SOC_EXTRAM_DATA_HIGH 0x3fc00000
/* Interrupt hardware source table
* This table is decided by hardware, don't touch this.
*/

View File

@ -0,0 +1,96 @@
/****************************************************************************
* arch/xtensa/src/esp32/rom/esp32_efuse.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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 __XTENSA_SRC_ESP32_ROM_ESP32_EFUSE_H
#define __XTENSA_SRC_ESP32_ROM_ESP32_EFUSE_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: ets_efuse_read_op
****************************************************************************/
void ets_efuse_read_op(void);
/****************************************************************************
* Name: ets_efuse_program_op
****************************************************************************/
void ets_efuse_program_op(void);
/****************************************************************************
* Name: ets_efuse_get_8m_clock
****************************************************************************/
uint32_t ets_efuse_get_8m_clock(void);
/****************************************************************************
* name: ets_efuse_get_spiconfig
****************************************************************************/
uint32_t ets_efuse_get_spiconfig(void);
#define EFUSE_SPICFG_SPI_DEFAULTS 0
#define EFUSE_SPICFG_HSPI_DEFAULTS 1
#define EFUSE_SPICFG_RET_SPICLK_MASK 0x3f
#define EFUSE_SPICFG_RET_SPICLK_SHIFT 0
#define EFUSE_SPICFG_RET_SPICLK(ret) (((ret) >> EFUSE_SPICFG_RET_SPICLK_SHIFT) & EFUSE_SPICFG_RET_SPICLK_MASK)
#define EFUSE_SPICFG_RET_SPIQ_MASK 0x3f
#define EFUSE_SPICFG_RET_SPIQ_SHIFT 6
#define EFUSE_SPICFG_RET_SPIQ(ret) (((ret) >> EFUSE_SPICFG_RET_SPIQ_SHIFT) & EFUSE_SPICFG_RET_SPIQ_MASK)
#define EFUSE_SPICFG_RET_SPID_MASK 0x3f
#define EFUSE_SPICFG_RET_SPID_SHIFT 12
#define EFUSE_SPICFG_RET_SPID(ret) (((ret) >> EFUSE_SPICFG_RET_SPID_SHIFT) & EFUSE_SPICFG_RET_SPID_MASK)
#define EFUSE_SPICFG_RET_SPICS0_MASK 0x3f
#define EFUSE_SPICFG_RET_SPICS0_SHIFT 18
#define EFUSE_SPICFG_RET_SPICS0(ret) (((ret) >> EFUSE_SPICFG_RET_SPICS0_SHIFT) & EFUSE_SPICFG_RET_SPICS0_MASK)
#define EFUSE_SPICFG_RET_SPIHD_MASK 0x3f
#define EFUSE_SPICFG_RET_SPIHD_SHIFT 24
#define EFUSE_SPICFG_RET_SPIHD(ret) (((ret) >> EFUSE_SPICFG_RET_SPIHD_SHIFT) & EFUSE_SPICFG_RET_SPIHD_MASK)
/****************************************************************************
* name: eps_crc8
****************************************************************************/
unsigned char esp_crc8(unsigned char const *p, unsigned int len);
#ifdef __cplusplus
}
#endif
#endif /* __XTENSA_SRC_ESP32_ROM_ESP32_EFUSE_H */