mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 13:34:54 +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
|
||||
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
|
||||
|
||||
# force import gpio to register pin schema
|
||||
from .gpio import esp8266_pin_to_code # noqa
|
||||
from .gpio import PinInitialState, add_pin_initial_states_array
|
||||
|
||||
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
|
@ -37,6 +42,9 @@ def set_core_data(config):
|
|||
config[CONF_FRAMEWORK][CONF_VERSION]
|
||||
)
|
||||
CORE.data[KEY_ESP8266][KEY_BOARD] = config[CONF_BOARD]
|
||||
CORE.data[KEY_ESP8266][KEY_PIN_INITIAL_STATES] = [
|
||||
PinInitialState() for _ in range(16)
|
||||
]
|
||||
return config
|
||||
|
||||
|
||||
|
@ -221,6 +229,8 @@ async def to_code(config):
|
|||
if ld_script is not None:
|
||||
cg.add_platformio_option("board_build.ldscript", ld_script)
|
||||
|
||||
CORE.add_job(add_pin_initial_states_array)
|
||||
|
||||
|
||||
# Called by writer.py
|
||||
def copy_files():
|
||||
|
|
|
@ -2,6 +2,7 @@ import esphome.codegen as cg
|
|||
|
||||
KEY_ESP8266 = "esp8266"
|
||||
KEY_BOARD = "board"
|
||||
KEY_PIN_INITIAL_STATES = "pin_initial_states"
|
||||
CONF_RESTORE_FROM_FLASH = "restore_from_flash"
|
||||
|
||||
# esp8266 namespace is already defined by arduino, manually prefix esphome
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#ifdef USE_ESP8266
|
||||
|
||||
#include "core.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "preferences.h"
|
||||
|
@ -53,6 +54,15 @@ extern "C" void resetPins() { // NOLINT
|
|||
// however, not strictly needed as we set up the pins properly
|
||||
// ourselves and this causes pins to toggle during reboot.
|
||||
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
|
||||
|
|
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
|
||||
from dataclasses import dataclass
|
||||
from typing import List
|
||||
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
|
@ -12,12 +14,12 @@ from esphome.const import (
|
|||
CONF_PULLUP,
|
||||
)
|
||||
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.codegen as cg
|
||||
|
||||
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__)
|
||||
|
@ -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)
|
||||
async def esp8266_pin_to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
num = config[CONF_NUMBER]
|
||||
mode = config[CONF_MODE]
|
||||
cg.add(var.set_pin(num))
|
||||
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
|
||||
|
||||
|
||||
@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