//Flush and enable icache for APP CPU
Cache_Flush(1);
Cache_Read_Enable(1);
- //Un-stall the app cpu; the panic handler may have stalled it.
- CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_APPCPU_C1_M);
- CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_APPCPU_C0_M);
+ esp_cpu_unstall(1);
//Enable clock gating and reset the app cpu.
SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN);
CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_C_REG, DPORT_APPCPU_RUNSTALL);
--- /dev/null
+// Copyright 2013-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "esp_attr.h"
+#include "soc/cpu.h"
+#include "soc/soc.h"
+#include "soc/rtc_cntl_reg.h"
+
+void IRAM_ATTR esp_cpu_stall(int cpu_id)
+{
+ if (cpu_id == 1) {
+ CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_APPCPU_C1_M);
+ SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21<<RTC_CNTL_SW_STALL_APPCPU_C1_S);
+ CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_APPCPU_C0_M);
+ SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2<<RTC_CNTL_SW_STALL_APPCPU_C0_S);
+ } else {
+ CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_PROCPU_C1_M);
+ SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21<<RTC_CNTL_SW_STALL_PROCPU_C1_S);
+ CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_PROCPU_C0_M);
+ SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2<<RTC_CNTL_SW_STALL_PROCPU_C0_S);
+ }
+}
+
+void IRAM_ATTR esp_cpu_unstall(int cpu_id)
+{
+ if (cpu_id == 1) {
+ CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_APPCPU_C1_M);
+ CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_APPCPU_C0_M);
+ } else {
+ CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_PROCPU_C1_M);
+ CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_PROCPU_C0_M);
+ }
+}
extern "C" {
#endif
-/** \defgroup System_APIs System APIs
- * @brief System APIs
- */
-
-/** @addtogroup System_APIs
- * @{
- */
-
/**
* @attention application don't need to call this function anymore. It do nothing and will
* be removed in future version.
*/
void system_init(void) __attribute__ ((deprecated));
-
/**
- * @brief Get information of the SDK version.
- *
- * @param null
+ * @brief Reset to default settings.
*
- * @return Information of the SDK version.
+ * Function has been deprecated, please use esp_wifi_restore instead.
+ * This name will be removed in a future release.
*/
-const char *system_get_sdk_version(void);
+void system_restore(void) __attribute__ ((deprecated));
/**
- * @brief Reset to default settings.
- *
- * Reset to default settings of the following APIs : wifi_station_set_auto_connect,
- * wifi_set_phy_mode, wifi_softap_set_config related, wifi_station_set_config
- * related, and wifi_set_opmode.
+ * @brief Restart PRO and APP CPUs.
*
- * @param null
- *
- * @return null
+ * This function can be called both from PRO and APP CPUs.
+ * After successful restart, CPU reset reason will be SW_CPU_RESET.
+ * Peripherals (except for WiFi, BT, UART0, SPI1, and legacy timers) are not reset.
+ * This function does not return.
*/
-void system_restore(void);
+void esp_restart(void) __attribute__ ((noreturn));
/**
* @brief Restart system.
*
- * @param null
- *
- * @return null
+ * Function has been renamed to esp_restart.
+ * This name will be removed in a future release.
*/
-void system_restart(void);
+void system_restart(void) __attribute((deprecated, noreturn));
/**
* @brief Get system time, unit: microsecond.
*
- * @param null
- *
- * @return System time, unit: microsecond.
+ * This function is deprecated. Use 'gettimeofday' function for 64-bit precision.
+ * This definition will be removed in a future release.
*/
-uint32_t system_get_time(void);
+uint32_t system_get_time(void) __attribute__ ((deprecated));
/**
* @brief Get the size of available heap.
*
- * @param null
+ * Note that the returned value may be larger than the maximum contiguous block
+ * which can be allocated.
*
- * @return Available heap size.
+ * @return Available heap size, in bytes.
*/
-uint32_t system_get_free_heap_size(void);
+uint32_t esp_get_free_heap_size(void);
-/**
- * @brief Get RTC time, unit: RTC clock cycle.
- *
- * @param null
- *
- * @return RTC time.
- */
-uint64_t system_get_rtc_time(void);
/**
- * @brief Read user data from the RTC memory.
- *
- * The user data segment (1024 bytes, as shown below) is used to store user data.
- *
- * |<---- system data(512 bytes) ---->|<----------- user data(1024 bytes) --------->|
- *
- * @attention Read and write unit for data stored in the RTC memory is 4 bytes.
- * @attention src_addr is the block number (4 bytes per block). So when reading data
- * at the beginning of the user data segment, src_addr will be 512/4 = 128,
- * n will be data length.
+ * @brief Get the size of available heap.
*
- * @param uint16 src : source address of rtc memory, src_addr >= 128
- * @param void *dst : data pointer
- * @param uint16 n : data length, unit: byte
+ * Function has been renamed to esp_get_free_heap_size.
+ * This name will be removed in a future release.
*
- * @return true : succeed
- * @return false : fail
+ * @return Available heap size, in bytes.
*/
-bool system_rtc_mem_read(uint16_t src, void *dst, uint16_t n);
+uint32_t system_get_free_heap_size(void) __attribute__ ((deprecated));
/**
- * @brief Write user data to the RTC memory.
- *
- * During deep-sleep, only RTC is working. So users can store their data
- * in RTC memory if it is needed. The user data segment below (1024 bytes)
- * is used to store the user data.
- *
- * |<---- system data(512 bytes) ---->|<----------- user data(1024 bytes) --------->|
- *
- * @attention Read and write unit for data stored in the RTC memory is 4 bytes.
- * @attention src_addr is the block number (4 bytes per block). So when storing data
- * at the beginning of the user data segment, src_addr will be 512/4 = 128,
- * n will be data length.
- *
- * @param uint16 src : source address of rtc memory, src_addr >= 128
- * @param void *dst : data pointer
- * @param uint16 n : data length, unit: byte
- *
- * @return true : succeed
- * @return false : fail
- */
-bool system_rtc_mem_write(uint16_t dst, const void *src, uint16_t n);
-
-/** \defgroup System_boot_APIs Boot APIs
- * @brief boot APIs
- */
-
-/** @addtogroup System_boot_APIs
- * @{
- */
+ * @brief Get one random 32-bit word from hardware RNG
+ *
+ * @return random value between 0 and UINT32_MAX
+ */
+uint32_t esp_random(void);
/**
- * @}
- */
-
-/** \defgroup Hardware_MAC_APIs Hardware MAC APIs
- * @brief Hardware MAC address APIs
+ * @brief Read hardware MAC address.
*
* In WiFi MAC, only ESP32 station MAC is the hardware MAC, ESP32 softAP MAC is a software MAC
* calculated from ESP32 station MAC.
- * So users need to call wifi_get_macaddr to query the ESP32 softAP MAC if ESP32 station MAC changed.
+ * So users need to call esp_wifi_get_macaddr to query the ESP32 softAP MAC if ESP32 station MAC changed.
*
+ * @param mac hardware MAC address, length: 6 bytes.
+ *
+ * @return ESP_OK on success
*/
-
-/** @addtogroup Hardware_MAC_APIs
- * @{
- */
+esp_err_t esp_efuse_read_mac(uint8_t mac[6]);
/**
* @brief Read hardware MAC address.
*
- * @param uint8 mac[6] : the hardware MAC address, length: 6 bytes.
+ * Function has been renamed to esp_efuse_read_mac.
+ * This name will be removed in a future release.
*
- * @return esp_err_t
- */
-esp_err_t system_efuse_read_mac(uint8_t mac[6]);
-
-
-/**
- * @}
+ * @param mac hardware MAC address, length: 6 bytes.
+ * @return ESP_OK on success
*/
+esp_err_t system_efuse_read_mac(uint8_t mac[6]) __attribute__ ((deprecated));
-/**
- * @}
- */
-
#ifdef __cplusplus
}
#endif
*/
esp_err_t esp_wifi_stop(void);
+/**
+ * @brief Restore WiFi stack persistent settings to default values
+ *
+ * This function will reset settings made using the following APIs:
+ * - esp_wifi_get_auto_connect,
+ * - esp_wifi_set_protocol,
+ * - esp_wifi_set_config related
+ * - esp_wifi_set_mode
+ *
+ * @return
+ * - ESP_OK: succeed
+ * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by eps_wifi_init
+ */
+esp_err_t esp_wifi_restore(void);
+
/**
* @brief Connect the ESP32 WiFi station to the AP.
*
/**
* @brief get whether the wifi driver is allowed to transmit data or not
*
- * @param none
- *
- * @return true : upper layer should stop to transmit data to wifi driver
- * @return false : upper layer can transmit data to wifi driver
+ * @return
+ * - true : upper layer should stop to transmit data to wifi driver
+ * - false : upper layer can transmit data to wifi driver
*/
bool esp_wifi_internal_tx_is_stop(void);
* @brief free the rx buffer which allocated by wifi driver
*
* @param void* buffer: rx buffer pointer
- *
- * @return nonoe
*/
void esp_wifi_internal_free_rx_buffer(void* buffer);
* @brief The WiFi RX callback function
*
* Each time the WiFi need to forward the packets to high layer, the callback function will be called
- *
*/
typedef esp_err_t (*wifi_rxcb_t)(void *buffer, uint16_t len, void *eb);
* @param wifi_interface_t ifx : interface
* @param wifi_rxcb_t fn : WiFi RX callback
*
- * @return ESP_OK : succeed
- * @return others : fail
+ * @return
+ * - ESP_OK : succeed
+ * - others : fail
*/
esp_err_t esp_wifi_internal_reg_rxcb(wifi_interface_t ifx, wifi_rxcb_t fn);
/**
* @brief Notify WIFI driver that the station got ip successfully
*
- * @param none
- *
- * @return ESP_OK : succeed
- * @return others : fail
+ * @return
+ * - ESP_OK : succeed
+ * - others : fail
*/
esp_err_t esp_wifi_internal_set_sta_ip(void);
asm volatile ("witlb %1, %0; isync\n" :: "r" (vpn), "r" (attr));
}
-/* Make page 0 access raise an exception.
+/**
+ * @brief Configure memory region protection
+ *
+ * Make page 0 access raise an exception.
* Also protect some other unused pages so we can catch weirdness.
* Useful attribute values:
* 0 — cached, RW
cpu_write_itlb(0x20000000, 0);
}
-
-
-/*
+/**
* @brief Set CPU frequency to the value defined in menuconfig
*
* Called from cpu_start.c, not intended to be called from other places.
*/
void esp_set_cpu_freq(void);
+/**
+ * @brief Stall CPU using RTC controller
+ * @param cpu_id ID of the CPU to stall (0 = PRO, 1 = APP)
+ */
+void esp_cpu_stall(int cpu_id);
+
+/**
+ * @brief Un-stall CPU using RTC controller
+ * @param cpu_id ID of the CPU to un-stall (0 = PRO, 1 = APP)
+ */
+void esp_cpu_unstall(int cpu_id);
+
#endif
#include "soc/rtc_cntl_reg.h"
#include "soc/timer_group_struct.h"
#include "soc/timer_group_reg.h"
+#include "soc/cpu.h"
#include "esp_gdbstub.h"
#include "esp_panic.h"
void commonErrorHandler(XtExcFrame *frame);
//The fact that we've panic'ed probably means the other CPU is now running wild, possibly
-//messing up the serial output, so we kill it here.
-static void haltOtherCore() {
- if (xPortGetCoreID()==0) {
- //Kill app cpu
- CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_APPCPU_C1_M);
- SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21<<RTC_CNTL_SW_STALL_APPCPU_C1_S);
- CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_APPCPU_C0_M);
- SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2<<RTC_CNTL_SW_STALL_APPCPU_C0_S);
- } else {
- //Kill pro cpu
- CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_PROCPU_C1_M);
- SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21<<RTC_CNTL_SW_STALL_PROCPU_C1_S);
- CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_PROCPU_C0_M);
- SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2<<RTC_CNTL_SW_STALL_PROCPU_C0_S);
- }
+//messing up the serial output, so we stall it here.
+static void haltOtherCore()
+{
+ esp_cpu_stall( xPortGetCoreID() == 0 ? 1 : 0 );
}
//Returns true when a debugger is attached using JTAG.
--- /dev/null
+// Copyright 2013-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "esp_system.h"
+#include "esp_attr.h"
+#include "esp_wifi.h"
+#include "esp_wifi_internal.h"
+#include "esp_log.h"
+#include "rom/efuse.h"
+#include "rom/cache.h"
+#include "rom/uart.h"
+#include "soc/dport_reg.h"
+#include "soc/efuse_reg.h"
+#include "soc/rtc_cntl_reg.h"
+#include "soc/timer_group_reg.h"
+#include "soc/timer_group_struct.h"
+#include "soc/cpu.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/xtensa_api.h"
+
+static const char* TAG = "system_api";
+
+esp_err_t system_efuse_read_mac(uint8_t mac[6])
+{
+ uint8_t efuse_crc;
+ uint8_t calc_crc;
+ uint32_t mac_low = REG_READ(EFUSE_BLK0_RDATA1_REG);
+ uint32_t mac_high = REG_READ(EFUSE_BLK0_RDATA2_REG);
+
+ mac[0] = mac_high >> 8;
+ mac[1] = mac_high;
+ mac[2] = mac_low >> 24;
+ mac[3] = mac_low >> 16;
+ mac[4] = mac_low >> 8;
+ mac[5] = mac_low;
+
+ efuse_crc = mac_high >> 16;
+ calc_crc = esp_crc8(mac, 6);
+
+ if (efuse_crc != calc_crc) {
+ // Small range of MAC addresses are accepted even if CRC is invalid.
+ // These addresses are reserved for Espressif internal use.
+ if ((mac_high & 0xFFFF) == 0x18fe) {
+ if ((mac_low >= 0x346a85c7) && (mac_low <= 0x346a85f8)) {
+ return ESP_OK;
+ }
+ } else {
+ ESP_LOGE(TAG, "MAC address CRC error, efuse_crc = 0x%02x; calc_crc = 0x%02x", efuse_crc, calc_crc);
+ abort();
+ }
+ }
+ return ESP_OK;
+}
+
+
+void IRAM_ATTR system_restart(void)
+{
+ esp_wifi_stop();
+
+ // Disable scheduler on this core.
+ vTaskSuspendAll();
+ const uint32_t core_id = xPortGetCoreID();
+ const uint32_t other_core_id = core_id == 0 ? 1 : 0;
+ esp_cpu_stall(other_core_id);
+
+ // We need to disable TG0/TG1 watchdogs
+ // First enable RTC watchdog to be on the safe side
+ REG_WRITE(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
+ REG_WRITE(RTC_CNTL_WDTCONFIG0_REG,
+ RTC_CNTL_WDT_FLASHBOOT_MOD_EN_M |
+ (1 << RTC_CNTL_WDT_SYS_RESET_LENGTH_S) |
+ (1 << RTC_CNTL_WDT_CPU_RESET_LENGTH_S) );
+ REG_WRITE(RTC_CNTL_WDTCONFIG1_REG, 128000);
+
+ // Disable TG0/TG1 watchdogs
+ TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
+ TIMERG0.wdt_config0.en = 0;
+ TIMERG0.wdt_wprotect=0;
+ TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
+ TIMERG1.wdt_config0.en = 0;
+ TIMERG1.wdt_wprotect=0;
+
+ // Disable all interrupts
+ xt_ints_off(0xFFFFFFFF);
+
+ // Disable cache
+ Cache_Read_Disable(0);
+ Cache_Read_Disable(1);
+
+ // Flush any data left in UART FIFO
+ uart_tx_flush(0);
+ uart_tx_flush(1);
+ uart_tx_flush(2);
+
+ // Reset wifi/bluetooth (bb/mac)
+ SET_PERI_REG_MASK(DPORT_WIFI_RST_EN_REG, 0x1f);
+ REG_WRITE(DPORT_WIFI_RST_EN_REG, 0);
+
+ // Reset timer/spi/uart
+ SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,
+ DPORT_TIMERS_RST | DPORT_SPI_RST_1 | DPORT_UART_RST);
+ REG_WRITE(DPORT_PERIP_RST_EN_REG, 0);
+
+ // Reset CPUs
+ if (core_id == 0) {
+ // Running on PRO CPU: APP CPU is stalled. Can reset both CPUs.
+ SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG,
+ RTC_CNTL_SW_PROCPU_RST_M | RTC_CNTL_SW_APPCPU_RST_M);
+ } else {
+ // Running on APP CPU: need to reset PRO CPU and unstall it,
+ // then stall APP CPU
+ SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_PROCPU_RST_M);
+ esp_cpu_unstall(0);
+ esp_cpu_stall(1);
+ }
+ while(true) {
+ ;
+ }
+}
+
+void system_restore(void)
+{
+ esp_wifi_restore();
+}
+
+#if 0
+void system_deep_sleep_instant(uint64_t time_in_us)
+{
+ u32 period, cycle_h, cycle_l;
+
+ {
+ struct rst_info debug_data;
+ memset(&debug_data, 0, sizeof(struct rst_info));
+
+ WRITE_PERI_REG(RTC_STORE0, DEEP_SLEEP_AWAKE_FLAG);
+ debug_data.flag = DEEP_SLEEP_AWAKE_FLAG;
+
+ system_write_rtc_mem(0, &debug_data, sizeof(struct rst_info));
+ }
+
+ rtc_set_cpu_freq(XTAL_AUTO, CPU_XTAL);
+ esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep);
+
+ period = rtc_slowck_cali(CALI_RTC_MUX, 128, XTAL_AUTO);
+ rtc_usec2rtc(time_in_us >> 32, time_in_us, period, &cycle_h, &cycle_l);
+
+ rtc_slp_prep_lite(1, 0);
+ rtc_sleep(cycle_h, cycle_l, TIMER_EXPIRE_EN, 0);
+}
+
+static uint64_t deep_sleep_time;
+
+static void system_deep_sleep_step2(void)
+{
+ system_deep_sleep_instant(deep_sleep_time);
+}
+
+void system_deep_sleep(uint64 time_in_us)
+{
+ wifi_set_sleep_flag(1);
+
+ deep_sleep_time = time_in_us;
+
+ os_timer_disarm(&sta_con_timer);
+ os_timer_setfn(&sta_con_timer, (os_timer_func_t *)system_deep_sleep_step2, NULL);
+ os_timer_arm(&sta_con_timer, 100, 0);
+}
+
+#endif
+
+uint32_t system_get_free_heap_size(void)
+{
+ return xPortGetFreeHeapSize();
+}
+
+
+struct rst_info *system_get_rst_info(void)
+{
+ return NULL;
+}
+
+const char* system_get_sdk_version(void)
+{
+ return "master";
+}
+
+
return -1;
#endif
}
+
+uint32_t system_get_time(void)
+{
+#if defined( WITH_FRC1 ) || defined( WITH_RTC )
+ return get_time_since_boot();
+#else
+ return 0;
+#endif
+}
+
+uint32_t system_get_current_time(void) __attribute__((alias("system_get_time")));
+
+uint32_t system_relative_time(uint32_t current_time)
+{
+ return system_get_time() - current_time;
+}
+
+uint64_t system_get_rtc_time(void)
+{
+#ifdef WITH_RTC
+ return get_rtc_time_us();
+#else
+ return 0;
+#endif
+}
+