diff --git a/esphomeyaml/const.py b/esphomeyaml/const.py index 73bee9d37e..e1715535be 100644 --- a/esphomeyaml/const.py +++ b/esphomeyaml/const.py @@ -255,6 +255,7 @@ CONF_IDLE = 'idle' CONF_NETWORKS = 'networks' CONF_INTERNAL = 'internal' CONF_BUILD_PATH = 'build_path' +CONF_PLATFORMIO_OPTIONS = 'platformio_options' CONF_REBOOT_TIMEOUT = 'reboot_timeout' CONF_INVERT = 'invert' CONF_DELAYED_ON = 'delayed_on' diff --git a/esphomeyaml/core_config.py b/esphomeyaml/core_config.py index 0e566585c2..b3ba6f384f 100644 --- a/esphomeyaml/core_config.py +++ b/esphomeyaml/core_config.py @@ -11,7 +11,7 @@ from esphomeyaml.const import ARDUINO_VERSION_ESP32_DEV, ARDUINO_VERSION_ESP8266 CONF_COMMIT, CONF_ESPHOMELIB_VERSION, CONF_ESPHOMEYAML, CONF_LOCAL, CONF_NAME, CONF_ON_BOOT, \ CONF_ON_LOOP, CONF_ON_SHUTDOWN, CONF_PLATFORM, CONF_PRIORITY, CONF_REPOSITORY, CONF_TAG, \ CONF_TRIGGER_ID, CONF_USE_CUSTOM_CODE, ESPHOMELIB_VERSION, ESP_PLATFORM_ESP32, \ - ESP_PLATFORM_ESP8266, CONF_LIBRARIES, CONF_INCLUDES + ESP_PLATFORM_ESP8266, CONF_LIBRARIES, CONF_INCLUDES, CONF_PLATFORMIO_OPTIONS from esphomeyaml.core import CORE, EsphomeyamlError from esphomeyaml.cpp_generator import Pvariable, RawExpression, add from esphomeyaml.cpp_types import App, NoArg, const_char_ptr, esphomelib_ns @@ -163,6 +163,9 @@ CONFIG_SCHEMA = vol.Schema({ vol.Optional(CONF_ARDUINO_VERSION, default='recommended'): validate_arduino_version, vol.Optional(CONF_USE_CUSTOM_CODE, default=False): cv.boolean, vol.Optional(CONF_BUILD_PATH, default=default_build_path): cv.string, + vol.Optional(CONF_PLATFORMIO_OPTIONS): vol.Schema({ + cv.string_strict: vol.Any([cv.string], cv.string), + }), vol.Optional(CONF_BOARD_FLASH_MODE): cv.one_of(*BUILD_FLASH_MODES, lower=True), vol.Optional(CONF_ON_BOOT): automation.validate_automation({ diff --git a/esphomeyaml/pins.py b/esphomeyaml/pins.py index 066a28611c..0cc47714c3 100644 --- a/esphomeyaml/pins.py +++ b/esphomeyaml/pins.py @@ -1,3 +1,5 @@ +from __future__ import division + import logging import voluptuous as vol @@ -57,6 +59,58 @@ ESP8266_BOARD_PINS = { 'xinabox_cw01': {'SDA': 2, 'SCL': 14, 'LED': 5, 'LED_RED': 12, 'LED_GREEN': 13} } +FLASH_SIZE_1_MB = 2**20 +FLASH_SIZE_512_KB = FLASH_SIZE_1_MB // 2 +FLASH_SIZE_2_MB = 2 * FLASH_SIZE_1_MB +FLASH_SIZE_4_MB = 4 * FLASH_SIZE_1_MB +FLASH_SIZE_16_MB = 4 * FLASH_SIZE_1_MB + +ESP8266_FLASH_SIZES = { + 'd1': FLASH_SIZE_4_MB, + 'd1_mini': FLASH_SIZE_4_MB, + 'd1_mini_lite': FLASH_SIZE_1_MB, + 'd1_mini_pro': FLASH_SIZE_16_MB, + 'esp01': FLASH_SIZE_512_KB, + 'esp01_1m': FLASH_SIZE_1_MB, + 'esp07': FLASH_SIZE_4_MB, + 'esp12e': FLASH_SIZE_4_MB, + 'esp210': FLASH_SIZE_4_MB, + 'esp8285': FLASH_SIZE_1_MB, + 'esp_wroom_02': FLASH_SIZE_2_MB, + 'espduino': FLASH_SIZE_4_MB, + 'espectro': FLASH_SIZE_4_MB, + 'espino': FLASH_SIZE_4_MB, + 'espinotee': FLASH_SIZE_4_MB, + 'espresso_lite_v1': FLASH_SIZE_4_MB, + 'espresso_lite_v2': FLASH_SIZE_4_MB, + 'gen4iod': FLASH_SIZE_512_KB, + 'heltec_wifi_kit_8': FLASH_SIZE_4_MB, + 'huzzah': FLASH_SIZE_4_MB, + 'modwifi': FLASH_SIZE_2_MB, + 'nodemcu': FLASH_SIZE_4_MB, + 'nodemcuv2': FLASH_SIZE_4_MB, + 'oak': FLASH_SIZE_4_MB, + 'phoenix_v1': FLASH_SIZE_4_MB, + 'phoenix_v2': FLASH_SIZE_4_MB, + 'sparkfunBlynk': FLASH_SIZE_4_MB, + 'thing': FLASH_SIZE_512_KB, + 'thingdev': FLASH_SIZE_512_KB, + 'wifi_slot': FLASH_SIZE_1_MB, + 'wifiduino': FLASH_SIZE_4_MB, + 'wifinfo': FLASH_SIZE_1_MB, + 'wio_link': FLASH_SIZE_4_MB, + 'wio_node': FLASH_SIZE_4_MB, + 'xinabox_cw01': FLASH_SIZE_4_MB, +} + +ESP8266_LD_SCRIPTS = { + FLASH_SIZE_512_KB: ('eagle.flash.512k0.ld', 'eagle.flash.512k.ld'), + FLASH_SIZE_1_MB: ('eagle.flash.1m0.ld', 'eagle.flash.1m.ld'), + FLASH_SIZE_2_MB: ('eagle.flash.2m.ld', 'eagle.flash.2m.ld'), + FLASH_SIZE_4_MB: ('eagle.flash.4m.ld', 'eagle.flash.4m.ld'), + FLASH_SIZE_16_MB: ('eagle.flash.16m.ld', 'eagle.flash.16m14m.ld'), +} + ESP32_BASE_PINS = { 'TX': 1, 'RX': 3, 'SDA': 21, 'SCL': 22, 'SS': 5, 'MOSI': 23, 'MISO': 19, 'SCK': 18, 'A0': 36, 'A3': 39, 'A4': 32, 'A5': 33, 'A6': 34, 'A7': 35, 'A10': 4, 'A11': 0, 'A12': 2, 'A13': 15, diff --git a/esphomeyaml/writer.py b/esphomeyaml/writer.py index e7b101b33a..27b3a0c157 100644 --- a/esphomeyaml/writer.py +++ b/esphomeyaml/writer.py @@ -9,11 +9,13 @@ import shutil from esphomeyaml.config import iter_components from esphomeyaml.const import ARDUINO_VERSION_ESP32_DEV, CONF_ARDUINO_VERSION, \ - CONF_BOARD_FLASH_MODE, CONF_BRANCH, CONF_COMMIT, CONF_ESPHOMELIB_VERSION, CONF_ESPHOMEYAML, \ - CONF_LOCAL, CONF_REPOSITORY, CONF_TAG, CONF_USE_CUSTOM_CODE + CONF_BRANCH, CONF_COMMIT, CONF_ESPHOMELIB_VERSION, CONF_ESPHOMEYAML, \ + CONF_LOCAL, CONF_REPOSITORY, CONF_TAG, CONF_USE_CUSTOM_CODE, CONF_PLATFORMIO_OPTIONS, \ + CONF_BOARD_FLASH_MODE, ARDUINO_VERSION_ESP8266_DEV from esphomeyaml.core import CORE, EsphomeyamlError from esphomeyaml.core_config import VERSION_REGEX, LIBRARY_URI_REPO, GITHUB_ARCHIVE_ZIP from esphomeyaml.helpers import mkdir_p, run_system_command +from esphomeyaml.pins import ESP8266_LD_SCRIPTS, ESP8266_FLASH_SIZES from esphomeyaml.storage_json import StorageJSON, storage_path from esphomeyaml.util import safe_print @@ -54,19 +56,6 @@ upload_flags = """) -INI_CONTENT_FORMAT = u"""[env:{env}] -platform = {platform} -board = {board} -framework = arduino -lib_deps = - {lib_deps} - ${{common.lib_deps}} -build_flags = - {build_flags} - ${{common.build_flags}} -upload_speed = {upload_speed} -""" - UPLOAD_SPEED_OVERRIDE = { 'esp210': 57600, } @@ -241,6 +230,18 @@ def symlink_esphomelib_version(esphomelib_version): os.unlink(dst_path) +def format_ini(data): + content = u'' + for key, value in sorted(data.items()): + if isinstance(value, (list, set, tuple)): + content += u'{} =\n'.format(key) + for x in value: + content += u' {}\n'.format(x) + else: + content += u'{} = {}\n'.format(key, value) + return content + + def gather_lib_deps(): lib_deps = set() esphomelib_version = CORE.config[CONF_ESPHOMEYAML][CONF_ESPHOMELIB_VERSION] @@ -281,7 +282,7 @@ def gather_lib_deps(): lib_deps.add('https://github.com/me-no-dev/AsyncTCP.git#idf-update') lib_deps.discard('AsyncTCP@1.0.1') # avoid changing build flags order - return sorted(x for x in lib_deps if x) + return list(sorted(x for x in lib_deps if x)) def gather_build_flags(): @@ -296,25 +297,45 @@ def gather_build_flags(): build_flags |= get_build_flags('REQUIRED_BUILD_FLAGS') # avoid changing build flags order - return sorted(list(build_flags)) + return list(sorted(list(build_flags))) def get_ini_content(): - version_specific_settings = determine_platformio_version_settings() - lib_deps = gather_lib_deps() - options = { - u'env': CORE.name, - u'platform': CORE.config[CONF_ESPHOMEYAML][CONF_ARDUINO_VERSION], - u'board': CORE.board, - u'build_flags': u'\n '.join(gather_build_flags()), - u'upload_speed': UPLOAD_SPEED_OVERRIDE.get(CORE.board, 115200), - u'lib_deps': u'\n '.join(lib_deps), + lib_deps = gather_lib_deps() + ['${common.lib_deps}'] + build_flags = gather_build_flags() + ['${common.build_flags}'] + + if CORE.is_esp8266 and CORE.board in ESP8266_FLASH_SIZES: + flash_size = ESP8266_FLASH_SIZES[CORE.board] + ld_scripts = ESP8266_LD_SCRIPTS[flash_size] + ld_script = None + + if CORE.arduino_version in ('espressif8266@1.8.0', 'espressif8266@1.7.3', + 'espressif8266@1.6.0', 'espressif8266@1.5.0'): + ld_script = ld_scripts[0] + elif CORE.arduino_version == ARDUINO_VERSION_ESP8266_DEV: + ld_script = ld_scripts[1] + + if ld_script is not None: + build_flags.append('-Wl,-T{}'.format(ld_script)) + + data = { + 'platform': CORE.config[CONF_ESPHOMEYAML][CONF_ARDUINO_VERSION], + 'board': CORE.board, + 'framework': 'arduino', + 'lib_deps': lib_deps, + 'build_flags': build_flags, + 'upload_speed': UPLOAD_SPEED_OVERRIDE.get(CORE.board, 115200), } - content = INI_CONTENT_FORMAT.format(**options) + if CONF_BOARD_FLASH_MODE in CORE.config[CONF_ESPHOMEYAML]: - flash_mode_key = version_specific_settings['flash_mode_key'] flash_mode = CORE.config[CONF_ESPHOMEYAML][CONF_BOARD_FLASH_MODE] - content += "{} = {}\n".format(flash_mode_key, flash_mode) + data['board_build.flash_mode'] = flash_mode + + data.update(CORE.config[CONF_ESPHOMEYAML].get(CONF_PLATFORMIO_OPTIONS, {})) + + content = u'[env:{}]\n'.format(CORE.name) + content += format_ini(data) + return content @@ -409,19 +430,6 @@ def write_cpp(code_s): f_handle.write(full_file) -def determine_platformio_version_settings(): - import platformio - - settings = {} - - if platformio.VERSION < (3, 5, 3): - settings['flash_mode_key'] = 'board_flash_mode' - else: - settings['flash_mode_key'] = 'board_build.flash_mode' - - return settings - - def clean_build(): for directory in ('.piolibdeps', '.pioenvs'): dir_path = CORE.relative_build_path(directory)