//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 io_statistics(void) { #ifdef PRINT_PORT p_printf("rep: inb: %i, inw: %i, inl: %i, outb: %i, outw: %i, outl: %i\n", r_inb,r_inw,r_inl,r_outb,r_outw,r_outl); p_printf("inb: %i, inw: %i, inl: %i, outb: %i, outw: %i, outl: %i\n", in_b,in_w,in_l,out_b,out_w,out_l); #endif }
void p_outw(CARD16 port, CARD16 val) { out_w++; p_printf(" outw(%#x, %4.4x)"RET_N,port,val); #ifdef PRINT_IP p_printf(" %x\n",getIP()); #endif outw(port,val); }
void p_outb(CARD16 port, CARD8 val) { out_b++; p_printf(" outb(%#x, %2.2x)"RET_N,port,val); #ifdef PRINT_IP p_printf(" %x\n",getIP()); #endif outb(port,val); }
CARD16 p_inw(CARD16 port) { CARD16 val = 0; in_w++; val = inw(port); p_printf(" inw(%#x) = %4.4x"RET_N,port,val); #ifdef PRINT_IP p_printf(" %x\n",getIP()); #endif return val; }
void p_outl(CARD16 port, CARD32 val) { out_l++; p_printf(" outl(%#x, %8.8x)"RET_N,port,val); #ifdef PRINT_IP p_printf(" %x\n",getIP()); #endif #ifdef NEED_PCI_IO if (cfg1out(port,val)) return; #endif outl(port,val); }
CARD8 p_inb(CARD16 port) { CARD8 val = 0; in_b++; val = inb(port); p_printf(" inb(%#x) = %2.2x"RET_N,port,val); #ifdef PRINT_IP p_printf(" %x\n",getIP()); #endif if (port == 0x3d5) s_break(); return val; }
int port_rep_outb(CARD16 port, CARD8 *base, int d_f, CARD32 count) { register int inc = d_f ? -1 : 1; CARD8 *dst = base; p_printf(" rep_outb(%#x) %d bytes at %p %s"RET_N, port, count, base, d_f?"up":"down"); #ifdef PRINT_IP p_printf(" %x\n",getIP()); #endif r_outb++; while (count--) { outb(port,*dst); dst += inc; } return (dst-base); }
CARD32 p_inl(CARD16 port) { CARD32 val = 0; in_l++; #ifdef NEED_PCI_IO if (cfg1in(port,&val)) return val; else #endif val = inl(port); p_printf(" inl(%#x) = %8.8x"RET_N,port,val); #ifdef PRINT_IP p_printf(" %x\n",getIP()); #endif return val; }