Merge branch 'master' into open-libmain
This commit is contained in:
commit
d8bcb5d702
65 changed files with 3272 additions and 739 deletions
|
|
@ -24,6 +24,7 @@
|
|||
#include "os_version.h"
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "espressif/phy_info.h"
|
||||
#include "sdk_internal.h"
|
||||
#include "esplibs/libmain.h"
|
||||
|
||||
|
|
@ -32,8 +33,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
|
||||
|
|
@ -44,26 +43,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;
|
||||
|
||||
|
|
@ -81,7 +60,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 user_start_phase2(void);
|
||||
static void dump_flash_sector(uint32_t start_sector, uint32_t length);
|
||||
|
|
@ -254,7 +233,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");
|
||||
abort();
|
||||
|
|
@ -361,9 +340,9 @@ extern void (*__init_array_start)(void);
|
|||
extern void (*__init_array_end)(void);
|
||||
|
||||
// .Lfunc009 -- .irom0.text+0x5b4
|
||||
static void user_start_phase2(void) {
|
||||
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.reason > 3) {
|
||||
|
|
@ -381,8 +360,16 @@ static void user_start_phase2(void) {
|
|||
sdk_info._unknown4 = 0x00ffffff;
|
||||
sdk_info._unknown8 = 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);
|
||||
|
|
@ -390,13 +377,7 @@ static 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);
|
||||
|
|
@ -433,11 +414,11 @@ static void dump_flash_sector(uint32_t start_sector, uint32_t length) {
|
|||
}
|
||||
|
||||
// .Lfunc011 -- .irom0.text+0x790
|
||||
static void dump_flash_config_sectors(uint32_t start_sector) {
|
||||
static __attribute__((noinline)) void dump_flash_config_sectors(uint32_t start_sector) {
|
||||
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");
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
#include <stdio.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "debug_dumps.h"
|
||||
#include "common_macros.h"
|
||||
|
|
@ -19,13 +21,19 @@
|
|||
#include "esp/uart.h"
|
||||
#include "espressif/esp_common.h"
|
||||
#include "sdk_internal.h"
|
||||
#include "esplibs/libmain.h"
|
||||
|
||||
/* Forward declarations */
|
||||
static void IRAM fatal_handler_prelude(void);
|
||||
/* Inner parts of crash handlers marked noinline to ensure they don't inline into IRAM. */
|
||||
static void __attribute__((noinline)) __attribute__((noreturn)) fatal_exception_handler_inner(uint32_t *sp, bool registers_saved_on_stack);
|
||||
|
||||
/* Inner parts of crash handlers */
|
||||
typedef void __attribute__((noreturn)) (*fatal_exception_handler_fn)(uint32_t *sp, bool registers_saved_on_stack);
|
||||
static void __attribute__((noreturn)) standard_fatal_exception_handler_inner(uint32_t *sp, bool registers_saved_on_stack);
|
||||
static void __attribute__((noreturn)) second_fatal_exception_handler_inner(uint32_t *sp, bool registers_saved_on_stack);
|
||||
static void __attribute__((noinline)) __attribute__((noreturn)) abort_handler_inner(uint32_t *caller, uint32_t *sp);
|
||||
|
||||
static IRAM_DATA fatal_exception_handler_fn fatal_exception_handler_inner = standard_fatal_exception_handler_inner;
|
||||
|
||||
/* fatal_exception_handler called from any unhandled user exception
|
||||
*
|
||||
* (similar to a hard fault on other processor architectures)
|
||||
|
|
@ -36,7 +44,8 @@ static void __attribute__((noinline)) __attribute__((noreturn)) abort_handler_in
|
|||
*/
|
||||
void IRAM __attribute__((noreturn)) fatal_exception_handler(uint32_t *sp, bool registers_saved_on_stack) {
|
||||
fatal_handler_prelude();
|
||||
fatal_exception_handler_inner(sp, registers_saved_on_stack);
|
||||
fatal_exception_handler_fn inner_fn = fatal_exception_handler_inner;
|
||||
inner_fn(sp, registers_saved_on_stack);
|
||||
}
|
||||
|
||||
/* Abort implementation
|
||||
|
|
@ -130,6 +139,12 @@ void dump_registers_in_exception_handler(uint32_t *sp) {
|
|||
printf("SAR %08x\n", saved[0x13]);
|
||||
}
|
||||
|
||||
static void __attribute__((noreturn)) post_crash_reset(void) {
|
||||
uart_flush_txfifo(0);
|
||||
uart_flush_txfifo(1);
|
||||
sdk_system_restart_in_nmi();
|
||||
while(1) {}
|
||||
}
|
||||
|
||||
/* Prelude ensures exceptions/NMI off and flash is mapped, allowing
|
||||
calls to non-IRAM functions.
|
||||
|
|
@ -148,7 +163,10 @@ static void IRAM fatal_handler_prelude(void) {
|
|||
/* Main part of fatal exception handler, is run from flash to save
|
||||
some IRAM.
|
||||
*/
|
||||
static void fatal_exception_handler_inner(uint32_t *sp, bool registers_saved_on_stack) {
|
||||
static void standard_fatal_exception_handler_inner(uint32_t *sp, bool registers_saved_on_stack) {
|
||||
/* Replace the fatal exception handler 'inner' function so we
|
||||
don't end up in a crash loop if this handler crashes. */
|
||||
fatal_exception_handler_inner = second_fatal_exception_handler_inner;
|
||||
dump_excinfo();
|
||||
if (sp) {
|
||||
if (registers_saved_on_stack) {
|
||||
|
|
@ -156,10 +174,52 @@ static void fatal_exception_handler_inner(uint32_t *sp, bool registers_saved_on_
|
|||
}
|
||||
dump_stack(sp);
|
||||
}
|
||||
uart_flush_txfifo(0);
|
||||
uart_flush_txfifo(1);
|
||||
sdk_system_restart_in_nmi();
|
||||
while(1) {}
|
||||
dump_heapinfo();
|
||||
post_crash_reset();
|
||||
}
|
||||
|
||||
/* This is the exception handler that gets called if a crash occurs inside the standard handler,
|
||||
so we don't end up in a crash loop. It doesn't rely on contents of stack or heap.
|
||||
*/
|
||||
static void second_fatal_exception_handler_inner(uint32_t *sp, bool registers_saved_on_stack) {
|
||||
dump_excinfo();
|
||||
printf("Second fatal exception occured inside fatal exception handler. Can't continue.\n");
|
||||
post_crash_reset();
|
||||
}
|
||||
|
||||
void dump_heapinfo(void)
|
||||
{
|
||||
extern char _heap_start;
|
||||
extern uint32_t xPortSupervisorStackPointer;
|
||||
struct mallinfo mi = mallinfo();
|
||||
uint32_t brk_val = (uint32_t) sbrk(0);
|
||||
uint32_t sp = xPortSupervisorStackPointer;
|
||||
if(sp == 0) {
|
||||
SP(sp);
|
||||
}
|
||||
|
||||
/* Total free heap is all memory that could be allocated via
|
||||
malloc (assuming fragmentation doesn't become a problem) */
|
||||
printf("\nFree Heap: %d\n", sp - brk_val + mi.fordblks);
|
||||
|
||||
/* delta between brk & supervisor sp is the contiguous memory
|
||||
region that is available to be put into heap space via
|
||||
brk(). */
|
||||
printf("_heap_start %p brk 0x%08x supervisor sp 0x%08x sp-brk %d bytes\n",
|
||||
&_heap_start, brk_val, sp, sp-brk_val);
|
||||
|
||||
/* arena/fordblks/uordblks determines the amount of free space
|
||||
inside the heap region already added via brk(). May be
|
||||
fragmented.
|
||||
|
||||
The values in parentheses are the values used internally by
|
||||
nano-mallocr.c, the field names outside parentheses are the
|
||||
POSIX compliant field names of the mallinfo structure.
|
||||
|
||||
"arena" should be equal to brk-_heap_start ie total size available.
|
||||
*/
|
||||
printf("arena (total_size) %d fordblks (free_size) %d uordblocks (used_size) %d\n",
|
||||
mi.arena, mi.fordblks, mi.uordblks);
|
||||
}
|
||||
|
||||
/* Main part of abort handler, can be run from flash to save some
|
||||
|
|
@ -168,8 +228,6 @@ static void fatal_exception_handler_inner(uint32_t *sp, bool registers_saved_on_
|
|||
static void abort_handler_inner(uint32_t *caller, uint32_t *sp) {
|
||||
printf("abort() invoked at %p.\n", caller);
|
||||
dump_stack(sp);
|
||||
uart_flush_txfifo(0);
|
||||
uart_flush_txfifo(1);
|
||||
sdk_system_restart_in_nmi();
|
||||
while(1) {}
|
||||
dump_heapinfo();
|
||||
post_crash_reset();
|
||||
}
|
||||
|
|
|
|||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -37,15 +37,71 @@
|
|||
#define VAL2FIELD_M(fieldname, value) (((value) & fieldname##_M) << fieldname##_S)
|
||||
#define SET_FIELD_M(regbits, fieldname, value) (((regbits) & ~FIELD_MASK(fieldname)) | VAL2FIELD_M(fieldname, value))
|
||||
|
||||
/* Use this macro to store constant values in IROM flash instead
|
||||
of having them loaded into rodata (which resides in DRAM)
|
||||
/* Use the IRAM macro to place functions into Instruction RAM (IRAM)
|
||||
instead of flash (aka irom).
|
||||
|
||||
Unlike the ESP8266 SDK you don't need an attribute like this for
|
||||
standard functions. They're stored in flash by default. But
|
||||
variables need them.
|
||||
(This is the opposite to the Espressif SDK, where functions default
|
||||
to being placed in IRAM but the ICACHE_FLASH_ATTR attribute will
|
||||
place them in flash.)
|
||||
|
||||
Important to note: IROM flash can only be accessed via 32-bit word
|
||||
aligned reads. It's up to the user of this attribute to ensure this.
|
||||
Use the IRAM attribute for functions which are called when the
|
||||
flash may not be available (for example during NMI exceptions), or
|
||||
for functions which are called very frequently and need high
|
||||
performance.
|
||||
|
||||
Usage example:
|
||||
|
||||
void IRAM high_performance_function(void)
|
||||
{
|
||||
// do important thing here
|
||||
}
|
||||
|
||||
Bear in mind IRAM is limited (32KB), compared to up to 1MB of flash.
|
||||
*/
|
||||
#define IRAM __attribute__((section(".iram1.text")))
|
||||
|
||||
/* Use the RAM macro to place constant data (rodata) into RAM (data
|
||||
RAM) instead of the default placement in flash. This is useful for
|
||||
constant data which needs high performance access.
|
||||
|
||||
Usage example:
|
||||
|
||||
const RAM uint8_t constants[] = { 1, 2, 3, 7 };
|
||||
|
||||
When placing string literals in RAM, they need to be declared with
|
||||
the type "const char[]" not "const char *"
|
||||
|
||||
Usage example:
|
||||
|
||||
const RAM char hello_world[] = "Hello World";
|
||||
*/
|
||||
#define RAM __attribute__((section(".data")))
|
||||
|
||||
/* Use the IRAM_DATA macro to place data into Instruction RAM (IRAM)
|
||||
instead of the default of flash (for constant data) or data RAM
|
||||
(for non-constant data).
|
||||
|
||||
This may be useful to free up data RAM. However all data read from
|
||||
any instruction space (either IRAM or Flash) must be 32-bit aligned
|
||||
word reads. Reading unaligned data stored with IRAM_DATA will be
|
||||
slower than reading data stored in RAM. You can't perform unaligned
|
||||
writes to IRAM.
|
||||
*/
|
||||
#define IRAM_DATA __attribute__((section(".iram1.data")))
|
||||
|
||||
/* Use the IROM macro to store constant values in IROM flash. In
|
||||
esp-open-rtos this is already the default location for most constant
|
||||
data (rodata), so you don't need this attribute in 99% of cases.
|
||||
|
||||
The exceptions are to mark data in the core & freertos libraries,
|
||||
where the default for constant data storage is RAM.
|
||||
|
||||
(Unlike the Espressif SDK you don't need to use an attribute like
|
||||
ICACHE_FLASH_ATTR for functions, they go into flash by default.)
|
||||
|
||||
Important to note: IROM flash is accessed via 32-bit word aligned
|
||||
reads. esp-open-rtos does some magic to "fix" unaligned reads, but
|
||||
performance is reduced.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define IROM __attribute__((section(".irom0.literal")))
|
||||
|
|
@ -53,30 +109,5 @@
|
|||
#define IROM __attribute__((section(".irom0.literal"))) const
|
||||
#endif
|
||||
|
||||
/* Use this macro to place functions into Instruction RAM (IRAM)
|
||||
instead of flash memory (IROM).
|
||||
|
||||
This is useful for functions which are called when the flash may
|
||||
not be available (for example during NMI exceptions), or for
|
||||
functions which are called very frequently and need high
|
||||
performance.
|
||||
|
||||
Bear in mind IRAM is limited (32KB), compared to up to 1MB of flash.
|
||||
*/
|
||||
#define IRAM __attribute__((section(".iram1.text")))
|
||||
|
||||
/* Use this macro to place read-only data into Instruction RAM (IRAM)
|
||||
instead of loaded into rodata which resides in DRAM.
|
||||
|
||||
This may be useful to free up data RAM. However all data read from
|
||||
the instruction space must be 32-bit aligned word reads
|
||||
(non-aligned reads will use an interrupt routine to "fix" them and
|
||||
still work, but are very slow..
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define IRAM_DATA __attribute__((section(".iram1.rodata")))
|
||||
#else
|
||||
#define IRAM_DATA __attribute__((section(".iram1.rodata"))) const
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -10,9 +10,12 @@
|
|||
#define _DEBUG_DUMPS_H
|
||||
#include <stdint.h>
|
||||
|
||||
/* Dump stack memory starting from stack pointer address sp. */
|
||||
/* Dump stack memory to stdout, starting from stack pointer address sp. */
|
||||
void dump_stack(uint32_t *sp);
|
||||
|
||||
/* Dump heap statistics to stdout */
|
||||
void dump_heapinfo(void);
|
||||
|
||||
/* Called from exception_vectors.S when a fatal exception occurs.
|
||||
|
||||
Probably not useful to be called in other contexts.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
#include "espressif/esp_wifi.h"
|
||||
#include "espressif/spi_flash.h"
|
||||
#include "etstimer.h"
|
||||
#include "espressif/phy_info.h"
|
||||
#include "lwip/netif.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -224,7 +225,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_wDevEnableRx(void);
|
||||
|
|
|
|||
|
|
@ -11,27 +11,12 @@
|
|||
#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))
|
||||
|
||||
// GCC macros for performing associated "*sync" opcodes
|
||||
|
||||
#define ISYNC() asm volatile ( "isync" )
|
||||
#define RSYNC() asm volatile ( "rsync" )
|
||||
#define ESYNC() asm volatile ( "esync" )
|
||||
#define DSYNC() asm volatile ( "dsync" )
|
||||
|
||||
|
||||
/* Read stack pointer to variable.
|
||||
*
|
||||
* Note that the compiler will push a stack frame (minimum 16 bytes)
|
||||
* in the prelude of a C function that calls any other functions.
|
||||
*/
|
||||
#define SP(var) asm volatile ("mov %0, a1" : "=r" (var));
|
||||
#define SP(var) asm volatile ("mov %0, a1" : "=r" (var))
|
||||
|
||||
/* Read the function return address to a variable.
|
||||
*
|
||||
|
|
@ -40,4 +25,17 @@
|
|||
*/
|
||||
#define RETADDR(var) asm volatile ("mov %0, a0" : "=r" (var))
|
||||
|
||||
/* 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));
|
||||
|
||||
// GCC macros for performing associated "*sync" opcodes
|
||||
#define ISYNC() asm volatile ( "isync" )
|
||||
#define RSYNC() asm volatile ( "rsync" )
|
||||
#define ESYNC() asm volatile ( "esync" )
|
||||
#define DSYNC() asm volatile ( "dsync" )
|
||||
|
||||
#endif /* _XTENSA_OPS_H */
|
||||
|
|
|
|||
|
|
@ -9,9 +9,12 @@
|
|||
#include <sys/errno.h>
|
||||
#include <espressif/sdk_private.h>
|
||||
#include <common_macros.h>
|
||||
#include <xtensa_ops.h>
|
||||
#include <esp/uart.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern void *xPortSupervisorStackPointer;
|
||||
|
||||
IRAM caddr_t _sbrk_r (struct _reent *r, int incr)
|
||||
{
|
||||
extern char _heap_start; /* linker script defined */
|
||||
|
|
@ -21,13 +24,17 @@ IRAM caddr_t _sbrk_r (struct _reent *r, int incr)
|
|||
if (heap_end == NULL)
|
||||
heap_end = &_heap_start;
|
||||
prev_heap_end = heap_end;
|
||||
/* TODO: Check stack collision
|
||||
if (heap_end + incr > stack_ptr)
|
||||
{
|
||||
_write (1, "_sbrk: Heap collided with stack\n", 32);
|
||||
abort();
|
||||
}
|
||||
*/
|
||||
|
||||
intptr_t sp = (intptr_t)xPortSupervisorStackPointer;
|
||||
if(sp == 0) /* scheduler not started */
|
||||
SP(sp);
|
||||
|
||||
if ((intptr_t)heap_end + incr >= sp)
|
||||
{
|
||||
r->_errno = ENOMEM;
|
||||
return (caddr_t)-1;
|
||||
}
|
||||
|
||||
heap_end += incr;
|
||||
|
||||
return (caddr_t) prev_heap_end;
|
||||
|
|
|
|||
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");
|
||||
}
|
||||
}
|
||||
74
core/spiflash-cache-enable.S
Normal file
74
core/spiflash-cache-enable.S
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/* OTA-compatible Cache_Read_Enable function
|
||||
*
|
||||
* This gets called from the SDK when it wants to enable the flash mapping.
|
||||
*
|
||||
* In recent SDK versions it's been replaced with a Cache_Read_Enable_New
|
||||
* function that takes note of OTA stuff.
|
||||
*
|
||||
* For esp-open-rtos we just replace the ROM function with this wrapper.
|
||||
*
|
||||
*
|
||||
* Part of esp-open-rtos
|
||||
* Copyright (C) 2015 Superhouse Automation Pty Ltd
|
||||
* BSD Licensed as described in the file LICENSE
|
||||
*/
|
||||
#define RBOOT_CONFIG_BASE (0x40200000 + 0x1000)
|
||||
#define RBOOT_ROMS_OFFS 0x8 /* offset of rboot_config_t.roms array in config */
|
||||
|
||||
#define RBOOT_MEGABYTE_DEFAULT 0x80
|
||||
|
||||
.section .data
|
||||
.global rboot_megabyte
|
||||
rboot_megabyte:
|
||||
.byte RBOOT_MEGABYTE_DEFAULT
|
||||
|
||||
.section .data
|
||||
.local cache_return_save
|
||||
.align 4
|
||||
cache_return_save:
|
||||
.word 0
|
||||
|
||||
.text
|
||||
.section .iram1.text, "x"
|
||||
.literal_position
|
||||
.align 4
|
||||
.global Cache_Read_Enable
|
||||
.type Cache_Read_Enable, @function /* it's not really a function, but treat it like one */
|
||||
Cache_Read_Enable:
|
||||
movi a2, cache_return_save
|
||||
s32i a0, a2, 0 /* save a0 here */
|
||||
movi a2, rboot_megabyte
|
||||
l8ui a2, a2, 0
|
||||
bnei a2, RBOOT_MEGABYTE_DEFAULT, .Lalready_initialised
|
||||
|
||||
/* map the first megabyte of flash */
|
||||
movi a2, 0
|
||||
movi a3, 0
|
||||
movi a4, 1
|
||||
call0 rom_Cache_Read_Enable
|
||||
|
||||
movi a3, RBOOT_CONFIG_BASE
|
||||
l32i a2, a3, 0 /* 32-bit flash read */
|
||||
extui a2, a2, 24, 8 /* 3rd byte is 'current' field of config */
|
||||
slli a2, a2, 2 /* Left shift by two, becomes offset into rom array */
|
||||
add a4, a2, a3 /* Add the base config address */
|
||||
l32i a4, a4, RBOOT_ROMS_OFFS /* Read from the ROM array */
|
||||
extui a4, a4, 20, 8 /* now a4 is number of megabytes */
|
||||
|
||||
/* save to rboot_megabyte */
|
||||
movi a3, rboot_megabyte
|
||||
s8i a4, a3, 0
|
||||
|
||||
/* re-disable cache? */
|
||||
call0 Cache_Read_Disable
|
||||
|
||||
.Lalready_initialised:
|
||||
movi a4, rboot_megabyte
|
||||
l32i a4, a4, 0
|
||||
extui a2, a4, 0, 1 /* a2 is now lsb of a4 (odd/even) */
|
||||
srli a3, a4, 1 /* a3 is half value of mb */
|
||||
movi a4, 1
|
||||
call0 rom_Cache_Read_Enable
|
||||
movi a0, cache_return_save /* restore a0 return address */
|
||||
l32i a0, a0, 0
|
||||
ret.n
|
||||
Loading…
Add table
Add a link
Reference in a new issue