mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	ESP8266 early init for pins (#3144)
This commit is contained in:
		| @@ -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}}}" | ||||
|         ) | ||||
|     ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user