Merge branch 'bugfix/psram_io_settings' into 'master'

Improve psram clock signal generation, increase drive strength, raise LDO voltage

See merge request !1474
This commit is contained in:
Jiang Jiang Jian 2017-11-03 17:34:32 +08:00
commit 34f4e46fbb
11 changed files with 257 additions and 30 deletions

View file

@ -43,6 +43,16 @@ config BOOTLOADER_SPI_WP_PIN
The default value (GPIO 7) is correct for WP pin on ESP32-D2WD integrated flash.
config BOOTLOADER_VDDSDIO_BOOST
bool "Increase VDDSDIO LDO voltage to 1.9V"
default y
help
If this option is enabled, and VDDSDIO LDO is set to 1.8V (using EFUSE
or MTDI bootstrapping pin), bootloader will change LDO settings to
output 1.9V instead. This helps prevent flash chip from browning out
during flash programming operations.
For 3.3V flash, this option has no effect.
endmenu # Bootloader

View file

@ -73,6 +73,8 @@ static void set_cache_and_start_app(uint32_t drom_addr,
uint32_t irom_size,
uint32_t entry_addr);
static void update_flash_config(const esp_image_header_t* pfhdr);
static void vddsdio_configure();
static void flash_gpio_configure();
static void clock_configure(void);
static void uart_console_configure(void);
static void wdt_reset_check(void);
@ -443,6 +445,8 @@ static bool load_boot_image(const bootloader_state_t *bs, int start_index, esp_i
void bootloader_main()
{
vddsdio_configure();
flash_gpio_configure();
clock_configure();
uart_console_configure();
wdt_reset_check();
@ -737,6 +741,105 @@ static void print_flash_info(const esp_image_header_t* phdr)
}
static void vddsdio_configure()
{
#if CONFIG_BOOTLOADER_VDDSDIO_BOOST
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
if (cfg.tieh == 0) { // 1.8V is used
cfg.drefh = 3;
cfg.drefm = 3;
cfg.drefl = 3;
cfg.force = 1;
cfg.enable = 1;
rtc_vddsdio_set_config(cfg);
ets_delay_us(10); // wait for regulator to become stable
}
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
}
#define FLASH_CLK_IO 6
#define FLASH_CS_IO 11
#define FLASH_SPIQ_IO 7
#define FLASH_SPID_IO 8
#define FLASH_SPIWP_IO 10
#define FLASH_SPIHD_IO 9
#define FLASH_IO_MATRIX_DUMMY_40M 1
#define FLASH_IO_MATRIX_DUMMY_80M 2
static void IRAM_ATTR flash_gpio_configure()
{
int spi_cache_dummy = 0;
int drv = 2;
#if CONFIG_FLASHMODE_QIO
spi_cache_dummy = SPI0_R_QIO_DUMMY_CYCLELEN; //qio 3
#elif CONFIG_FLASHMODE_QOUT
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN; //qout 7
#elif CONFIG_FLASHMODE_DIO
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN; //dio 3
#elif CONFIG_FLASHMODE_DOUT
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN; //dout 7
#endif
/* dummy_len_plus values defined in ROM for SPI flash configuration */
extern uint8_t g_rom_spiflash_dummy_len_plus[];
#if CONFIG_ESPTOOLPY_FLASHFREQ_40M
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_40M;
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_40M;
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
#elif CONFIG_ESPTOOLPY_FLASHFREQ_80M
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_80M;
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_80M;
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
drv = 3;
#endif
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
uint32_t pkg_ver = chip_ver & 0x7;
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
// For ESP32D2WD the SPI pins are already configured
ESP_LOGI(TAG, "Detected ESP32D2WD");
//flash clock signal should come from IO MUX.
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
// For ESP32PICOD2 the SPI pins are already configured
ESP_LOGI(TAG, "Detected ESP32PICOD2");
//flash clock signal should come from IO MUX.
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
// For ESP32PICOD4 the SPI pins are already configured
ESP_LOGI(TAG, "Detected ESP32PICOD4");
//flash clock signal should come from IO MUX.
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
} else {
ESP_LOGI(TAG, "Detected ESP32");
const uint32_t spiconfig = ets_efuse_get_spiconfig();
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
gpio_matrix_out(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
gpio_matrix_in(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0);
gpio_matrix_out(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0);
gpio_matrix_in(FLASH_SPID_IO, SPID_IN_IDX, 0);
gpio_matrix_out(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0);
gpio_matrix_in(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0);
gpio_matrix_out(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0);
gpio_matrix_in(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0);
//select pin function gpio
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
// flash clock signal should come from IO MUX.
// set drive ability for clock
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
}
}
}
static void clock_configure(void)
{
/* Set CPU to 80MHz. Keep other clocks unmodified. */

View file

@ -198,14 +198,22 @@ static void rtc_wdt_disable()
* Placed into IRAM as flash may need some time to be powered on.
*/
static esp_err_t esp_light_sleep_inner(uint32_t pd_flags,
rtc_cpu_freq_t cpu_freq, uint32_t flash_enable_time_us) IRAM_ATTR __attribute__((noinline));
rtc_cpu_freq_t cpu_freq, uint32_t flash_enable_time_us,
rtc_vddsdio_config_t vddsdio_config) IRAM_ATTR __attribute__((noinline));
static esp_err_t esp_light_sleep_inner(uint32_t pd_flags,
rtc_cpu_freq_t cpu_freq, uint32_t flash_enable_time_us)
rtc_cpu_freq_t cpu_freq, uint32_t flash_enable_time_us,
rtc_vddsdio_config_t vddsdio_config)
{
// Enter sleep
esp_err_t err = esp_sleep_start(pd_flags);
// If VDDSDIO regulator was controlled by RTC registers before sleep,
// restore the configuration.
if (vddsdio_config.force) {
rtc_vddsdio_set_config(vddsdio_config);
}
// Restore CPU frequency
rtc_clk_cpu_freq_set(cpu_freq);
@ -244,6 +252,7 @@ esp_err_t esp_light_sleep_start()
s_config.sleep_duration -= flash_enable_time_us;
}
#endif //CONFIG_SPIRAM_SUPPORT
rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config();
// Safety net: enable WDT in case exit from light sleep fails
rtc_wdt_enable(1000);
@ -252,7 +261,8 @@ esp_err_t esp_light_sleep_start()
rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get();
// Enter sleep, then wait for flash to be ready on wakeup
esp_err_t err = esp_light_sleep_inner(pd_flags, cpu_freq, flash_enable_time_us);
esp_err_t err = esp_light_sleep_inner(pd_flags, cpu_freq,
flash_enable_time_us, vddsdio_config);
// At this point, if FRC1 is used for timekeeping, time will be lagging behind.
// This will update the microsecond count based on RTC timer.

View file

@ -22,6 +22,7 @@
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_types.h"
#include "esp_log.h"
#include "spiram_psram.h"
#include "rom/ets_sys.h"
#include "rom/spi_flash.h"
@ -30,6 +31,7 @@
#include "soc/io_mux_reg.h"
#include "soc/dport_reg.h"
#include "soc/gpio_sig_map.h"
#include "soc/efuse_reg.h"
#include "driver/gpio.h"
#include "driver/spi_common.h"
@ -71,6 +73,8 @@
#define PSRAM_SPIWP_IO 10
#define PSRAM_SPIHD_IO 9
#define PSRAM_INTERNAL_IO_28 28
#define PSRAM_INTERNAL_IO_29 29
#define PSRAM_IO_MATRIX_DUMMY_40M 1
#define PSRAM_IO_MATRIX_DUMMY_80M 2
@ -84,7 +88,7 @@
#define SPI_CACHE_DUMMY SPI0_R_FAST_DUMMY_CYCLELEN //dout 7
#endif
static const char* TAG = "psram";
typedef enum {
PSRAM_SPI_1 = 0x1,
PSRAM_SPI_2,
@ -418,7 +422,6 @@ void IRAM_ATTR psram_spi_init(psram_spi_num_t spi_num, psram_cache_mode_t mode)
static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
{
gpio_matrix_out(FLASH_CLK_IO, SPICLK_OUT_IDX, 0, 0);
gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
gpio_matrix_out(PSRAM_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
gpio_matrix_in(PSRAM_SPIQ_IO, SPIQ_IN_IDX, 0);
@ -434,16 +437,25 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M;
g_rom_spiflash_dummy_len_plus[1] = PSRAM_IO_MATRIX_DUMMY_40M;
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, SPI_CACHE_DUMMY + PSRAM_IO_MATRIX_DUMMY_80M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
//set drive ability for clock
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 2, FUN_DRV_S);
break;
case PSRAM_CACHE_F80M_S80M:
extra_dummy = PSRAM_IO_MATRIX_DUMMY_80M;
g_rom_spiflash_dummy_len_plus[1] = PSRAM_IO_MATRIX_DUMMY_80M;
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, SPI_CACHE_DUMMY + PSRAM_IO_MATRIX_DUMMY_80M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
//set drive ability for clock
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 3, FUN_DRV_S);
break;
case PSRAM_CACHE_F40M_S40M:
extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M;
g_rom_spiflash_dummy_len_plus[1] = PSRAM_IO_MATRIX_DUMMY_40M;
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, SPI_CACHE_DUMMY + PSRAM_IO_MATRIX_DUMMY_40M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
//set drive ability for clock
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 2, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 2, FUN_DRV_S);
break;
default:
break;
@ -451,17 +463,31 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_USR_DUMMY); // dummy en
//select pin function gpio
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 2);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 2);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, 2);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, 2);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 2);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 2);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
//flash clock signal should come from IO MUX.
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
}
//psram gpio init , different working frequency we have different solutions
esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vaddrmode) //psram init
{
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
uint32_t pkg_ver = chip_ver & 0x7;
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
ESP_EARLY_LOGE(TAG, "ESP32D2WD do not support psram yet");
return ESP_FAIL;
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
ESP_EARLY_LOGE(TAG, "ESP32PICOD2 do not support psram yet");
return ESP_FAIL;
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
ESP_EARLY_LOGE(TAG, "ESP32PICOD4 do not support psram yet");
return ESP_FAIL;
}
/* note: If the third mode(80Mhz+80Mhz) is enabled, VSPI port will be occupied by the system,
Application code should never touch VSPI hardware in this case. We try to stop applications
from doing this using the drivers by claiming the port for ourselves*/
@ -515,20 +541,20 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
We do this by routing it signal to signal 224/225, which are used as a loopback; the extra run through
the GPIO matrix causes the delay. We use GPIO20 (which is not in any package but has pad logic in
silicon) as a temporary pad for this. So the signal path is:
GPIO6(SPI CLK) --> signal224(in then out) --> internal GPIO20 --> signal225(in then out) --> GPIO17(PSRAM CLK)
SPI CLK --> GPIO28 --> signal224(in then out) --> internal GPIO29 --> signal225(in then out) --> GPIO17(PSRAM CLK)
*/
gpio_matrix_in(FLASH_CLK_IO, SIG_IN_FUNC224_IDX, 0);
gpio_matrix_out(20, SIG_IN_FUNC224_IDX, 0, 0);
gpio_matrix_in(20, SIG_IN_FUNC225_IDX, 0);
gpio_matrix_out(PSRAM_INTERNAL_IO_28, SPICLK_OUT_IDX, 0, 0);
gpio_matrix_in(PSRAM_INTERNAL_IO_28, SIG_IN_FUNC224_IDX, 0);
gpio_matrix_out(PSRAM_INTERNAL_IO_29, SIG_IN_FUNC224_IDX, 0, 0);
gpio_matrix_in(PSRAM_INTERNAL_IO_29, SIG_IN_FUNC225_IDX, 0);
gpio_matrix_out(PSRAM_CLK_IO, SIG_IN_FUNC225_IDX, 0, 0);
break;
}
CLEAR_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_CS_SETUP_M);
psram_gpio_config(mode);
WRITE_PERI_REG(GPIO_ENABLE_W1TS_REG, BIT(PSRAM_CS_IO)| BIT(PSRAM_CLK_IO));
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CS_IO], 2);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], 2);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CS_IO], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], PIN_FUNC_GPIO);
uint32_t id;
psram_read_id(&id);
if (((id >> PSRAM_MFG_ID_S) & PSRAM_MFG_ID_M) != PSRAM_MFG_ID_V) {

View file

@ -397,8 +397,10 @@ static void get_chip_info_esp32(esp_chip_info_t* out_info)
if ((reg & EFUSE_RD_CHIP_VER_DIS_BT_M) == 0) {
out_info->features |= CHIP_FEATURE_BT | CHIP_FEATURE_BLE;
}
if (((reg & EFUSE_RD_CHIP_VER_PKG_M) >> EFUSE_RD_CHIP_VER_PKG_S) ==
EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
int package = (reg & EFUSE_RD_CHIP_VER_PKG_M) >> EFUSE_RD_CHIP_VER_PKG_S;
if (package == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 ||
package == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2 ||
package == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
out_info->features |= CHIP_FEATURE_EMB_FLASH;
}
}

View file

@ -100,6 +100,8 @@
#define EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ6 0
#define EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ5 1
#define EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 2
#define EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2 4
#define EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4 5
/* EFUSE_RD_SPI_PAD_CONFIG_HD : RO ;bitpos:[8:4] ;default: 5'b0 ; */
/*description: read for SPI_pad_config_hd*/
#define EFUSE_RD_SPI_PAD_CONFIG_HD 0x0000001F

View file

@ -129,8 +129,7 @@
#define GPIO_STRAP_REG (DR_REG_GPIO_BASE + 0x0038)
/* GPIO_STRAPPING : RO ;bitpos:[15:0] ;default: ; */
/*description: GPIO strapping results: {2'd0 boot_sel_dig[7:1] vsdio_boot_sel
boot_sel_chip[5:0]}. Boot_sel_dig[7:1]: {U0RXD SD_CLK SD_CMD SD_DATA0 SD_DATA1 SD_DATA2 SD_DATA3}. vsdio_boot_sel: MTDI. boot_sel_chip[5:0]: {GPIO0 U0TXD GPIO2 GPIO4 MTDO GPIO5}*/
/*description: {10'b0, MTDI, GPIO0, GPIO2, GPIO4, MTDO, GPIO5} */
#define GPIO_STRAPPING 0x0000FFFF
#define GPIO_STRAPPING_M ((GPIO_STRAPPING_V)<<(GPIO_STRAPPING_S))
#define GPIO_STRAPPING_V 0xFFFF

View file

@ -554,6 +554,36 @@ typedef struct {
*/
void rtc_init(rtc_config_t cfg);
/**
* Structure describing vddsdio configuration
*/
typedef struct {
uint32_t force : 1; //!< If 1, use configuration from RTC registers; if 0, use EFUSE/bootstrapping pins.
uint32_t enable : 1; //!< Enable VDDSDIO regulator
uint32_t tieh : 1; //!< Select VDDSDIO voltage: 1 — 1.8V, 0 — 3.3V
uint32_t drefh : 2; //!< Tuning parameter for VDDSDIO regulator
uint32_t drefm : 2; //!< Tuning parameter for VDDSDIO regulator
uint32_t drefl : 2; //!< Tuning parameter for VDDSDIO regulator
} rtc_vddsdio_config_t;
/**
* Get current VDDSDIO configuration
* If VDDSDIO configuration is overridden by RTC, get values from RTC
* Otherwise, if VDDSDIO is configured by EFUSE, get values from EFUSE
* Otherwise, use default values and the level of MTDI bootstrapping pin.
* @return currently used VDDSDIO configuration
*/
rtc_vddsdio_config_t rtc_vddsdio_get_config();
/**
* Set new VDDSDIO configuration using RTC registers.
* If config.force == 1, this overrides configuration done using bootstrapping
* pins and EFUSE.
*
* @param config new VDDSDIO configuration
*/
void rtc_vddsdio_set_config(rtc_vddsdio_config_t config);
#ifdef __cplusplus
}

View file

@ -18,6 +18,8 @@
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/dport_reg.h"
#include "soc/efuse_reg.h"
#include "soc/gpio_reg.h"
void rtc_init(rtc_config_t cfg)
@ -94,3 +96,51 @@ void rtc_init(rtc_config_t cfg)
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_NOISO);
}
}
rtc_vddsdio_config_t rtc_vddsdio_get_config()
{
rtc_vddsdio_config_t result;
uint32_t sdio_conf_reg = REG_READ(RTC_CNTL_SDIO_CONF_REG);
result.drefh = (sdio_conf_reg & RTC_CNTL_DREFH_SDIO_M) >> RTC_CNTL_DREFH_SDIO_S;
result.drefm = (sdio_conf_reg & RTC_CNTL_DREFM_SDIO_M) >> RTC_CNTL_DREFM_SDIO_S;
result.drefl = (sdio_conf_reg & RTC_CNTL_DREFL_SDIO_M) >> RTC_CNTL_DREFL_SDIO_S;
if (sdio_conf_reg & RTC_CNTL_SDIO_FORCE) {
// Get configuration from RTC
result.force = 1;
result.enable = (sdio_conf_reg & RTC_CNTL_XPD_SDIO_REG_M) >> RTC_CNTL_XPD_SDIO_REG_S;
result.tieh = (sdio_conf_reg & RTC_CNTL_SDIO_TIEH_M) >> RTC_CNTL_SDIO_TIEH_S;
return result;
}
uint32_t efuse_reg = REG_READ(EFUSE_BLK0_RDATA4_REG);
if (efuse_reg & EFUSE_RD_SDIO_FORCE) {
// Get configuration from EFUSE
result.force = 0;
result.enable = (efuse_reg & EFUSE_RD_XPD_SDIO_REG_M) >> EFUSE_RD_XPD_SDIO_REG_S;
result.tieh = (efuse_reg & EFUSE_RD_SDIO_TIEH_M) >> EFUSE_RD_SDIO_TIEH_S;
// in this case, DREFH/M/L are also set from EFUSE
result.drefh = (efuse_reg & EFUSE_RD_SDIO_DREFH_M) >> EFUSE_RD_SDIO_DREFH_S;
result.drefm = (efuse_reg & EFUSE_RD_SDIO_DREFM_M) >> EFUSE_RD_SDIO_DREFM_S;
result.drefl = (efuse_reg & EFUSE_RD_SDIO_DREFL_M) >> EFUSE_RD_SDIO_DREFL_S;
return result;
}
// Otherwise, VDD_SDIO is controlled by bootstrapping pin
uint32_t strap_reg = REG_READ(GPIO_STRAP_REG);
result.force = 0;
result.tieh = (strap_reg & BIT(5)) ? 0 : 1;
result.enable = result.tieh == 0; // only power on the regulator if VDD=1.8
return result;
}
void rtc_vddsdio_set_config(rtc_vddsdio_config_t config)
{
uint32_t val = 0;
val |= (config.force << RTC_CNTL_SDIO_FORCE_S);
val |= (config.enable << RTC_CNTL_XPD_SDIO_REG_S);
val |= (config.drefh << RTC_CNTL_DREFH_SDIO_S);
val |= (config.drefm << RTC_CNTL_DREFM_SDIO_S);
val |= (config.drefl << RTC_CNTL_DREFL_SDIO_S);
val |= (config.tieh << RTC_CNTL_SDIO_TIEH_S);
val |= RTC_CNTL_SDIO_PD_EN;
REG_WRITE(RTC_CNTL_SDIO_CONF_REG, val);
}

View file

@ -198,11 +198,9 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN, 0);
}
if (cfg.vddsdio_pd_en) {
SET_PERI_REG_MASK(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN);
}
/* enable VDDSDIO control by state machine */
REG_CLR_BIT(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_FORCE);
REG_SET_FIELD(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN, cfg.vddsdio_pd_en);
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_SLP, cfg.rtc_dbias_slp);
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_WAK, cfg.rtc_dbias_wak);

View file

@ -7,9 +7,6 @@ PROJECT_NAME := unit-test-app
include $(IDF_PATH)/make/project.mk
print_flash_cmd:
echo $(ESPTOOL_WRITE_FLASH_OPTIONS) $(ESPTOOL_ALL_FLASH_ARGS) | sed -e 's:'$(PWD)/build/'::g'
# List of unit-test-app configurations.
# Each file in configs/ directory defines a configuration. The format is the
# same as sdkconfig file. Configuration is applied on top of sdkconfig.defaults