mirror of
https://github.com/esphome/esphome.git
synced 2024-11-17 10:55:36 +01:00
add deep sleep
This commit is contained in:
parent
793e90a0e0
commit
c5b70bad84
@ -438,6 +438,7 @@ void DebugComponent::dump_config() {
|
||||
|
||||
void DebugComponent::loop() {
|
||||
//TODO move to logger
|
||||
//TOOD do not print when exit from deep sleep
|
||||
static bool d = false;
|
||||
if (d != Serial){
|
||||
if(false == d){
|
||||
|
@ -16,6 +16,7 @@ from esphome.const import (
|
||||
CONF_WAKEUP_PIN,
|
||||
PLATFORM_ESP32,
|
||||
PLATFORM_ESP8266,
|
||||
PLATFORM_NRF52,
|
||||
)
|
||||
|
||||
from esphome.components.esp32 import get_esp32_variant
|
||||
@ -198,7 +199,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.Optional(CONF_TOUCH_WAKEUP): cv.All(cv.only_on_esp32, cv.boolean),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA),
|
||||
cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266]),
|
||||
cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_NRF52]),
|
||||
)
|
||||
|
||||
|
||||
|
54
esphome/components/deep_sleep/deep_sleep_backend_nrf52.cpp
Normal file
54
esphome/components/deep_sleep/deep_sleep_backend_nrf52.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#ifdef USE_NRF52
|
||||
#include "deep_sleep_backend_nrf52.h"
|
||||
#include "nrf_power.h"
|
||||
#include <cassert>
|
||||
#include "Adafruit_TinyUSB.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace deep_sleep {
|
||||
|
||||
#define DFU_MAGIC_SKIP 0x6d
|
||||
|
||||
static const char *const TAG = "deep_sleep.nrf52";
|
||||
|
||||
void Nrf52DeepSleepBackend::begin_sleep(const optional<uint64_t>& sleep_duration) {
|
||||
// RTC works only during System On
|
||||
if (sleep_duration.has_value())
|
||||
{
|
||||
// TinyUSBDevice.detach();
|
||||
// TODO deinit USB
|
||||
// TOOD and the rest of peripherals
|
||||
uint32_t start_time = millis();
|
||||
portSUPPRESS_TICKS_AND_SLEEP(ms2tick(*sleep_duration/1000));
|
||||
last_sleep_duration_ = millis() - start_time;
|
||||
// TinyUSBDevice.attach();
|
||||
} else {
|
||||
NRF_POWER->GPREGRET = DFU_MAGIC_SKIP;
|
||||
// Enter System OFF.
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
uint8_t sd_en = 0;
|
||||
(void) sd_softdevice_is_enabled(&sd_en);
|
||||
if (sd_en)
|
||||
{
|
||||
uint32_t ret_code = sd_power_system_off();
|
||||
assert((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED));
|
||||
}
|
||||
#endif // SOFTDEVICE_PRESENT
|
||||
nrf_power_system_off(NRF_POWER);
|
||||
// it should never reach here...
|
||||
}
|
||||
}
|
||||
|
||||
void Nrf52DeepSleepBackend::dump_config() {
|
||||
if (last_sleep_duration_.has_value()) {
|
||||
ESP_LOGD(TAG, "Last sleep duration: %lu ms", *last_sleep_duration_ );
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Last sleep duration: unknown");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace deep_sleep
|
||||
} // namespace esphome
|
||||
|
||||
#endif
|
21
esphome/components/deep_sleep/deep_sleep_backend_nrf52.h
Normal file
21
esphome/components/deep_sleep/deep_sleep_backend_nrf52.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#ifdef USE_NRF52
|
||||
|
||||
#include "esphome/core/optional.h"
|
||||
#include "Arduino.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace deep_sleep {
|
||||
|
||||
class Nrf52DeepSleepBackend {
|
||||
public:
|
||||
void begin_sleep(const optional<uint64_t>& sleep_duration);
|
||||
void dump_config();
|
||||
protected:
|
||||
optional<uint32_t> last_sleep_duration_;
|
||||
};
|
||||
|
||||
} // namespace deep_sleep
|
||||
} // namespace esphome
|
||||
|
||||
#endif
|
@ -7,6 +7,10 @@
|
||||
#include <Esp.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_NRF52
|
||||
#include "deep_sleep_backend_nrf52.h"
|
||||
#endif
|
||||
|
||||
namespace esphome {
|
||||
namespace deep_sleep {
|
||||
|
||||
@ -33,10 +37,9 @@ optional<uint32_t> DeepSleepComponent::get_run_duration_() const {
|
||||
return this->run_duration_;
|
||||
}
|
||||
|
||||
void DeepSleepComponent::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up Deep Sleep...");
|
||||
global_has_deep_sleep = true;
|
||||
|
||||
void DeepSleepComponent::setup_deep_sleep_()
|
||||
{
|
||||
this->next_enter_deep_sleep_ = false;
|
||||
const optional<uint32_t> run_duration = get_run_duration_();
|
||||
if (run_duration.has_value()) {
|
||||
ESP_LOGI(TAG, "Scheduling Deep Sleep to start in %" PRIu32 " ms", *run_duration);
|
||||
@ -45,6 +48,14 @@ void DeepSleepComponent::setup() {
|
||||
ESP_LOGD(TAG, "Not scheduling Deep Sleep, as no run duration is configured.");
|
||||
}
|
||||
}
|
||||
|
||||
void DeepSleepComponent::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up Deep Sleep...");
|
||||
global_has_deep_sleep = true;
|
||||
|
||||
setup_deep_sleep_();
|
||||
}
|
||||
|
||||
void DeepSleepComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up Deep Sleep...");
|
||||
if (this->sleep_duration_.has_value()) {
|
||||
@ -65,6 +76,9 @@ void DeepSleepComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, " GPIO Wakeup Run Duration: %" PRIu32 " ms", this->wakeup_cause_to_run_duration_->gpio_cause);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_NRF52
|
||||
backend_.dump_config();
|
||||
#endif
|
||||
}
|
||||
void DeepSleepComponent::loop() {
|
||||
if (this->next_enter_deep_sleep_)
|
||||
@ -139,7 +153,7 @@ void DeepSleepComponent::begin_sleep(bool manual) {
|
||||
esp_sleep_enable_touchpad_wakeup();
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
}
|
||||
#endif
|
||||
#endif // USE_ESP32_VARIANT_ESP32C3
|
||||
#ifdef USE_ESP32_VARIANT_ESP32C3
|
||||
if (this->sleep_duration_.has_value())
|
||||
esp_sleep_enable_timer_wakeup(*this->sleep_duration_);
|
||||
@ -151,13 +165,17 @@ void DeepSleepComponent::begin_sleep(bool manual) {
|
||||
esp_deep_sleep_enable_gpio_wakeup(1 << this->wakeup_pin_->get_pin(),
|
||||
static_cast<esp_deepsleep_gpio_wake_up_mode_t>(level));
|
||||
}
|
||||
#endif
|
||||
#endif // USE_ESP32_VARIANT_ESP32C3
|
||||
esp_deep_sleep_start();
|
||||
#endif
|
||||
#endif // USE_ESP32
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
ESP.deepSleep(*this->sleep_duration_); // NOLINT(readability-static-accessed-through-instance)
|
||||
#endif
|
||||
#ifdef USE_NRF52
|
||||
backend_.begin_sleep(this->sleep_duration_);
|
||||
setup_deep_sleep_();
|
||||
#endif
|
||||
}
|
||||
float DeepSleepComponent::get_setup_priority() const { return setup_priority::LATE; }
|
||||
void DeepSleepComponent::prevent_deep_sleep() { this->prevent_ = true; }
|
||||
|
@ -14,6 +14,10 @@
|
||||
#include "esphome/core/time.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_NRF52
|
||||
#include "deep_sleep_backend_nrf52.h"
|
||||
#endif
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
namespace esphome {
|
||||
@ -106,6 +110,8 @@ class DeepSleepComponent : public Component {
|
||||
// duration before entering deep sleep.
|
||||
optional<uint32_t> get_run_duration_() const;
|
||||
|
||||
void setup_deep_sleep_();
|
||||
|
||||
optional<uint64_t> sleep_duration_;
|
||||
#ifdef USE_ESP32
|
||||
InternalGPIOPin *wakeup_pin_;
|
||||
@ -117,6 +123,9 @@ class DeepSleepComponent : public Component {
|
||||
optional<uint32_t> run_duration_;
|
||||
bool next_enter_deep_sleep_{false};
|
||||
bool prevent_{false};
|
||||
#ifdef USE_NRF52
|
||||
Nrf52DeepSleepBackend backend_;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern bool global_has_deep_sleep; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import os
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
@ -13,6 +14,8 @@ from esphome.core import CORE, coroutine_with_priority
|
||||
# force import gpio to register pin schema
|
||||
from .gpio import nrf52_pin_to_code # noqa
|
||||
|
||||
AUTO_LOAD = ["nrf52_nrfx"]
|
||||
|
||||
|
||||
def set_core_data(config):
|
||||
CORE.data[KEY_CORE][KEY_TARGET_PLATFORM] = PLATFORM_NRF52
|
||||
@ -84,6 +87,12 @@ async def to_code(config):
|
||||
cg.add_platformio_option("board_upload.use_1200bps_touch", "true")
|
||||
cg.add_platformio_option("board_upload.require_upload_port", "true")
|
||||
cg.add_platformio_option("board_upload.wait_for_upload_port", "true")
|
||||
# watchdog
|
||||
cg.add_build_flag("-DNRFX_WDT_ENABLED=1")
|
||||
cg.add_build_flag("-DNRFX_WDT0_ENABLED=1")
|
||||
cg.add_build_flag("-DNRFX_WDT_CONFIG_NO_IRQ=1")
|
||||
# prevent setting up GPIO PINs
|
||||
cg.add_platformio_option("board_build.variant", "nrf52840")
|
||||
cg.add_platformio_option(
|
||||
"board_build.variants_dir", os.path.dirname(os.path.realpath(__file__))
|
||||
)
|
||||
|
@ -16,6 +16,7 @@ struct nrf5x_wdt_obj
|
||||
nrfx_wdt_t wdt;
|
||||
nrfx_wdt_channel_id ch;
|
||||
};
|
||||
//TODO what value for watchdog?
|
||||
static nrfx_wdt_config_t nrf5x_wdt_cfg = NRFX_WDT_DEFAULT_CONFIG;
|
||||
|
||||
static struct nrf5x_wdt_obj nrf5x_wdt = {
|
||||
@ -24,6 +25,7 @@ static struct nrf5x_wdt_obj nrf5x_wdt = {
|
||||
|
||||
void arch_init() {
|
||||
//Configure WDT.
|
||||
nrf5x_wdt_cfg.behaviour = NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT;
|
||||
nrfx_wdt_init(&nrf5x_wdt.wdt, &nrf5x_wdt_cfg, nullptr);
|
||||
nrfx_wdt_channel_alloc(&nrf5x_wdt.wdt, &nrf5x_wdt.ch);
|
||||
nrfx_wdt_enable(&nrf5x_wdt.wdt);
|
||||
@ -42,7 +44,9 @@ void arch_feed_wdt() {
|
||||
nrfx_wdt_feed(&nrf5x_wdt.wdt);
|
||||
}
|
||||
|
||||
void arch_restart() { /* TODO */ }
|
||||
void arch_restart() {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
void nrf52GetMacAddr(uint8_t *mac)
|
||||
{
|
||||
|
15
esphome/components/nrf52/nrf52840/variant.cpp
Normal file
15
esphome/components/nrf52/nrf52840/variant.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "variant.h"
|
||||
|
||||
const uint32_t g_ADigitalPinMap[] =
|
||||
{
|
||||
// P0
|
||||
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ,
|
||||
8 , 9 , 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31,
|
||||
|
||||
// P1
|
||||
32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47
|
||||
};
|
||||
|
16
esphome/components/nrf52/nrf52840/variant.h
Normal file
16
esphome/components/nrf52/nrf52840/variant.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "WVariant.h"
|
||||
|
||||
#define PINS_COUNT (48)
|
||||
#define LED_BUILTIN (64)
|
||||
#if PINS_COUNT > LED_BUILTIN
|
||||
#error LED_BUILTIN should be bigger than PINS_COUNT. To ignore settings.
|
||||
#endif
|
||||
#define LED_BLUE (LED_BUILTIN)
|
||||
// TODO other are also needed?
|
||||
#define USE_LFXO // Board uses 32khz crystal for LF
|
||||
#define LED_STATE_ON (1)
|
||||
#define PIN_SERIAL1_RX (33) // P1.01
|
||||
#define PIN_SERIAL1_TX (34) // P1.02
|
||||
|
Loading…
Reference in New Issue
Block a user