mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/esp32_d2wd_support' into 'master'
ESP32-D2WD support Support ESP32-D2WD with integrated flash in ESP-IDF. Includes fix for https://github.com/espressif/esp-idf/issues /521 See merge request !639
This commit is contained in:
commit
15ec487fde
@ -19,6 +19,7 @@
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/efuse.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/crc.h"
|
||||
@ -260,6 +261,15 @@ void bootloader_main()
|
||||
/* disable watch dog here */
|
||||
REG_CLR_BIT( RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN );
|
||||
REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
|
||||
|
||||
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
|
||||
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||
if(spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) {
|
||||
ESP_LOGE(TAG, "SPI flash pins are overridden. \"Enable SPI flash ROM driver patched functions\" must be enabled in menuconfig");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_rom_spiflash_unlock();
|
||||
|
||||
ESP_LOGI(TAG, "Enabling RNG early entropy source...");
|
||||
|
@ -16,7 +16,9 @@
|
||||
#include "flash_qio_mode.h"
|
||||
#include "esp_log.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/efuse.h"
|
||||
#include "soc/spi_struct.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/* SPI flash controller */
|
||||
@ -33,6 +35,9 @@
|
||||
#define CMD_RDSR 0x05
|
||||
#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */
|
||||
|
||||
|
||||
#define ESP32_D2WD_WP_GPIO 7 /* ESP32-D2WD has this GPIO wired to WP pin of flash */
|
||||
|
||||
static const char *TAG = "qio_mode";
|
||||
|
||||
typedef unsigned (*read_status_fn_t)();
|
||||
@ -77,7 +82,7 @@ static void write_status_16b_wrsr(unsigned new_status);
|
||||
const static qio_info_t chip_data[] = {
|
||||
/* Manufacturer, mfg_id, flash_id, id mask, Read Status, Write Status, QIE Bit */
|
||||
{ "MXIC", 0xC2, 0x2000, 0xFF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 },
|
||||
{ "ISSI", 0x9D, 0x4000, 0xFF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 },
|
||||
{ "ISSI", 0x9D, 0x4000, 0xCF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 }, /* IDs 0x40xx, 0x70xx */
|
||||
{ "WinBond", 0xEF, 0x4000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 },
|
||||
|
||||
/* Final entry is default entry, if no other IDs have matched.
|
||||
@ -102,6 +107,9 @@ static void enable_qio_mode(read_status_fn_t read_status_fn,
|
||||
*/
|
||||
static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len);
|
||||
|
||||
/* dummy_len_plus values defined in ROM for SPI flash configuration */
|
||||
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||
|
||||
void bootloader_enable_qio_mode(void)
|
||||
{
|
||||
uint32_t raw_flash_id;
|
||||
@ -149,6 +157,20 @@ static void enable_qio_mode(read_status_fn_t read_status_fn,
|
||||
uint8_t status_qio_bit)
|
||||
{
|
||||
uint32_t status;
|
||||
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||
|
||||
if (spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) {
|
||||
// spiconfig specifies a custom efuse pin configuration. This config defines all pins -except- WP.
|
||||
//
|
||||
// For now, in this situation we only support Quad I/O mode for ESP32-D2WD where WP pin is known.
|
||||
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_RESERVE);
|
||||
uint32_t pkg_ver = chip_ver & 0x7;
|
||||
const uint32_t PKG_VER_ESP32_D2WD = 2; // TODO: use chip detection API once available
|
||||
if (pkg_ver != PKG_VER_ESP32_D2WD) {
|
||||
ESP_LOGE(TAG, "Quad I/O is only supported for standard pin numbers or ESP32-D2WD. Falling back to Dual I/O.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
|
||||
@ -180,7 +202,10 @@ static void enable_qio_mode(read_status_fn_t read_status_fn,
|
||||
#else
|
||||
mode = ESP_ROM_SPIFLASH_QIO_MODE;
|
||||
#endif
|
||||
esp_rom_spiflash_master_config_readmode(mode);
|
||||
|
||||
esp_rom_spiflash_config_readmode(mode);
|
||||
|
||||
esp_rom_spiflash_select_qio_pins(ESP32_D2WD_WP_GPIO, spiconfig);
|
||||
}
|
||||
|
||||
static unsigned read_status_8b_rdsr()
|
||||
@ -222,6 +247,17 @@ static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8
|
||||
SPIFLASH.mosi_dlen.usr_mosi_dbitlen = mosi_len ? (mosi_len - 1) : 0;
|
||||
SPIFLASH.data_buf[0] = mosi_data;
|
||||
|
||||
if (g_rom_spiflash_dummy_len_plus[1]) {
|
||||
/* When flash pins are mapped via GPIO matrix, need a dummy cycle before reading via MISO */
|
||||
if (miso_len > 0) {
|
||||
SPIFLASH.user.usr_dummy = 1;
|
||||
SPIFLASH.user1.usr_dummy_cyclelen = g_rom_spiflash_dummy_len_plus[1] - 1;
|
||||
} else {
|
||||
SPIFLASH.user.usr_dummy = 0;
|
||||
SPIFLASH.user1.usr_dummy_cyclelen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SPIFLASH.cmd.usr = 1;
|
||||
while(SPIFLASH.cmd.usr != 0)
|
||||
{ }
|
||||
|
@ -60,15 +60,20 @@ void ets_efuse_program_op(void);
|
||||
uint32_t ets_efuse_get_8M_clock(void);
|
||||
|
||||
/**
|
||||
* @brief Read spi pad configuration, show gpio number of flash pad, includes 5 pads.
|
||||
* @brief Read spi flash pin configuration from Efuse
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return uint32_t: 0, invalid, flash pad decided by strapping
|
||||
* else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, bit[23:18] spics0, bit[29:24] spihd
|
||||
* @return
|
||||
* - 0 for default SPI pins.
|
||||
* - 1 for default HSPI pins.
|
||||
* - Other values define a custom pin configuration mask. Pins are encoded as per the EFUSE_SPICONFIG_RET_SPICLK,
|
||||
* EFUSE_SPICONFIG_RET_SPIQ, EFUSE_SPICONFIG_RET_SPID, EFUSE_SPICONFIG_RET_SPICS0, EFUSE_SPICONFIG_RET_SPIHD macros.
|
||||
* WP pin (for quad I/O modes) is not saved in efuse and not returned by this function.
|
||||
*/
|
||||
uint32_t ets_efuse_get_spiconfig(void);
|
||||
|
||||
#define EFUSE_SPICONFIG_SPI_DEFAULTS 0
|
||||
#define EFUSE_SPICONFIG_HSPI_DEFAULTS 1
|
||||
|
||||
#define EFUSE_SPICONFIG_RET_SPICLK_MASK 0x3f
|
||||
#define EFUSE_SPICONFIG_RET_SPICLK_SHIFT 0
|
||||
#define EFUSE_SPICONFIG_RET_SPICLK(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPICLK_SHIFT) & EFUSE_SPICONFIG_RET_SPICLK_MASK)
|
||||
|
@ -279,25 +279,13 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read_user_cmd(uint32_t *status, uint8
|
||||
*
|
||||
* @param esp_rom_spiflash_read_mode_t mode : QIO/QOUT/DIO/DOUT/FastRD/SlowRD.
|
||||
*
|
||||
* @param uint8_t legacy: In legacy mode, more SPI command is used in line.
|
||||
* This function does not try to set the QIO Enable bit in the status register, caller is responsible for this.
|
||||
*
|
||||
* @return ESP_ROM_SPIFLASH_RESULT_OK : config OK.
|
||||
* ESP_ROM_SPIFLASH_RESULT_ERR : config error.
|
||||
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : config timeout.
|
||||
*/
|
||||
esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode, bool legacy);
|
||||
|
||||
/**
|
||||
* @brief Config SPI Flash read mode when Flash is running in some mode.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param esp_rom_spiflash_read_mode_t mode : QIO/QOUT/DIO/DOUT/FastRD/SlowRD.
|
||||
*
|
||||
* @return ESP_ROM_SPIFLASH_RESULT_OK : config OK.
|
||||
* ESP_ROM_SPIFLASH_RESULT_ERR : config error.
|
||||
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : config timeout.
|
||||
*/
|
||||
esp_rom_spiflash_result_t esp_rom_spiflash_master_config_readmode(esp_rom_spiflash_read_mode_t mode);
|
||||
esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Config SPI Flash clock divisor.
|
||||
@ -524,6 +512,24 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write_encrypted(uint32_t flash_addr,
|
||||
esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp_rom_spiflash_chip_t *spi);
|
||||
|
||||
|
||||
/** @brief Enable Quad I/O pin functions
|
||||
*
|
||||
* @note Please do not call this function in SDK.
|
||||
*
|
||||
* Sets the HD & WP pin functions for Quad I/O modes, based on the
|
||||
* efuse SPI pin configuration.
|
||||
*
|
||||
* @param wp_gpio_num - Number of the WP pin to reconfigure for quad I/O.
|
||||
*
|
||||
* @param spiconfig - Pin configuration, as returned from ets_efuse_get_spiconfig().
|
||||
* - If this parameter is 0, default SPI pins are used and wp_gpio_num parameter is ignored.
|
||||
* - If this parameter is 1, default HSPI pins are used and wp_gpio_num parameter is ignored.
|
||||
* - For other values, this parameter encodes the HD pin number and also the CLK pin number. CLK pin selection is used
|
||||
* to determine if HSPI or SPI peripheral will be used (use HSPI if CLK pin is the HSPI clock pin, otherwise use SPI).
|
||||
* Both HD & WP pins are configured via GPIO matrix to map to the selected peripheral.
|
||||
*/
|
||||
void esp_rom_spiflash_select_qio_pins(uint8_t wp_gpio_num, uint32_t spiconfig);
|
||||
|
||||
/** @brief Global esp_rom_spiflash_chip_t structure used by ROM functions
|
||||
*
|
||||
*/
|
||||
|
@ -1537,6 +1537,7 @@ PROVIDE ( esp_rom_spiflash_read_user_cmd = 0x400621b0 );
|
||||
PROVIDE ( esp_rom_spiflash_write_encrypted_disable = 0x40062e60 );
|
||||
PROVIDE ( esp_rom_spiflash_write_encrypted_enable = 0x40062df4 );
|
||||
PROVIDE ( esp_rom_spiflash_prepare_encrypted_data = 0x40062e1c );
|
||||
PROVIDE ( esp_rom_spiflash_select_qio_pins = 0x40061ddc );
|
||||
PROVIDE ( g_rom_spiflash_chip = 0x3ffae270 );
|
||||
|
||||
/*
|
||||
|
@ -10,7 +10,7 @@ PROVIDE ( esp_rom_spiflash_erase_chip = 0x40062c14 );
|
||||
PROVIDE ( esp_rom_spiflash_erase_sector = 0x40062ccc );
|
||||
PROVIDE ( esp_rom_spiflash_lock = 0x400628f0 );
|
||||
PROVIDE ( esp_rom_spiflash_read = 0x40062ed8 );
|
||||
PROVIDE ( esp_rom_spiflash_config_readmode = 0x40062944 );
|
||||
PROVIDE ( esp_rom_spiflash_config_readmode = 0x40062b64 ); /* SPIMasterReadModeCnfig */
|
||||
PROVIDE ( esp_rom_spiflash_read_status = 0x4006226c );
|
||||
PROVIDE ( esp_rom_spiflash_read_statushigh = 0x40062448 );
|
||||
PROVIDE ( esp_rom_spiflash_write = 0x40062d50 );
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 907273664ada32fc33f3fbfeba99550512c67e4d
|
||||
Subproject commit 96698a3da9acc6e357741663830f97524b688ade
|
@ -87,9 +87,6 @@ extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||
|
||||
|
||||
static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_chip_t *spi);
|
||||
static esp_rom_spiflash_result_t esp_rom_spiflash_enable_qmode(esp_rom_spiflash_chip_t *spi);
|
||||
static esp_rom_spiflash_result_t esp_rom_spiflash_disable_qmode(esp_rom_spiflash_chip_t *spi);
|
||||
|
||||
|
||||
//only support spi1
|
||||
static esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip_internal(esp_rom_spiflash_chip_t *spi)
|
||||
@ -309,65 +306,6 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_
|
||||
return ESP_ROM_SPIFLASH_RESULT_OK;
|
||||
}
|
||||
|
||||
static esp_rom_spiflash_result_t esp_rom_spiflash_enable_qmode(esp_rom_spiflash_chip_t *spi)
|
||||
{
|
||||
uint32_t flash_status;
|
||||
uint32_t status;
|
||||
//read QE bit, not write if QE
|
||||
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_statushigh(spi, &status)) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
}
|
||||
if (status & ESP_ROM_SPIFLASH_QE) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_OK;
|
||||
}
|
||||
|
||||
//enable 2 byte status writing
|
||||
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, ESP_ROM_SPIFLASH_TWO_BYTE_STATUS_EN);
|
||||
|
||||
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(spi)) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
}
|
||||
|
||||
esp_rom_spiflash_read_status(spi, &flash_status);
|
||||
|
||||
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_write_status(spi, flash_status | ESP_ROM_SPIFLASH_QE)) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
}
|
||||
|
||||
return ESP_ROM_SPIFLASH_RESULT_OK;
|
||||
}
|
||||
|
||||
static esp_rom_spiflash_result_t esp_rom_spiflash_disable_qmode(esp_rom_spiflash_chip_t *spi)
|
||||
{
|
||||
uint32_t flash_status;
|
||||
uint32_t status;
|
||||
|
||||
//read QE bit, not write if not QE
|
||||
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_statushigh(spi, &status)) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
}
|
||||
//ets_printf("status %08x, line:%u\n", status, __LINE__);
|
||||
|
||||
if (!(status & ESP_ROM_SPIFLASH_QE)) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_OK;
|
||||
}
|
||||
|
||||
//enable 2 byte status writing
|
||||
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, ESP_ROM_SPIFLASH_TWO_BYTE_STATUS_EN);
|
||||
|
||||
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(spi)) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
}
|
||||
|
||||
esp_rom_spiflash_read_status(spi, &flash_status);
|
||||
//keep low 8 bit
|
||||
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_write_status(spi, flash_status & 0xff)) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
}
|
||||
|
||||
return ESP_ROM_SPIFLASH_RESULT_OK;
|
||||
}
|
||||
|
||||
static void spi_cache_mode_switch(uint32_t modebit)
|
||||
{
|
||||
if ((modebit & SPI_FREAD_QIO) && (modebit & SPI_FASTRD_MODE)) {
|
||||
@ -431,7 +369,7 @@ esp_rom_spiflash_result_t esp_rom_spiflash_lock()
|
||||
}
|
||||
|
||||
|
||||
esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode, bool legacy)
|
||||
esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode)
|
||||
{
|
||||
uint32_t modebit;
|
||||
|
||||
@ -453,15 +391,6 @@ esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read
|
||||
default : modebit = 0;
|
||||
}
|
||||
|
||||
if ((ESP_ROM_SPIFLASH_QIO_MODE == mode) || (ESP_ROM_SPIFLASH_QOUT_MODE == mode)) {
|
||||
esp_rom_spiflash_enable_qmode(&g_rom_spiflash_chip);
|
||||
} else {
|
||||
//do not need disable QMode in faster boot
|
||||
if (legacy) {
|
||||
esp_rom_spiflash_disable_qmode(&g_rom_spiflash_chip);
|
||||
}
|
||||
}
|
||||
|
||||
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, modebit);
|
||||
SET_PERI_REG_MASK(SPI_CTRL_REG(0), modebit);
|
||||
spi_cache_mode_switch(modebit);
|
||||
@ -668,7 +597,10 @@ esp_rom_spiflash_result_t esp_rom_spiflash_erase_area(uint32_t start_addr, uint3
|
||||
uint32_t sector_num_per_block;
|
||||
|
||||
//set read mode to Fastmode ,not QDIO mode for erase
|
||||
esp_rom_spiflash_config_readmode(ESP_ROM_SPIFLASH_SLOWRD_MODE, true);
|
||||
//
|
||||
// TODO: this is probably a bug as it doesn't re-enable QIO mode, not serious as this
|
||||
// function is not used in IDF.
|
||||
esp_rom_spiflash_config_readmode(ESP_ROM_SPIFLASH_SLOWRD_MODE);
|
||||
|
||||
//check if area is oversize of flash
|
||||
if ((start_addr + area_len) > g_rom_spiflash_chip.chip_size) {
|
||||
|
@ -6,7 +6,9 @@ nvs, data, nvs, 0x9000, 0x4000
|
||||
otadata, data, ota, 0xd000, 0x2000
|
||||
phy_init, data, phy, 0xf000, 0x1000
|
||||
factory, 0, 0, 0x10000, 1M
|
||||
ota_0, 0, ota_0, , 1M
|
||||
ota_1, 0, ota_1, , 1M
|
||||
# these OTA partitions are used for tests, but can't fit real OTA apps in them
|
||||
# (done this way so tests can run in 2MB of flash.)
|
||||
ota_0, 0, ota_0, , 128K
|
||||
ota_1, 0, ota_1, , 128K
|
||||
# flash_test partition used for SPI flash tests
|
||||
flash_test, 0x55, 0x55, , 512K
|
||||
|
|
Loading…
x
Reference in New Issue
Block a user