void fatal_error(uint32_t errn, void *addr, void *txt) { uint32_t *ptr = (uint32_t *)(RTC_MEM_BASE); *ptr++ = errn; *ptr++ = (uint32_t)addr; *ptr++ = (uint32_t)txt; _ResetVector(); }
//extern char _text_end; //============================================================================= // IRAM code //============================================================================= // call_user_start() - вызов из заголовка, загрузчиком // ENTRY(call_user_start) in eagle.app.v6.ld //----------------------------------------------------------------------------- void __attribute__ ((noreturn)) call_user_start(void) { // Cache_Read_Disable(); IO_RTC_4 = 0; // Отключить блок WiFi (уменьшение потребления на время загрузки) GPIO0_MUX_alt = VAL_MUX_GPIO0_SDK_DEF; // Отключить вывод CLK на GPIO0 SPI0_USER |= SPI_CS_SETUP; // +1 такт перед CS = 0x80000064 #if FQSPI == 80 // xSPI на 80 MHz GPIO_MUX_CFG_alt |= BIT(MUX_SPI0_CLK_BIT); // QSPI = 80 MHz SPI0_CTRL = (SPI0_CTRL & SPI_CTRL_F_MASK) | SPI_CTRL_F80MHZ; #else // xSPI на 40 MHz GPIO_MUX_CFG_alt &= ~(1<< MUX_SPI0_CLK_BIT); SPI0_CTRL = (SPI0_CTRL & SPI_CTRL_F_MASK) | SPI_CTRL_F40MHZ; #endif // OTA #if DEBUGSOO > 1 p_printf("\nStart OTA loader.\n"); #endif uint32_t buffer[SPI_FLASH_SEC_SIZE/4]; SPIRead(esp_init_data_default_addr + MAX_SYS_CONST_BLOCK, buffer, (sizeof(OTA_flash_struct)+3)&~3); OTA_flash_struct *OTA = (OTA_flash_struct *)buffer; if(OTA->id == OTA_flash_struct_id) { uint32 image_start = OTA->image_addr; uint32 sectors = OTA->image_sectors; SPIRead(image_start, buffer, 4); if(*(uint8 *)buffer == firmware_start_magic) { #if DEBUGSOO > 0 p_printf("Update firmware from 0x%x, %u sectors: ", image_start, sectors); #endif ets_delay_us(1000000); // 1 sec uint32 write_to = 0; for(uint32 i = 0; i < sectors; i++) { SPIRead(image_start + i * SPI_FLASH_SEC_SIZE, buffer, SPI_FLASH_SEC_SIZE); SPIEraseSector(i); SPIWrite(write_to, buffer, SPI_FLASH_SEC_SIZE); write_to += SPI_FLASH_SEC_SIZE; #if DEBUGSOO > 0 p_printf("x"); #endif } #if DEBUGSOO > 0 p_printf("\nOk."); #endif if(image_start >= write_to) SPIEraseSector(image_start / SPI_FLASH_SEC_SIZE); _ResetVector(); } } #if DEBUGSOO > 1 p_printf("\nGoto next loader.\n"); #endif // Всё, включаем кеширование, далее можно вызывать процедуры из flash Cache_Read_Enable(0, 0, 0); // Переход в область кеширования flash, // Запускаем загрузку SDK с указателем на заголовок SPIFlashHeader (находится за данным загручиком по адресу с align 16) // ((loader_call)((uint32)(&loader_flash_boot) + FLASH_BASE - IRAM_BASE + 0x10))((struct SPIFlashHeader *)(((uint32)(&_text_end) + FLASH_BASE - IRAM_BASE + 0x17) & (~15))); ((loader_call)(loader_flash_boot_addr))((struct SPIFlashHeader *)(next_flash_header_addr)); }
void store_exception_error(uint32_t errn) { uint32_t *ptr = (uint32_t *)(RTC_MEM_BASE); *ptr++ = errn; *ptr++ = RSR(EXCCAUSE); *ptr++ = RSR(EPC1); *ptr++ = RSR(EPC2); *ptr++ = RSR(EPC3); *ptr++ = RSR(EXCVADDR); *ptr++ = RSR(DEPC); if(errn > RST_EVENT_WDT) _ResetVector(); }
void stub_main() { uint8_t dummy; uint32_t flash_size = 0; while (1) { if (SPIRead(flash_size, &dummy, 1) != 0) break; if (flash_size == 0) { /* Start at 256K */ flash_size = 256 * 1024; } else { flash_size *= 2; } } send_packet(&flash_size, sizeof(flash_size)); send_packet(&flash_size, 0); _ResetVector(); }
void stub_main() { send_packet(hello, 5); _ResetVector(); }