void rtctime_early_startup (void) { Cache_Read_Enable (0, 0, 1); rtc_time_register_bootup (); rtc_time_switch_clocks (); Cache_Read_Disable (); }
void pp_soft_wdt_feed() { struct rst_info rst_info; rst_info.exccause = RSR(EXCCAUSE); rst_info.epc1 = RSR(EPC1); rst_info.epc2 = RSR(EPC2); rst_info.epc3 = RSR(EPC3); rst_info.excvaddr = RSR(EXCVADDR); rst_info.depc = RSR(DEPC); rst_info.reason = WDT_RST_FLAG; system_rtc_mem_write(0, &rst_info, sizeof(rst_info)); if(wdt_flg == true) { Cache_Read_Disable(); Cache_Read_Enable_New(); system_restart_local(); } else { #if SDK_VERSION >= 1119 wDev_MacTim1Arm(soft_wdt_interval); #else ets_timer_disarm(SoftWdtTimer); ets_timer_arm_new(SoftWdtTimer, soft_wdt_interval, 0, 1); #endif wdt_flg = true; pp_post(12); } }
void arch_init (void) { trap_init(); Cache_Read_Disable(); call_user_start(); }
// ******* C API functions ************* void __attribute__((noreturn)) TEXT_SECTION_ATTR rtc_time_enter_deep_sleep_final (void) { ets_intr_lock(); Cache_Read_Disable(); rtc_reg_write(0x18,8); rtc_reg_write_and_loop(0x08,0x00100000); // go to sleep __builtin_unreachable(); }
/* Prelude ensures exceptions/NMI off and flash is mapped, allowing calls to non-IRAM functions. */ static void IRAM fatal_handler_prelude(void) { if (!sdk_NMIIrqIsOn) { vPortEnterCritical(); do { DPORT.DPORT0 &= 0xffffffe0; } while (DPORT.DPORT0 & 0x00000001); } Cache_Read_Disable(); Cache_Read_Enable(0, 0, 1); }
void __attribute__((section(".entry.text"))) call_user_start1(void) { // Загрузка заголовка flash struct SPIFlashHead fhead; Cache_Read_Disable(); SPI0_USER |= SPI_CS_SETUP; // +1 такт перед CS SPIRead(0, (uint32_t *)&fhead, sizeof(fhead)); // Установка размера Flash от 256Kbytes до 32Mbytes // High four bits fhead.hsz.flash_size: 0 = 512K, 1 = 256K, 2 = 1M, 3 = 2M, 4 = 4M, ... 7 = 32M uint32 fsize = fhead.hsz.flash_size & 7; if(fsize < 2) flashchip->chip_size = (8 >> fsize) << 16; else flashchip->chip_size = (4 << fsize) << 16;
/****************************************************************************** * FunctionName : spi_flash_read * Description : чтение массива байт из flash * читает из flash по QSPI блоками по SPI_FBLK байт * в ROM-BIOS SPI_FBLK = 32 байта, 64 - предел SPI буфера * Parameters : flash Addr, pointer, кол-во * Returns : SpiFlashOpResult 0 - ok * Опции gcc: -mno-serialize-volatile ! *******************************************************************************/ SpiFlashOpResult __attribute__((optimize("O2"))) spi_flash_read(uint32 faddr, void *des, uint32 size) { #if DEBUGSOO > 5 ets_printf("fread:%p<-%p[%u]\n", des, faddr, size); #endif if(des == NULL) return SPI_FLASH_RESULT_ERR; if(size != 0) { faddr <<= 8; faddr >>= 8; Cache_Read_Disable(); Wait_SPI_Idle(flashchip); uint32 blksize = (uint32)des & 3; if(blksize) { blksize = 4 - blksize; if(size < blksize) blksize = size; SPI0_ADDR = faddr | (blksize << 24); SPI0_CMD = SPI_READ; size -= blksize; faddr += blksize; while(SPI0_CMD); register uint32 data_buf = SPI0_W0; do { *(uint8 *)des = data_buf; des = (uint8 *)des + 1; data_buf >>= 8; } while(--blksize); } while(size) { if(size < SPI_FBLK) blksize = size; else blksize = SPI_FBLK; SPI0_ADDR = faddr | (blksize << 24); SPI0_CMD = SPI_READ; size -= blksize; faddr += blksize; while(SPI0_CMD); uint32 *srcdw = (uint32 *)(&SPI0_W0); while(blksize >> 2) { *((uint32 *)des) = *srcdw++; des = ((uint32 *)des) + 1; blksize -= 4; } if(blksize) { uint32 data_buf = *srcdw; do { *(uint8 *)des = data_buf; des = (uint8 *)des + 1; data_buf >>= 8; } while(--blksize); break; } } Cache_Read_Enable_def(); }
SpiFlashOpResult IRAM spi_flash_erase_sector(uint16_t sec) { CHECK_PARAM_RET (sec < flashchip->chip_size / flashchip->sector_size, SPI_FLASH_RESULT_ERR); critical_enter (); Cache_Read_Disable(); SpiFlashOpResult ret = SPIEraseSector (sec); Cache_Read_Enable(0, 0, 1); critical_exit (); return ret; }
static void set_cache_and_start_app( uint32_t drom_addr, uint32_t drom_load_addr, uint32_t drom_size, uint32_t irom_addr, uint32_t irom_load_addr, uint32_t irom_size, uint32_t entry_addr) { ESP_LOGD(TAG, "configure drom and irom and start"); Cache_Read_Disable( 0 ); Cache_Flush( 0 ); /* Clear the MMU entries that are already set up, so the new app only has the mappings it creates. */ for (int i = 0; i < DPORT_FLASH_MMU_TABLE_SIZE; i++) { DPORT_PRO_FLASH_MMU_TABLE[i] = DPORT_FLASH_MMU_TABLE_INVALID_VAL; } uint32_t drom_page_count = (drom_size + 64*1024 - 1) / (64*1024); // round up to 64k ESP_LOGV(TAG, "d mmu set paddr=%08x vaddr=%08x size=%d n=%d", drom_addr & 0xffff0000, drom_load_addr & 0xffff0000, drom_size, drom_page_count ); int rc = cache_flash_mmu_set( 0, 0, drom_load_addr & 0xffff0000, drom_addr & 0xffff0000, 64, drom_page_count ); ESP_LOGV(TAG, "rc=%d", rc ); rc = cache_flash_mmu_set( 1, 0, drom_load_addr & 0xffff0000, drom_addr & 0xffff0000, 64, drom_page_count ); ESP_LOGV(TAG, "rc=%d", rc ); uint32_t irom_page_count = (irom_size + 64*1024 - 1) / (64*1024); // round up to 64k ESP_LOGV(TAG, "i mmu set paddr=%08x vaddr=%08x size=%d n=%d", irom_addr & 0xffff0000, irom_load_addr & 0xffff0000, irom_size, irom_page_count ); rc = cache_flash_mmu_set( 0, 0, irom_load_addr & 0xffff0000, irom_addr & 0xffff0000, 64, irom_page_count ); ESP_LOGV(TAG, "rc=%d", rc ); rc = cache_flash_mmu_set( 1, 0, irom_load_addr & 0xffff0000, irom_addr & 0xffff0000, 64, irom_page_count ); ESP_LOGV(TAG, "rc=%d", rc ); DPORT_REG_CLR_BIT( DPORT_PRO_CACHE_CTRL1_REG, (DPORT_PRO_CACHE_MASK_IRAM0) | (DPORT_PRO_CACHE_MASK_IRAM1 & 0) | (DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 | DPORT_PRO_CACHE_MASK_DRAM1 ); DPORT_REG_CLR_BIT( DPORT_APP_CACHE_CTRL1_REG, (DPORT_APP_CACHE_MASK_IRAM0) | (DPORT_APP_CACHE_MASK_IRAM1 & 0) | (DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 | DPORT_APP_CACHE_MASK_DRAM1 ); Cache_Read_Enable( 0 ); // Application will need to do Cache_Flush(1) and Cache_Read_Enable(1) ESP_LOGD(TAG, "start: 0x%08x", entry_addr); typedef void (*entry_t)(void) __attribute__((noreturn)); entry_t entry = ((entry_t) entry_addr); // TODO: we have used quite a bit of stack at this point. // use "movsp" instruction to reset stack back to where ROM stack starts. (*entry)(); }
IRAM NOINSTR void Cache_Read_Enable_New(void) { static uint8_t m1 = 0xff, m2 = 0xff; if (m1 == 0xff) { uint32_t addr; rboot_config conf; Cache_Read_Disable(); SPIRead(BOOT_CONFIG_SECTOR * SECTOR_SIZE, &conf, sizeof(conf)); addr = conf.roms[conf.current_rom]; addr /= 0x100000; m1 = addr % 2; m2 = addr / 2; } Cache_Read_Enable(m1, m2, 1); }
SpiFlashOpResult IRAM spi_flash_write (uint32_t faddr, uint32_t *src, size_t size) { /* * For simplicity, we use the ROM function. Since we need to disable the * IROM cache function for that purpose, we have to be in IRAM. * Please note, faddr, src and size have to be aligned to 4 byte */ SpiFlashOpResult ret; CHECK_PARAM_RET (src != NULL, SPI_FLASH_RESULT_ERR); CHECK_PARAM_RET (faddr + size <= flashchip->chip_size, SPI_FLASH_RESULT_ERR); critical_enter (); Cache_Read_Disable (); ret = SPIWrite (faddr, src, size); Cache_Read_Enable(0, 0, 1); critical_exit (); return ret; }
/* "inner" restart function for after RTOS, interrupts & anything else on this * core are already stopped. Stalls other core, resets hardware, * triggers restart. */ void IRAM_ATTR esp_restart_noos() { // Disable interrupts xt_ints_off(0xFFFFFFFF); // Enable RTC watchdog for 1 second rtc_wdt_protect_off(); rtc_wdt_disable(); rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_RTC); rtc_wdt_set_stage(RTC_WDT_STAGE1, RTC_WDT_STAGE_ACTION_RESET_SYSTEM); rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_200ns); rtc_wdt_set_length_of_reset_signal(RTC_WDT_CPU_RESET_SIG, RTC_WDT_LENGTH_200ns); rtc_wdt_set_time(RTC_WDT_STAGE0, 1000); rtc_wdt_flashboot_mode_enable(); // Reset and stall the other CPU. // CPU must be reset before stalling, in case it was running a s32c1i // instruction. This would cause memory pool to be locked by arbiter // to the stalled CPU, preventing current CPU from accessing this pool. const uint32_t core_id = xPortGetCoreID(); const uint32_t other_core_id = (core_id == 0) ? 1 : 0; esp_cpu_reset(other_core_id); esp_cpu_stall(other_core_id); // Other core is now stalled, can access DPORT registers directly esp_dport_access_int_abort(); // Disable TG0/TG1 watchdogs TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG0.wdt_config0.en = 0; TIMERG0.wdt_wprotect=0; TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG1.wdt_config0.en = 0; TIMERG1.wdt_wprotect=0; // Flush any data left in UART FIFOs uart_tx_wait_idle(0); uart_tx_wait_idle(1); uart_tx_wait_idle(2); // Disable cache Cache_Read_Disable(0); Cache_Read_Disable(1); // 2nd stage bootloader reconfigures SPI flash signals. // Reset them to the defaults expected by ROM. WRITE_PERI_REG(GPIO_FUNC0_IN_SEL_CFG_REG, 0x30); WRITE_PERI_REG(GPIO_FUNC1_IN_SEL_CFG_REG, 0x30); WRITE_PERI_REG(GPIO_FUNC2_IN_SEL_CFG_REG, 0x30); WRITE_PERI_REG(GPIO_FUNC3_IN_SEL_CFG_REG, 0x30); WRITE_PERI_REG(GPIO_FUNC4_IN_SEL_CFG_REG, 0x30); WRITE_PERI_REG(GPIO_FUNC5_IN_SEL_CFG_REG, 0x30); // Reset wifi/bluetooth/ethernet/sdio (bb/mac) DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, DPORT_BB_RST | DPORT_FE_RST | DPORT_MAC_RST | DPORT_BT_RST | DPORT_BTMAC_RST | DPORT_SDIO_RST | DPORT_SDIO_HOST_RST | DPORT_EMAC_RST | DPORT_MACPWR_RST | DPORT_RW_BTMAC_RST | DPORT_RW_BTLP_RST); DPORT_REG_WRITE(DPORT_CORE_RST_EN_REG, 0); // Reset timer/spi/uart DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_TIMERS_RST | DPORT_SPI01_RST | DPORT_UART_RST); DPORT_REG_WRITE(DPORT_PERIP_RST_EN_REG, 0); // Set CPU back to XTAL source, no PLL, same as hard reset rtc_clk_cpu_freq_set_xtal(); // Clear entry point for APP CPU DPORT_REG_WRITE(DPORT_APPCPU_CTRL_D_REG, 0); // Reset CPUs if (core_id == 0) { // Running on PRO CPU: APP CPU is stalled. Can reset both CPUs. esp_cpu_reset(1); esp_cpu_reset(0); } else { // Running on APP CPU: need to reset PRO CPU and unstall it, // then reset APP CPU esp_cpu_reset(0); esp_cpu_unstall(0); esp_cpu_reset(1); } while(true) { ; } }
void user_start_trampoline (void) { Cache_Read_Disable(); call_user_start(); }
SpiFlashOpResult __attribute__((optimize("O3"))) spi_flash_read(uint32 faddr, void *des, uint32 size) { #if DEBUGSOO > 5 ets_printf("fread:%p<-%p[%u]\n", des, faddr, size); #endif if(des == NULL) return SPI_FLASH_RESULT_ERR; if(size != 0) { faddr <<= 8; faddr >>= 8; // faddr &= (1 << 24) - 1; // if((faddr >> 24) || ((faddr + size) >> 24)) return SPI_FLASH_RESULT_ERR; Cache_Read_Disable(); Wait_SPI_Idle(flashchip); uint32 blksize = (uint32)des & 3; if(blksize) { blksize = 4 - blksize; #if DEBUGSOO > 4 ets_printf("fr1:%p<-%p[%u]\n", des, faddr, blksize); #endif if(size < blksize) blksize = size; SPI0_ADDR = faddr | (blksize << 24); SPI0_CMD = SPI_READ; size -= blksize; faddr += blksize; while(SPI0_CMD); register uint32 data_buf = SPI0_W0; do { *(uint8 *)des = data_buf; des = (uint8 *)des + 1; data_buf >>= 8; } while(--blksize); } while(size) { if(size < SPI_FBLK) blksize = size; else blksize = SPI_FBLK; #if DEBUGSOO > 5 ets_printf("fr2:%p<-%p[%u]\n", des, faddr, blksize); #endif SPI0_ADDR = faddr | (blksize << 24); SPI0_CMD = SPI_READ; size -= blksize; faddr += blksize; while(SPI0_CMD); //__asm__ __volatile__("memw" : : : "memory"); // volatile uint32 *srcdw = (volatile uint32 *)(SPI0_BASE+0x40); uint32 *srcdw = (uint32 *)(&SPI0_W0); // uint32 *srcdw = (uint32 *)(SPI0_BASE+0x40); while(blksize >> 2) { *((uint32 *)des) = *srcdw++; des = ((uint32 *)des) + 1; blksize -= 4; } if(blksize) { #if DEBUGSOO > 4 ets_printf("fr3:%p<-%p[%u]\n", des, faddr, blksize); #endif uint32 data_buf = *srcdw; do { *(uint8 *)des = data_buf; des = (uint8 *)des + 1; data_buf >>= 8; } while(--blksize); break; } } Cache_Read_Enable_def(); }