mirror of
https://github.com/esphome/esphome.git
synced 2025-11-02 16:11:53 +00:00
Compare commits
22 Commits
2024.12.0b
...
2024.12.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b51ba3fa4 | ||
|
|
499953e3f4 | ||
|
|
69f1a81e1d | ||
|
|
37fcccbb1c | ||
|
|
fe0700166a | ||
|
|
d28cf011d1 | ||
|
|
434879ea04 | ||
|
|
0f0b829bc6 | ||
|
|
d330e73c1e | ||
|
|
561d92d402 | ||
|
|
1a69236473 | ||
|
|
c86ea99145 | ||
|
|
7661609049 | ||
|
|
c38826824f | ||
|
|
e890486043 | ||
|
|
6dcbd1a8ae | ||
|
|
63b0930ae8 | ||
|
|
5382bd2a97 | ||
|
|
de1fbd390b | ||
|
|
af23357dca | ||
|
|
0fbe6c0d8b | ||
|
|
4e1ff31342 |
48
esphome/components/adc/adc_sensor_libretiny.cpp
Normal file
48
esphome/components/adc/adc_sensor_libretiny.cpp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#ifdef USE_LIBRETINY
|
||||||
|
|
||||||
|
#include "adc_sensor.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace adc {
|
||||||
|
|
||||||
|
static const char *const TAG = "adc.libretiny";
|
||||||
|
|
||||||
|
void ADCSensor::setup() {
|
||||||
|
ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str());
|
||||||
|
#ifndef USE_ADC_SENSOR_VCC
|
||||||
|
this->pin_->setup();
|
||||||
|
#endif // !USE_ADC_SENSOR_VCC
|
||||||
|
}
|
||||||
|
|
||||||
|
void ADCSensor::dump_config() {
|
||||||
|
LOG_SENSOR("", "ADC Sensor", this);
|
||||||
|
#ifdef USE_ADC_SENSOR_VCC
|
||||||
|
ESP_LOGCONFIG(TAG, " Pin: VCC");
|
||||||
|
#else // USE_ADC_SENSOR_VCC
|
||||||
|
LOG_PIN(" Pin: ", this->pin_);
|
||||||
|
#endif // USE_ADC_SENSOR_VCC
|
||||||
|
ESP_LOGCONFIG(TAG, " Samples: %i", this->sample_count_);
|
||||||
|
LOG_UPDATE_INTERVAL(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
float ADCSensor::sample() {
|
||||||
|
uint32_t raw = 0;
|
||||||
|
if (this->output_raw_) {
|
||||||
|
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
||||||
|
raw += analogRead(this->pin_->get_pin()); // NOLINT
|
||||||
|
}
|
||||||
|
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
||||||
|
raw += analogReadVoltage(this->pin_->get_pin()); // NOLINT
|
||||||
|
}
|
||||||
|
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
|
||||||
|
return raw / 1000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace adc
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif // USE_LIBRETINY
|
||||||
@@ -602,6 +602,9 @@ async def to_code(config):
|
|||||||
cg.add_platformio_option(
|
cg.add_platformio_option(
|
||||||
"platform_packages", ["espressif/toolchain-esp32ulp@2.35.0-20220830"]
|
"platform_packages", ["espressif/toolchain-esp32ulp@2.35.0-20220830"]
|
||||||
)
|
)
|
||||||
|
add_idf_sdkconfig_option(
|
||||||
|
f"CONFIG_ESPTOOLPY_FLASHSIZE_{config[CONF_FLASH_SIZE]}", True
|
||||||
|
)
|
||||||
add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_SINGLE_APP", False)
|
add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_SINGLE_APP", False)
|
||||||
add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_CUSTOM", True)
|
add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_CUSTOM", True)
|
||||||
add_idf_sdkconfig_option(
|
add_idf_sdkconfig_option(
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ namespace esp32_ble {
|
|||||||
|
|
||||||
static const char *const TAG = "esp32_ble";
|
static const char *const TAG = "esp32_ble";
|
||||||
|
|
||||||
|
static RAMAllocator<BLEEvent> EVENT_ALLOCATOR( // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
|
RAMAllocator<BLEEvent>::ALLOW_FAILURE | RAMAllocator<BLEEvent>::ALLOC_INTERNAL);
|
||||||
|
|
||||||
void ESP32BLE::setup() {
|
void ESP32BLE::setup() {
|
||||||
global_ble = this;
|
global_ble = this;
|
||||||
ESP_LOGCONFIG(TAG, "Setting up BLE...");
|
ESP_LOGCONFIG(TAG, "Setting up BLE...");
|
||||||
@@ -322,7 +325,8 @@ void ESP32BLE::loop() {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
delete ble_event; // NOLINT(cppcoreguidelines-owning-memory)
|
ble_event->~BLEEvent();
|
||||||
|
EVENT_ALLOCATOR.deallocate(ble_event, 1);
|
||||||
ble_event = this->ble_events_.pop();
|
ble_event = this->ble_events_.pop();
|
||||||
}
|
}
|
||||||
if (this->advertising_ != nullptr) {
|
if (this->advertising_ != nullptr) {
|
||||||
@@ -331,9 +335,14 @@ void ESP32BLE::loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ESP32BLE::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
|
void ESP32BLE::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
|
||||||
BLEEvent *new_event = new BLEEvent(event, param); // NOLINT(cppcoreguidelines-owning-memory)
|
BLEEvent *new_event = EVENT_ALLOCATOR.allocate(1);
|
||||||
|
if (new_event == nullptr) {
|
||||||
|
// Memory too fragmented to allocate new event. Can only drop it until memory comes back
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
new (new_event) BLEEvent(event, param);
|
||||||
global_ble->ble_events_.push(new_event);
|
global_ble->ble_events_.push(new_event);
|
||||||
} // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
|
} // NOLINT(clang-analyzer-unix.Malloc)
|
||||||
|
|
||||||
void ESP32BLE::real_gap_event_handler_(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
|
void ESP32BLE::real_gap_event_handler_(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
|
||||||
ESP_LOGV(TAG, "(BLE) gap_event_handler - %d", event);
|
ESP_LOGV(TAG, "(BLE) gap_event_handler - %d", event);
|
||||||
@@ -344,9 +353,14 @@ void ESP32BLE::real_gap_event_handler_(esp_gap_ble_cb_event_t event, esp_ble_gap
|
|||||||
|
|
||||||
void ESP32BLE::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
void ESP32BLE::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
||||||
esp_ble_gatts_cb_param_t *param) {
|
esp_ble_gatts_cb_param_t *param) {
|
||||||
BLEEvent *new_event = new BLEEvent(event, gatts_if, param); // NOLINT(cppcoreguidelines-owning-memory)
|
BLEEvent *new_event = EVENT_ALLOCATOR.allocate(1);
|
||||||
|
if (new_event == nullptr) {
|
||||||
|
// Memory too fragmented to allocate new event. Can only drop it until memory comes back
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
new (new_event) BLEEvent(event, gatts_if, param);
|
||||||
global_ble->ble_events_.push(new_event);
|
global_ble->ble_events_.push(new_event);
|
||||||
} // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
|
} // NOLINT(clang-analyzer-unix.Malloc)
|
||||||
|
|
||||||
void ESP32BLE::real_gatts_event_handler_(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
void ESP32BLE::real_gatts_event_handler_(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
||||||
esp_ble_gatts_cb_param_t *param) {
|
esp_ble_gatts_cb_param_t *param) {
|
||||||
@@ -358,9 +372,14 @@ void ESP32BLE::real_gatts_event_handler_(esp_gatts_cb_event_t event, esp_gatt_if
|
|||||||
|
|
||||||
void ESP32BLE::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
void ESP32BLE::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
||||||
esp_ble_gattc_cb_param_t *param) {
|
esp_ble_gattc_cb_param_t *param) {
|
||||||
BLEEvent *new_event = new BLEEvent(event, gattc_if, param); // NOLINT(cppcoreguidelines-owning-memory)
|
BLEEvent *new_event = EVENT_ALLOCATOR.allocate(1);
|
||||||
|
if (new_event == nullptr) {
|
||||||
|
// Memory too fragmented to allocate new event. Can only drop it until memory comes back
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
new (new_event) BLEEvent(event, gattc_if, param);
|
||||||
global_ble->ble_events_.push(new_event);
|
global_ble->ble_events_.push(new_event);
|
||||||
} // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
|
} // NOLINT(clang-analyzer-unix.Malloc)
|
||||||
|
|
||||||
void ESP32BLE::real_gattc_event_handler_(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
void ESP32BLE::real_gattc_event_handler_(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
||||||
esp_ble_gattc_cb_param_t *param) {
|
esp_ble_gattc_cb_param_t *param) {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ esp_err_t BLEAdvertising::services_advertisement_() {
|
|||||||
esp_err_t err;
|
esp_err_t err;
|
||||||
|
|
||||||
this->advertising_data_.set_scan_rsp = false;
|
this->advertising_data_.set_scan_rsp = false;
|
||||||
this->advertising_data_.include_name = true;
|
this->advertising_data_.include_name = !this->scan_response_;
|
||||||
this->advertising_data_.include_txpower = !this->scan_response_;
|
this->advertising_data_.include_txpower = !this->scan_response_;
|
||||||
err = esp_ble_gap_config_adv_data(&this->advertising_data_);
|
err = esp_ble_gap_config_adv_data(&this->advertising_data_);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
|
|||||||
@@ -51,8 +51,11 @@ CONF_IGNORE_MISSING_GLYPHS = "ignore_missing_glyphs"
|
|||||||
# Cache loaded freetype fonts
|
# Cache loaded freetype fonts
|
||||||
class FontCache(dict):
|
class FontCache(dict):
|
||||||
def __missing__(self, key):
|
def __missing__(self, key):
|
||||||
res = self[key] = freetype.Face(key)
|
try:
|
||||||
return res
|
res = self[key] = freetype.Face(key)
|
||||||
|
return res
|
||||||
|
except freetype.FT_Exception as e:
|
||||||
|
raise cv.Invalid(f"Could not load Font file {key}: {e}") from e
|
||||||
|
|
||||||
|
|
||||||
FONT_CACHE = FontCache()
|
FONT_CACHE = FontCache()
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ void I2SAudioSpeaker::speaker_task(void *params) {
|
|||||||
|
|
||||||
// Ensure ring buffer is at least as large as the total size of the DMA buffers
|
// Ensure ring buffer is at least as large as the total size of the DMA buffers
|
||||||
const size_t ring_buffer_size =
|
const size_t ring_buffer_size =
|
||||||
std::min((uint32_t) dma_buffers_size, this_speaker->buffer_duration_ms_ * bytes_per_ms);
|
std::max((uint32_t) dma_buffers_size, this_speaker->buffer_duration_ms_ * bytes_per_ms);
|
||||||
|
|
||||||
if (this_speaker->send_esp_err_to_event_group_(this_speaker->allocate_buffers_(dma_buffers_size, ring_buffer_size))) {
|
if (this_speaker->send_esp_err_to_event_group_(this_speaker->allocate_buffers_(dma_buffers_size, ring_buffer_size))) {
|
||||||
// Failed to allocate buffers
|
// Failed to allocate buffers
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
import esphome.codegen as cg
|
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome import pins
|
from esphome import pins
|
||||||
from esphome.components import remote_base, esp32_rmt
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import esp32_rmt, remote_base
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_BUFFER_SIZE,
|
CONF_BUFFER_SIZE,
|
||||||
|
CONF_CLOCK_DIVIDER,
|
||||||
CONF_DUMP,
|
CONF_DUMP,
|
||||||
CONF_FILTER,
|
CONF_FILTER,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
CONF_IDLE,
|
CONF_IDLE,
|
||||||
|
CONF_MEMORY_BLOCKS,
|
||||||
CONF_PIN,
|
CONF_PIN,
|
||||||
|
CONF_RMT_CHANNEL,
|
||||||
CONF_TOLERANCE,
|
CONF_TOLERANCE,
|
||||||
CONF_TYPE,
|
CONF_TYPE,
|
||||||
CONF_MEMORY_BLOCKS,
|
|
||||||
CONF_RMT_CHANNEL,
|
|
||||||
CONF_VALUE,
|
CONF_VALUE,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, TimePeriod
|
from esphome.core import CORE, TimePeriod
|
||||||
|
|
||||||
CONF_CLOCK_DIVIDER = "clock_divider"
|
|
||||||
|
|
||||||
AUTO_LOAD = ["remote_base"]
|
AUTO_LOAD = ["remote_base"]
|
||||||
remote_receiver_ns = cg.esphome_ns.namespace("remote_receiver")
|
remote_receiver_ns = cg.esphome_ns.namespace("remote_receiver")
|
||||||
remote_base_ns = cg.esphome_ns.namespace("remote_base")
|
remote_base_ns = cg.esphome_ns.namespace("remote_base")
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import i2c, sensirion_common, sensor
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.components import i2c, sensor, sensirion_common
|
|
||||||
|
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_COMPENSATION,
|
|
||||||
CONF_ID,
|
|
||||||
CONF_BASELINE,
|
CONF_BASELINE,
|
||||||
|
CONF_COMPENSATION,
|
||||||
CONF_ECO2,
|
CONF_ECO2,
|
||||||
|
CONF_ID,
|
||||||
CONF_STORE_BASELINE,
|
CONF_STORE_BASELINE,
|
||||||
CONF_TEMPERATURE_SOURCE,
|
CONF_TEMPERATURE_SOURCE,
|
||||||
CONF_TVOC,
|
CONF_TVOC,
|
||||||
ICON_RADIATOR,
|
|
||||||
DEVICE_CLASS_CARBON_DIOXIDE,
|
DEVICE_CLASS_CARBON_DIOXIDE,
|
||||||
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
|
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
|
||||||
STATE_CLASS_MEASUREMENT,
|
|
||||||
UNIT_PARTS_PER_MILLION,
|
|
||||||
UNIT_PARTS_PER_BILLION,
|
|
||||||
ICON_MOLECULE_CO2,
|
|
||||||
ENTITY_CATEGORY_DIAGNOSTIC,
|
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
ICON_MOLECULE_CO2,
|
||||||
|
ICON_RADIATOR,
|
||||||
|
STATE_CLASS_MEASUREMENT,
|
||||||
|
UNIT_PARTS_PER_BILLION,
|
||||||
|
UNIT_PARTS_PER_MILLION,
|
||||||
)
|
)
|
||||||
|
|
||||||
DEPENDENCIES = ["i2c"]
|
DEPENDENCIES = ["i2c"]
|
||||||
@@ -77,7 +76,7 @@ CONFIG_SCHEMA = (
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.extend(cv.polling_component_schema("1s"))
|
.extend(cv.polling_component_schema("60s"))
|
||||||
.extend(i2c.i2c_device_schema(0x58))
|
.extend(i2c.i2c_device_schema(0x58))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "sgp30.h"
|
#include "sgp30.h"
|
||||||
|
#include <cinttypes>
|
||||||
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
#include "esphome/core/application.h"
|
|
||||||
#include <cinttypes>
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace sgp30 {
|
namespace sgp30 {
|
||||||
@@ -295,10 +295,6 @@ void SGP30Component::update() {
|
|||||||
if (this->tvoc_sensor_ != nullptr)
|
if (this->tvoc_sensor_ != nullptr)
|
||||||
this->tvoc_sensor_->publish_state(tvoc);
|
this->tvoc_sensor_->publish_state(tvoc);
|
||||||
|
|
||||||
if (this->get_update_interval() != 1000) {
|
|
||||||
ESP_LOGW(TAG, "Update interval for SGP30 sensor must be set to 1s for optimized readout");
|
|
||||||
}
|
|
||||||
|
|
||||||
this->status_clear_warning();
|
this->status_clear_warning();
|
||||||
this->send_env_data_();
|
this->send_env_data_();
|
||||||
this->read_iaq_baseline_();
|
this->read_iaq_baseline_();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""Constants used by esphome."""
|
"""Constants used by esphome."""
|
||||||
|
|
||||||
__version__ = "2024.12.0b1"
|
__version__ = "2024.12.2"
|
||||||
|
|
||||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||||
VALID_SUBSTITUTIONS_CHARACTERS = (
|
VALID_SUBSTITUTIONS_CHARACTERS = (
|
||||||
@@ -131,7 +131,9 @@ CONF_CLIENT_CERTIFICATE = "client_certificate"
|
|||||||
CONF_CLIENT_CERTIFICATE_KEY = "client_certificate_key"
|
CONF_CLIENT_CERTIFICATE_KEY = "client_certificate_key"
|
||||||
CONF_CLIENT_ID = "client_id"
|
CONF_CLIENT_ID = "client_id"
|
||||||
CONF_CLK_PIN = "clk_pin"
|
CONF_CLK_PIN = "clk_pin"
|
||||||
|
CONF_CLOCK_DIVIDER = "clock_divider"
|
||||||
CONF_CLOCK_PIN = "clock_pin"
|
CONF_CLOCK_PIN = "clock_pin"
|
||||||
|
CONF_CLOCK_RESOLUTION = "clock_resolution"
|
||||||
CONF_CLOSE_ACTION = "close_action"
|
CONF_CLOSE_ACTION = "close_action"
|
||||||
CONF_CLOSE_DURATION = "close_duration"
|
CONF_CLOSE_DURATION = "close_duration"
|
||||||
CONF_CLOSE_ENDSTOP = "close_endstop"
|
CONF_CLOSE_ENDSTOP = "close_endstop"
|
||||||
@@ -739,6 +741,7 @@ CONF_RGB_ORDER = "rgb_order"
|
|||||||
CONF_RGBW = "rgbw"
|
CONF_RGBW = "rgbw"
|
||||||
CONF_RISING_EDGE = "rising_edge"
|
CONF_RISING_EDGE = "rising_edge"
|
||||||
CONF_RMT_CHANNEL = "rmt_channel"
|
CONF_RMT_CHANNEL = "rmt_channel"
|
||||||
|
CONF_RMT_SYMBOLS = "rmt_symbols"
|
||||||
CONF_ROTATION = "rotation"
|
CONF_ROTATION = "rotation"
|
||||||
CONF_ROW = "row"
|
CONF_ROW = "row"
|
||||||
CONF_RS_PIN = "rs_pin"
|
CONF_RS_PIN = "rs_pin"
|
||||||
@@ -918,6 +921,7 @@ CONF_UPDATE_ON_BOOT = "update_on_boot"
|
|||||||
CONF_URL = "url"
|
CONF_URL = "url"
|
||||||
CONF_USE_ABBREVIATIONS = "use_abbreviations"
|
CONF_USE_ABBREVIATIONS = "use_abbreviations"
|
||||||
CONF_USE_ADDRESS = "use_address"
|
CONF_USE_ADDRESS = "use_address"
|
||||||
|
CONF_USE_DMA = "use_dma"
|
||||||
CONF_USE_FAHRENHEIT = "use_fahrenheit"
|
CONF_USE_FAHRENHEIT = "use_fahrenheit"
|
||||||
CONF_USERNAME = "username"
|
CONF_USERNAME = "username"
|
||||||
CONF_UUID = "uuid"
|
CONF_UUID = "uuid"
|
||||||
|
|||||||
@@ -767,7 +767,8 @@ bool mac_address_is_valid(const uint8_t *mac) {
|
|||||||
return !(is_all_zeros || is_all_ones);
|
return !(is_all_zeros || is_all_ones);
|
||||||
}
|
}
|
||||||
|
|
||||||
void delay_microseconds_safe(uint32_t us) { // avoids CPU locks that could trigger WDT or affect WiFi/BT stability
|
void IRAM_ATTR HOT delay_microseconds_safe(uint32_t us) {
|
||||||
|
// avoids CPU locks that could trigger WDT or affect WiFi/BT stability
|
||||||
uint32_t start = micros();
|
uint32_t start = micros();
|
||||||
|
|
||||||
const uint32_t lag = 5000; // microseconds, specifies the maximum time for a CPU busy-loop.
|
const uint32_t lag = 5000; // microseconds, specifies the maximum time for a CPU busy-loop.
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ static const char *const TAG = "ring_buffer";
|
|||||||
|
|
||||||
RingBuffer::~RingBuffer() {
|
RingBuffer::~RingBuffer() {
|
||||||
if (this->handle_ != nullptr) {
|
if (this->handle_ != nullptr) {
|
||||||
vStreamBufferDelete(this->handle_);
|
vRingbufferDelete(this->handle_);
|
||||||
ExternalRAMAllocator<uint8_t> allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
|
RAMAllocator<uint8_t> allocator(RAMAllocator<uint8_t>::ALLOW_FAILURE);
|
||||||
allocator.deallocate(this->storage_, this->size_);
|
allocator.deallocate(this->storage_, this->size_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,26 +22,49 @@ RingBuffer::~RingBuffer() {
|
|||||||
std::unique_ptr<RingBuffer> RingBuffer::create(size_t len) {
|
std::unique_ptr<RingBuffer> RingBuffer::create(size_t len) {
|
||||||
std::unique_ptr<RingBuffer> rb = make_unique<RingBuffer>();
|
std::unique_ptr<RingBuffer> rb = make_unique<RingBuffer>();
|
||||||
|
|
||||||
rb->size_ = len + 1;
|
rb->size_ = len;
|
||||||
|
|
||||||
ExternalRAMAllocator<uint8_t> allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
|
RAMAllocator<uint8_t> allocator(RAMAllocator<uint8_t>::ALLOW_FAILURE);
|
||||||
rb->storage_ = allocator.allocate(rb->size_);
|
rb->storage_ = allocator.allocate(rb->size_);
|
||||||
if (rb->storage_ == nullptr) {
|
if (rb->storage_ == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
rb->handle_ = xStreamBufferCreateStatic(rb->size_, 1, rb->storage_, &rb->structure_);
|
rb->handle_ = xRingbufferCreateStatic(rb->size_, RINGBUF_TYPE_BYTEBUF, rb->storage_, &rb->structure_);
|
||||||
ESP_LOGD(TAG, "Created ring buffer with size %u", len);
|
ESP_LOGD(TAG, "Created ring buffer with size %u", len);
|
||||||
|
|
||||||
return rb;
|
return rb;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RingBuffer::read(void *data, size_t len, TickType_t ticks_to_wait) {
|
size_t RingBuffer::read(void *data, size_t len, TickType_t ticks_to_wait) {
|
||||||
if (ticks_to_wait > 0)
|
size_t bytes_read = 0;
|
||||||
xStreamBufferSetTriggerLevel(this->handle_, len);
|
|
||||||
|
|
||||||
size_t bytes_read = xStreamBufferReceive(this->handle_, data, len, ticks_to_wait);
|
void *buffer_data = xRingbufferReceiveUpTo(this->handle_, &bytes_read, ticks_to_wait, len);
|
||||||
|
|
||||||
xStreamBufferSetTriggerLevel(this->handle_, 1);
|
if (buffer_data == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memcpy(data, buffer_data, bytes_read);
|
||||||
|
|
||||||
|
vRingbufferReturnItem(this->handle_, buffer_data);
|
||||||
|
|
||||||
|
if (bytes_read < len) {
|
||||||
|
// Data may have wrapped around, so read a second time to receive the remainder
|
||||||
|
size_t follow_up_bytes_read = 0;
|
||||||
|
size_t bytes_remaining = len - bytes_read;
|
||||||
|
|
||||||
|
buffer_data = xRingbufferReceiveUpTo(this->handle_, &follow_up_bytes_read, 0, bytes_remaining);
|
||||||
|
|
||||||
|
if (buffer_data == nullptr) {
|
||||||
|
return bytes_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memcpy((void *) ((uint8_t *) (data) + bytes_read), buffer_data, follow_up_bytes_read);
|
||||||
|
|
||||||
|
vRingbufferReturnItem(this->handle_, buffer_data);
|
||||||
|
bytes_read += follow_up_bytes_read;
|
||||||
|
}
|
||||||
|
|
||||||
return bytes_read;
|
return bytes_read;
|
||||||
}
|
}
|
||||||
@@ -49,22 +72,55 @@ size_t RingBuffer::read(void *data, size_t len, TickType_t ticks_to_wait) {
|
|||||||
size_t RingBuffer::write(const void *data, size_t len) {
|
size_t RingBuffer::write(const void *data, size_t len) {
|
||||||
size_t free = this->free();
|
size_t free = this->free();
|
||||||
if (free < len) {
|
if (free < len) {
|
||||||
size_t needed = len - free;
|
// Free enough space in the ring buffer to fit the new data
|
||||||
uint8_t discard[needed];
|
this->discard_bytes_(len - free);
|
||||||
xStreamBufferReceive(this->handle_, discard, needed, 0);
|
|
||||||
}
|
}
|
||||||
return xStreamBufferSend(this->handle_, data, len, 0);
|
return this->write_without_replacement(data, len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RingBuffer::write_without_replacement(const void *data, size_t len, TickType_t ticks_to_wait) {
|
size_t RingBuffer::write_without_replacement(const void *data, size_t len, TickType_t ticks_to_wait) {
|
||||||
return xStreamBufferSend(this->handle_, data, len, ticks_to_wait);
|
if (!xRingbufferSend(this->handle_, data, len, ticks_to_wait)) {
|
||||||
|
// Couldn't fit all the data, so only write what will fit
|
||||||
|
size_t free = std::min(this->free(), len);
|
||||||
|
if (xRingbufferSend(this->handle_, data, free, 0)) {
|
||||||
|
return free;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RingBuffer::available() const { return xStreamBufferBytesAvailable(this->handle_); }
|
size_t RingBuffer::available() const {
|
||||||
|
UBaseType_t ux_items_waiting = 0;
|
||||||
|
vRingbufferGetInfo(this->handle_, nullptr, nullptr, nullptr, nullptr, &ux_items_waiting);
|
||||||
|
return ux_items_waiting;
|
||||||
|
}
|
||||||
|
|
||||||
size_t RingBuffer::free() const { return xStreamBufferSpacesAvailable(this->handle_); }
|
size_t RingBuffer::free() const { return xRingbufferGetCurFreeSize(this->handle_); }
|
||||||
|
|
||||||
BaseType_t RingBuffer::reset() { return xStreamBufferReset(this->handle_); }
|
BaseType_t RingBuffer::reset() {
|
||||||
|
// Discards all the available data
|
||||||
|
return this->discard_bytes_(this->available());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RingBuffer::discard_bytes_(size_t discard_bytes) {
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
|
||||||
|
void *buffer_data = xRingbufferReceiveUpTo(this->handle_, &bytes_read, 0, discard_bytes);
|
||||||
|
if (buffer_data != nullptr)
|
||||||
|
vRingbufferReturnItem(this->handle_, buffer_data);
|
||||||
|
|
||||||
|
if (bytes_read < discard_bytes) {
|
||||||
|
size_t wrapped_bytes_read = 0;
|
||||||
|
buffer_data = xRingbufferReceiveUpTo(this->handle_, &wrapped_bytes_read, 0, discard_bytes - bytes_read);
|
||||||
|
if (buffer_data != nullptr) {
|
||||||
|
vRingbufferReturnItem(this->handle_, buffer_data);
|
||||||
|
bytes_read += wrapped_bytes_read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (bytes_read == discard_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
|
|
||||||
#include <freertos/FreeRTOS.h>
|
#include <freertos/FreeRTOS.h>
|
||||||
#include <freertos/stream_buffer.h>
|
#include <freertos/ringbuf.h>
|
||||||
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -82,9 +82,14 @@ class RingBuffer {
|
|||||||
static std::unique_ptr<RingBuffer> create(size_t len);
|
static std::unique_ptr<RingBuffer> create(size_t len);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StreamBufferHandle_t handle_;
|
/// @brief Discards data from the ring buffer.
|
||||||
StaticStreamBuffer_t structure_;
|
/// @param discard_bytes amount of bytes to discard
|
||||||
uint8_t *storage_;
|
/// @return True if all bytes were successfully discarded, false otherwise
|
||||||
|
bool discard_bytes_(size_t discard_bytes);
|
||||||
|
|
||||||
|
RingbufHandle_t handle_{nullptr};
|
||||||
|
StaticRingbuffer_t structure_;
|
||||||
|
uint8_t *storage_{nullptr};
|
||||||
size_t size_{0};
|
size_t size_{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -108,6 +108,12 @@ def is_authenticated(handler: BaseHandler) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
if settings.using_auth:
|
if settings.using_auth:
|
||||||
|
if auth_header := handler.request.headers.get("Authorization"):
|
||||||
|
assert isinstance(auth_header, str)
|
||||||
|
if auth_header.startswith("Basic "):
|
||||||
|
auth_decoded = base64.b64decode(auth_header[6:]).decode()
|
||||||
|
username, password = auth_decoded.split(":", 1)
|
||||||
|
return settings.check_password(username, password)
|
||||||
return handler.get_secure_cookie(AUTH_COOKIE_NAME) == COOKIE_AUTHENTICATED_YES
|
return handler.get_secure_cookie(AUTH_COOKIE_NAME) == COOKIE_AUTHENTICATED_YES
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ pyserial==3.5
|
|||||||
platformio==6.1.16 # When updating platformio, also update Dockerfile
|
platformio==6.1.16 # When updating platformio, also update Dockerfile
|
||||||
esptool==4.7.0
|
esptool==4.7.0
|
||||||
click==8.1.7
|
click==8.1.7
|
||||||
esphome-dashboard==20241120.0
|
esphome-dashboard==20241217.1
|
||||||
aioesphomeapi==24.6.2
|
aioesphomeapi==24.6.2
|
||||||
zeroconf==0.132.2
|
zeroconf==0.132.2
|
||||||
puremagic==1.27
|
puremagic==1.27
|
||||||
|
|||||||
4
tests/components/adc/test.bk72xx-ard.yaml
Normal file
4
tests/components/adc/test.bk72xx-ard.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
sensor:
|
||||||
|
- platform: adc
|
||||||
|
pin: P23
|
||||||
|
name: Basic ADC Test
|
||||||
Reference in New Issue
Block a user