mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 21:44:55 +01:00
ESP8266 early init for pins (#3144)
This commit is contained in:
parent
ffa19426d7
commit
5a0b8328d8
5 changed files with 89 additions and 6 deletions
|
@ -17,11 +17,16 @@ import esphome.config_validation as cv
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.helpers import copy_file_if_changed
|
from esphome.helpers import copy_file_if_changed
|
||||||
|
|
||||||
from .const import CONF_RESTORE_FROM_FLASH, KEY_BOARD, KEY_ESP8266, esp8266_ns
|
from .const import (
|
||||||
|
CONF_RESTORE_FROM_FLASH,
|
||||||
|
KEY_BOARD,
|
||||||
|
KEY_ESP8266,
|
||||||
|
KEY_PIN_INITIAL_STATES,
|
||||||
|
esp8266_ns,
|
||||||
|
)
|
||||||
from .boards import ESP8266_FLASH_SIZES, ESP8266_LD_SCRIPTS
|
from .boards import ESP8266_FLASH_SIZES, ESP8266_LD_SCRIPTS
|
||||||
|
|
||||||
# force import gpio to register pin schema
|
from .gpio import PinInitialState, add_pin_initial_states_array
|
||||||
from .gpio import esp8266_pin_to_code # noqa
|
|
||||||
|
|
||||||
|
|
||||||
CODEOWNERS = ["@esphome/core"]
|
CODEOWNERS = ["@esphome/core"]
|
||||||
|
@ -37,6 +42,9 @@ def set_core_data(config):
|
||||||
config[CONF_FRAMEWORK][CONF_VERSION]
|
config[CONF_FRAMEWORK][CONF_VERSION]
|
||||||
)
|
)
|
||||||
CORE.data[KEY_ESP8266][KEY_BOARD] = config[CONF_BOARD]
|
CORE.data[KEY_ESP8266][KEY_BOARD] = config[CONF_BOARD]
|
||||||
|
CORE.data[KEY_ESP8266][KEY_PIN_INITIAL_STATES] = [
|
||||||
|
PinInitialState() for _ in range(16)
|
||||||
|
]
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
@ -221,6 +229,8 @@ async def to_code(config):
|
||||||
if ld_script is not None:
|
if ld_script is not None:
|
||||||
cg.add_platformio_option("board_build.ldscript", ld_script)
|
cg.add_platformio_option("board_build.ldscript", ld_script)
|
||||||
|
|
||||||
|
CORE.add_job(add_pin_initial_states_array)
|
||||||
|
|
||||||
|
|
||||||
# Called by writer.py
|
# Called by writer.py
|
||||||
def copy_files():
|
def copy_files():
|
||||||
|
|
|
@ -2,6 +2,7 @@ import esphome.codegen as cg
|
||||||
|
|
||||||
KEY_ESP8266 = "esp8266"
|
KEY_ESP8266 = "esp8266"
|
||||||
KEY_BOARD = "board"
|
KEY_BOARD = "board"
|
||||||
|
KEY_PIN_INITIAL_STATES = "pin_initial_states"
|
||||||
CONF_RESTORE_FROM_FLASH = "restore_from_flash"
|
CONF_RESTORE_FROM_FLASH = "restore_from_flash"
|
||||||
|
|
||||||
# esp8266 namespace is already defined by arduino, manually prefix esphome
|
# esp8266 namespace is already defined by arduino, manually prefix esphome
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#ifdef USE_ESP8266
|
#ifdef USE_ESP8266
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
#include "esphome/core/helpers.h"
|
#include "esphome/core/helpers.h"
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
|
@ -53,6 +54,15 @@ extern "C" void resetPins() { // NOLINT
|
||||||
// however, not strictly needed as we set up the pins properly
|
// however, not strictly needed as we set up the pins properly
|
||||||
// ourselves and this causes pins to toggle during reboot.
|
// ourselves and this causes pins to toggle during reboot.
|
||||||
force_link_symbols();
|
force_link_symbols();
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
uint8_t mode = ESPHOME_ESP8266_GPIO_INITIAL_MODE[i];
|
||||||
|
uint8_t level = ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[i];
|
||||||
|
if (mode != 255)
|
||||||
|
pinMode(i, mode); // NOLINT
|
||||||
|
if (level != 255)
|
||||||
|
digitalWrite(i, level); // NOLINT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
14
esphome/components/esp8266/core.h
Normal file
14
esphome/components/esp8266/core.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef USE_ESP8266
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
extern const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_MODE[16];
|
||||||
|
extern const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[16];
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace esp8266 {} // namespace esp8266
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif // USE_ESP8266
|
|
@ -1,4 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import List
|
||||||
|
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
|
@ -12,12 +14,12 @@ from esphome.const import (
|
||||||
CONF_PULLUP,
|
CONF_PULLUP,
|
||||||
)
|
)
|
||||||
from esphome import pins
|
from esphome import pins
|
||||||
from esphome.core import CORE
|
from esphome.core import CORE, coroutine_with_priority
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
|
||||||
from . import boards
|
from . import boards
|
||||||
from .const import KEY_BOARD, KEY_ESP8266, esp8266_ns
|
from .const import KEY_BOARD, KEY_ESP8266, KEY_PIN_INITIAL_STATES, esp8266_ns
|
||||||
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -160,11 +162,57 @@ ESP8266_PIN_SCHEMA = cv.All(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PinInitialState:
|
||||||
|
mode = 255
|
||||||
|
level: int = 255
|
||||||
|
|
||||||
|
|
||||||
@pins.PIN_SCHEMA_REGISTRY.register("esp8266", ESP8266_PIN_SCHEMA)
|
@pins.PIN_SCHEMA_REGISTRY.register("esp8266", ESP8266_PIN_SCHEMA)
|
||||||
async def esp8266_pin_to_code(config):
|
async def esp8266_pin_to_code(config):
|
||||||
var = cg.new_Pvariable(config[CONF_ID])
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
num = config[CONF_NUMBER]
|
num = config[CONF_NUMBER]
|
||||||
|
mode = config[CONF_MODE]
|
||||||
cg.add(var.set_pin(num))
|
cg.add(var.set_pin(num))
|
||||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
cg.add(var.set_flags(pins.gpio_flags_expr(mode)))
|
||||||
|
if num < 16:
|
||||||
|
initial_state: PinInitialState = CORE.data[KEY_ESP8266][KEY_PIN_INITIAL_STATES][
|
||||||
|
num
|
||||||
|
]
|
||||||
|
if mode[CONF_INPUT]:
|
||||||
|
if mode[CONF_PULLDOWN]:
|
||||||
|
initial_state.mode = cg.global_ns.INPUT_PULLDOWN_16
|
||||||
|
elif mode[CONF_PULLUP]:
|
||||||
|
initial_state.mode = cg.global_ns.INPUT_PULLUP
|
||||||
|
else:
|
||||||
|
initial_state.mode = cg.global_ns.INPUT
|
||||||
|
elif mode[CONF_OUTPUT]:
|
||||||
|
if mode[CONF_OPEN_DRAIN]:
|
||||||
|
initial_state.mode = cg.global_ns.OUTPUT_OPEN_DRAIN
|
||||||
|
else:
|
||||||
|
initial_state.mode = cg.global_ns.OUTPUT
|
||||||
|
initial_state.level = int(config[CONF_INVERTED])
|
||||||
|
|
||||||
return var
|
return var
|
||||||
|
|
||||||
|
|
||||||
|
@coroutine_with_priority(-999.0)
|
||||||
|
async def add_pin_initial_states_array():
|
||||||
|
# Add includes at the very end, so that they override everything
|
||||||
|
initial_states: List[PinInitialState] = CORE.data[KEY_ESP8266][
|
||||||
|
KEY_PIN_INITIAL_STATES
|
||||||
|
]
|
||||||
|
initial_modes_s = ", ".join(str(x.mode) for x in initial_states)
|
||||||
|
initial_levels_s = ", ".join(str(x.level) for x in initial_states)
|
||||||
|
|
||||||
|
cg.add_global(
|
||||||
|
cg.RawExpression(
|
||||||
|
f"const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_MODE[16] = {{{initial_modes_s}}}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
cg.add_global(
|
||||||
|
cg.RawExpression(
|
||||||
|
f"const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[16] = {{{initial_levels_s}}}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in a new issue