Replace libmain:app_main.o with core/app_main.c
This commit is contained in:
parent
8b8f7c9de4
commit
a044c061d5
7 changed files with 805 additions and 0 deletions
501
core/app_main.c
Normal file
501
core/app_main.c
Normal file
|
@ -0,0 +1,501 @@
|
||||||
|
/* Implementation of libmain/app_main.o from the Espressif SDK.
|
||||||
|
*
|
||||||
|
* This contains most of the startup code for the SDK/OS, some event handlers,
|
||||||
|
* etc.
|
||||||
|
*
|
||||||
|
* Part of esp-open-rtos
|
||||||
|
* Copyright (C) 2015 Superhouse Automation Pty Ltd
|
||||||
|
* BSD Licensed as described in the file LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <FreeRTOS.h>
|
||||||
|
#include <task.h>
|
||||||
|
#include <lwip/tcpip.h>
|
||||||
|
|
||||||
|
#include "common_macros.h"
|
||||||
|
#include "xtensa_ops.h"
|
||||||
|
#include "esp/rom.h"
|
||||||
|
#include "esp/iomux_regs.h"
|
||||||
|
#include "esp/uart_regs.h"
|
||||||
|
#include "esp/spi_regs.h"
|
||||||
|
#include "esp/dport_regs.h"
|
||||||
|
#include "esp/wdev_regs.h"
|
||||||
|
#include "os_version.h"
|
||||||
|
|
||||||
|
#include "espressif/esp_system.h"
|
||||||
|
#include "sdk_internal.h"
|
||||||
|
|
||||||
|
/* This is not declared in any header file (but arguably should be) */
|
||||||
|
|
||||||
|
void user_init(void);
|
||||||
|
|
||||||
|
#define UART_DIVISOR 1068 // 74906 bps (yeah, I don't understand it either)
|
||||||
|
#define BOOT_INFO_SIZE 28
|
||||||
|
//TODO: phy_info should probably be a struct (no idea about its organization, though)
|
||||||
|
#define PHY_INFO_SIZE 128
|
||||||
|
|
||||||
|
// These are the offsets of these values within the RTCMEM regions. It appears
|
||||||
|
// that the ROM saves them to RTCMEM before calling us, and we pull them out of
|
||||||
|
// there to display them in startup messages (not sure why it works that way).
|
||||||
|
#define RTCMEM_BACKUP_PHY_VER 31
|
||||||
|
#define RTCMEM_SYSTEM_PP_VER 62
|
||||||
|
|
||||||
|
#define halt() while (1) {}
|
||||||
|
|
||||||
|
extern uint32_t *_bss_start;
|
||||||
|
extern uint32_t *_bss_end;
|
||||||
|
|
||||||
|
// .Ldata003 -- .irom.text+0x0
|
||||||
|
static const uint8_t IROM default_phy_info[PHY_INFO_SIZE] = {
|
||||||
|
0x05, 0x00, 0x04, 0x02, 0x05, 0x05, 0x05, 0x02,
|
||||||
|
0x05, 0x00, 0x04, 0x05, 0x05, 0x04, 0x05, 0x05,
|
||||||
|
0x04, 0xfe, 0xfd, 0xff, 0xf0, 0xf0, 0xf0, 0xe0,
|
||||||
|
0xe0, 0xe0, 0xe1, 0x0a, 0xff, 0xff, 0xf8, 0x00,
|
||||||
|
0xf8, 0xf8, 0x52, 0x4e, 0x4a, 0x44, 0x40, 0x38,
|
||||||
|
0x00, 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xe1, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x01, 0x93, 0x43, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
// user_init_flag -- .bss+0x0
|
||||||
|
uint8_t sdk_user_init_flag;
|
||||||
|
|
||||||
|
// info -- .bss+0x4
|
||||||
|
struct sdk_info_st sdk_info;
|
||||||
|
|
||||||
|
// xUserTaskHandle -- .bss+0x28
|
||||||
|
xTaskHandle sdk_xUserTaskHandle;
|
||||||
|
|
||||||
|
// xWatchDogTaskHandle -- .bss+0x2c
|
||||||
|
xTaskHandle sdk_xWatchDogTaskHandle;
|
||||||
|
|
||||||
|
/* Static function prototypes */
|
||||||
|
|
||||||
|
static void IRAM get_otp_mac_address(uint8_t *buf);
|
||||||
|
static void IRAM set_spi0_divisor(uint32_t divisor);
|
||||||
|
static void IRAM default_putc(uint8_t c);
|
||||||
|
static void IRAM default_putc1(uint8_t c);
|
||||||
|
static void zero_bss(void);
|
||||||
|
static void init_networking(uint8_t *phy_info, uint8_t *mac_addr);
|
||||||
|
static void init_g_ic(void);
|
||||||
|
static void dump_excinfo(void);
|
||||||
|
static void user_start_phase2(void);
|
||||||
|
static void dump_flash_data(uint32_t start_addr, uint32_t length);
|
||||||
|
static void dump_flash_config_sectors(uint32_t start_addr);
|
||||||
|
|
||||||
|
// .Lfunc001 -- .text+0x14
|
||||||
|
static void IRAM get_otp_mac_address(uint8_t *buf) {
|
||||||
|
uint32_t otp_flags;
|
||||||
|
uint32_t otp_id0, otp_id1;
|
||||||
|
uint32_t otp_vendor_id;
|
||||||
|
|
||||||
|
otp_flags = DPORT.OTP_CHIPID;
|
||||||
|
otp_id1 = DPORT.OTP_MAC1;
|
||||||
|
otp_id0 = DPORT.OTP_MAC0;
|
||||||
|
if (!(otp_flags & 0x8000)) {
|
||||||
|
//FIXME: do we really need this check?
|
||||||
|
printf("Firmware ONLY supports ESP8266!!!\n");
|
||||||
|
halt();
|
||||||
|
}
|
||||||
|
if (otp_id0 == 0 && otp_id1 == 0) {
|
||||||
|
printf("empty otp\n");
|
||||||
|
halt();
|
||||||
|
}
|
||||||
|
if (otp_flags & 0x1000) {
|
||||||
|
// If bit 12 is set, it indicates that the vendor portion of the MAC
|
||||||
|
// address is stored in DPORT.OTP_MAC2.
|
||||||
|
otp_vendor_id = DPORT.OTP_MAC2;
|
||||||
|
buf[0] = otp_vendor_id >> 16;
|
||||||
|
buf[1] = otp_vendor_id >> 8;
|
||||||
|
buf[2] = otp_vendor_id;
|
||||||
|
} else {
|
||||||
|
// If bit 12 is clear, there's no MAC vendor in DPORT.OTP_MAC2, so
|
||||||
|
// default to the Espressif MAC vendor prefix instead.
|
||||||
|
buf[1] = 0xfe;
|
||||||
|
buf[0] = 0x18;
|
||||||
|
buf[2] = 0x34;
|
||||||
|
}
|
||||||
|
buf[3] = otp_id1 >> 8;
|
||||||
|
buf[4] = otp_id1;
|
||||||
|
buf[5] = otp_id0 >> 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .Lfunc002 -- .text+0xa0
|
||||||
|
static void IRAM set_spi0_divisor(uint32_t divisor) {
|
||||||
|
int cycle_len, half_cycle_len, clkdiv;
|
||||||
|
|
||||||
|
if (divisor < 2) {
|
||||||
|
clkdiv = 0;
|
||||||
|
SPI(0).CTRL0 |= SPI_CTRL0_CLOCK_EQU_SYS_CLOCK;
|
||||||
|
IOMUX.CONF |= IOMUX_CONF_SPI0_CLOCK_EQU_SYS_CLOCK;
|
||||||
|
} else {
|
||||||
|
cycle_len = divisor - 1;
|
||||||
|
half_cycle_len = (divisor / 2) - 1;
|
||||||
|
clkdiv = VAL2FIELD(SPI_CTRL0_CLOCK_NUM, cycle_len)
|
||||||
|
| VAL2FIELD(SPI_CTRL0_CLOCK_HIGH, half_cycle_len)
|
||||||
|
| VAL2FIELD(SPI_CTRL0_CLOCK_LOW, cycle_len);
|
||||||
|
SPI(0).CTRL0 &= ~SPI_CTRL0_CLOCK_EQU_SYS_CLOCK;
|
||||||
|
IOMUX.CONF &= ~IOMUX_CONF_SPI0_CLOCK_EQU_SYS_CLOCK;
|
||||||
|
}
|
||||||
|
SPI(0).CTRL0 = SET_FIELD(SPI(0).CTRL0, SPI_CTRL0_CLOCK, clkdiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// .text+0x148
|
||||||
|
void sdk_user_fatal_exception_handler(void) {
|
||||||
|
if (!sdk_NMIIrqIsOn) {
|
||||||
|
vPortEnterCritical();
|
||||||
|
do {
|
||||||
|
DPORT.DPORT0 &= 0xffffffe0;
|
||||||
|
} while (DPORT.DPORT0 & 0x00000001);
|
||||||
|
}
|
||||||
|
Cache_Read_Disable();
|
||||||
|
Cache_Read_Enable(0, 0, 1);
|
||||||
|
dump_excinfo();
|
||||||
|
while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS)) {}
|
||||||
|
while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(1).STATUS)) {}
|
||||||
|
sdk_system_restart_in_nmi();
|
||||||
|
halt();
|
||||||
|
}
|
||||||
|
|
||||||
|
// .Lfunc003 -- .text+0x1d0
|
||||||
|
static void IRAM default_putc(uint8_t c) {
|
||||||
|
while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS) > 125) {}
|
||||||
|
UART(0).FIFO = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .Lfunc004 -- .text+0x1f4
|
||||||
|
static void IRAM default_putc1(uint8_t c) {
|
||||||
|
if (c == '\n') {
|
||||||
|
default_putc('\r');
|
||||||
|
} else if (c == '\r') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default_putc(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// .text+0x258
|
||||||
|
void IRAM sdk_user_start(void) {
|
||||||
|
uint32_t buf32[sizeof(struct sdk_g_ic_saved_st) / 4];
|
||||||
|
uint8_t *buf8 = (uint8_t *)buf32;
|
||||||
|
uint32_t flash_speed_divisor;
|
||||||
|
uint32_t flash_sectors;
|
||||||
|
uint32_t flash_size;
|
||||||
|
int boot_slot;
|
||||||
|
uint32_t cksum_magic;
|
||||||
|
uint32_t cksum_len;
|
||||||
|
uint32_t cksum_value;
|
||||||
|
uint32_t ic_flash_addr;
|
||||||
|
|
||||||
|
SPI(0).USER0 |= SPI_USER0_CS_SETUP;
|
||||||
|
sdk_SPIRead(0, buf32, 4);
|
||||||
|
|
||||||
|
switch (buf8[3] & 0x0f) {
|
||||||
|
case 0xf: // 80 MHz
|
||||||
|
flash_speed_divisor = 1;
|
||||||
|
break;
|
||||||
|
case 0x0: // 40 MHz
|
||||||
|
flash_speed_divisor = 2;
|
||||||
|
break;
|
||||||
|
case 0x1: // 26 MHz
|
||||||
|
flash_speed_divisor = 3;
|
||||||
|
break;
|
||||||
|
case 0x2: // 20 MHz
|
||||||
|
flash_speed_divisor = 4;
|
||||||
|
break;
|
||||||
|
default: // Invalid -- Assume 40 MHz
|
||||||
|
flash_speed_divisor = 2;
|
||||||
|
}
|
||||||
|
switch (buf8[3] >> 4) {
|
||||||
|
case 0x0: // 4 Mbit (512 KByte)
|
||||||
|
flash_sectors = 128;
|
||||||
|
break;
|
||||||
|
case 0x1: // 2 Mbit (256 Kbyte)
|
||||||
|
flash_sectors = 64;
|
||||||
|
break;
|
||||||
|
case 0x2: // 8 Mbit (1 Mbyte)
|
||||||
|
flash_sectors = 256;
|
||||||
|
break;
|
||||||
|
case 0x3: // 16 Mbit (2 Mbyte)
|
||||||
|
flash_sectors = 512;
|
||||||
|
break;
|
||||||
|
case 0x4: // 32 Mbit (4 Mbyte)
|
||||||
|
flash_sectors = 1024;
|
||||||
|
break;
|
||||||
|
default: // Invalid -- Assume 4 Mbit (512 KByte)
|
||||||
|
flash_sectors = 128;
|
||||||
|
}
|
||||||
|
//FIXME: we should probably calculate flash_sectors by starting with flash_size and dividing by sdk_flashchip.sector_size instead of vice-versa.
|
||||||
|
flash_size = flash_sectors * 4096;
|
||||||
|
sdk_flashchip.chip_size = flash_size;
|
||||||
|
set_spi0_divisor(flash_speed_divisor);
|
||||||
|
sdk_SPIRead(flash_size - 256, buf32, BOOT_INFO_SIZE);
|
||||||
|
boot_slot = buf8[0];
|
||||||
|
cksum_magic = buf32[1];
|
||||||
|
cksum_len = buf32[3 + boot_slot];
|
||||||
|
cksum_value = buf32[5 + boot_slot];
|
||||||
|
ic_flash_addr = (flash_sectors - 2 + boot_slot) * sdk_flashchip.sector_size;
|
||||||
|
sdk_SPIRead(ic_flash_addr, buf32, sizeof(struct sdk_g_ic_saved_st));
|
||||||
|
Cache_Read_Enable(0, 0, 1);
|
||||||
|
zero_bss();
|
||||||
|
sdk_os_install_putc1(default_putc1);
|
||||||
|
if (cksum_magic == 0xffffffff) {
|
||||||
|
// No checksum required
|
||||||
|
} else if ((cksum_magic == 0x55aa55aa) &&
|
||||||
|
(sdk_system_get_checksum(buf8, cksum_len) == cksum_value)) {
|
||||||
|
// Checksum OK
|
||||||
|
} else {
|
||||||
|
// Bad checksum or bad cksum_magic value
|
||||||
|
dump_flash_config_sectors(flash_sectors - 4);
|
||||||
|
//FIXME: should we halt here? (original SDK code doesn't)
|
||||||
|
}
|
||||||
|
memcpy(&sdk_g_ic.s, buf32, sizeof(struct sdk_g_ic_saved_st));
|
||||||
|
|
||||||
|
user_start_phase2();
|
||||||
|
}
|
||||||
|
|
||||||
|
// .text+0x3a8
|
||||||
|
void vApplicationStackOverflowHook(xTaskHandle task, char *task_name) {
|
||||||
|
printf("\"%s\"(stack_size = %lu) overflow the heap_size.\n", task_name, uxTaskGetStackHighWaterMark(task));
|
||||||
|
}
|
||||||
|
|
||||||
|
// .text+0x3d8
|
||||||
|
void vApplicationIdleHook(void) {
|
||||||
|
printf("idle %lu\n", WDEV.SYS_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
// .text+0x404
|
||||||
|
void vApplicationTickHook(void) {
|
||||||
|
printf("tick %lu\n", WDEV.SYS_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
// .Lfunc005 -- .irom0.text+0x8
|
||||||
|
static void zero_bss(void) {
|
||||||
|
uint32_t *addr;
|
||||||
|
|
||||||
|
for (addr = _bss_start; addr < _bss_end; addr++) {
|
||||||
|
*addr = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// .Lfunc006 -- .irom0.text+0x70
|
||||||
|
static void init_networking(uint8_t *phy_info, uint8_t *mac_addr) {
|
||||||
|
if (sdk_register_chipv6_phy(phy_info)) {
|
||||||
|
printf("FATAL: sdk_register_chipv6_phy failed");
|
||||||
|
halt();
|
||||||
|
}
|
||||||
|
sdk_uart_div_modify(0, UART_DIVISOR);
|
||||||
|
sdk_uart_div_modify(1, UART_DIVISOR);
|
||||||
|
sdk_phy_disable_agc();
|
||||||
|
sdk_ieee80211_phy_init(sdk_g_ic.s.phy_mode);
|
||||||
|
sdk_lmacInit();
|
||||||
|
sdk_wDev_Initialize();
|
||||||
|
sdk_pp_attach();
|
||||||
|
sdk_ieee80211_ifattach(sdk_g_ic, mac_addr);
|
||||||
|
_xt_isr_mask(1);
|
||||||
|
DPORT.DPORT0 = SET_FIELD(DPORT.DPORT0, DPORT_DPORT0_FIELD0, 1);
|
||||||
|
sdk_pm_attach();
|
||||||
|
sdk_phy_enable_agc();
|
||||||
|
sdk_cnx_attach(sdk_g_ic);
|
||||||
|
sdk_wDevEnableRx();
|
||||||
|
}
|
||||||
|
|
||||||
|
// .Lfunc007 -- .irom0.text+0x148
|
||||||
|
static void init_g_ic(void) {
|
||||||
|
if (sdk_g_ic.s.wifi_mode == 0xff) {
|
||||||
|
sdk_g_ic.s.wifi_mode = 2;
|
||||||
|
}
|
||||||
|
sdk_wifi_softap_set_default_ssid();
|
||||||
|
if (sdk_g_ic.s._unknown30d < 1 || sdk_g_ic.s._unknown30d > 14) {
|
||||||
|
sdk_g_ic.s._unknown30d = 1;
|
||||||
|
}
|
||||||
|
if (sdk_g_ic.s._unknown544 < 100 || sdk_g_ic.s._unknown544 > 60000) {
|
||||||
|
sdk_g_ic.s._unknown544 = 100;
|
||||||
|
}
|
||||||
|
if (sdk_g_ic.s._unknown30e == 1 || sdk_g_ic.s._unknown30e > 4) {
|
||||||
|
sdk_g_ic.s._unknown30e = 0;
|
||||||
|
}
|
||||||
|
bzero(sdk_g_ic.s._unknown2ac, sizeof(sdk_g_ic.s._unknown2ac));
|
||||||
|
if (sdk_g_ic.s._unknown30f > 1) {
|
||||||
|
sdk_g_ic.s._unknown30f = 0;
|
||||||
|
}
|
||||||
|
if (sdk_g_ic.s._unknown310 > 4) {
|
||||||
|
sdk_g_ic.s._unknown310 = 4;
|
||||||
|
}
|
||||||
|
if (sdk_g_ic.s._unknown1e4._unknown1e4 == 0xffffffff) {
|
||||||
|
bzero(&sdk_g_ic.s._unknown1e4, sizeof(sdk_g_ic.s._unknown1e4));
|
||||||
|
bzero(&sdk_g_ic.s._unknown20f, sizeof(sdk_g_ic.s._unknown20f));
|
||||||
|
}
|
||||||
|
sdk_g_ic.s.wifi_led_enable = 0;
|
||||||
|
if (sdk_g_ic.s._unknown281 > 1) {
|
||||||
|
sdk_g_ic.s._unknown281 = 0;
|
||||||
|
}
|
||||||
|
if (sdk_g_ic.s.ap_number > 5) {
|
||||||
|
sdk_g_ic.s.ap_number = 1;
|
||||||
|
}
|
||||||
|
if (sdk_g_ic.s.phy_mode < 1 || sdk_g_ic.s.phy_mode > 3) {
|
||||||
|
sdk_g_ic.s.phy_mode = PHY_MODE_11N;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// .Lfunc008 -- .irom0.text+0x2a0
|
||||||
|
static void dump_excinfo(void) {
|
||||||
|
uint32_t exccause, epc1, epc2, epc3, excvaddr, depc, excsave1;
|
||||||
|
uint32_t excinfo[8];
|
||||||
|
|
||||||
|
RSR(exccause, exccause);
|
||||||
|
printf("Fatal exception (%d): \n", (int)exccause);
|
||||||
|
RSR(epc1, epc1);
|
||||||
|
RSR(epc2, epc2);
|
||||||
|
RSR(epc3, epc3);
|
||||||
|
RSR(excvaddr, excvaddr);
|
||||||
|
RSR(depc, depc);
|
||||||
|
RSR(excsave1, excsave1);
|
||||||
|
printf("%s=0x%08lx\n", "epc1", epc1);
|
||||||
|
printf("%s=0x%08lx\n", "epc2", epc2);
|
||||||
|
printf("%s=0x%08lx\n", "epc3", epc3);
|
||||||
|
printf("%s=0x%08lx\n", "excvaddr", excvaddr);
|
||||||
|
printf("%s=0x%08lx\n", "depc", depc);
|
||||||
|
printf("%s=0x%08lx\n", "excsave1", excsave1);
|
||||||
|
sdk_system_rtc_mem_read(0, excinfo, 32); // Why?
|
||||||
|
excinfo[0] = 2;
|
||||||
|
excinfo[1] = exccause;
|
||||||
|
excinfo[2] = epc1;
|
||||||
|
excinfo[3] = epc2;
|
||||||
|
excinfo[4] = epc3;
|
||||||
|
excinfo[5] = excvaddr;
|
||||||
|
excinfo[6] = depc;
|
||||||
|
excinfo[7] = excsave1;
|
||||||
|
sdk_system_rtc_mem_write(0, excinfo, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// .irom0.text+0x368
|
||||||
|
int sdk_uart_rx_one_char(char *buf) {
|
||||||
|
if (FIELD2VAL(UART_STATUS_RXFIFO_COUNT, UART(0).STATUS)) {
|
||||||
|
*buf = UART(0).FIFO;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .irom0.text+0x398
|
||||||
|
void sdk_wdt_init(void) {
|
||||||
|
WDT.CTRL &= ~WDT_CTRL_ENABLE;
|
||||||
|
DPORT.INT_ENABLE |= DPORT_INT_ENABLE_WDT;
|
||||||
|
WDT.REG1 = 0x0000000b;
|
||||||
|
WDT.REG2 = 0x0000000c;
|
||||||
|
WDT.CTRL |= WDT_CTRL_FLAG3 | WDT_CTRL_FLAG4 | WDT_CTRL_FLAG5;
|
||||||
|
WDT.CTRL = SET_FIELD(WDT.CTRL, WDT_CTRL_FIELD0, 0);
|
||||||
|
WDT.CTRL |= WDT_CTRL_ENABLE;
|
||||||
|
sdk_pp_soft_wdt_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
// .irom0.text+0x474
|
||||||
|
void sdk_user_init_task(void *params) {
|
||||||
|
int phy_ver, pp_ver;
|
||||||
|
|
||||||
|
sdk_ets_timer_init();
|
||||||
|
printf("\nESP-Open-SDK ver: %s compiled @ %s %s\n", OS_VERSION_STR, __DATE__, __TIME__);
|
||||||
|
phy_ver = RTCMEM_BACKUP[RTCMEM_BACKUP_PHY_VER] >> 16;
|
||||||
|
printf("phy ver: %d, ", phy_ver);
|
||||||
|
pp_ver = RTCMEM_SYSTEM[RTCMEM_SYSTEM_PP_VER];
|
||||||
|
printf("pp ver: %d.%d\n\n", (pp_ver >> 8) & 0xff, pp_ver & 0xff);
|
||||||
|
user_init();
|
||||||
|
sdk_user_init_flag = 1;
|
||||||
|
sdk_wifi_mode_set(sdk_g_ic.s.wifi_mode);
|
||||||
|
if (sdk_g_ic.s.wifi_mode == 1) {
|
||||||
|
sdk_wifi_station_start();
|
||||||
|
netif_set_default(sdk_g_ic.v.station_netif_info->netif);
|
||||||
|
}
|
||||||
|
if (sdk_g_ic.s.wifi_mode == 2) {
|
||||||
|
sdk_wifi_softap_start();
|
||||||
|
netif_set_default(sdk_g_ic.v.softap_netif_info->netif);
|
||||||
|
}
|
||||||
|
if (sdk_g_ic.s.wifi_mode == 3) {
|
||||||
|
sdk_wifi_station_start();
|
||||||
|
sdk_wifi_softap_start();
|
||||||
|
netif_set_default(sdk_g_ic.v.softap_netif_info->netif);
|
||||||
|
}
|
||||||
|
if (sdk_wifi_station_get_auto_connect()) {
|
||||||
|
sdk_wifi_station_connect();
|
||||||
|
}
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// .Lfunc009 -- .irom0.text+0x5b4
|
||||||
|
static void user_start_phase2(void) {
|
||||||
|
uint8_t *buf;
|
||||||
|
uint8_t *phy_info;
|
||||||
|
|
||||||
|
sdk_system_rtc_mem_read(0, &sdk_rst_if, sizeof(sdk_rst_if));
|
||||||
|
if (sdk_rst_if.version > 3) {
|
||||||
|
// Bad version number. Probably garbage.
|
||||||
|
bzero(&sdk_rst_if, sizeof(sdk_rst_if));
|
||||||
|
}
|
||||||
|
buf = malloc(sizeof(sdk_rst_if));
|
||||||
|
bzero(buf, sizeof(sdk_rst_if));
|
||||||
|
sdk_system_rtc_mem_write(0, buf, sizeof(sdk_rst_if));
|
||||||
|
free(buf);
|
||||||
|
sdk_sleep_reset_analog_rtcreg_8266();
|
||||||
|
get_otp_mac_address(sdk_info.sta_mac_addr);
|
||||||
|
sdk_wifi_softap_cacl_mac(sdk_info.softap_mac_addr, sdk_info.sta_mac_addr);
|
||||||
|
sdk_info._unknown0 = 0x0104a8c0;
|
||||||
|
sdk_info._unknown1 = 0x00ffffff;
|
||||||
|
sdk_info._unknown2 = 0x0104a8c0;
|
||||||
|
init_g_ic();
|
||||||
|
phy_info = malloc(PHY_INFO_SIZE);
|
||||||
|
sdk_spi_flash_read(sdk_flashchip.chip_size - sdk_flashchip.sector_size * 4, (uint32_t *)phy_info, PHY_INFO_SIZE);
|
||||||
|
|
||||||
|
// Wait for UARTs to finish sending anything in their queues.
|
||||||
|
while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS) > 0) {}
|
||||||
|
while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(1).STATUS) > 0) {}
|
||||||
|
|
||||||
|
if (phy_info[0] != 5) {
|
||||||
|
// Bad version byte. Discard what we read and use default values
|
||||||
|
// instead.
|
||||||
|
memcpy(phy_info, default_phy_info, PHY_INFO_SIZE);
|
||||||
|
}
|
||||||
|
init_networking(phy_info, sdk_info.sta_mac_addr);
|
||||||
|
free(phy_info);
|
||||||
|
tcpip_init(NULL, NULL);
|
||||||
|
sdk_wdt_init();
|
||||||
|
xTaskCreate(sdk_user_init_task, (signed char *)"uiT", 1024, 0, 14, sdk_xUserTaskHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// .Lfunc010 -- .irom0.text+0x710
|
||||||
|
static void dump_flash_data(uint32_t start_addr, uint32_t length) {
|
||||||
|
uint8_t *buf;
|
||||||
|
int bufsize, i;
|
||||||
|
|
||||||
|
bufsize = (length + 3) & 0xfffc;
|
||||||
|
buf = malloc(bufsize);
|
||||||
|
sdk_spi_flash_read(start_addr, (uint32_t *)buf, bufsize);
|
||||||
|
for (i = 0; i < length; ) {
|
||||||
|
printf("%02x ", buf[i]);
|
||||||
|
if ((i & 0x1f) == 0) {
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// .Lfunc011 -- .irom0.text+0x790
|
||||||
|
static void dump_flash_config_sectors(uint32_t start_addr) {
|
||||||
|
printf("system param error\n");
|
||||||
|
// The original code used start_addr+1, start_addr+2, etc. This is
|
||||||
|
// obviously wrong as start_addr is clearly a byte address, not a sector
|
||||||
|
// address.
|
||||||
|
dump_flash_data(start_addr + sdk_flashchip.sector_size, sizeof(struct sdk_g_ic_saved_st));
|
||||||
|
dump_flash_data(start_addr + sdk_flashchip.sector_size * 2, sizeof(struct sdk_g_ic_saved_st));
|
||||||
|
dump_flash_data(start_addr + sdk_flashchip.sector_size * 3, BOOT_INFO_SIZE);
|
||||||
|
}
|
||||||
|
|
30
core/include/esp/wdev_regs.h
Normal file
30
core/include/esp/wdev_regs.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/* esp/wdev_regs.h
|
||||||
|
*
|
||||||
|
* ESP8266 register definitions for the "wdev" region (0x3FF2xxx)
|
||||||
|
*
|
||||||
|
* Not compatible with ESP SDK register access code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ESP_WDEV_REGS_H
|
||||||
|
#define _ESP_WDEV_REGS_H
|
||||||
|
|
||||||
|
#include "esp/types.h"
|
||||||
|
#include "common_macros.h"
|
||||||
|
|
||||||
|
#define WDEV_BASE 0x3FF20000
|
||||||
|
#define WDEV (*(struct WDEV_REGS *)(WDEV_BASE))
|
||||||
|
|
||||||
|
/* Note: This memory region is not currently well understood. Pretty much all
|
||||||
|
* of the definitions here are from reverse-engineering the Espressif SDK code,
|
||||||
|
* many are just educated guesses, and almost certainly some are misleading or
|
||||||
|
* wrong. If you can improve on any of this, please contribute!
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct WDEV_REGS {
|
||||||
|
uint32_t volatile _unknown[768]; // 0x0000 - 0x0bfc
|
||||||
|
uint32_t volatile SYS_TIME; // 0x0c00
|
||||||
|
} __attribute__ (( packed ));
|
||||||
|
|
||||||
|
_Static_assert(sizeof(struct WDEV_REGS) == 0xc04, "WDEV_REGS is the wrong size");
|
||||||
|
|
||||||
|
#endif /* _ESP_WDEV_REGS_H */
|
|
@ -31,6 +31,17 @@ struct WDT_REGS {
|
||||||
|
|
||||||
_Static_assert(sizeof(struct WDT_REGS) == 0x18, "WDT_REGS is the wrong size");
|
_Static_assert(sizeof(struct WDT_REGS) == 0x18, "WDT_REGS is the wrong size");
|
||||||
|
|
||||||
|
/* Details for CTRL register */
|
||||||
|
|
||||||
|
/* Note: these are currently just guesses based on interpretation of the startup code */
|
||||||
|
|
||||||
|
#define WDT_CTRL_ENABLE BIT(0)
|
||||||
|
#define WDT_CTRL_FIELD0_M 0x00000003
|
||||||
|
#define WDT_CTRL_FIELD0_S 1
|
||||||
|
#define WDT_CTRL_FLAG3 BIT(3)
|
||||||
|
#define WDT_CTRL_FLAG4 BIT(4)
|
||||||
|
#define WDT_CTRL_FLAG5 BIT(5)
|
||||||
|
|
||||||
/* Writing WDT_FEED_MAGIC to WDT.FEED register "feeds the dog" and holds off
|
/* Writing WDT_FEED_MAGIC to WDT.FEED register "feeds the dog" and holds off
|
||||||
* triggering for another cycle (unconfirmed) */
|
* triggering for another cycle (unconfirmed) */
|
||||||
#define WDT_FEED_MAGIC 0x73
|
#define WDT_FEED_MAGIC 0x73
|
||||||
|
|
6
core/include/os_version.h
Normal file
6
core/include/os_version.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef _VERSION_H
|
||||||
|
#define _VERSION_H
|
||||||
|
|
||||||
|
#define OS_VERSION_STR "0.0.1"
|
||||||
|
|
||||||
|
#endif /* _VERSION_H */
|
235
core/include/sdk_internal.h
Normal file
235
core/include/sdk_internal.h
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
#ifndef _INTERNAL_SDK_STRUCTURES_H
|
||||||
|
#define _INTERNAL_SDK_STRUCTURES_H
|
||||||
|
|
||||||
|
#include "espressif/esp_wifi.h"
|
||||||
|
#include "espressif/spi_flash.h"
|
||||||
|
#include "lwip/netif.h"
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Internal structures and data objects //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// 'info' is declared in app_main.o at .bss+0x4
|
||||||
|
|
||||||
|
struct sdk_info_st {
|
||||||
|
uint32_t _unknown0;
|
||||||
|
uint32_t _unknown1;
|
||||||
|
uint32_t _unknown2;
|
||||||
|
uint8_t _unknown3[12];
|
||||||
|
uint8_t softap_mac_addr[6];
|
||||||
|
uint8_t sta_mac_addr[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct sdk_info_st sdk_info;
|
||||||
|
|
||||||
|
// 'rst_if' is declared in user_interface.o at .bss+0xfc
|
||||||
|
|
||||||
|
struct sdk_rst_if_st {
|
||||||
|
uint32_t version;
|
||||||
|
uint8_t _unknown[28];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct sdk_rst_if_st sdk_rst_if;
|
||||||
|
|
||||||
|
// 'g_ic' is declared in libnet80211/ieee80211.o at .bss+0x0
|
||||||
|
// See also: http://esp8266-re.foogod.com/wiki/G_ic_(IoT_RTOS_SDK_0.9.9)
|
||||||
|
|
||||||
|
struct sdk_g_ic_netif_info {
|
||||||
|
struct netif *netif;
|
||||||
|
//TODO: rest of this structure is unknown.
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is the portion of g_ic which is not loaded/saved to the flash ROM, and
|
||||||
|
// starts out zeroed on every boot.
|
||||||
|
struct sdk_g_ic_volatile_st {
|
||||||
|
void *_unknown0;
|
||||||
|
void *_unknown4;
|
||||||
|
|
||||||
|
uint8_t _unknown8[8];
|
||||||
|
|
||||||
|
struct sdk_g_ic_netif_info *station_netif_info;
|
||||||
|
struct sdk_g_ic_netif_info *softap_netif_info;
|
||||||
|
uint8_t _unknown18;
|
||||||
|
uint32_t _unknown1c;
|
||||||
|
uint32_t _unknown20;
|
||||||
|
|
||||||
|
uint8_t _unknown24[8];
|
||||||
|
|
||||||
|
uint8_t _unknown2c;
|
||||||
|
|
||||||
|
uint8_t _unknown30[76];
|
||||||
|
|
||||||
|
uint8_t _unknown7c;
|
||||||
|
uint8_t _unknown7d;
|
||||||
|
uint8_t _unknown7e;
|
||||||
|
uint8_t _unknown7f;
|
||||||
|
|
||||||
|
uint8_t _unknown80[204];
|
||||||
|
|
||||||
|
void *_unknown14c;
|
||||||
|
|
||||||
|
uint8_t _unknown150[20];
|
||||||
|
|
||||||
|
uint32_t _unknown164;
|
||||||
|
void *_unknown168;
|
||||||
|
void *_unknown16c;
|
||||||
|
void *_unknown170;
|
||||||
|
void *_unknown174;
|
||||||
|
void *_unknown178;
|
||||||
|
|
||||||
|
uint8_t _unknown17c[4];
|
||||||
|
|
||||||
|
void *_unknown180;
|
||||||
|
void *_unknown184;
|
||||||
|
struct station_info *station_info_head;
|
||||||
|
struct station_info *station_info_tail;
|
||||||
|
uint32_t _unknown190;
|
||||||
|
uint32_t _unknown194;
|
||||||
|
|
||||||
|
uint8_t _unknown198[40];
|
||||||
|
|
||||||
|
void *_unknown1c0;
|
||||||
|
void *_unknown1c4;
|
||||||
|
uint32_t _unknown1c8;
|
||||||
|
|
||||||
|
uint8_t _unknown1cc[4];
|
||||||
|
|
||||||
|
uint16_t _unknown1d0;
|
||||||
|
|
||||||
|
uint8_t _unknown1d2[2];
|
||||||
|
|
||||||
|
uint8_t _unknown1d4;
|
||||||
|
|
||||||
|
uint8_t _unknown1d5[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sdk_g_ic_unk0_st {
|
||||||
|
uint32_t _unknown1e4;
|
||||||
|
uint8_t _unknown1e8[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is the portion of g_ic which is loaded/saved to the flash ROM, and thus
|
||||||
|
// is preserved across reboots.
|
||||||
|
struct sdk_g_ic_saved_st {
|
||||||
|
uint8_t _unknown1d8;
|
||||||
|
uint8_t boot_info;
|
||||||
|
uint8_t user0_addr[3];
|
||||||
|
uint8_t user1_addr[3];
|
||||||
|
uint8_t wifi_mode;
|
||||||
|
uint8_t wifi_led_enable;
|
||||||
|
uint8_t wifi_led_gpio;
|
||||||
|
uint8_t _unknown1e3;
|
||||||
|
|
||||||
|
struct sdk_g_ic_unk0_st _unknown1e4;
|
||||||
|
|
||||||
|
uint8_t _unknown208;
|
||||||
|
uint8_t _unknown209;
|
||||||
|
uint8_t _unknown20a;
|
||||||
|
uint8_t _unknown20b;
|
||||||
|
uint8_t _unknown20c;
|
||||||
|
uint8_t _unknown20d;
|
||||||
|
uint8_t _unknown20e;
|
||||||
|
uint8_t _unknown20f[64];
|
||||||
|
uint8_t _unknown24f;
|
||||||
|
|
||||||
|
uint8_t _unknown250[49];
|
||||||
|
|
||||||
|
uint8_t _unknown281;
|
||||||
|
|
||||||
|
uint8_t _unknown282[6];
|
||||||
|
|
||||||
|
uint32_t _unknown288;
|
||||||
|
uint8_t _unknown28c;
|
||||||
|
|
||||||
|
uint8_t _unknown290[28];
|
||||||
|
|
||||||
|
uint8_t _unknown2ac[64];
|
||||||
|
uint8_t _unknonwn2ec;
|
||||||
|
|
||||||
|
uint8_t _unknown2ed[32];
|
||||||
|
|
||||||
|
uint8_t _unknown30d;
|
||||||
|
uint8_t _unknown30e;
|
||||||
|
uint8_t _unknown30f;
|
||||||
|
uint8_t _unknown310;
|
||||||
|
|
||||||
|
uint8_t _unknown311[3];
|
||||||
|
|
||||||
|
uint8_t ap_number;
|
||||||
|
uint8_t current_ap_id;
|
||||||
|
|
||||||
|
uint8_t _unknown316[502];
|
||||||
|
|
||||||
|
uint32_t _unknown50c;
|
||||||
|
uint16_t _unknown510;
|
||||||
|
uint16_t _unknown512;
|
||||||
|
uint16_t _unknown514;
|
||||||
|
|
||||||
|
uint8_t _unknown516[2];
|
||||||
|
|
||||||
|
uint8_t auto_connect;
|
||||||
|
|
||||||
|
uint8_t _unknown519[3];
|
||||||
|
|
||||||
|
enum sdk_phy_mode phy_mode;
|
||||||
|
|
||||||
|
uint8_t _unknown520[36];
|
||||||
|
|
||||||
|
uint16_t _unknown544;
|
||||||
|
|
||||||
|
uint8_t _unknown546[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sdk_g_ic_st {
|
||||||
|
struct sdk_g_ic_volatile_st v; // 0x0 - 0x1d8
|
||||||
|
struct sdk_g_ic_saved_st s; // 0x1d8 - 0x548
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct sdk_g_ic_st sdk_g_ic;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// The above structures all refer to data regions outside our control, and a
|
||||||
|
// simple mistake/misunderstanding editing things here can completely screw up
|
||||||
|
// how we access them, so do some basic sanity checks to make sure that they
|
||||||
|
// appear to match up correctly with the actual data structures other parts of
|
||||||
|
// the SDK are expecting.
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
_Static_assert(sizeof(struct sdk_info_st) == 0x24, "info_st is the wrong size!");
|
||||||
|
_Static_assert(sizeof(struct sdk_rst_if_st) == 0x20, "sdk_rst_if_st is the wrong size!");
|
||||||
|
_Static_assert(sizeof(struct sdk_g_ic_volatile_st) == 0x1d8, "sdk_g_ic_volatile_st is the wrong size!");
|
||||||
|
_Static_assert(sizeof(struct sdk_g_ic_saved_st) == 0x370, "sdk_g_ic_saved_st is the wrong size!");
|
||||||
|
_Static_assert(sizeof(struct sdk_g_ic_st) == 0x548, "sdk_g_ic_st is the wrong size!");
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Function Prototypes //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
sdk_SpiFlashOpResult sdk_SPIRead(uint32_t src_addr, uint32_t *des_addr, uint32_t size);
|
||||||
|
sdk_SpiFlashOpResult sdk_SPIWrite(uint32_t des_addr, uint32_t *src_addr, uint32_t size);
|
||||||
|
void sdk_cnx_attach(struct sdk_g_ic_st);
|
||||||
|
void sdk_ets_timer_init(void);
|
||||||
|
void sdk_ieee80211_ifattach(struct sdk_g_ic_st, uint8_t *);
|
||||||
|
void sdk_ieee80211_phy_init(enum sdk_phy_mode);
|
||||||
|
void sdk_lmacInit(void);
|
||||||
|
void sdk_os_install_putc1( void (*func)(uint8_t) );
|
||||||
|
void sdk_phy_disable_agc(void);
|
||||||
|
void sdk_phy_enable_agc(void);
|
||||||
|
void sdk_pm_attach(void);
|
||||||
|
void sdk_pp_attach(void);
|
||||||
|
void sdk_pp_soft_wdt_init(void);
|
||||||
|
int sdk_register_chipv6_phy(uint8_t *);
|
||||||
|
void sdk_sleep_reset_analog_rtcreg_8266(void);
|
||||||
|
uint32_t sdk_system_get_checksum(uint8_t *, uint32_t);
|
||||||
|
void sdk_system_restart_in_nmi(void);
|
||||||
|
void sdk_wDevEnableRx(void);
|
||||||
|
void sdk_wDev_Initialize(void);
|
||||||
|
void sdk_wifi_mode_set(uint8_t);
|
||||||
|
void sdk_wifi_softap_cacl_mac(uint8_t *, uint8_t *);
|
||||||
|
void sdk_wifi_softap_set_default_ssid(void);
|
||||||
|
void sdk_wifi_softap_start(void);
|
||||||
|
void sdk_wifi_station_connect(void);
|
||||||
|
bool sdk_wifi_station_get_auto_connect(void);
|
||||||
|
void sdk_wifi_station_start(void);
|
||||||
|
|
||||||
|
#endif /* _INTERNAL_SDK_STRUCTURES_H */
|
21
core/include/xtensa_ops.h
Normal file
21
core/include/xtensa_ops.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/** xtensa_ops.h
|
||||||
|
*
|
||||||
|
* Special macros/etc which deal with Xtensa-specific architecture/CPU
|
||||||
|
* considerations.
|
||||||
|
*
|
||||||
|
* Part of esp-open-rtos
|
||||||
|
* Copyright (C) 2015 Superhouse Automation Pty Ltd
|
||||||
|
* BSD Licensed as described in the file LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _XTENSA_OPS_H
|
||||||
|
#define _XTENSA_OPS_H
|
||||||
|
|
||||||
|
// GCC macros for reading, writing, and exchanging Xtensa processor special
|
||||||
|
// registers:
|
||||||
|
|
||||||
|
#define RSR(var, reg) asm volatile ("rsr %0, " #reg : "=r" (var));
|
||||||
|
#define WSR(var, reg) asm volatile ("wsr %0, " #reg : : "r" (var));
|
||||||
|
#define XSR(var, reg) asm volatile ("xsr %0, " #reg : "+r" (var));
|
||||||
|
|
||||||
|
#endif /* _XTENSA_OPS_H */
|
|
@ -2,3 +2,4 @@
|
||||||
printf-stdarg.o
|
printf-stdarg.o
|
||||||
libc.o
|
libc.o
|
||||||
xtensa_vectors.o
|
xtensa_vectors.o
|
||||||
|
app_main.o
|
||||||
|
|
Loading…
Reference in a new issue