Beispiel #1
0
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;
}
Beispiel #2
0
/**
 * @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);
}
Beispiel #3
0
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);
    }
}
Beispiel #4
0
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;
	}
Beispiel #5
0
void call_user_start(void) {
	uint8 loop;
	for(loop = 0; loop < 50; loop++) {
		ets_printf("testload 1\r\n");
		ets_delay_us(20000);
	}
}
Beispiel #6
0
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 {
Beispiel #7
0
//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));
}
Beispiel #8
0
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();
    }
}
Beispiel #9
0
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;
}
Beispiel #10
0
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
}
Beispiel #11
0
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);
}
Beispiel #12
0
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);
}
Beispiel #13
0
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);
}
Beispiel #14
0
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);
}
Beispiel #15
0
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;
}
Beispiel #16
0
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();
}
Beispiel #17
0
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);
}
Beispiel #18
0
// 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;

}
Beispiel #19
0
//=============================================================================
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++;
	}
}
Beispiel #20
0
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;
}
Beispiel #21
0
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);
}
Beispiel #23
0
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();
}
Beispiel #24
0
void mp_hal_delay_us(uint32_t us) {
    ets_delay_us(us);
}
Beispiel #25
0
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();
}