esp_err_t iot_relay_state_write(relay_handle_t relay_handle, relay_status_t state) { relay_dev_t* relay_dev = (relay_dev_t*) relay_handle; POINT_ASSERT(TAG, relay_handle); if (relay_dev->ctl_mode == RELAY_DFLIP_CONTROL) { if (relay_dev->io_mode == RELAY_IO_NORMAL) { gpio_set_level(relay_dev->relay_io.flip_io.cp_io_num, 0); gpio_set_level(relay_dev->relay_io.flip_io.d_io_num, (0x01 & state) ^ relay_dev->close_level); ets_delay_us(DFLIPFLOP_DELAY_US); gpio_set_level(relay_dev->relay_io.flip_io.cp_io_num, 1); ets_delay_us(DFLIPFLOP_DELAY_US); gpio_set_level(relay_dev->relay_io.flip_io.cp_io_num, 0); } else { rtc_gpio_set_level(relay_dev->relay_io.flip_io.cp_io_num, 0); rtc_gpio_set_level(relay_dev->relay_io.flip_io.d_io_num, (0x01 & state) ^ relay_dev->close_level); ets_delay_us(DFLIPFLOP_DELAY_US); rtc_gpio_set_level(relay_dev->relay_io.flip_io.cp_io_num, 1); ets_delay_us(DFLIPFLOP_DELAY_US); rtc_gpio_set_level(relay_dev->relay_io.flip_io.cp_io_num, 0); } } else { if (relay_dev->io_mode == RELAY_IO_NORMAL) { gpio_set_level(relay_dev->relay_io.single_io.ctl_io_num, (0x01 & state) ^ relay_dev->close_level); } else { rtc_gpio_set_level(relay_dev->relay_io.single_io.ctl_io_num, (0x01 & state) ^ relay_dev->close_level); } } relay_dev->state = state; return ESP_OK; }
/** * @brief Clock calibration function used by rtc_clk_cal and rtc_clk_cal_ratio * @param cal_clk which clock to calibrate * @param slowclk_cycles number of slow clock cycles to count * @return number of XTAL clock cycles within the given number of slow clock cycles */ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { /* Enable requested clock (150k clock is always on) */ int dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN); if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) { REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1); } if (cal_clk == RTC_CAL_8MD256) { SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN); } /* Prepare calibration */ REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); /* Figure out how long to wait for calibration to finish */ uint32_t expected_freq; rtc_slow_freq_t slow_freq = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL); if (cal_clk == RTC_CAL_32K_XTAL || (cal_clk == RTC_CAL_RTC_MUX && slow_freq == RTC_SLOW_FREQ_32K_XTAL)) { expected_freq = 32768; /* standard 32k XTAL */ } else if (cal_clk == RTC_CAL_8MD256 || (cal_clk == RTC_CAL_RTC_MUX && slow_freq == RTC_SLOW_FREQ_8MD256)) { expected_freq = RTC_FAST_CLK_FREQ_APPROX / 256; } else { expected_freq = 150000; /* 150k internal oscillator */ } uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq); /* Start calibration */ CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); /* Wait the expected time calibration should take. * TODO: if running under RTOS, and us_time_estimate > RTOS tick, use the * RTOS delay function. */ ets_delay_us(us_time_estimate); /* Wait for calibration to finish up to another us_time_estimate */ int timeout_us = us_time_estimate; while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY) && timeout_us > 0) { timeout_us--; ets_delay_us(1); } REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, dig_32k_xtal_state); if (cal_clk == RTC_CAL_8MD256) { CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN); } if (timeout_us == 0) { /* timed out waiting for calibration */ return 0; } return REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE); }
void rtc_clk_wait_for_slow_cycle(void) { REG_CLR_BIT(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING | TIMG_RTC_CALI_START); REG_CLR_BIT(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, RTC_CAL_RTC_MUX); /* Request to run calibration for 0 slow clock cycles. * RDY bit will be set on the nearest slow clock cycle. */ REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, 0); REG_SET_BIT(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); ets_delay_us(1); /* RDY needs some time to go low */ while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) { ets_delay_us(1); } }
void phy_adc_read_fast(uint16 *adc_addr, uint16 adc_num, uint8 adc_clk_div) { tout_dis_txpwr_track = 1; if(adc_clk_div < 2) adc_clk_div = 2; uint32 save_20 = SAR_BASE[20]; uint32 save_21 = SAR_BASE[21]; uint32 save_22 = SAR_BASE[22]; SAR_BASE[20] = (SAR_BASE[20] & 0xFFFF00FF) | ((adc_clk_div & 0xFF) << 8); SAR_BASE[21] = (SAR_BASE[21] & 0xFF000000) | (adc_clk_div * 5 + ((adc_clk_div - 1) << 16) + ((adc_clk_div - 1) << 8) - 1); SAR_BASE[22] = (SAR_BASE[22] & 0xFF000000) | (adc_clk_div * 11 + ((adc_clk_div * 3 - 1) << 8) + ((adc_clk_div * 11 - 1) << 16) - 1); SAR_BASE[20] &= 0xFFFFFFE3; rom_i2c_writeReg_Mask(108,2,0,5,5,1); SAR_BASE[23] |= 1 << 21; while((SAR_BASE[20] >> 24) & 0x07); // while(READ_PERI_REG(0x60000D50)&(0x7<<24)); // wait r_state == 0 while(adc_num--) { SAR_BASE[20] &= 0xFFFFFFE3; SAR_BASE[20] |= 1 << 1; ets_delay_us(1); while((SAR_BASE[20] >> 24) & 0x07); // while(READ_PERI_REG(0x60000D50)&(0x7<<24)); // wait r_state == 0 uint32 x = ~(SAR_BASE[32]); uint32 z = x & 0x7FF; x &= 0xFF; z &= 0xF00; x -= 21; if((signed int) x > 0) { x = (x * 279) >> 8; if(x > 0xff) x = 0xff; z += x; } z++; z >>= 1; if(chip6_phy_init_ctrl[108] == 0xff) z = 0xFFFF; *adc_addr++ = z; }
void call_user_start(void) { uint8 loop; for(loop = 0; loop < 50; loop++) { ets_printf("testload 1\r\n"); ets_delay_us(20000); } }
void stub_main() { uint32_t baud_rate = params[0]; uint32_t greeting = 0x4941484f; /* OHAI */ uint8_t last_cmd; /* This points at us right now, reset for next boot. */ ets_set_user_start(NULL); /* Selects SPI functions for flash pins. */ SelectSpiFunction(); if (baud_rate > 0) { ets_delay_us(1000); uart_div_modify(0, UART_CLKDIV_26MHZ(baud_rate)); } /* Give host time to get ready too. */ ets_delay_us(10000); SLIP_send(&greeting, 4); last_cmd = cmd_loop(); ets_delay_us(10000); if (last_cmd == CMD_BOOT_FW) { /* * Find the return address in our own stack and change it. * "flash_finish" it gets to the same point, except it doesn't need to * patch up its RA: it returns from UartDwnLdProc, then from f_400011ac, * then jumps to 0x4000108a, then checks strapping bits again (which will * not have changed), and then proceeds to 0x400010a8. */ volatile uint32_t *sp = &baud_rate; while (*sp != (uint32_t) 0x40001100) sp++; *sp = 0x400010a8; /* * The following dummy asm fragment acts as a barrier, to make sure function * epilogue, including return address loading, is added after our stack * patching. */ __asm volatile("nop.n"); return; /* To 0x400010a8 */ } else {
//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 main_loop(void* arg) { (void)arg; // timeout of 500ms const TickType_t xTicksToWait = 500 / portTICK_PERIOD_MS; while(1) { EventBits_t uxBits = xEventGroupWaitBits(g_pot_event_group, (POT_PORT1_BIT | POT_PORT2_BIT), pdTRUE, pdFALSE, xTicksToWait); // xEventGroupClearBits(g_pot_event_group, (POT_PORT1_BIT | POT_PORT2_BIT)); // if not timeout, change the state if (uxBits != 0) { // gpio_set_level(GPIO_NUM_5, 0); // gpio_set_level(GPIO_NUM_21, 1); // ets_delay_us(50); gpio_set_level(GPIO_NUM_21, 0); ets_delay_us(223); ets_delay_us(g_joy_state.joy1_potx); gpio_set_level(GPIO_NUM_21, 1); // gpio_set_level(GPIO_NUM_5, 1); // ets_delay_us(50); // gpio_set_level(GPIO_NUM_21, 0); // gpio_set_level(GPIO_NUM_5, 0); // const TickType_t xDelay = 100 / portTICK_PERIOD_MS; // vTaskDelay(xDelay); } else { // timeout gpio_set_level(GPIO_NUM_21, 0); } // taskYIELD(); } }
uint64_t rtc_time_get(void) { SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE); while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID) == 0) { ets_delay_us(1); // might take 1 RTC slowclk period, don't flood RTC bus } SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_TIME_VALID_INT_CLR); uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG); t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32; return t; }
void bootloader_reset(void) { #ifdef BOOTLOADER_BUILD uart_tx_flush(0); /* Ensure any buffered log output is displayed */ uart_tx_flush(1); ets_delay_us(1000); /* Allow last byte to leave FIFO */ REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST); while (1) { } /* This line will never be reached, used to keep gcc happy */ #else abort(); /* This function should really not be called from application code */ #endif }
static void sdmmc_host_input_clk_enable() { // Set frequency to 160MHz / (p + 1) = 40MHz, duty cycle (h + 1)/(p + 1) = 1/2 SDMMC.clock.div_factor_p = 3; SDMMC.clock.div_factor_h = 1; SDMMC.clock.div_factor_m = 3; // Set phases for in/out clocks SDMMC.clock.phase_dout = 4; SDMMC.clock.phase_din = 4; SDMMC.clock.phase_core = 0; // Wait for the clock to propagate ets_delay_us(10); }
void IROM SysLog(SysLogLevel level, const char* file, const char* function, const char * format, ...) { char *p; buffer[0] = 0; va_list args; va_start(args, format); if (GetMutex(&logMutex) == 0) { for (p = "$$$:"; *p != 0; p++) uart0WriteWait(*p); for (p = file; *p != 0; p++) uart0WriteWait(*p); for (p = "$$$"; *p != 0; p++) uart0WriteWait(*p); for (p = function; *p != 0; p++) uart0WriteWait(*p); // uart0WriteBytes(":",1); // uart0WriteBytes(function,strlen(function)); // os_printf_plus(" Syslog called by %s ",function); conflicts += 1000; va_end(args); return; } uint32_t time = SysMillis(); ets_vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); char dst[40]; dst[0] = '\0'; strAlign(dst, 18, file, strlen(file)); strAlign(&dst[18], 18, function, strlen(function)); // if (level > LOG_INFO) { // put log in mqtt buffer // ets_sprintf(lastLog, "%s:%s:%s", SysLogLevelStr[level], dst, buffer); // } ets_snprintf(lastLog, sizeof(lastLog), "%10u | %s | %s\n", time, dst, buffer); uart0WriteBytes(lastLog, strlen(lastLog)); // os_delay_us(1000); ets_delay_us(10000); // os_printf_plus(); ReleaseMutex(&logMutex); }
static void sdmmc_host_set_clk_div(int div) { // Set frequency to 160MHz / div // div = p + 1 // duty cycle = (h + 1)/(p + 1) (should be = 1/2) assert (div > 1 && div <= 16); int p = div - 1; int h = div / 2 - 1; SDMMC.clock.div_factor_p = p; SDMMC.clock.div_factor_h = h; SDMMC.clock.div_factor_m = p; // Set phases for in/out clocks SDMMC.clock.phase_dout = 4; // 180 degree phase on the output clock SDMMC.clock.phase_din = 4; // 180 degree phase on the input clock SDMMC.clock.phase_core = 0; // Wait for the clock to propagate ets_delay_us(10); }
static void test_delay_task(void* p) { delay_test_arg_t* arg = (delay_test_arg_t*) p; vTaskDelay(1); uint64_t start = ref_clock_get(); switch (arg->method) { case 0: ets_delay_us(arg->delay_us); break; case 1: vTaskDelay(arg->delay_us / portTICK_PERIOD_MS / 1000); break; default: TEST_FAIL(); } uint64_t stop = ref_clock_get(); arg->result = (int) (stop - start); xSemaphoreGive(arg->done); vTaskDelete(NULL); }
bool ICACHE_FLASH_ATTR tcp_listen(unsigned int port) { int ret; httpConn.type = ESPCONN_TCP; httpConn.state = ESPCONN_NONE; httpConn.proto.tcp = &httpTcp; httpConn.proto.tcp->local_port = port; espconn_regist_connectcb(&httpConn, tcp_connect_cb); espconn_regist_reconcb(&httpConn, tcp_reconnect_cb); espconn_regist_disconcb(&httpConn, tcp_disconnect_cb); ret = espconn_accept(&httpConn); espconn_regist_time(&httpConn, 15, 0); //timeout if (ret != ESPCONN_OK) { TESTP("Error when starting the listener: %d.\n", ret); ets_delay_us(2000); return false; } return true; }
void phy_tlk110_init(void) { ESP_LOGD(TAG, "phy_tlk110_init()"); phy_tlk110_dump_registers(); esp_eth_smi_write(PHY_RESET_CONTROL_REG, SOFTWARE_RESET); esp_err_t res1, res2; do { // Call esp_eth_smi_wait_value() with a timeout so it prints an error periodically res1 = esp_eth_smi_wait_value(MII_PHY_IDENTIFIER_1_REG, TLK110_PHY_ID1, UINT16_MAX, 1000); res2 = esp_eth_smi_wait_value(MII_PHY_IDENTIFIER_2_REG, TLK110_PHY_ID2, TLK110_PHY_ID2_MASK, 1000); } while(res1 != ESP_OK || res2 != ESP_OK); esp_eth_smi_write(SW_STRAP_CONTROL_REG, DEFAULT_STRAP_CONFIG | SW_STRAP_CONFIG_DONE); ets_delay_us(300); // TODO: only do this if config.flow_ctrl_enable == true phy_mii_enable_flow_ctrl(); }
static void test_delay_task(void* p) { const delay_test_arg_t* arg = (delay_test_arg_t*) p; struct timeval tv_start, tv_stop; gettimeofday(&tv_start, NULL); switch (arg->method) { case 0: ets_delay_us(arg->delay_us); break; case 1: vTaskDelay(arg->delay_us / portTICK_PERIOD_MS / 1000); break; default: TEST_FAIL(); } gettimeofday(&tv_stop, NULL); int real_delay_us = (tv_stop.tv_sec - tv_start.tv_sec) * 1000000 + tv_stop.tv_usec - tv_start.tv_usec; printf("%s core=%d expected=%d actual=%d\n", arg->method ? "vTaskDelay" : "ets_delay_us", xPortGetCoreID(), arg->delay_us, real_delay_us); TEST_ASSERT_TRUE(abs(real_delay_us - arg->delay_us) < 1000); vTaskDelay(1); vTaskDelete(NULL); }
// prevent this function being placed inline with main // to keep main's stack size as small as possible static uint32 NOINLINE find_image() { uint8 flag; uint32 runAddr; uint32 flashsize; int32 romToBoot; uint8 gpio_boot = FALSE; uint8 updateConfig = TRUE; uint8 buffer[SECTOR_SIZE]; rboot_config *romconf = (rboot_config*)buffer; rom_header *header = (rom_header*)buffer; ets_delay_us(2000000); ets_printf("\r\nrBoot v1.0.0 - [email protected]\r\n"); // read rom header SPIRead(0, header, sizeof(rom_header)); // print and get flash size ets_printf("Flash Size: "); flag = header->flags2 >> 4; if (flag == 0) { ets_printf("4 Mbit\r\n"); flashsize = 0x80000; } else if (flag == 1) { ets_printf("2 Mbit\r\n"); flashsize = 0x40000; } else if (flag == 2) { ets_printf("8 Mbit\r\n"); flashsize = 0x100000; } else if (flag == 3) { ets_printf("16 Mbit\r\n"); flashsize = 0x200000; } else if (flag == 4) { ets_printf("32 Mbit\r\n"); flashsize = 0x400000; } else { ets_printf("unknown\r\n"); // assume at least 4mbit flashsize = 0x80000; } // print spi mode ets_printf("Flash Mode: "); if (header->flags1 == 0) { ets_printf("QIO\r\n"); } else if (header->flags1 == 1) { ets_printf("QOUT\r\n"); } else if (header->flags1 == 2) { ets_printf("DIO\r\n"); } else if (header->flags1 == 3) { ets_printf("DOUT\r\n"); } else { ets_printf("unknown\r\n"); } // print spi speed ets_printf("Flash Speed: "); flag = header->flags2 & 0x0f; if (flag == 0) ets_printf("40 MHz\r\n"); else if (flag == 1) ets_printf("26.7 MHz\r\n"); else if (flag == 2) ets_printf("20 MHz\r\n"); else if (flag == 0x0f) ets_printf("80 MHz\r\n"); else ets_printf("unknown\r\n"); // read boot config SPIRead(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE); // fresh install or old version? if (romconf->magic != BOOT_CONFIG_MAGIC || romconf->version != BOOT_CONFIG_VERSION) { // create a default config for a standard 2 rom setup ets_printf("Writing default boot config.\r\n"); ets_memset(romconf, 0x00, sizeof(rboot_config)); romconf->magic = BOOT_CONFIG_MAGIC; romconf->version = BOOT_CONFIG_VERSION; romconf->mode = MODE_STANDARD; romconf->current_rom = 0; romconf->count = 2; romconf->current_rom = 0; romconf->roms[0] = SECTOR_SIZE * 2; romconf->roms[1] = (flashsize / 2) + (SECTOR_SIZE * 2); // write new config sector SPIEraseSector(BOOT_CONFIG_SECTOR); SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE); } // if gpio mode enabled check status of the gpio if ((romconf->mode & MODE_GPIO_ROM) && (get_gpio16() == 0)) { ets_printf("Booting GPIO-selected.\r\n"); romToBoot = romconf->gpio_rom; gpio_boot = TRUE; } else if (romconf->current_rom >= romconf->count) { // if invalid rom selected try rom 0 ets_printf("Invalid rom selected, defaulting.\r\n"); romToBoot = 0; romconf->current_rom = 0; updateConfig = TRUE; } else { // try rom selected in the config romToBoot = romconf->current_rom; } // try to find a good rom do { runAddr = check_image(romconf->roms[romToBoot]); if (runAddr == 0) { ets_printf("Rom %d is bad.\r\n", romToBoot); if (gpio_boot) { // don't switch to backup for gpio-selected rom ets_printf("GPIO boot failed.\r\n"); return 0; } else { // for normal mode try each previous rom // until we find a good one or run out updateConfig = TRUE; romToBoot--; if (romToBoot < 0) romToBoot = romconf->count - 1; if (romToBoot == romconf->current_rom) { // tried them all and all are bad! ets_printf("No good rom available.\r\n"); return 0; } } } } while (runAddr == 0); // re-write config, if required if (updateConfig) { romconf->current_rom = romToBoot; SPIEraseSector(BOOT_CONFIG_SECTOR); SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE); } ets_printf("Booting rom %d.\r\n", romToBoot); // copy the loader to top of iram ets_memcpy((void*)_text_addr, _text_data, _text_len); // return address to load from return runAddr; }
//============================================================================= bool init_mpu9250(void) { struct smpu9250_config * p = init_mpu9250_tab; uint8 buf[32]; while(1) { if(p->addr == INIT_BRK_PAUSE) { if(p->data == INIT_BRK_I2C_READY) { int i = 0; do { hspi_cmd_read(CS_MPU9250_PIN, SPI_CMD_READ | MPU9250_RA_INT_STATUS, buf, 1); if(++i & 0x100) { #if DEBUGSOO > 2 os_printf("INT: %02x\n", buf[0]); #endif return false; // break; } } while ((buf[0] & MPU9250_RAW_DATA_RDY_INT) == 0); hspi_cmd_read(CS_MPU9250_PIN, SPI_CMD_READ | MPU9250_RA_I2C_MST_STATUS, &buf[1], 1); #if DEBUGSOO > 2 os_printf("INT: %02x %02x, %u\n", buf[0], buf[1], i); #endif } else if (p->data == INIT_BRK_I2C_MAG) { hspi_cmd_read(CS_MPU9250_PIN, SPI_CMD_READ | MPU9250_RA_EXT_SENS_DATA_00, (uint8 *)&mag_regs, sizeof(mag_regs)); if(mag_regs.wia != AK8963_WIA_ID) return false; #if DEBUGSOO > 1 os_printf("Mag:"); uint8 * ptr = (uint8 *)&mag_regs; int i = sizeof(mag_regs); while(i--) os_printf(" %02x", *ptr++); os_printf("\n"); #endif kasa[0] = mag_regs.asax-128; kasa[1] = mag_regs.asay-128; kasa[2] = mag_regs.asaz-128; } else if (p->data > INIT_BRK_I2C_READY) { int i = 0; uint8 x = MPU9250_I2C_SLV4_DONE; if(p->data != INIT_BRK_I2C_READY4) x = 1<<(p->data - INIT_BRK_I2C_READY0); do { hspi_cmd_read(CS_MPU9250_PIN, SPI_CMD_READ | MPU9250_RA_I2C_MST_STATUS, buf, 1); if(++i & 0x100) { #if DEBUGSOO > 2 os_printf("MST: %02x\n", buf[0]); #endif return false; // break; } } while ((buf[0] & x)==0); #if DEBUGSOO > 2 os_printf("MST: %02x, %u\n", buf[0], i); #endif } else if (p->data == 0) return true; else ets_delay_us(p->data*1000); } else { if(p->addr & SPI_CMD_READ) { hspi_cmd_read(CS_MPU9250_PIN, p->addr, buf, p->data); // ets_delay_us(1000); #if DEBUGSOO > 2 os_printf("R%02x(%u):", p->addr & (~(SPI_CMD_READ)), p->addr & (~(SPI_CMD_READ))); uint8 * ptr = buf; int i = p->data; while(i--) os_printf(" %02x", *ptr++); os_printf("\n"); #endif } else { hspi_cmd_write(CS_MPU9250_PIN, p->addr, &p->data, 1); ets_delay_us(200); // 1000 } } p++; } }
void cmd_loop() { while(1) { /* Wait for a command */ while(ub.command == NULL) { } esp_command_req_t *command = ub.command; ub.command = NULL; /* provide easy access for 32-bit data words */ uint32_t *data_words = (uint32_t *)command->data_buf; /* Send command response header */ esp_command_response_t resp = { .resp = 1, .op_ret = command->op, .len_ret = 0, /* esptool.py ignores this value */ .value = 0, }; /* ESP_READ_REG is the only command that needs to write into the 'resp' structure before we send it back. */ if (command->op == ESP_READ_REG && command->data_len == 4) { resp.value = REG_READ(data_words[0]); } /* Send the command response. */ SLIP_send_frame_delimiter(); SLIP_send_frame_data_buf(&resp, sizeof(esp_command_response_t)); if(command->data_len > MAX_WRITE_BLOCK+16) { SLIP_send_frame_data(ESP_BAD_DATA_LEN); SLIP_send_frame_data(0xEE); SLIP_send_frame_delimiter(); continue; } /* ... some commands will insert in-frame response data between here and when we send the end of the frame */ esp_command_error error = ESP_CMD_NOT_IMPLEMENTED; int status = 0; /* First stage of command processing - before sending error/status */ switch (command->op) { case ESP_ERASE_FLASH: error = verify_data_len(command, 0) || SPIEraseChip(); break; case ESP_ERASE_REGION: /* Params for ERASE_REGION are addr, len */ error = verify_data_len(command, 8) || handle_flash_erase(data_words[0], data_words[1]); break; case ESP_SET_BAUD: /* ESP_SET_BAUD sends two args, we ignore the second one */ error = verify_data_len(command, 8); /* actual baud setting happens after we send the reply */ break; case ESP_READ_FLASH: error = verify_data_len(command, 16); /* actual data is sent after we send the reply */ break; case ESP_FLASH_VERIFY_MD5: /* unsure why the MD5 command has 4 params but we only pass 2 of them, but this is in ESP32 ROM so we can't mess with it. */ error = verify_data_len(command, 16) || handle_flash_get_md5sum(data_words[0], data_words[1]); break; case ESP_FLASH_BEGIN: /* parameters (interpreted differently to ROM flasher): 0 - erase_size (used as total size to write) 1 - num_blocks (ignored) 2 - block_size (should be MAX_WRITE_BLOCK, relies on num_blocks * block_size >= erase_size) 3 - offset (used as-is) */ if (command->data_len == 16 && data_words[2] != MAX_WRITE_BLOCK) { error = ESP_BAD_BLOCKSIZE; } else { error = verify_data_len(command, 16) || handle_flash_begin(data_words[0], data_words[3]); } break; case ESP_FLASH_DEFLATED_BEGIN: /* parameters: 0 - uncompressed size 1 - num_blocks (based on compressed size) 2 - block_size (should be MAX_WRITE_BLOCK, total bytes over serial = num_blocks * block_size) 3 - offset (used as-is) */ if (command->data_len == 16 && data_words[2] != MAX_WRITE_BLOCK) { error = ESP_BAD_BLOCKSIZE; } else { error = verify_data_len(command, 16) || handle_flash_deflated_begin(data_words[0], data_words[1] * data_words[2], data_words[3]); } break; case ESP_FLASH_DATA: case ESP_FLASH_DEFLATED_DATA: /* ACK DATA commands immediately, then process them a few lines down, allowing next command to buffer */ if(is_in_flash_mode()) { error = get_flash_error(); int payload_len = command->data_len - 16; if (data_words[0] != payload_len) { /* First byte of data payload header is length (repeated) as a word */ error = ESP_BAD_DATA_LEN; } uint8_t data_checksum = calculate_checksum(command->data_buf + 16, payload_len); if (data_checksum != command->checksum) { error = ESP_BAD_DATA_CHECKSUM; } } else { error = ESP_NOT_IN_FLASH_MODE; } break; case ESP_FLASH_END: case ESP_FLASH_DEFLATED_END: error = handle_flash_end(); break; case ESP_SPI_SET_PARAMS: /* data params: fl_id, total_size, block_size, sector_Size, page_size, status_mask */ error = verify_data_len(command, 24) || handle_spi_set_params(data_words, &status); break; case ESP_SPI_ATTACH: /* parameter is 'hspi mode' (0, 1 or a pin mask for ESP32. Ignored on ESP8266.) */ error = verify_data_len(command, 4) || handle_spi_attach(data_words[0]); break; case ESP_WRITE_REG: /* params are addr, value, mask (ignored), delay_us (ignored) */ error = verify_data_len(command, 16); if (error == ESP_OK) { REG_WRITE(data_words[0], data_words[1]); } break; case ESP_READ_REG: /* actual READ_REG operation happens higher up */ error = verify_data_len(command, 4); break; case ESP_MEM_BEGIN: error = verify_data_len(command, 16) || handle_mem_begin(data_words[0], data_words[3]); break; case ESP_MEM_DATA: error = handle_mem_data(command->data_buf + 16, command->data_len - 16); break; case ESP_MEM_END: error = verify_data_len(command, 8) || handle_mem_finish(); break; case ESP_RUN_USER_CODE: /* Returning from here will run user code, ie standard boot process This command does not send a response. */ return; } SLIP_send_frame_data(error); SLIP_send_frame_data(status); SLIP_send_frame_delimiter(); /* Some commands need to do things after after sending this response */ if (error == ESP_OK) { switch(command->op) { case ESP_SET_BAUD: ets_delay_us(10000); uart_div_modify(0, baud_rate_to_divider(data_words[0])); ets_delay_us(1000); break; case ESP_READ_FLASH: /* args are: offset, length, block_size, max_in_flight */ handle_flash_read(data_words[0], data_words[1], data_words[2], data_words[3]); break; case ESP_FLASH_DATA: /* drop into flashing mode, discard 16 byte payload header */ handle_flash_data(command->data_buf + 16, command->data_len - 16); break; case ESP_FLASH_DEFLATED_DATA: handle_flash_deflated_data(command->data_buf + 16, command->data_len - 16); break; case ESP_FLASH_DEFLATED_END: case ESP_FLASH_END: /* passing 0 as parameter for ESP_FLASH_END means reboot now */ if (data_words[0] == 0) { /* Flush the FLASH_END response before rebooting */ #ifdef ESP32 uart_tx_flush(0); #endif ets_delay_us(10000); software_reset(); } break; case ESP_MEM_END: if (data_words[1] != 0) { void (*entrypoint_fn)(void) = (void (*))data_words[1]; /* this is a little different from the ROM loader, which exits the loader routine and _then_ calls this function. But for our purposes so far, having a bit of extra stuff on the stack doesn't really matter. */ entrypoint_fn(); } break; } } } } extern uint32_t _bss_start; extern uint32_t _bss_end; void __attribute__((used)) stub_main(); #ifdef ESP8266 __asm__ ( ".global stub_main_8266\n" ".literal_position\n" ".align 4\n" "stub_main_8266:\n" /* ESP8266 wrapper for "stub_main()" manipulates the return address in * a0, so 'return' from here runs user code. * * After setting a0, we jump directly to stub_main_inner() which is a * normal C function * * Adapted from similar approach used by Cesanta Software for ESP8266 * flasher stub. * */ "movi a0, 0x400010a8;" "j stub_main;"); #endif /* This function is called from stub_main, with return address reset to point to user code. */ void stub_main() { const uint32_t greeting = 0x4941484f; /* OHAI */ /* this points to stub_main now, clear for next boot */ ets_set_user_start(0); /* zero bss */ for(uint32_t *p = &_bss_start; p < &_bss_end; p++) { *p = 0; } SLIP_send(&greeting, 4); /* All UART reads come via uart_isr */ ub.reading_buf = ub.buf_a; ets_isr_attach(ETS_UART0_INUM, uart_isr, NULL); SET_PERI_REG_MASK(UART_INT_ENA(0), UART_RX_INTS); ets_isr_unmask(1 << ETS_UART0_INUM); /* Configure default SPI flash functionality. Can be overriden later by esptool.py. */ #ifdef ESP8266 SelectSpiFunction(); #else uint32_t spiconfig = ets_efuse_get_spiconfig(); uint32_t strapping = REG_READ(GPIO_STRAP_REG); /* If GPIO1 (U0TXD) is pulled low and no other boot mode is set in efuse, assume HSPI flash mode (same as normal boot) */ if (spiconfig == 0 && (strapping & 0x1c) == 0x08) { spiconfig = 1; /* HSPI flash mode */ } spi_flash_attach(spiconfig, 0); #endif SPIParamCfg(0, 16*1024*1024, FLASH_BLOCK_SIZE, FLASH_SECTOR_SIZE, FLASH_PAGE_SIZE, FLASH_STATUS_MASK); cmd_loop(); /* if cmd_loop returns, it's due to ESP_RUN_USER_CODE command. */ return; }
esp_err_t sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card) { ESP_LOGD(TAG, "%s", __func__); memset(card, 0, sizeof(*card)); memcpy(&card->host, config, sizeof(*config)); esp_err_t err = sdmmc_send_cmd_go_idle_state(card); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: go_idle_state (1) returned 0x%x", __func__, err); return err; } ets_delay_us(10000); uint32_t host_ocr = get_host_ocr(config->io_voltage); err = sdmmc_send_cmd_send_if_cond(card, host_ocr); if (err == ESP_OK) { ESP_LOGD(TAG, "SDHC/SDXC card"); host_ocr |= SD_OCR_SDHC_CAP; } else if (err == ESP_ERR_TIMEOUT) { ESP_LOGD(TAG, "CMD8 timeout; not an SDHC/SDXC card"); } else { ESP_LOGE(TAG, "%s: send_if_cond (1) returned 0x%x", __func__, err); return err; } err = sdmmc_send_cmd_send_op_cond(card, host_ocr, &card->ocr); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: send_op_cond (1) returned 0x%x", __func__, err); return err; } host_ocr &= card->ocr; ESP_LOGD(TAG, "sdmmc_card_init: host_ocr=%08x, card_ocr=%08x", host_ocr, card->ocr); err = sddmc_send_cmd_all_send_cid(card, &card->cid); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: all_send_cid returned 0x%x", __func__, err); return err; } err = sdmmc_send_cmd_set_relative_addr(card, &card->rca); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: set_relative_addr returned 0x%x", __func__, err); return err; } err = sdmmc_send_cmd_send_csd(card, &card->csd); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: send_csd returned 0x%x", __func__, err); return err; } const size_t max_sdsc_capacity = UINT32_MAX / card->csd.sector_size + 1; if (!(card->ocr & SD_OCR_SDHC_CAP) && card->csd.capacity > max_sdsc_capacity) { ESP_LOGW(TAG, "%s: SDSC card reports capacity=%u. Limiting to %u.", __func__, card->csd.capacity, max_sdsc_capacity); card->csd.capacity = max_sdsc_capacity; } err = sdmmc_send_cmd_select_card(card); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: select_card returned 0x%x", __func__, err); return err; } if ((card->ocr & SD_OCR_SDHC_CAP) == 0) { err = sdmmc_send_cmd_set_blocklen(card, &card->csd); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: set_blocklen returned 0x%x", __func__, err); return err; } } err = sdmmc_send_cmd_send_scr(card, &card->scr); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: send_scr returned 0x%x", __func__, err); return err; } if ((config->flags & SDMMC_HOST_FLAG_4BIT) && (card->scr.bus_width & SCR_SD_BUS_WIDTHS_4BIT)) { ESP_LOGD(TAG, "switching to 4-bit bus mode"); err = sdmmc_send_cmd_set_bus_width(card, 4); if (err != ESP_OK) { ESP_LOGE(TAG, "set_bus_width failed"); return err; } err = (*config->set_bus_width)(config->slot, 4); if (err != ESP_OK) { ESP_LOGE(TAG, "slot->set_bus_width failed"); return err; } uint32_t status; err = sdmmc_send_cmd_stop_transmission(card, &status); if (err != ESP_OK) { ESP_LOGE(TAG, "stop_transmission failed (0x%x)", err); return err; } } uint32_t status = 0; while (!(status & MMC_R1_READY_FOR_DATA)) { // TODO: add some timeout here uint32_t count = 0; err = sdmmc_send_cmd_send_status(card, &status); if (err != ESP_OK) { return err; } if (++count % 10 == 0) { ESP_LOGV(TAG, "waiting for card to become ready (%d)", count); } } if (config->max_freq_khz >= SDMMC_FREQ_HIGHSPEED && card->csd.tr_speed / 1000 >= SDMMC_FREQ_HIGHSPEED) { ESP_LOGD(TAG, "switching to HS bus mode"); err = (*config->set_card_clk)(config->slot, SDMMC_FREQ_HIGHSPEED); if (err != ESP_OK) { ESP_LOGE(TAG, "failed to switch peripheral to HS bus mode"); return err; } } else if (config->max_freq_khz >= SDMMC_FREQ_DEFAULT && card->csd.tr_speed / 1000 >= SDMMC_FREQ_DEFAULT) { ESP_LOGD(TAG, "switching to DS bus mode"); err = (*config->set_card_clk)(config->slot, SDMMC_FREQ_DEFAULT); if (err != ESP_OK) { ESP_LOGE(TAG, "failed to switch peripheral to HS bus mode"); return err; } } sdmmc_scr_t scr_tmp; err = sdmmc_send_cmd_send_scr(card, &scr_tmp); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: send_scr returned 0x%x", __func__, err); return err; } if (memcmp(&card->scr, &scr_tmp, sizeof(scr_tmp)) != 0) { ESP_LOGE(TAG, "data check fail!"); return ESP_ERR_INVALID_RESPONSE; } return ESP_OK; }
static void tsk_self_del_us_delay(void *param) { uint32_t delay = (uint32_t)param; ets_delay_us(delay); vTaskDelete(NULL); }
static void ICACHE_FLASH_ATTR tcp_disconnect_cb(void *arg) { struct espconn *conn = (struct espconn*) arg; TESTP("Disconnected %s\n", reboot ? "rebooting" : ""); ets_delay_us(5000); if (reboot) system_restart(); }
void mp_hal_delay_us(uint32_t us) { ets_delay_us(us); }
ICACHE_FLASH_ATTR void promisc_start() { wDevDisableRx(); //size_t flags = 0b11011110011111100111; // tx, no rx //size_t flags = 0b00000000011111100000; // broken //size_t flags = 0b00000000010101100000; // works const static size_t flags = 0b11011110000001100111; // 66s2555550000564g666 //flags = 0; extern char g_ic[0]; size_t *a6 = (size_t *)0x3ff1fe00; size_t *a2 = (size_t *)0x60009a00; size_t *a10 = (size_t *)0x3ff20600; extern size_t wDevCtrl[0]; size_t *a4 = wDevCtrl; size_t *a5 = (size_t *)0x3ff20a00; { if (flags & 0x1) a6[0x26c / 4] &= ~1; if (flags & 0x2) a6[0x26c / 4] &= ~2; if (flags & 0x4) a6[0x26c / 4] &= ~4; if (flags & 0x8) (g_ic + 0x180)[100] = 1; if (flags & 0x10) ((char *)a4)[5] = 1; } { if (flags & 0x20) a6[0x20c / 4] = a4[12]; if (flags & 0x40) a5[0x288 / 4] |= 0x00040000; if (flags & 0x80) a10[0x200 / 4] |= 0x03000000; if (flags & 0x100) a10[0x200 / 4] &= ~0x00010000; if (flags & 0x200) a10[0x204 / 4] |= 0x03000000; if (flags & 0x400) a10[0x204 / 4] &= ~0x00010000; if (flags & 0x800) a5[0x258 / 4] = 0; if (flags & 0x1000) a5[0x25c / 4] = 0x00010000; if (flags & 0x2000) a5[0x238 / 4] = 0; if (flags & 0x4000) a5[0x23c / 4] = 0x00010000; if (flags & 0x8000) a5[0x218 / 4] |= 12; if (flags & 0x10000) a2[0x344 / 4] &= ~0x24000000; if (flags & 0x20000) ets_delay_us(15000); if (flags & 0x40000) a6 = (size_t *)a5; if (flags & 0x80000) a6[0x294 / 4] &= ~1; } assert((g_ic + 0x180)[100] != 1); wDevEnableRx(); }