xtensa/esp32s3: Support 32MB SPI flash
This commit is contained in:
parent
69081a72d7
commit
b24f931aca
@ -230,6 +230,11 @@ config ESP32S3_FLASH_16M
|
||||
bool
|
||||
default n
|
||||
|
||||
config ESP32S3_FLASH_32M
|
||||
bool
|
||||
default n
|
||||
select ESP32S3S_SPI_FLASH_USE_32BIT_ADDRESS
|
||||
|
||||
config ESP32S3_ESPTOOLPY_NO_STUB
|
||||
bool "Disable download stub"
|
||||
default n
|
||||
@ -1036,6 +1041,23 @@ choice ESP32S3_FLASH_SAMPLE_MODE
|
||||
bool "STR Mode"
|
||||
endchoice
|
||||
|
||||
config ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE
|
||||
bool "Don't use SPI flash driver in ROM"
|
||||
default n
|
||||
help
|
||||
Use source code for SPI flash driver instead of functions
|
||||
in ROM.
|
||||
|
||||
config ESP32S3S_SPI_FLASH_USE_32BIT_ADDRESS
|
||||
bool "SPI flash uses 32-bit address"
|
||||
default n
|
||||
select ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE
|
||||
help
|
||||
SPI flash driver in ROM only support 24-bit address access,
|
||||
if select the option, it will force to use source code instead
|
||||
of functions in ROM, so that SPI flash driver can access full
|
||||
32-bit address.
|
||||
|
||||
config ESP32S3_HAVE_OTA_PARTITION
|
||||
bool
|
||||
default n
|
||||
|
@ -29,16 +29,19 @@
|
||||
#include <debug.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <inttypes.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/init.h>
|
||||
|
||||
#include "hardware/esp32s3_soc.h"
|
||||
|
||||
#include "xtensa.h"
|
||||
#include "xtensa_attr.h"
|
||||
#include "hardware/esp32s3_spi_mem_reg.h"
|
||||
#include "rom/esp32s3_spiflash.h"
|
||||
#include "rom/esp32s3_opi_flash.h"
|
||||
#include "esp32s3_irq.h"
|
||||
|
||||
#include "esp32s3_spiflash.h"
|
||||
|
||||
/****************************************************************************
|
||||
@ -71,6 +74,99 @@
|
||||
#define MMU_BYTES2PAGES(_n) (((_n) + SPI_FLASH_MMU_PAGE_SIZE - 1) / \
|
||||
SPI_FLASH_MMU_PAGE_SIZE)
|
||||
|
||||
#ifdef CONFIG_ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE
|
||||
|
||||
/* SPI port number */
|
||||
|
||||
# define SPI_PORT (1)
|
||||
|
||||
/* SPI buffer size */
|
||||
|
||||
# define SPI_BUFFER_WORDS (16)
|
||||
# define SPI_BUFFER_BYTES (SPI_BUFFER_WORDS * 4)
|
||||
|
||||
/* SPI flash hardware definition */
|
||||
|
||||
# define FLASH_SECTOR_SIZE (4096)
|
||||
|
||||
/* SPI flash command */
|
||||
|
||||
# define FLASH_CMD_WRDI ROM_FLASH_CMD_WRDI
|
||||
# define FLASH_CMD_WREN ROM_FLASH_CMD_WREN
|
||||
# define FLASH_CMD_RDSR ROM_FLASH_CMD_RDSR
|
||||
# define FLASH_CMD_SE4B ROM_FLASH_CMD_SE4B
|
||||
# define FLASH_CMD_SE ROM_FLASH_CMD_ERASE_SEC
|
||||
# define FLASH_CMD_PP4B ROM_FLASH_CMD_PP4B
|
||||
# define FLASH_CMD_PP 0x02
|
||||
# define FLASH_CMD_FSTRD4B ROM_FLASH_CMD_FSTRD4B
|
||||
# define FLASH_CMD_FSTRD 0x0B
|
||||
|
||||
/* SPI flash SR1 bits */
|
||||
|
||||
# define FLASH_SR1_BUSY ESP_ROM_SPIFLASH_BUSY_FLAG
|
||||
# define FLASH_SR1_WREN ESP_ROM_SPIFLASH_WRENABLE_FLAG
|
||||
|
||||
/* SPI flash operation */
|
||||
|
||||
# ifdef CONFIG_ESP32S3S_SPI_FLASH_USE_32BIT_ADDRESS
|
||||
# define ADDR_BITS(addr) (((addr) & 0xff000000) ? 32 : 24)
|
||||
# define READ_CMD(addr) (ADDR_BITS(addr) == 32 ? FLASH_CMD_FSTRD4B : \
|
||||
FLASH_CMD_FSTRD)
|
||||
# define WRITE_CMD(addr) (ADDR_BITS(addr) == 32 ? FLASH_CMD_PP4B : \
|
||||
FLASH_CMD_PP)
|
||||
# define ERASE_CMD(addr) (ADDR_BITS(addr) == 32 ? FLASH_CMD_SE4B : \
|
||||
FLASH_CMD_SE)
|
||||
# define READ_DUMMY(addr) (8)
|
||||
# else
|
||||
# define ADDR_BITS(addr) 24
|
||||
# define READ_CMD(addr) FLASH_CMD_FSTRD
|
||||
# define WRITE_CMD(addr) FLASH_CMD_PP
|
||||
# define ERASE_CMD(addr) FLASH_CMD_SE
|
||||
# define READ_DUMMY(addr) (8)
|
||||
# endif
|
||||
|
||||
# define SEND_CMD8_TO_FLASH(cmd) \
|
||||
esp32s3_spi_trans((cmd), 8, \
|
||||
0, 0, \
|
||||
NULL, 0, \
|
||||
NULL, 0, \
|
||||
0, \
|
||||
false)
|
||||
|
||||
# define READ_SR1_FROM_FLASH(cmd, status) \
|
||||
esp32s3_spi_trans((cmd), 8, \
|
||||
0, 0, \
|
||||
NULL, 0, \
|
||||
(status), 1, \
|
||||
0, \
|
||||
false)
|
||||
|
||||
# define ERASE_FLASH_SECTOR(addr) \
|
||||
esp32s3_spi_trans(ERASE_CMD(addr), 8, \
|
||||
(addr), ADDR_BITS(addr), \
|
||||
NULL, 0, \
|
||||
NULL, 0, \
|
||||
0, \
|
||||
true)
|
||||
|
||||
# define WRITE_DATA_TO_FLASH(addr, buffer, size) \
|
||||
esp32s3_spi_trans(WRITE_CMD(addr), 8, \
|
||||
(addr), ADDR_BITS(addr), \
|
||||
buffer, size, \
|
||||
NULL, 0, \
|
||||
0, \
|
||||
true)
|
||||
|
||||
# define READ_DATA_FROM_FLASH(addr, buffer, size) \
|
||||
esp32s3_spi_trans(READ_CMD(addr), 8, \
|
||||
(addr), ADDR_BITS(addr), \
|
||||
NULL, 0, \
|
||||
buffer, size, \
|
||||
READ_DUMMY(addr), \
|
||||
false)
|
||||
|
||||
#endif /* CONFIG_ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE */
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@ -100,24 +196,6 @@ struct spiflash_map_req_s
|
||||
uint32_t page_cnt;
|
||||
};
|
||||
|
||||
/* Structure holding SPI flash access critical sections management
|
||||
* functions.
|
||||
*/
|
||||
|
||||
struct spiflash_guard_funcs_s
|
||||
{
|
||||
void (*start)(void); /* critical section start function */
|
||||
void (*end)(void); /* critical section end function */
|
||||
void (*op_lock)(void); /* flash access API lock function */
|
||||
void (*op_unlock)(void); /* flash access API unlock function */
|
||||
|
||||
/* checks flash write addresses */
|
||||
|
||||
bool (*address_is_safe)(size_t addr, size_t size);
|
||||
|
||||
void (*yield)(void); /* yield to the OS during flash erase */
|
||||
};
|
||||
|
||||
struct spiflash_cachestate_s
|
||||
{
|
||||
uint32_t value;
|
||||
@ -139,7 +217,6 @@ static void spiflash_end(void);
|
||||
* Public Functions Declaration
|
||||
****************************************************************************/
|
||||
|
||||
extern void spi_flash_guard_set(const struct spiflash_guard_funcs_s *funcs);
|
||||
extern uint32_t cache_suspend_icache(void);
|
||||
extern uint32_t cache_suspend_dcache(void);
|
||||
extern void cache_resume_icache(uint32_t val);
|
||||
@ -150,7 +227,7 @@ extern int cache_invalidate_addr(uint32_t addr, uint32_t size);
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct spiflash_guard_funcs_s g_spi_flash_guard_funcs =
|
||||
static struct spiflash_guard_funcs g_spi_flash_guard_funcs =
|
||||
{
|
||||
.start = spiflash_start,
|
||||
.end = spiflash_end,
|
||||
@ -216,6 +293,258 @@ static IRAM_ATTR void spiflash_end(void)
|
||||
leave_critical_section(g_state.flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_spi_trans
|
||||
*
|
||||
* Description:
|
||||
* Transmit given command, address and data.
|
||||
*
|
||||
* Input Parameters:
|
||||
* command - command value
|
||||
* command_bits - command bits
|
||||
* address - address value
|
||||
* address_bits - address bits
|
||||
* tx_buffer - write buffer
|
||||
* tx_bytes - write buffer size
|
||||
* rx_buffer - read buffer
|
||||
* rx_bytes - read buffer size
|
||||
* dummy_bits - dummy bits
|
||||
* is_program - true if operation is program or erase
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 if success or a negative value if fail.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE
|
||||
static IRAM_ATTR void esp32s3_spi_trans(uint32_t command,
|
||||
uint32_t command_bits,
|
||||
uint32_t address,
|
||||
uint32_t address_bits,
|
||||
uint32_t *tx_buffer,
|
||||
uint32_t tx_bytes,
|
||||
uint32_t *rx_buffer,
|
||||
uint32_t rx_bytes,
|
||||
uint32_t dummy_bits,
|
||||
bool is_program)
|
||||
{
|
||||
uint32_t regval;
|
||||
uint32_t cmd_reg;
|
||||
uint32_t user1_reg = getreg32(SPI_MEM_USER1_REG(SPI_PORT));
|
||||
uint32_t user_reg = getreg32(SPI_MEM_USER_REG(SPI_PORT));
|
||||
|
||||
/* Initiliaze SPI user register */
|
||||
|
||||
user_reg &= ~(SPI_MEM_USR_ADDR_M | SPI_MEM_USR_DUMMY_M |
|
||||
SPI_MEM_USR_MOSI_M | SPI_MEM_USR_MISO_M);
|
||||
user_reg |= SPI_MEM_USR_COMMAND_M;
|
||||
|
||||
/* Wait until SPI is idle */
|
||||
|
||||
do
|
||||
{
|
||||
cmd_reg = getreg32(SPI_MEM_CMD_REG(SPI_PORT));
|
||||
}
|
||||
while ((cmd_reg & SPI_MEM_USR_M) != 0);
|
||||
|
||||
/* Set command bits and value, and command is always needed */
|
||||
|
||||
regval = getreg32(SPI_MEM_USER2_REG(SPI_PORT));
|
||||
regval &= ~(SPI_MEM_USR_COMMAND_BITLEN_M | SPI_MEM_USR_COMMAND_VALUE_M);
|
||||
regval |= ((command_bits - 1) << SPI_MEM_USR_COMMAND_BITLEN_S) |
|
||||
(command << SPI_MEM_USR_COMMAND_VALUE_S);
|
||||
putreg32(regval, SPI_MEM_USER2_REG(SPI_PORT));
|
||||
|
||||
/* Set address bits and value */
|
||||
|
||||
if (address_bits)
|
||||
{
|
||||
user1_reg &= ~SPI_MEM_USR_ADDR_BITLEN_M;
|
||||
user1_reg |= (address_bits - 1) << SPI_MEM_USR_ADDR_BITLEN_S;
|
||||
|
||||
putreg32(address, SPI_MEM_ADDR_REG(SPI_PORT));
|
||||
|
||||
user_reg |= SPI_MEM_USR_ADDR_M;
|
||||
|
||||
regval = getreg32(SPI_MEM_CACHE_FCTRL_REG(SPI_PORT));
|
||||
if (address_bits > 24)
|
||||
{
|
||||
regval |= SPI_MEM_CACHE_USR_CMD_4BYTE_M;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval &= ~SPI_MEM_CACHE_USR_CMD_4BYTE_M;
|
||||
}
|
||||
|
||||
putreg32(regval, SPI_MEM_CACHE_FCTRL_REG(SPI_PORT));
|
||||
}
|
||||
|
||||
/* Set dummy */
|
||||
|
||||
if (dummy_bits)
|
||||
{
|
||||
user1_reg &= ~SPI_MEM_USR_DUMMY_CYCLELEN_M;
|
||||
user1_reg |= (dummy_bits - 1) << SPI_MEM_USR_DUMMY_CYCLELEN_S;
|
||||
|
||||
user_reg |= SPI_MEM_USR_DUMMY_M;
|
||||
}
|
||||
|
||||
/* Set TX data */
|
||||
|
||||
if (tx_bytes)
|
||||
{
|
||||
putreg32(tx_bytes * 8 - 1, SPI_MEM_MOSI_DLEN_REG(SPI_PORT));
|
||||
for (uint32_t i = 0; i < tx_bytes; i += 4)
|
||||
{
|
||||
putreg32(tx_buffer[i / 4], SPI_MEM_W0_REG(SPI_PORT) + i);
|
||||
}
|
||||
|
||||
user_reg |= SPI_MEM_USR_MOSI_M;
|
||||
}
|
||||
|
||||
/* Set RX data */
|
||||
|
||||
if (rx_bytes)
|
||||
{
|
||||
putreg32(rx_bytes * 8 - 1, SPI_MEM_MISO_DLEN_REG(SPI_PORT));
|
||||
|
||||
user_reg |= SPI_MEM_USR_MISO_M;
|
||||
}
|
||||
|
||||
putreg32(user_reg, SPI_MEM_USER_REG(SPI_PORT));
|
||||
putreg32(user1_reg, SPI_MEM_USER1_REG(SPI_PORT));
|
||||
|
||||
/* Set I/O mode */
|
||||
|
||||
regval = getreg32(SPI_MEM_CTRL_REG(SPI_PORT));
|
||||
regval &= ~(SPI_MEM_FREAD_QIO_M | SPI_MEM_FREAD_DIO_M |
|
||||
SPI_MEM_FREAD_QUAD_M | SPI_MEM_FREAD_DUAL_M |
|
||||
SPI_MEM_FCMD_OCT_M | SPI_MEM_FCMD_QUAD_M |
|
||||
SPI_MEM_FCMD_DUAL_M | SPI_MEM_FADDR_OCT_M |
|
||||
SPI_MEM_FDIN_OCT_M | SPI_MEM_FDOUT_OCT_M |
|
||||
SPI_MEM_FDUMMY_OUT_M | SPI_MEM_RESANDRES_M |
|
||||
SPI_MEM_WP_REG_M | SPI_MEM_WRSR_2B_M);
|
||||
regval |= SPI_MEM_FASTRD_MODE_M;
|
||||
putreg32(regval, SPI_MEM_CTRL_REG(SPI_PORT));
|
||||
|
||||
/* Set clock and delay */
|
||||
|
||||
regval = SPI_MEM_FLASH_PES_WAIT_EN_M |
|
||||
SPI_MEM_FLASH_PER_WAIT_EN_M;
|
||||
putreg32(regval, SPI_MEM_FLASH_SUS_CMD_REG(SPI_PORT));
|
||||
putreg32(0, SPI_MEM_CLOCK_GATE_REG(SPI_PORT));
|
||||
|
||||
/* Set if this is program or erase operation */
|
||||
|
||||
if (is_program)
|
||||
{
|
||||
cmd_reg |= SPI_MEM_FLASH_PE_M;
|
||||
}
|
||||
|
||||
/* Start transmision */
|
||||
|
||||
cmd_reg |= SPI_MEM_USR_M;
|
||||
putreg32(cmd_reg, SPI_MEM_CMD_REG(SPI_PORT));
|
||||
|
||||
/* Wait until transmission is done */
|
||||
|
||||
while ((getreg32(SPI_MEM_CMD_REG(SPI_PORT)) & SPI_MEM_USR_M) != 0)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
/* Get read data */
|
||||
|
||||
if (rx_bytes)
|
||||
{
|
||||
for (uint32_t i = 0; i < rx_bytes; i += 4)
|
||||
{
|
||||
rx_buffer[i / 4] = getreg32(SPI_MEM_W0_REG(SPI_PORT) + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: wait_flash_idle
|
||||
*
|
||||
* Description:
|
||||
* Wait until flash enters idle state
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static IRAM_ATTR void wait_flash_idle(void)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
do
|
||||
{
|
||||
READ_SR1_FROM_FLASH(FLASH_CMD_RDSR, &status);
|
||||
if ((status & FLASH_SR1_BUSY) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: enable_flash_write
|
||||
*
|
||||
* Description:
|
||||
* Enable Flash write mode
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static IRAM_ATTR void enable_flash_write(void)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
do
|
||||
{
|
||||
SEND_CMD8_TO_FLASH(FLASH_CMD_WREN);
|
||||
READ_SR1_FROM_FLASH(FLASH_CMD_RDSR, &status);
|
||||
if ((status & FLASH_SR1_WREN) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: disable_flash_write
|
||||
*
|
||||
* Description:
|
||||
* Disable Flash write mode
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static IRAM_ATTR void disable_flash_write(void)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
do
|
||||
{
|
||||
SEND_CMD8_TO_FLASH(FLASH_CMD_WRDI);
|
||||
READ_SR1_FROM_FLASH(FLASH_CMD_RDSR, &status);
|
||||
if ((status & FLASH_SR1_WREN) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
#endif /* CONFIG_ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_mmap
|
||||
*
|
||||
@ -357,6 +686,178 @@ int spi_flash_read_encrypted(uint32_t addr, void *buffer, uint32_t size)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_erase_sector
|
||||
*
|
||||
* Description:
|
||||
* Erase the Flash sector.
|
||||
*
|
||||
* Parameters:
|
||||
* sector - Sector number, the count starts at sector 0, 4KB per sector.
|
||||
*
|
||||
* Returned Values: esp_err_t
|
||||
* Zero (OK) is returned or a negative error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE
|
||||
IRAM_ATTR int spi_flash_erase_sector(uint32_t sector)
|
||||
{
|
||||
int ret = OK;
|
||||
uint32_t addr = sector * FLASH_SECTOR_SIZE;
|
||||
|
||||
spiflash_start();
|
||||
|
||||
wait_flash_idle();
|
||||
enable_flash_write();
|
||||
|
||||
ERASE_FLASH_SECTOR(addr);
|
||||
|
||||
wait_flash_idle();
|
||||
disable_flash_write();
|
||||
|
||||
spiflash_end();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_erase_range
|
||||
*
|
||||
* Description:
|
||||
* Erase a range of flash sectors
|
||||
*
|
||||
* Parameters:
|
||||
* start_address - Address where erase operation has to start.
|
||||
* Must be 4kB-aligned
|
||||
* size - Size of erased range, in bytes. Must be divisible by
|
||||
* 4kB.
|
||||
*
|
||||
* Returned Values:
|
||||
* Zero (OK) is returned or a negative error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
IRAM_ATTR int spi_flash_erase_range(uint32_t start_address, uint32_t size)
|
||||
{
|
||||
int ret = OK;
|
||||
uint32_t addr = start_address;
|
||||
|
||||
spiflash_start();
|
||||
|
||||
for (uint32_t i = 0; i < size; i += FLASH_SECTOR_SIZE)
|
||||
{
|
||||
wait_flash_idle();
|
||||
enable_flash_write();
|
||||
|
||||
ERASE_FLASH_SECTOR(addr);
|
||||
addr += FLASH_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
wait_flash_idle();
|
||||
disable_flash_write();
|
||||
|
||||
spiflash_end();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_write
|
||||
*
|
||||
* Description:
|
||||
* Write data to Flash.
|
||||
*
|
||||
* Parameters:
|
||||
* dest_addr - Destination address in Flash.
|
||||
* src - Pointer to the source buffer.
|
||||
* size - Length of data, in bytes.
|
||||
*
|
||||
* Returned Values:
|
||||
* Zero (OK) is returned or a negative error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
IRAM_ATTR int spi_flash_write(uint32_t dest_addr,
|
||||
const void *buffer,
|
||||
uint32_t size)
|
||||
{
|
||||
int ret = OK;
|
||||
const uint8_t *tx_buf = (const uint8_t *)buffer;
|
||||
uint32_t tx_bytes = size;
|
||||
uint32_t tx_addr = dest_addr;
|
||||
|
||||
spiflash_start();
|
||||
|
||||
for (int i = 0; i < size; i += SPI_BUFFER_BYTES)
|
||||
{
|
||||
uint32_t spi_buffer[SPI_BUFFER_WORDS];
|
||||
uint32_t n = MIN(tx_bytes, SPI_BUFFER_BYTES);
|
||||
|
||||
memcpy(spi_buffer, tx_buf, n);
|
||||
|
||||
wait_flash_idle();
|
||||
enable_flash_write();
|
||||
|
||||
WRITE_DATA_TO_FLASH(tx_addr, spi_buffer, n);
|
||||
|
||||
tx_bytes -= n;
|
||||
tx_buf += n;
|
||||
tx_addr += n;
|
||||
}
|
||||
|
||||
wait_flash_idle();
|
||||
disable_flash_write();
|
||||
|
||||
spiflash_end();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_read
|
||||
*
|
||||
* Description:
|
||||
* Read data from Flash.
|
||||
*
|
||||
* Parameters:
|
||||
* src_addr - source address of the data in Flash.
|
||||
* dest - pointer to the destination buffer
|
||||
* size - length of data
|
||||
*
|
||||
* Returned Values:
|
||||
* Zero (OK) is returned or a negative error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
IRAM_ATTR int spi_flash_read(uint32_t src_addr, void *dest, uint32_t size)
|
||||
{
|
||||
int ret = OK;
|
||||
uint8_t *rx_buf = (uint8_t *)dest;
|
||||
uint32_t rx_bytes = size;
|
||||
uint32_t rx_addr = src_addr;
|
||||
|
||||
spiflash_start();
|
||||
|
||||
for (uint32_t i = 0; i < size; i += SPI_BUFFER_BYTES)
|
||||
{
|
||||
uint32_t spi_buffer[SPI_BUFFER_WORDS];
|
||||
uint32_t n = MIN(rx_bytes, SPI_BUFFER_BYTES);
|
||||
|
||||
READ_DATA_FROM_FLASH(rx_addr, spi_buffer, n);
|
||||
|
||||
memcpy(rx_buf, spi_buffer, n);
|
||||
rx_bytes -= n;
|
||||
rx_buf += n;
|
||||
rx_addr += n;
|
||||
}
|
||||
|
||||
spiflash_end();
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_spiflash_init
|
||||
*
|
||||
|
@ -36,6 +36,41 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Register Bits */
|
||||
|
||||
#define BIT31 0x80000000
|
||||
#define BIT30 0x40000000
|
||||
#define BIT29 0x20000000
|
||||
#define BIT28 0x10000000
|
||||
#define BIT27 0x08000000
|
||||
#define BIT26 0x04000000
|
||||
#define BIT25 0x02000000
|
||||
#define BIT24 0x01000000
|
||||
#define BIT23 0x00800000
|
||||
#define BIT22 0x00400000
|
||||
#define BIT21 0x00200000
|
||||
#define BIT20 0x00100000
|
||||
#define BIT19 0x00080000
|
||||
#define BIT18 0x00040000
|
||||
#define BIT17 0x00020000
|
||||
#define BIT16 0x00010000
|
||||
#define BIT15 0x00008000
|
||||
#define BIT14 0x00004000
|
||||
#define BIT13 0x00002000
|
||||
#define BIT12 0x00001000
|
||||
#define BIT11 0x00000800
|
||||
#define BIT10 0x00000400
|
||||
#define BIT9 0x00000200
|
||||
#define BIT8 0x00000100
|
||||
#define BIT7 0x00000080
|
||||
#define BIT6 0x00000040
|
||||
#define BIT5 0x00000020
|
||||
#define BIT4 0x00000010
|
||||
#define BIT3 0x00000008
|
||||
#define BIT2 0x00000004
|
||||
#define BIT1 0x00000002
|
||||
#define BIT0 0x00000001
|
||||
|
||||
#define PRO_CPU_NUM (0)
|
||||
#define APP_CPU_NUM (1)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user