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 | 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}}}" | ||||||
|  |         ) | ||||||
|  |     ) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user