Wrap structure around phy_info PHY initialisation settings

Add notes based on testing some of the values found there.
This commit is contained in:
Angus Gratton 2016-04-07 17:23:30 +10:00
parent b2c032a867
commit b61d06e940
4 changed files with 661 additions and 36 deletions

View file

@ -24,6 +24,7 @@
#include "os_version.h"
#include "espressif/esp_common.h"
#include "espressif/phy_info.h"
#include "sdk_internal.h"
/* This is not declared in any header file (but arguably should be) */
@ -31,8 +32,6 @@
void user_init(void);
#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
@ -45,26 +44,6 @@ void user_init(void);
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;
@ -82,7 +61,7 @@ xTaskHandle sdk_xWatchDogTaskHandle;
static void IRAM get_otp_mac_address(uint8_t *buf);
static void IRAM set_spi0_divisor(uint32_t divisor);
static void zero_bss(void);
static void init_networking(uint8_t *phy_info, uint8_t *mac_addr);
static void init_networking(sdk_phy_info_t *phy_info, uint8_t *mac_addr);
static void init_g_ic(void);
static void dump_excinfo(void);
static void user_start_phase2(void);
@ -273,7 +252,7 @@ static void zero_bss(void) {
}
// .Lfunc006 -- .irom0.text+0x70
static void init_networking(uint8_t *phy_info, uint8_t *mac_addr) {
static void init_networking(sdk_phy_info_t *phy_info, uint8_t *mac_addr) {
if (sdk_register_chipv6_phy(phy_info)) {
printf("FATAL: sdk_register_chipv6_phy failed");
halt();
@ -413,7 +392,7 @@ extern void (*__init_array_end)(void);
// .Lfunc009 -- .irom0.text+0x5b4
static __attribute__((noinline)) void user_start_phase2(void) {
uint8_t *buf;
uint8_t *phy_info;
sdk_phy_info_t phy_info, default_phy_info;
sdk_system_rtc_mem_read(0, &sdk_rst_if, sizeof(sdk_rst_if));
if (sdk_rst_if.version > 3) {
@ -431,8 +410,16 @@ static __attribute__((noinline)) void user_start_phase2(void) {
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);
read_saved_phy_info(&phy_info);
get_default_phy_info(&default_phy_info);
if (phy_info.version != default_phy_info.version) {
/* Versions don't match, use default for PHY info
(may be a blank config sector, or a new default version.)
*/
memcpy(&phy_info, &default_phy_info, sizeof(sdk_phy_info_t));
}
// Disable default buffering on stdout
setbuf(stdout, NULL);
@ -440,13 +427,7 @@ static __attribute__((noinline)) void user_start_phase2(void) {
uart_flush_txfifo(0);
uart_flush_txfifo(1);
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);
init_networking(&phy_info, sdk_info.sta_mac_addr);
// Call gcc constructor functions
void (**ctor)(void);
@ -487,7 +468,7 @@ static __attribute__((noinline)) void dump_flash_config_sectors(uint32_t start_s
printf("system param error\n");
// Note: original SDK code didn't dump PHY info
printf("phy_info:\n");
dump_flash_sector(start_sector, PHY_INFO_SIZE);
dump_flash_sector(start_sector, sizeof(sdk_phy_info_t));
printf("\ng_ic saved 0:\n");
dump_flash_sector(start_sector + 1, sizeof(struct sdk_g_ic_saved_st));
printf("\ng_ic saved 1:\n");

View file

@ -3,6 +3,7 @@
#include "espressif/esp_wifi.h"
#include "espressif/spi_flash.h"
#include "espressif/phy_info.h"
#include "lwip/netif.h"
///////////////////////////////////////////////////////////////////////////////
@ -217,7 +218,7 @@ 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 *);
int sdk_register_chipv6_phy(sdk_phy_info_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);

161
core/phy_info.c Normal file
View file

@ -0,0 +1,161 @@
/* Routines to allow custom access to the Internal Espressif
SDK PHY datastructures.
Matches espressif/phy_internal.h
Part of esp-open-rtos. Copyright (C) 2016 Angus Gratton,
BSD Licensed as described in the file LICENSE.
*/
#include <espressif/phy_info.h>
#include <espressif/esp_common.h>
#include <common_macros.h>
#include <string.h>
static const sdk_phy_info_t IROM default_phy_info = {
._reserved00 = { 0x05, 0x00, 0x04, 0x02, 0x05 },
.version = 5,
._reserved06 = { 0x05, 0x02, 0x05, 0x00, 0x04, 0x05, 0x05, 0x04,
0x05, 0x05, 0x04,-0x02,-0x03,-0x01,-0x10,-0x10,
-0x10,-0x20,-0x20, -0x20},
.spur_freq_primary = 225,
.spur_freq_divisor = 10,
.spur_freq_en_h = 0xFF,
.spur_freq_en_l = 0xFF,
._reserved1e = { 0xf8, 0, 0xf8, 0xf8 },
.target_power = { 82, 78, 74, 68, 64, 56 },
.target_power_index_mcs = { 0, 0, 1, 1, 2, 3, 4, 5 },
.crystal_freq = CRYSTAL_FREQ_26M,
.sdio_config = SDIO_CONFIG_AUTO,
.bt_coexist_config = BT_COEXIST_CONFIG_NONE,
.bt_coexist_protocol = BT_COEXIST_PROTOCOL_WIFI_ONLY,
.dual_ant_config = DUAL_ANT_CONFIG_NONE,
._reserved34 = 0x02,
.crystal_sleep = CRYSTAL_SLEEP_OFF,
.spur_freq_2_primary = 225,
.spur_freq_2_divisor = 10,
.spur_freq_2_en_h = 0x00,
.spur_freq_2_en_l = 0x00,
.spur_freq_cfg_msb = 0x00,
.spur_freq_2_cfg_msb = 0x00,
.spur_freq_3_cfg = 0x0000,
.spur_freq_4_cfg = 0x0000,
._reserved4a = { 0x01, 0x93, 0x43, 0x00 },
.low_power_en = false,
.lp_atten_stage01 = LP_ATTEN_STAGE01_23DB,
.lp_atten_bb = 0,
.pwr_ind_11b_en = false,
.pwr_ind_11b_0 = 0,
.pwr_ind_11b_1 = 0,
/* Nominal 3.3V VCC. NOTE: This value is 0 in the
esp-open-rtos SDK default config sector, and may be unused
by that version of the SDK?
*/
.pa_vdd = 33,
/* Note: untested with the esp-open-rtos SDK default config sector, may be unused? */
.freq_correct_mode = FREQ_CORRECT_DISABLE,
.force_freq_offset = 0,
/* Note: is zero with the esp-open-rtos SDK default config sector, may be unused? */
.rf_cal_mode = RF_CAL_MODE_SAVED,
};
void get_default_phy_info(sdk_phy_info_t *info) __attribute__((weak, alias("get_sdk_default_phy_info")));
void get_sdk_default_phy_info(sdk_phy_info_t *info)
{
memcpy(info, &default_phy_info, sizeof(sdk_phy_info_t));
}
void read_saved_phy_info(sdk_phy_info_t *info)
{
sdk_spi_flash_read(sdk_flashchip.chip_size - sdk_flashchip.sector_size * 4, (uint32_t *)info, sizeof(sdk_phy_info_t));
}
void write_saved_phy_info(const sdk_phy_info_t *info)
{
sdk_spi_flash_write(sdk_flashchip.chip_size - sdk_flashchip.sector_size * 4, (uint32_t *)info, sizeof(sdk_phy_info_t));
}
void dump_phy_info(const sdk_phy_info_t *info, bool raw)
{
printf("version=%d\n", info->version);
printf("spur_freq = %.3f (%d/%d)\n",
(float)info->spur_freq_primary / info->spur_freq_divisor,
info->spur_freq_primary,
info->spur_freq_divisor);
printf("spur_freq_en = 0x%02x 0x%02x\n", info->spur_freq_en_h,
info->spur_freq_en_l);
printf("target_power\n");
for(int i = 0; i < 6; i++) {
printf(" %d: %.2fdB (raw 0x%02x)\n", i,
info->target_power[i]/4.0,
info->target_power[i]);
}
printf("target_power_index_mcs:");
for(int i = 0; i < 8; i++) {
printf(" %d%c", info->target_power_index_mcs[i],
i == 7 ? '\n' : ',');
}
printf("crystal_freq: %s (raw %d)\n",
(info->crystal_freq == CRYSTAL_FREQ_40M ? "40MHz" :
(info->crystal_freq == CRYSTAL_FREQ_26M ? "26MHz" :
(info->crystal_freq == CRYSTAL_FREQ_24M ? "24MHz" : "???"))),
info->crystal_freq);
printf("sdio_config: %d\n", info->sdio_config);
printf("bt_coexist config: %d protocol: 0x%02x\n",
info->bt_coexist_config, info->bt_coexist_protocol);
printf("dual_ant_config: %d\n", info->dual_ant_config);
printf("crystal_sleep: %d\n", info->crystal_sleep);
printf("spur_freq_2 = %.3f (%d/%d)\n",
(float)info->spur_freq_2_primary / info->spur_freq_2_divisor,
info->spur_freq_2_primary,
info->spur_freq_2_divisor);
printf("spur_freq_2_en = 0x%02x 0x%02x\n", info->spur_freq_2_en_h,
info->spur_freq_2_en_l);
printf("spur_freq_cfg_msb = 0x%02x\n", info->spur_freq_cfg_msb);
printf("spur_freq_2_)cfg_msb = 0x%02x\n", info->spur_freq_2_cfg_msb);
printf("spur_freq_3_cfg = 0x%04x\n", info->spur_freq_3_cfg);
printf("spur_freq_4_cfg = 0x%04x\n", info->spur_freq_4_cfg);
printf("low_power_en = %d\n", info->low_power_en);
printf("lp_atten_stage01 = 0x%02x\n", info->lp_atten_stage01);
printf("lp_atten_bb = %.2f (raw 0x%02x)\n", info->lp_atten_bb / 4.0,
info->lp_atten_bb);
printf("pa_vdd = %d\n", info->pa_vdd);
printf("freq_correct_mode = 0x%02x\n", info->freq_correct_mode);
printf("force_freq_offset = %d\n", info->force_freq_offset);
printf("rf_cal_mode = 0x%02x\n", info->rf_cal_mode);
if(raw) {
printf("Raw values:");
uint8_t *p = (uint8_t *)info;
for(int i = 0; i < sizeof(sdk_phy_info_t); i ++) {
if(i % 8 == 0) {
printf("\n0x%02x:", i);
}
printf(" %02x", p[i]);
}
printf("\n\n");
}
}