mirror of
https://github.com/esphome/esphome.git
synced 2026-02-24 02:08:23 -07:00
Merge branch 'fix_logger_loop_disable' into integration
This commit is contained in:
@@ -87,6 +87,7 @@ IS_TARGET_PLATFORM = True
|
||||
CONF_ASSERTION_LEVEL = "assertion_level"
|
||||
CONF_COMPILER_OPTIMIZATION = "compiler_optimization"
|
||||
CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES = "enable_idf_experimental_features"
|
||||
CONF_ENGINEERING_SAMPLE = "engineering_sample"
|
||||
CONF_INCLUDE_BUILTIN_IDF_COMPONENTS = "include_builtin_idf_components"
|
||||
CONF_ENABLE_LWIP_ASSERT = "enable_lwip_assert"
|
||||
CONF_ENABLE_OTA_ROLLBACK = "enable_ota_rollback"
|
||||
@@ -785,6 +786,15 @@ def _detect_variant(value):
|
||||
# variant has already been validated against the known set
|
||||
value = value.copy()
|
||||
value[CONF_BOARD] = STANDARD_BOARDS[variant]
|
||||
if variant == VARIANT_ESP32P4:
|
||||
engineering_sample = value.get(CONF_ENGINEERING_SAMPLE)
|
||||
if engineering_sample is None:
|
||||
_LOGGER.warning(
|
||||
"No board specified for ESP32-P4. Defaulting to production silicon (rev3). "
|
||||
"If you have an early engineering sample (pre-rev3), set 'engineering_sample: true'."
|
||||
)
|
||||
elif engineering_sample:
|
||||
value[CONF_BOARD] = "esp32-p4-evboard"
|
||||
elif board in BOARDS:
|
||||
variant = variant or BOARDS[board][KEY_VARIANT]
|
||||
if variant != BOARDS[board][KEY_VARIANT]:
|
||||
@@ -848,6 +858,30 @@ def final_validate(config):
|
||||
path=[CONF_FRAMEWORK, CONF_ADVANCED, CONF_MINIMUM_CHIP_REVISION],
|
||||
)
|
||||
)
|
||||
if (
|
||||
config[CONF_VARIANT] != VARIANT_ESP32P4
|
||||
and config.get(CONF_ENGINEERING_SAMPLE) is not None
|
||||
):
|
||||
errs.append(
|
||||
cv.Invalid(
|
||||
f"'{CONF_ENGINEERING_SAMPLE}' is only supported on {VARIANT_ESP32P4}",
|
||||
path=[CONF_ENGINEERING_SAMPLE],
|
||||
)
|
||||
)
|
||||
if (
|
||||
config[CONF_VARIANT] == VARIANT_ESP32P4
|
||||
and config.get(CONF_ENGINEERING_SAMPLE) is not None
|
||||
):
|
||||
board_is_es = BOARDS.get(config[CONF_BOARD], {}).get(
|
||||
"engineering_sample", False
|
||||
)
|
||||
if config[CONF_ENGINEERING_SAMPLE] != board_is_es:
|
||||
errs.append(
|
||||
cv.Invalid(
|
||||
f"'{CONF_ENGINEERING_SAMPLE}' does not match board '{config[CONF_BOARD]}'",
|
||||
path=[CONF_ENGINEERING_SAMPLE],
|
||||
)
|
||||
)
|
||||
if advanced[CONF_EXECUTE_FROM_PSRAM]:
|
||||
if config[CONF_VARIANT] != VARIANT_ESP32S3:
|
||||
errs.append(
|
||||
@@ -1197,6 +1231,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.Optional(CONF_CPU_FREQUENCY): cv.one_of(
|
||||
*FULL_CPU_FREQUENCIES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_ENGINEERING_SAMPLE): cv.boolean,
|
||||
cv.Optional(CONF_FLASH_SIZE, default="4MB"): cv.one_of(
|
||||
*FLASH_SIZES, upper=True
|
||||
),
|
||||
@@ -1482,10 +1517,12 @@ async def to_code(config):
|
||||
# ESP32-P4: ESP-IDF 5.5.3 changed the default of ESP32P4_SELECTS_REV_LESS_V3
|
||||
# from y to n. PlatformIO uses sections.ld.in (for rev <3) or
|
||||
# sections.rev3.ld.in (for rev >=3) based on board definition.
|
||||
# Set the sdkconfig option to match the board's revision.
|
||||
# Set the sdkconfig option to match the board's chip revision.
|
||||
if variant == VARIANT_ESP32P4:
|
||||
is_rev3 = "_r3" in config[CONF_BOARD]
|
||||
add_idf_sdkconfig_option("CONFIG_ESP32P4_SELECTS_REV_LESS_V3", not is_rev3)
|
||||
is_eng_sample = BOARDS.get(config[CONF_BOARD], {}).get(
|
||||
"engineering_sample", False
|
||||
)
|
||||
add_idf_sdkconfig_option("CONFIG_ESP32P4_SELECTS_REV_LESS_V3", is_eng_sample)
|
||||
|
||||
# Set minimum chip revision for ESP32 variant
|
||||
# Setting this to 3.0 or higher reduces flash size by excluding workaround code,
|
||||
|
||||
@@ -20,7 +20,7 @@ STANDARD_BOARDS = {
|
||||
VARIANT_ESP32C6: "esp32-c6-devkitm-1",
|
||||
VARIANT_ESP32C61: "esp32-c61-devkitc1-n8r2",
|
||||
VARIANT_ESP32H2: "esp32-h2-devkitm-1",
|
||||
VARIANT_ESP32P4: "esp32-p4-evboard",
|
||||
VARIANT_ESP32P4: "esp32-p4_r3-evboard",
|
||||
VARIANT_ESP32S2: "esp32-s2-kaluga-1",
|
||||
VARIANT_ESP32S3: "esp32-s3-devkitc-1",
|
||||
}
|
||||
@@ -1713,10 +1713,12 @@ BOARDS = {
|
||||
"esp32-p4": {
|
||||
"name": "Espressif ESP32-P4 ES (pre rev.300) generic",
|
||||
"variant": VARIANT_ESP32P4,
|
||||
"engineering_sample": True,
|
||||
},
|
||||
"esp32-p4-evboard": {
|
||||
"name": "Espressif ESP32-P4 Function EV Board (ES pre rev.300)",
|
||||
"variant": VARIANT_ESP32P4,
|
||||
"engineering_sample": True,
|
||||
},
|
||||
"esp32-p4_r3": {
|
||||
"name": "Espressif ESP32-P4 rev.300 generic",
|
||||
@@ -2141,6 +2143,7 @@ BOARDS = {
|
||||
"m5stack-tab5-p4": {
|
||||
"name": "M5STACK Tab5 esp32-p4 Board (ES pre rev.300)",
|
||||
"variant": VARIANT_ESP32P4,
|
||||
"engineering_sample": True,
|
||||
},
|
||||
"m5stack-timer-cam": {
|
||||
"name": "M5Stack Timer CAM",
|
||||
|
||||
@@ -432,6 +432,7 @@ async def to_code(config):
|
||||
if config[CONF_HARDWARE_UART] == UART1:
|
||||
zephyr_add_overlay("""&uart1 { status = "okay";};""")
|
||||
if config[CONF_HARDWARE_UART] == USB_CDC:
|
||||
cg.add_define("USE_LOGGER_UART_SELECTION_USB_CDC")
|
||||
zephyr_add_prj_conf("UART_LINE_CTRL", True)
|
||||
zephyr_add_cdc_acm(config, 0)
|
||||
|
||||
|
||||
@@ -170,19 +170,19 @@ void Logger::init_log_buffer(size_t total_buffer_size) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory) - allocated once, never freed
|
||||
this->log_buffer_ = new logger::TaskLogBuffer(total_buffer_size);
|
||||
|
||||
// Zephyr needs loop working to check when CDC port is open
|
||||
#if !(defined(USE_ZEPHYR) || defined(USE_LOGGER_USB_CDC))
|
||||
// Start with loop disabled when using task buffer (unless using USB CDC on ESP32)
|
||||
#if !(defined(USE_ZEPHYR) && defined(USE_LOGGER_UART_SELECTION_USB_CDC))
|
||||
// Start with loop disabled when using task buffer
|
||||
// The loop will be enabled automatically when messages arrive
|
||||
// Zephyr with USB CDC needs loop active to poll port readiness via cdc_loop_()
|
||||
this->disable_loop_when_buffer_empty_();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_ESPHOME_TASK_LOG_BUFFER) || (defined(USE_ZEPHYR) && defined(USE_LOGGER_USB_CDC))
|
||||
#if defined(USE_ESPHOME_TASK_LOG_BUFFER) || (defined(USE_ZEPHYR) && defined(USE_LOGGER_UART_SELECTION_USB_CDC))
|
||||
void Logger::loop() {
|
||||
this->process_messages_();
|
||||
#if defined(USE_ZEPHYR) && defined(USE_LOGGER_USB_CDC)
|
||||
#if defined(USE_ZEPHYR) && defined(USE_LOGGER_UART_SELECTION_USB_CDC)
|
||||
this->cdc_loop_();
|
||||
#endif
|
||||
}
|
||||
@@ -204,8 +204,7 @@ void Logger::process_messages_() {
|
||||
this->write_log_buffer_to_console_(buf);
|
||||
}
|
||||
}
|
||||
// Zephyr needs loop working to check when CDC port is open
|
||||
#if !(defined(USE_ZEPHYR) || defined(USE_LOGGER_USB_CDC))
|
||||
#if !(defined(USE_ZEPHYR) && defined(USE_LOGGER_UART_SELECTION_USB_CDC))
|
||||
else {
|
||||
// No messages to process, disable loop if appropriate
|
||||
// This reduces overhead when there's no async logging activity
|
||||
|
||||
@@ -147,7 +147,7 @@ class Logger : public Component {
|
||||
#ifdef USE_ESPHOME_TASK_LOG_BUFFER
|
||||
void init_log_buffer(size_t total_buffer_size);
|
||||
#endif
|
||||
#if defined(USE_ESPHOME_TASK_LOG_BUFFER) || (defined(USE_ZEPHYR) && defined(USE_LOGGER_USB_CDC))
|
||||
#if defined(USE_ESPHOME_TASK_LOG_BUFFER) || (defined(USE_ZEPHYR) && defined(USE_LOGGER_UART_SELECTION_USB_CDC))
|
||||
void loop() override;
|
||||
#endif
|
||||
/// Manually set the baud rate for serial, set to 0 to disable.
|
||||
@@ -229,7 +229,7 @@ class Logger : public Component {
|
||||
void log_vprintf_non_main_thread_(uint8_t level, const char *tag, int line, const char *format, va_list args,
|
||||
const char *thread_name);
|
||||
#endif
|
||||
#if defined(USE_ZEPHYR) && defined(USE_LOGGER_USB_CDC)
|
||||
#if defined(USE_ZEPHYR) && defined(USE_LOGGER_UART_SELECTION_USB_CDC)
|
||||
void cdc_loop_();
|
||||
#endif
|
||||
void process_messages_();
|
||||
@@ -464,9 +464,9 @@ class Logger : public Component {
|
||||
inline RecursionGuard make_non_main_task_guard_() { return RecursionGuard(non_main_task_recursion_guard_); }
|
||||
#endif
|
||||
|
||||
// Zephyr needs loop working to check when CDC port is open
|
||||
#if defined(USE_ESPHOME_TASK_LOG_BUFFER) && !(defined(USE_ZEPHYR) || defined(USE_LOGGER_USB_CDC))
|
||||
// Disable loop when task buffer is empty (with USB CDC check on ESP32)
|
||||
#if defined(USE_ESPHOME_TASK_LOG_BUFFER) && !(defined(USE_ZEPHYR) && defined(USE_LOGGER_UART_SELECTION_USB_CDC))
|
||||
// Disable loop when task buffer is empty
|
||||
// Zephyr with USB CDC needs loop active to poll port readiness via cdc_loop_()
|
||||
inline void disable_loop_when_buffer_empty_() {
|
||||
// Thread safety note: This is safe even if another task calls enable_loop_soon_any_context()
|
||||
// concurrently. If that happens between our check and disable_loop(), the enable request
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace esphome::logger {
|
||||
|
||||
static const char *const TAG = "logger";
|
||||
|
||||
#ifdef USE_LOGGER_USB_CDC
|
||||
#ifdef USE_LOGGER_UART_SELECTION_USB_CDC
|
||||
void Logger::cdc_loop_() {
|
||||
if (this->uart_ != UART_SELECTION_USB_CDC || this->uart_dev_ == nullptr) {
|
||||
return;
|
||||
|
||||
@@ -5,7 +5,12 @@ from esphome import automation
|
||||
from esphome.automation import Condition
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.const import CONF_USE_PSRAM
|
||||
from esphome.components.esp32 import add_idf_sdkconfig_option, const, get_esp32_variant
|
||||
from esphome.components.esp32 import (
|
||||
add_idf_sdkconfig_option,
|
||||
const,
|
||||
get_esp32_variant,
|
||||
only_on_variant,
|
||||
)
|
||||
from esphome.components.network import (
|
||||
has_high_performance_networking,
|
||||
ip_address_literal,
|
||||
@@ -64,6 +69,7 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
NO_WIFI_VARIANTS = [const.VARIANT_ESP32H2, const.VARIANT_ESP32P4]
|
||||
CONF_SAVE = "save"
|
||||
CONF_BAND_MODE = "band_mode"
|
||||
CONF_MIN_AUTH_MODE = "min_auth_mode"
|
||||
CONF_POST_CONNECT_ROAMING = "post_connect_roaming"
|
||||
|
||||
@@ -90,6 +96,13 @@ WIFI_POWER_SAVE_MODES = {
|
||||
"HIGH": WiFiPowerSaveMode.WIFI_POWER_SAVE_HIGH,
|
||||
}
|
||||
|
||||
WiFiBandMode = cg.global_ns.enum("wifi_band_mode_t")
|
||||
WIFI_BAND_MODES = {
|
||||
"AUTO": WiFiBandMode.WIFI_BAND_MODE_AUTO,
|
||||
"2.4GHZ": WiFiBandMode.WIFI_BAND_MODE_2G_ONLY,
|
||||
"5GHZ": WiFiBandMode.WIFI_BAND_MODE_5G_ONLY,
|
||||
}
|
||||
|
||||
WifiMinAuthMode = wifi_ns.enum("WifiMinAuthMode")
|
||||
WIFI_MIN_AUTH_MODES = {
|
||||
"WPA": WifiMinAuthMode.WIFI_MIN_AUTH_MODE_WPA,
|
||||
@@ -353,6 +366,11 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.SplitDefault(CONF_ENABLE_RRM, esp32=False): cv.All(
|
||||
cv.boolean, cv.only_on_esp32
|
||||
),
|
||||
cv.Optional(CONF_BAND_MODE): cv.All(
|
||||
cv.enum(WIFI_BAND_MODES, upper=True),
|
||||
cv.only_on_esp32,
|
||||
only_on_variant(supported=[const.VARIANT_ESP32C5]),
|
||||
),
|
||||
cv.Optional(CONF_PASSIVE_SCAN, default=False): cv.boolean,
|
||||
cv.Optional(CONF_ENABLE_ON_BOOT, default=True): cv.boolean,
|
||||
cv.Optional(CONF_POST_CONNECT_ROAMING, default=True): cv.boolean,
|
||||
@@ -527,6 +545,8 @@ async def to_code(config):
|
||||
cg.add(var.set_btm(config[CONF_ENABLE_BTM]))
|
||||
if config[CONF_ENABLE_RRM]:
|
||||
cg.add(var.set_rrm(config[CONF_ENABLE_RRM]))
|
||||
if CONF_BAND_MODE in config:
|
||||
cg.add(var.set_band_mode(config[CONF_BAND_MODE]))
|
||||
|
||||
if config.get(CONF_USE_PSRAM):
|
||||
add_idf_sdkconfig_option("CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP", True)
|
||||
|
||||
@@ -1511,6 +1511,22 @@ void WiFiComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, " Disabled");
|
||||
return;
|
||||
}
|
||||
#if defined(USE_ESP32) && defined(SOC_WIFI_SUPPORT_5G)
|
||||
const char *band_mode_s;
|
||||
switch (this->band_mode_) {
|
||||
case WIFI_BAND_MODE_2G_ONLY:
|
||||
band_mode_s = "2.4GHz";
|
||||
break;
|
||||
case WIFI_BAND_MODE_5G_ONLY:
|
||||
band_mode_s = "5GHz";
|
||||
break;
|
||||
case WIFI_BAND_MODE_AUTO:
|
||||
default:
|
||||
band_mode_s = "Auto";
|
||||
break;
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, " Band Mode: %s", band_mode_s);
|
||||
#endif
|
||||
if (this->is_connected()) {
|
||||
this->print_connect_params_();
|
||||
}
|
||||
|
||||
@@ -46,6 +46,10 @@ extern "C" {
|
||||
#include <WiFi.h>
|
||||
#endif
|
||||
|
||||
#if defined(USE_ESP32) && defined(SOC_WIFI_SUPPORT_5G)
|
||||
#include <esp_wifi_types.h>
|
||||
#endif
|
||||
|
||||
#if defined(USE_ESP32) && defined(USE_WIFI_RUNTIME_POWER_SAVE)
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/semphr.h>
|
||||
@@ -444,6 +448,9 @@ class WiFiComponent : public Component {
|
||||
void set_power_save_mode(WiFiPowerSaveMode power_save);
|
||||
void set_min_auth_mode(WifiMinAuthMode min_auth_mode) { min_auth_mode_ = min_auth_mode; }
|
||||
void set_output_power(float output_power) { output_power_ = output_power; }
|
||||
#if defined(USE_ESP32) && defined(SOC_WIFI_SUPPORT_5G)
|
||||
void set_band_mode(wifi_band_mode_t band_mode) { this->band_mode_ = band_mode; }
|
||||
#endif
|
||||
|
||||
void set_passive_scan(bool passive);
|
||||
|
||||
@@ -661,6 +668,9 @@ class WiFiComponent : public Component {
|
||||
bool wifi_sta_pre_setup_();
|
||||
bool wifi_apply_output_power_(float output_power);
|
||||
bool wifi_apply_power_save_();
|
||||
#if defined(USE_ESP32) && defined(SOC_WIFI_SUPPORT_5G)
|
||||
bool wifi_apply_band_mode_();
|
||||
#endif
|
||||
bool wifi_sta_ip_config_(const optional<ManualIP> &manual_ip);
|
||||
bool wifi_apply_hostname_();
|
||||
bool wifi_sta_connect_(const WiFiAP &ap);
|
||||
@@ -783,6 +793,9 @@ class WiFiComponent : public Component {
|
||||
// 1-byte enums and integers
|
||||
WiFiComponentState state_{WIFI_COMPONENT_STATE_OFF};
|
||||
WiFiPowerSaveMode power_save_{WIFI_POWER_SAVE_NONE};
|
||||
#if defined(USE_ESP32) && defined(SOC_WIFI_SUPPORT_5G)
|
||||
wifi_band_mode_t band_mode_{WIFI_BAND_MODE_AUTO};
|
||||
#endif
|
||||
WifiMinAuthMode min_auth_mode_{WIFI_MIN_AUTH_MODE_WPA2};
|
||||
WiFiRetryPhase retry_phase_{WiFiRetryPhase::INITIAL_CONNECT};
|
||||
uint8_t num_retried_{0};
|
||||
|
||||
@@ -292,6 +292,10 @@ bool WiFiComponent::wifi_apply_power_save_() {
|
||||
return success;
|
||||
}
|
||||
|
||||
#ifdef SOC_WIFI_SUPPORT_5G
|
||||
bool WiFiComponent::wifi_apply_band_mode_() { return esp_wifi_set_band_mode(this->band_mode_) == ESP_OK; }
|
||||
#endif
|
||||
|
||||
bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) {
|
||||
// enable STA
|
||||
if (!this->wifi_mode_(true, {}))
|
||||
@@ -726,6 +730,9 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
|
||||
s_sta_started = true;
|
||||
// re-apply power save mode
|
||||
wifi_apply_power_save_();
|
||||
#ifdef SOC_WIFI_SUPPORT_5G
|
||||
wifi_apply_band_mode_();
|
||||
#endif
|
||||
|
||||
} else if (data->event_base == WIFI_EVENT && data->event_id == WIFI_EVENT_STA_STOP) {
|
||||
ESP_LOGV(TAG, "STA stop");
|
||||
|
||||
@@ -272,10 +272,12 @@
|
||||
|
||||
#if defined(USE_ESP32_VARIANT_ESP32S2)
|
||||
#define USE_LOGGER_USB_CDC
|
||||
#define USE_LOGGER_UART_SELECTION_USB_CDC
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C5) || \
|
||||
defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32C61) || defined(USE_ESP32_VARIANT_ESP32H2) || \
|
||||
defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
#define USE_LOGGER_USB_CDC
|
||||
#define USE_LOGGER_UART_SELECTION_USB_CDC
|
||||
#define USE_LOGGER_USB_SERIAL_JTAG
|
||||
#endif
|
||||
#endif
|
||||
@@ -336,6 +338,8 @@
|
||||
|
||||
#ifdef USE_NRF52
|
||||
#define USE_ESPHOME_TASK_LOG_BUFFER
|
||||
#define USE_LOGGER_UART_SELECTION_USB_CDC
|
||||
#define USE_LOGGER_USB_CDC
|
||||
#define USE_NRF52_DFU
|
||||
#define USE_NRF52_REG0_VOUT 5
|
||||
#define USE_NRF52_UICR_ERASE
|
||||
|
||||
@@ -43,10 +43,14 @@ def get_boards():
|
||||
name = board_info["name"]
|
||||
board = fname.stem
|
||||
variant = mcu.upper()
|
||||
boards[board] = {
|
||||
chip_variant = board_info["build"].get("chip_variant", "")
|
||||
entry = {
|
||||
"name": name,
|
||||
"variant": f"VARIANT_{variant}",
|
||||
}
|
||||
if chip_variant.endswith("_es"):
|
||||
entry["engineering_sample"] = True
|
||||
boards[board] = entry
|
||||
return boards
|
||||
|
||||
|
||||
@@ -55,6 +59,12 @@ TEMPLATE = """ "%s": {
|
||||
"variant": %s,
|
||||
},"""
|
||||
|
||||
TEMPLATE_ES = """ "%s": {
|
||||
"name": "%s",
|
||||
"variant": %s,
|
||||
"engineering_sample": True,
|
||||
},"""
|
||||
|
||||
|
||||
def main(check: bool):
|
||||
boards = get_boards()
|
||||
@@ -66,7 +76,8 @@ def main(check: bool):
|
||||
if line == "BOARDS = {":
|
||||
parts.append(line)
|
||||
parts.extend(
|
||||
TEMPLATE % (board, info["name"], info["variant"])
|
||||
(TEMPLATE_ES if info.get("engineering_sample") else TEMPLATE)
|
||||
% (board, info["name"], info["variant"])
|
||||
for board, info in sorted(boards.items())
|
||||
)
|
||||
parts.append("}")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
esp32:
|
||||
variant: esp32p4
|
||||
engineering_sample: true
|
||||
flash_size: 32MB
|
||||
cpu_frequency: 400MHz
|
||||
framework:
|
||||
|
||||
5
tests/components/wifi/test.esp32-c5-idf.yaml
Normal file
5
tests/components/wifi/test.esp32-c5-idf.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
wifi:
|
||||
band_mode: 5GHZ
|
||||
|
||||
packages:
|
||||
- !include common.yaml
|
||||
Reference in New Issue
Block a user