Merge pull request #135 from SuperHouse/feature/phy
PHY management features
This commit is contained in:
		
						commit
						3da022c132
					
				
					 8 changed files with 770 additions and 40 deletions
				
			
		|  | @ -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"); | ||||
|  |  | |||
							
								
								
									
										32
									
								
								core/esp_phy.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								core/esp_phy.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| /** esp/phy.h
 | ||||
|  * | ||||
|  * PHY hardware management functions. | ||||
|  * | ||||
|  * Part of esp-open-rtos | ||||
|  * Copyright (C) 2016 ChefSteps, Inc | ||||
|  * BSD Licensed as described in the file LICENSE | ||||
|  */ | ||||
| #include <esp/phy.h> | ||||
| #include <esp/gpio.h> | ||||
| 
 | ||||
| void bt_coexist_configure(bt_coexist_mode_t mode, uint8_t bt_active_pin, uint8_t bt_priority_pin) | ||||
| { | ||||
|     /* Disable coexistence entirely before changing pin assignments */ | ||||
|     GPIO.OUT &= ~(GPIO_OUT_BT_COEXIST_MASK); | ||||
|     uint32_t new_mask = 0; | ||||
| 
 | ||||
|     new_mask = VAL2FIELD_M(GPIO_OUT_BT_ACTIVE_PIN, bt_active_pin) + | ||||
|         VAL2FIELD_M(GPIO_OUT_BT_PRIORITY_PIN, bt_priority_pin); | ||||
| 
 | ||||
|     if(mode == BT_COEXIST_USE_BT_ACTIVE || mode == BT_COEXIST_USE_BT_ACTIVE_PRIORITY) { | ||||
|         gpio_enable(bt_active_pin, GPIO_INPUT); | ||||
|         new_mask |= GPIO_OUT_BT_ACTIVE_ENABLE; | ||||
|     } | ||||
|     if(mode == BT_COEXIST_USE_BT_ACTIVE_PRIORITY) { | ||||
|         gpio_enable(bt_priority_pin, GPIO_INPUT); | ||||
|         new_mask |= GPIO_OUT_BT_PRIORITY_ENABLE; | ||||
|     } | ||||
|     GPIO.OUT |= new_mask; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -81,9 +81,9 @@ static inline void gpio_set_output_on_sleep(const uint8_t gpio_num, bool enabled | |||
| static inline void gpio_write(const uint8_t gpio_num, const bool set) | ||||
| { | ||||
|     if (set) | ||||
|         GPIO.OUT_SET = BIT(gpio_num); | ||||
|         GPIO.OUT_SET = BIT(gpio_num) & GPIO_OUT_PIN_MASK; | ||||
|     else | ||||
|         GPIO.OUT_CLEAR = BIT(gpio_num); | ||||
|         GPIO.OUT_CLEAR = BIT(gpio_num) & GPIO_OUT_PIN_MASK; | ||||
| } | ||||
| 
 | ||||
| /* Toggle output of a pin
 | ||||
|  | @ -102,9 +102,9 @@ static inline void gpio_toggle(const uint8_t gpio_num) | |||
|        task's pins, without needing to disable/enable interrupts. | ||||
|     */ | ||||
|     if(GPIO.OUT & BIT(gpio_num)) | ||||
|         GPIO.OUT_CLEAR = BIT(gpio_num); | ||||
|         GPIO.OUT_CLEAR = BIT(gpio_num) & GPIO_OUT_PIN_MASK; | ||||
|     else | ||||
|         GPIO.OUT_SET = BIT(gpio_num); | ||||
|         GPIO.OUT_SET = BIT(gpio_num) & GPIO_OUT_PIN_MASK; | ||||
| } | ||||
| 
 | ||||
| /* Read input value of a GPIO pin.
 | ||||
|  |  | |||
|  | @ -61,6 +61,21 @@ struct GPIO_REGS { | |||
| 
 | ||||
| _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size"); | ||||
| 
 | ||||
| /* Details for additional OUT register fields */ | ||||
| 
 | ||||
| /* Bottom 16 bits of GPIO.OUT are for GPIOs 0-15, but upper 16 bits
 | ||||
|    are used to configure the input signalling pins for Bluetooth | ||||
|    Coexistence config (see esp/phy.h for a wrapper function). | ||||
| */ | ||||
| #define GPIO_OUT_PIN_MASK 0x0000FFFF | ||||
| #define GPIO_OUT_BT_COEXIST_MASK 0x03FF0000 | ||||
| #define GPIO_OUT_BT_ACTIVE_ENABLE BIT(24) | ||||
| #define GPIO_OUT_BT_PRIORITY_ENABLE BIT(25) | ||||
| #define GPIO_OUT_BT_ACTIVE_PIN_M 0x0F | ||||
| #define GPIO_OUT_BT_ACTIVE_PIN_S 16 | ||||
| #define GPIO_OUT_BT_PRIORITY_PIN_M 0x0F | ||||
| #define GPIO_OUT_BT_PRIORITY_PIN_S 20 | ||||
| 
 | ||||
| /* Details for CONF[i] registers */ | ||||
| 
 | ||||
| /* GPIO.CONF[i] control the pin behavior for the corresponding GPIO in/output.
 | ||||
|  |  | |||
							
								
								
									
										58
									
								
								core/include/esp/phy.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								core/include/esp/phy.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,58 @@ | |||
| /** esp/phy.h
 | ||||
|  * | ||||
|  * PHY hardware management functions. | ||||
|  * | ||||
|  * These are not enough to configure the ESP8266 PHY by themselves | ||||
|  * (yet), but they provide utilities to modify the configuration set | ||||
|  * up via the SDK. | ||||
|  * | ||||
|  * Functions implemented here deal directly with the hardware, not the | ||||
|  * SDK software layers. | ||||
|  * | ||||
|  * Part of esp-open-rtos | ||||
|  * Copyright (C) 2016 ChefSteps, Inc | ||||
|  * BSD Licensed as described in the file LICENSE | ||||
|  */ | ||||
| #ifndef _ESP_PHY_H | ||||
| #define _ESP_PHY_H | ||||
| 
 | ||||
| #include <esp/types.h> | ||||
| #include <common_macros.h> | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| typedef enum { | ||||
|     BT_COEXIST_NONE, | ||||
|     BT_COEXIST_USE_BT_ACTIVE, | ||||
|     BT_COEXIST_USE_BT_ACTIVE_PRIORITY, | ||||
| } bt_coexist_mode_t; | ||||
| 
 | ||||
| /** Override the Bluetooth Coexistence BT_ACTIVE pin setting
 | ||||
|     taken from the phy_info structure. | ||||
| 
 | ||||
|     This enables other pins to be used for Bluetooth Coexistence | ||||
|     signals (rather than just the two provided for by phy_info). (Note | ||||
|     that not that not all pins are confirmed to work, GPIO 0 is | ||||
|     confirmed not usable as the SDK configures it as the WLAN_ACTIVE | ||||
|     output - even if you change the pin mode the SDK will change it | ||||
|     back.) | ||||
| 
 | ||||
|     To change pins and have coexistence work successfully the BT | ||||
|     coexistence feature must be enabled in the phy_info configuration | ||||
|     (get_default_phy_info()). You can then modify the initial | ||||
|     configuration by calling this function from your own user_init | ||||
|     function. | ||||
| 
 | ||||
|     (Eventually we should be able to support enough PHY registers | ||||
|     to enable coexistence without SDK support at all, but not yet.) | ||||
| 
 | ||||
|     This function will enable bt_active_pin & bt_priority_as GPIO | ||||
|     inputs, according to the mode parameter. | ||||
| 
 | ||||
|     Remember that the default Bluetooth Coexistence pins will be | ||||
|     configured as GPIOs by the SDK already, so you may want to | ||||
|     reconfigure/re-iomux them after calling this function. | ||||
| */ | ||||
| void bt_coexist_configure(bt_coexist_mode_t mode, uint8_t bt_active_pin, uint8_t bt_priority_pin); | ||||
| 
 | ||||
| #endif | ||||
|  | @ -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
									
								
							
							
						
						
									
										161
									
								
								core/phy_info.c
									
										
									
									
									
										Normal 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"); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										482
									
								
								include/espressif/phy_info.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										482
									
								
								include/espressif/phy_info.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,482 @@ | |||
| /** Internal Espressif SDK "PHY info" data structure
 | ||||
| 
 | ||||
|    The data structure (sdk_phy_info_t) is used to configure the | ||||
|    ESP8266 PHY layer via the SDK. The fields here are not written | ||||
|    directly to hardware, the SDK code (mostly in libphy) parses this | ||||
|    structure and configures the hardware. | ||||
| 
 | ||||
|    The structure loaded at reset time from a flash configuration | ||||
|    sector (see read_saved_phy_info()) (Espressif's SDK sources this | ||||
|    from a file "esp_init_data_default.bin"). If no valid structure is | ||||
|    found in the flash config sector then the SDK loads default values | ||||
|    (see get_default_phy_info()). It is possible to implement a custom | ||||
|    get_default_phy_info() to change the PHY default settings (see the | ||||
|    'version' field below). | ||||
| 
 | ||||
|    @note It is possible that the SDK will quietly write a new | ||||
|    configuration sector to flash itself following internal | ||||
|    calibration, etc. However this does not seem to happen, you need to | ||||
|    flash it explicitly if you want it stored there. | ||||
| 
 | ||||
|    @note Most of what is below is unconfirmed, except where a @note | ||||
|    says that it has been confirmed to work as expected. Please | ||||
|    consider submitting notes if you find behaviour here that works or | ||||
|    doesn't work as expected. | ||||
| 
 | ||||
|    Information on the meaning/offset of fields comes from Espressif's | ||||
|    flash download tool, which uses an Excel spreadsheet (in the | ||||
|    init_data directory of the ZIP file) to configure and a Python | ||||
|    script to convert an esp_init_data_custom.bin file to flash: | ||||
|    http://bbs.espressif.com/viewtopic.php?f=5&t=433
 | ||||
| 
 | ||||
|    Many fields remain undocumented (& disassembly of libphy suggests | ||||
|    that some documented fields supported undocumented values.) | ||||
| 
 | ||||
|    A few additional notes about the phy_info fields can be found | ||||
|    in the ESP Arduino ESP8266 phy_init_data structure (however most of | ||||
|    that content is verbatim from Espressif's spreadsheet): | ||||
|    https://github.com/esp8266/Arduino/blob/master/cores/esp8266/core_esp8266_phy.c#L29
 | ||||
| 
 | ||||
|    Part of esp-open-rtos. Copyright (C) 2016 Angus Gratton, | ||||
|    BSD Licensed as described in the file LICENSE. | ||||
|  */ | ||||
| #ifndef _ESPRESSIF_PHY_INFO_H | ||||
| #define _ESPRESSIF_PHY_INFO_H | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| #include <stddef.h> | ||||
| 
 | ||||
| /* CRYSTAL_FREQ_xx values as used by sdk_phy_info_t.crystal_freq */ | ||||
| #define CRYSTAL_FREQ_40M 0 | ||||
| #define CRYSTAL_FREQ_26M 1 | ||||
| #define CRYSTAL_FREQ_24M 2 | ||||
| 
 | ||||
| /* SDIO_CONFIG_xx values as used by sdk_phy_info_t.sdio_config */ | ||||
| #define SDIO_CONFIG_AUTO 0   /* Uses pin strapping to determine */ | ||||
| #define SDIO_CONFIG_SDIOV1_1 /* Data output on negative edge */ | ||||
| #define SDIO_CONFIG_SDIOV2_0 /* data output on positive edge */ | ||||
| 
 | ||||
| /* BT_COEXIST_CONFIG_xx values as used by sdk_phy_info_t.bt_coexist */ | ||||
| /* No bluetooth */ | ||||
| #define BT_COEXIST_CONFIG_NONE 0 | ||||
| /* Coexistence configuration A:
 | ||||
|    GPIO 0  - WLAN_ACTIVE | ||||
|    GPIO 14 - BT_ACTIVE | ||||
|    GPIO 13 - BT_PRIORITY | ||||
|    GPIO 3  - ANT_SEL_BT | ||||
| */ | ||||
| #define BT_COEXIST_CONFIG_A 1 | ||||
| /* No coexistence, but Bluetooth enabled?
 | ||||
|    Unsure how this works? | ||||
|  */ | ||||
| #define BT_COEXIST_CONFIG_PRESENT 2 | ||||
| /* Coexistence configuration B:
 | ||||
|    GPIO 0 - WLAN_ACTIVE | ||||
|    GPIO 14 - BT_PRIORITY | ||||
|    GPIO 13 - BT_ACTIVE | ||||
|    GPIO 3  - ANT_SEL_BT | ||||
| */ | ||||
| #define BT_COEXIST_CONFIG_B 3 | ||||
| 
 | ||||
| /* BT_COEXIST_PROTOCOL_xx values for coexistence protocol,
 | ||||
|    field sdk_phy_info_t.bt_coexist_protocol | ||||
|  */ | ||||
| #define BT_COEXIST_PROTOCOL_WIFI_ONLY 0 | ||||
| #define BT_COEXIST_PROTOCOL_BT_ONLY 1 | ||||
| 
 | ||||
| /* Coexistence is enabled, Bluetooth has its own antenna */ | ||||
| #define BT_COEXIST_PROTOCOL_FLAG_SEPARATE_ANT 2 | ||||
| /* Coexistence is enabled, Bluetooth shares WiFi antenna */ | ||||
| #define BT_COEXIST_PROTOCOL_FLAG_SHARE_ANT 4 | ||||
| 
 | ||||
| /* Coexistence is enabled, use only BT_ACTIVE signal */ | ||||
| #define BT_COEXIST_PROTOCOL_FLAG_BT_ACTIVE_ONLY 0 | ||||
| /* Coexistence is enabled, use both BT_ACTIVE and BT_PRIORITY signals */ | ||||
| #define BT_COEXIST_PROTOCOL_FLAG_BT_ACTIVE_PRIORITY 1 | ||||
| 
 | ||||
| /* DUAL_ANT_CONFIG_xx values for dual antenna config,
 | ||||
|    field sdk_phy_info_t.dual_ant_config | ||||
| 
 | ||||
|    (Not really clear how this feature works, if at all.) | ||||
| */ | ||||
| #define DUAL_ANT_CONFIG_NONE 0 | ||||
| /* antenna diversity for WiFi, use GPIO0 + U0RXD (?) */ | ||||
| #define DUAL_ANT_CONFIG_DUAL 1 | ||||
| /* TX/RX switch for external PA & LNA: GPIO 0 high, GPIO 3 low during TX */ | ||||
| #define DUAL_ANT_CONFIG_TX_GPIO0_HIGH_GPIO3_LOW | ||||
| /* TX/RX switch for external PA & LNA: GPIO 0 low, GPIO 3 high during TX */ | ||||
| #define DUAL_ANT_CONFIG_TX_GPIO0_LOW_GPIO3_HIGH | ||||
| 
 | ||||
| 
 | ||||
| /* CRYSTAL_SLEEP_xx values used for sdk_phy_info_t.crystal_sleep
 | ||||
|  */ | ||||
| #define CRYSTAL_SLEEP_OFF 0 | ||||
| #define CRYSTAL_SLEEP_ON 1 | ||||
| #define CRYSTAL_SLEEP_GPIO16 2 | ||||
| #define CRYSTAL_SLEEP_GPIO2 3 | ||||
| 
 | ||||
| /* RF Stage 0 & 1 attenuation constants. Use for sdk_phy_info_t.lp_atten_stage01
 | ||||
| 
 | ||||
|    @note These values have been tested and are confirmed to work as | ||||
|    expected by measuring RSSI w/ rt73 USB adapter in monitor mode | ||||
|    (some values also checked on spectrum analyzer) - provided | ||||
|    low_power_en is set then the signal is attenuated as per this | ||||
|    setting. | ||||
| 
 | ||||
|    (It may look like LP_ATTEN_STAGE01_11_5DB is out of order, but | ||||
|    according to monitor mode captures this is the correct ordering of | ||||
|    these constants.) | ||||
| 
 | ||||
|    Setting the numeric values in between these constants appears to | ||||
|    also attenuate the signal, but not necessarily by the amount you'd | ||||
|    expect. | ||||
| */ | ||||
| #define LP_ATTEN_STAGE01_0DB    0x0f /*     0dB */ | ||||
| #define LP_ATTEN_STAGE01_2_5DB  0x0e /*  -2.5dB */ | ||||
| #define LP_ATTEN_STAGE01_6DB    0x0d /*    -6dB */ | ||||
| #define LP_ATTEN_STAGE01_8_5DB  0x09 /*  -8.5dB */ | ||||
| #define LP_ATTEN_STAGE01_11_5DB 0x0c /* -11.5dB */ | ||||
| #define LP_ATTEN_STAGE01_14DB   0x08 /*   -14dB */ | ||||
| #define LP_ATTEN_STAGE01_17_5DB 0x04 /* -17.5dB */ | ||||
| #define LP_ATTEN_STAGE01_23DB   0x00 /*   -23dB */ | ||||
| 
 | ||||
| /* Constant for sdk_phy_info_t.pa_vdd */ | ||||
| #define PA_VDD_MEASURE_VCC 0xFF | ||||
| 
 | ||||
| /* Bitmask flags for sdk_phy_info_t.freq_correct_mode */ | ||||
| 
 | ||||
| /* Set this flag to disable frequency offset correction */ | ||||
| #define FREQ_CORRECT_DISABLE 0 | ||||
| 
 | ||||
| /* Set this flag to enable frequency offset correction */ | ||||
| #define FREQ_CORRECT_ENABLE BIT(0) | ||||
| 
 | ||||
| /* Set = Baseband PLL frequency is 160MHz (can only apply +ve offset)
 | ||||
|  * Unset = Baseband PLL frequency is 168MHz (can apply +ve/-ve offset */ | ||||
| #define FREQ_CORRECT_BB_160M BIT(1) | ||||
| 
 | ||||
| /* Set = use force_freq_offset field to correct, Unset = automatically
 | ||||
|    measure & correct offset | ||||
| */ | ||||
| #define FREQ_CORRECT_FORCE BIT(2) | ||||
| 
 | ||||
| 
 | ||||
| /* RF_CAL_MODE_xx fields used for sdk_phy_info_t.rf_cal_mode
 | ||||
|  */ | ||||
| /* Use saved RF CAL data from flash, only. RF init takes 2ms. */ | ||||
| #define RF_CAL_MODE_SAVED 0 | ||||
| /* Calibrate TX power control only, use saved RF CAL data for others.
 | ||||
|    RF init takes 20ms. */ | ||||
| #define RF_CAL_MODE_TXPOWER_ONLY 1 | ||||
| /* Unclear if/how this mode is different to 2? */ | ||||
| #define RF_CAL_MODE_SAVED_2 2 | ||||
| /* Run full RF CAL routine. RF init takes approx 200ms. */ | ||||
| #define RF_CAL_MODE_FULL 3 | ||||
| 
 | ||||
| /* Data structure that maps to the phy_info configuration block */ | ||||
| typedef struct __attribute__((packed)) { | ||||
|     uint8_t _reserved00[0x05]; /* 0x00 - 0x04 */ | ||||
| 
 | ||||
|     /* This "version" field was set to 5 in the SDK phy_info,
 | ||||
|        and the original SDK startup code checks it is 5 and then loads | ||||
|        default PHY configuration otherwise. | ||||
| 
 | ||||
|        esp-open-rtos will load phy_info from get_default_phy_info() if | ||||
|        the value stored in flash has a different value to the value | ||||
|        returned in get_default_phy_info(). This means you can | ||||
|        increment the version return by get_default_phy_info() (to any | ||||
|        value but 0xFF), and know that the new defaults will replace | ||||
|        any older stored values. | ||||
| 
 | ||||
|        @notes It's not clear whether this is actually a version field | ||||
|        (the other 24 bytes here have equally arbitrary numbers in | ||||
|        them.) Changing the "version" to other values does not seem to | ||||
|        effect WiFi performance at all, neither does zeroing out the | ||||
|        first 5 reserved bytes in _reserved00. However zeroing bytes in | ||||
|        the _reserved06 region will break WiFi entirely. | ||||
|     */ | ||||
|     uint8_t version;          /* 0x05 */ | ||||
|     int8_t _reserved06[0x14]; /* 0x06 - 0x19 */ | ||||
| 
 | ||||
|     /* spur_freq = spur_freq_primary / spur_freq_divisor */ | ||||
|     uint8_t spur_freq_primary; /* 0x1a */ | ||||
|     uint8_t spur_freq_divisor; /* 0x1b */ | ||||
| 
 | ||||
|     /* Bitmask to enable spur_freq for each channel
 | ||||
|        Appears to be a big endian short word? | ||||
|      */ | ||||
|     uint8_t spur_freq_en_h;      /* 0x1c */ | ||||
|     uint8_t spur_freq_en_l;      /* 0x1d */ | ||||
| 
 | ||||
|     uint8_t _reserved1e[4];   /* 0x1e - 0x21 */ | ||||
| 
 | ||||
|     /* Each value is a target power level.
 | ||||
|        Units are 1/4 dBm ie value 64 = 16dBm. | ||||
| 
 | ||||
|        SDK defaults to using these transmit powers: | ||||
| 	   20.5dBm, 19.5dBm, 18.5dBm, 17dBm, 16dBm, 14dBm | ||||
| 
 | ||||
| 	   @note Adjusting these values is confirmed to reduce | ||||
| 	   transmit power accordingly. | ||||
|     */ | ||||
|     uint8_t target_power[6]; /* 0x22 - 0x27 */ | ||||
| 
 | ||||
|     /* Maps 8 MCS (modulation & coding schemes) types for 802.11b, g &
 | ||||
|      * n to a target_power level index (0-5), set above. | ||||
| 
 | ||||
|      This mapping of MCS slot to MCS type is derived from the | ||||
|      spreadsheet and also a table sent by Espressif, but is untested | ||||
|      and may be SDK version dependendent (especially any 802.11n | ||||
|      rates). However the general relationship is confirmed to hold | ||||
|      (higher MCS index = higher bit rate). | ||||
| 
 | ||||
|      MCS 0: 1Mbps/2Mbps/5.5Mbps/11Mbps (802.11b) / 6Mbps/9Mbps (802.11g) | ||||
|          default target_power 0 (default 20.5dBm) | ||||
|          (see also pwr_ind_11b_en) | ||||
| 
 | ||||
|      MCS 1: 12Mbps (802.11g) | ||||
|          default target_power 0 (default 20.5dBm) | ||||
| 
 | ||||
|      MCS 2: 18Mbps (802.11g) | ||||
|          default target_power 1 (19.5dBm) | ||||
| 
 | ||||
|      MCS 3: 24Mbps (802.11g) | ||||
|          default target_power 1 (19.5dBm) | ||||
| 
 | ||||
|      MCS 4: 36Mbps (802.11g) | ||||
|          default target_power 2 (18.5dBm) | ||||
| 
 | ||||
|      MCS 5: 48Mbps (802.11g) | ||||
|          default target_power 3 (17dBm) | ||||
| 
 | ||||
|      MCS 6: 54Mbps (802.11g) | ||||
|          default target_power 4 (16dBm) | ||||
| 
 | ||||
|      MCS 7: 65Mbps (802.11n) - unclear if ever used? | ||||
|          default target_power 5 (14dBm) | ||||
|     */ | ||||
|     uint8_t target_power_index_mcs[8]; /* 0x28 - 0x2f */ | ||||
| 
 | ||||
|     /* One of CRYSTAL_FREQ_40M / CRYSTAL_FREQ_26M / CRYSTAL_FREQ_24M
 | ||||
| 
 | ||||
| 	   The crystal configured here is the input to the PLL setting | ||||
| 	   calculations which are used to derive the CPU & APB peripheral | ||||
| 	   clock frequency, and probably the WiFi PLLs (unconfirmed.) | ||||
| 	 */ | ||||
|     uint8_t crystal_freq; /* 0x30 */ | ||||
| 
 | ||||
|     uint8_t _unused31; /* 0x31: Possibly high byte of crystal freq? */ | ||||
| 
 | ||||
|     /* One of SDIO_CONFIG_AUTO, SDIO_CONFIG_SDIOV1_1, SDIO_CONFIG_SDIOV2_0 */ | ||||
|     uint8_t sdio_config; /* 0x32 */ | ||||
| 
 | ||||
|     /* BT coexistence pin configuration.
 | ||||
| 
 | ||||
|        One of BT_COEXIST_CONFIG_NONE, BT_COEXIST_CONFIG_A, | ||||
|        BT_COEXIST_CONFIG_PRESENT, BT_COEXIST_CONFIG_B | ||||
|     */ | ||||
|     uint8_t bt_coexist_config; /* 0x33 */ | ||||
| 
 | ||||
|     /* BT coexistence pin protocol.
 | ||||
| 
 | ||||
|        If no coexistence: | ||||
|        Either BT_COEXIST_PROTOCOL_WIFI_ONLY, or | ||||
|        BT_COEXIST_PROTOCOL_BT_ONLY. | ||||
| 
 | ||||
|        If coexistence: | ||||
|        Combine one of | ||||
|        BT_COEXIST_PROTOCOL_FLAG_SEPARATE_ANT or | ||||
|        BT_COEXIST_PROTOCOL_FLAG_SHARE_ANT | ||||
|        with one of | ||||
|        BT_COEXIST_PROTOCOL_FLAG_BT_ACTIVE_ONLY or | ||||
|        BT_COEXIST_PROTOCOL_FLAG_BT_ACTIVE_BT_PRIORITY | ||||
|     */ | ||||
|     uint8_t bt_coexist_protocol; /* 0x34 */ | ||||
| 
 | ||||
|     /* Dual antenna configuration
 | ||||
| 
 | ||||
|        One of DUAL_ANT_CONFIG_NONE, DUAL_ANT_CONFIG_DUAL, | ||||
|        DUAL_ANT_CONFIG_TX_GPIO0_HIGH_GPIO3_LOW, | ||||
|        DUAL_ANT_CONFIG_TX_GPIO0_LOW_GPIO3_HIGH | ||||
|     */ | ||||
|     uint8_t dual_ant_config; /* 0x35 */ | ||||
| 
 | ||||
|     uint8_t _reserved34; /* 0x36 */ | ||||
| 
 | ||||
|     /* For sharing crystal clock with other devices:
 | ||||
|        one of CRYSTAL_SLEEP_OFF, CRYSTAL_SLEEP_ON, | ||||
|        CRYSTAL_SLEEP_GPIO16, CRYSTAL_SLEEP_GPIO2 | ||||
|     */ | ||||
|     uint8_t crystal_sleep; /* 0x37 */ | ||||
| 
 | ||||
|     uint8_t _unused38[8]; | ||||
| 
 | ||||
|     /* spur_freq_2 = spur_freq_2_primary / spur_freq_2_divisor */ | ||||
|     uint8_t spur_freq_2_primary; /* 0x40 */ | ||||
|     uint8_t spur_freq_2_divisor; /* 0x41 */ | ||||
| 
 | ||||
|     /* Bitmask to enable spur_freq_2 for each channel?
 | ||||
|        Appears to be a big endian short word? | ||||
|     */ | ||||
|     uint8_t spur_freq_2_en_h; /* 0x42 */ | ||||
|     uint8_t spur_freq_2_en_l; /* 0x43 */ | ||||
| 
 | ||||
|     /* Not really clear what these do */ | ||||
|     uint8_t spur_freq_cfg_msb; /* 0x44 */ | ||||
|     uint8_t spur_freq_2_cfg_msb; /* 0x45 */ | ||||
|     uint16_t spur_freq_3_cfg; /* 0x46 - 0x47 */ | ||||
|     uint16_t spur_freq_4_cfg; /* 0x48 - 0x49 */ | ||||
| 
 | ||||
|     uint8_t _reserved4a[4]; /* 0x4a - 0x4d */ | ||||
| 
 | ||||
|     uint8_t _unused78[15]; /* 0x4e - 0x5c */ | ||||
| 
 | ||||
|     /* Flag to enable low power mode */ | ||||
|     uint8_t low_power_en; /* 0x5d */ | ||||
| 
 | ||||
|     /* Low Power attenuation of RF gain stages 0 & 1
 | ||||
| 
 | ||||
|        Attenuates transmit power if/when low_power_en is set. | ||||
| 
 | ||||
|        Use one of the constants LP_ATTEN_STAGE01_0DB, | ||||
|        LP_ATTEN_STAGE01_2_5DB, LP_ATTEN_STAGE01_6DB, | ||||
|        LP_ATTEN_STAGE01_8_5DB, LP_ATTEN_STAGE01_11_5DB, | ||||
|        LP_ATTEN_STAGE01_14DB, LP_ATTEN_STAGE01_17_5DB, | ||||
|        LP_ATTEN_STAGE01_23DB. | ||||
|      */ | ||||
|     uint8_t lp_atten_stage01; /* 0x5e */ | ||||
| 
 | ||||
|     /* Low Power(?) attenuation of baseband gain
 | ||||
| 
 | ||||
|        Units are minus 1/4 dB, ie value 4 == -1dB. | ||||
| 
 | ||||
|        Maximum value is 24 (0x18) == -6dB | ||||
|      */ | ||||
|     uint8_t lp_atten_bb; /* 0x5f */ | ||||
| 
 | ||||
|     /* I believe this means, when pwr_ind_11b_en == 0 then the 802.11g
 | ||||
|        MCS 0 level from target_power_index_mcs are used to | ||||
|        determine 802.11b transmit power level. | ||||
| 
 | ||||
|        However, when pwr_ind_11b_en == 1 then the index values in | ||||
|        pwr_ind_11b_0 & pwr_ind_11b_1 are used for 802.11b instead. | ||||
| 
 | ||||
|        This is all unconfirmed, if you can confirm then please update | ||||
|        this comment. | ||||
|      */ | ||||
|     uint8_t pwr_ind_11b_en; /* 0x60 */ | ||||
| 
 | ||||
|     /* 802.11b low data rate power index (0~5).
 | ||||
|        Sets the power level index for operation at 1 & 2Mbps | ||||
|     */ | ||||
|     uint8_t pwr_ind_11b_0; /* 0x61 */ | ||||
| 
 | ||||
|     /* 802.11b high data rate power index (0~5)
 | ||||
|        Sets the power level index for operation at 5.5 & 11Mbps | ||||
|     */ | ||||
|     uint8_t pwr_ind_11b_1; /* 0x62 */ | ||||
| 
 | ||||
|     uint8_t _unused63[8]; /* 0x63 - 0x6a */ | ||||
| 
 | ||||
|     /* Set the voltage of PA_VDD, which appears to be an internal analog
 | ||||
|        reference voltage(?) | ||||
| 
 | ||||
|        This field is called vdd33_const in the Arduino phy fields, | ||||
|        and relates to usage of the TOUT pin (ADC pin). | ||||
| 
 | ||||
|        Set to PA_VDD_MEASURE_VCC (0xFF) and leave TOUT (ADC) pin | ||||
|        floating in order to use the ADC to measure the 3.3V input | ||||
|        voltage. | ||||
| 
 | ||||
|        Set to value in the range 18-36 (1.8V to 3.6V) to set a | ||||
|        reference voltage(?) when using TOUT pin as an ADC input. I | ||||
|        think this is the reference voltage used to scale the 0-1V | ||||
|        which is allowed on the pin, in order to get an accurate | ||||
|        reading. So it should be set to a value that matches system | ||||
|        VCC... I think! | ||||
|     */ | ||||
|     uint8_t pa_vdd; /* 0x6b */ | ||||
| 
 | ||||
|     /* Disable RF calibration cycle for this many times */ | ||||
|     uint8_t disable_rfcal_count; /* 0x6c */ | ||||
| 
 | ||||
|     uint8_t _unused6d[3]; | ||||
| 
 | ||||
|     /* Flags for frequency correction
 | ||||
| 
 | ||||
|        A bitmask combination of any of: FREQ_CORRECT_DISABLE, | ||||
|        FREQ_CORRECT_ENABLE, FREQ_CORRECT_BB_160M, FREQ_CORRECT_FORCE | ||||
|      */ | ||||
|     uint8_t freq_correct_mode; /* 0x70 */ | ||||
| 
 | ||||
|     /* Force frequency offset adjustment (instead of auto measuring)
 | ||||
|        units are 1 = 8kHz, full range +/- 1016kHz. | ||||
| 
 | ||||
|        Only used if FREQ_CORRECT_ENABLE and FREQ_CORRECT_FORCE are | ||||
|        set in freq_correct_mode. | ||||
| 
 | ||||
|        Unclear whether setting FREQ_CORRECT_BB_160M (which allows only positive offsets) changes the usable range. | ||||
|     */ | ||||
|     int8_t force_freq_offset; /* 0x71 */ | ||||
| 
 | ||||
|     /* Use stored data in flash for RF calibration.
 | ||||
| 
 | ||||
|        This field was previously called rf_cal_use_flash. | ||||
| 
 | ||||
|        Acceptable values one of RF_CAL_MODE_SAVED, RF_CAL_MODE_TXPOWER_ONLY, RF_CAL_MODE_SAVED_2, RF_CAL_MODE_FULL. | ||||
|      */ | ||||
|     uint8_t rf_cal_mode; /* 0x72 */ | ||||
| 
 | ||||
|     uint8_t _unused73[13]; | ||||
| } sdk_phy_info_t; | ||||
| 
 | ||||
| /* Some sanity check static assertions. These can probably be
 | ||||
|    removed after this structure has been better tested. | ||||
| */ | ||||
| _Static_assert(sizeof(sdk_phy_info_t) == 128, "sdk_phy_info_t is wrong size!"); | ||||
| _Static_assert(offsetof(sdk_phy_info_t, version) == 5, "version at wrong offset"); | ||||
| _Static_assert(offsetof(sdk_phy_info_t, target_power) == 34, "target_power_qdb at wrong offset"); | ||||
| _Static_assert(offsetof(sdk_phy_info_t, bt_coexist_protocol) == 52, "bt_coexist_protocol at wrong offset"); | ||||
| _Static_assert(offsetof(sdk_phy_info_t, spur_freq_2_primary) == 64, "spur_freq_2_primary at wrong offset"); | ||||
| _Static_assert(offsetof(sdk_phy_info_t, lp_atten_stage01) == 94, "lp_atten_stage01 at wrong offset"); | ||||
| _Static_assert(offsetof(sdk_phy_info_t, pa_vdd) == 107, "pa_vdd aka vdd33_const at wrong offset"); | ||||
| _Static_assert(offsetof(sdk_phy_info_t, rf_cal_mode) == 114, "rf_cal_use_flash at wrong offset!"); | ||||
| 
 | ||||
| /* Read the default PHY info into the supplied structure.
 | ||||
| 
 | ||||
|    This function is weak-aliased to get_sdk_default_phy_info() so you | ||||
|    can replace it with your own if you want to vary the default values | ||||
|    - suggested way to do this is to call get_sdk_default_phy_info() | ||||
|    and then only update the fields you care about. | ||||
| 
 | ||||
|    The default PHY info is used at startup whenever the version field | ||||
|    in the default sdk_phy_info_t does not match the version field | ||||
|    stored in flash. So you can increment the version field to force a | ||||
|    reset to defaults, regardless of what values are in flash. | ||||
| */ | ||||
| void get_default_phy_info(sdk_phy_info_t *info); | ||||
| 
 | ||||
| /* Read the "SDK default" PHY info as used by the Espressif SDK */ | ||||
| void get_sdk_default_phy_info(sdk_phy_info_t *info); | ||||
| 
 | ||||
| /* Read the PHY info currently stored in the SPI flash SDK configuration sector.
 | ||||
| 
 | ||||
|    This PHY info is updated by the SDK following RF calibration, etc. | ||||
| 
 | ||||
|    Note that the saved data may be corrupt - read the 'version' field to verify. | ||||
| */ | ||||
| void read_saved_phy_info(sdk_phy_info_t *info); | ||||
| 
 | ||||
| /* Update the saved PHY info in the SPI flash. A reset is necessary to use these values.
 | ||||
| 
 | ||||
|    Note that the SDK may clobber these values, so it's recommended you reset ASAP after updating them. | ||||
| */ | ||||
| void write_saved_phy_info(const sdk_phy_info_t *info); | ||||
| 
 | ||||
| /* Dump known fields in the phy info structure to stdout,
 | ||||
|    if 'raw' flag is set then the raw hex values are also dumped. | ||||
| */ | ||||
| void dump_phy_info(const sdk_phy_info_t *info, bool raw); | ||||
| 
 | ||||
| #endif | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue