mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Merge branch 'gap_events' into integration
This commit is contained in:
		
							
								
								
									
										2
									
								
								.github/workflows/ci-docker.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/ci-docker.yml
									
									
									
									
										vendored
									
									
								
							| @@ -49,7 +49,7 @@ jobs: | ||||
|         with: | ||||
|           python-version: "3.10" | ||||
|       - name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3.11.0 | ||||
|         uses: docker/setup-buildx-action@v3.11.1 | ||||
|  | ||||
|       - name: Set TAG | ||||
|         run: | | ||||
|   | ||||
							
								
								
									
										4
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -99,7 +99,7 @@ jobs: | ||||
|           python-version: "3.10" | ||||
|  | ||||
|       - name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3.11.0 | ||||
|         uses: docker/setup-buildx-action@v3.11.1 | ||||
|  | ||||
|       - name: Log in to docker hub | ||||
|         uses: docker/login-action@v3.4.0 | ||||
| @@ -178,7 +178,7 @@ jobs: | ||||
|           merge-multiple: true | ||||
|  | ||||
|       - name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3.11.0 | ||||
|         uses: docker/setup-buildx-action@v3.11.1 | ||||
|  | ||||
|       - name: Log in to docker hub | ||||
|         if: matrix.registry == 'dockerhub' | ||||
|   | ||||
| @@ -193,14 +193,13 @@ void AcDimmer::setup() { | ||||
|   setTimer1Callback(&timer_interrupt); | ||||
| #endif | ||||
| #ifdef USE_ESP32 | ||||
|   // 80 Divider -> 1 count=1µs | ||||
|   dimmer_timer = timerBegin(0, 80, true); | ||||
|   timerAttachInterrupt(dimmer_timer, &AcDimmerDataStore::s_timer_intr, true); | ||||
|   // timer frequency of 1mhz | ||||
|   dimmer_timer = timerBegin(1000000); | ||||
|   timerAttachInterrupt(dimmer_timer, &AcDimmerDataStore::s_timer_intr); | ||||
|   // For ESP32, we can't use dynamic interval calculation because the timerX functions | ||||
|   // are not callable from ISR (placed in flash storage). | ||||
|   // Here we just use an interrupt firing every 50 µs. | ||||
|   timerAlarmWrite(dimmer_timer, 50, true); | ||||
|   timerAlarmEnable(dimmer_timer); | ||||
|   timerAlarm(dimmer_timer, 50, true, 0); | ||||
| #endif | ||||
| } | ||||
| void AcDimmer::write_state(float state) { | ||||
|   | ||||
| @@ -41,6 +41,7 @@ async def to_code(config): | ||||
|  | ||||
|     if CORE.using_arduino: | ||||
|         if CORE.is_esp32: | ||||
|             cg.add_library("ESP32 Async UDP", None) | ||||
|             cg.add_library("DNSServer", None) | ||||
|             cg.add_library("WiFi", None) | ||||
|         if CORE.is_esp8266: | ||||
|   | ||||
| @@ -132,6 +132,8 @@ def set_core_data(config): | ||||
|         choices = CPU_FREQUENCIES[variant] | ||||
|         if "160MHZ" in choices: | ||||
|             cpu_frequency = "160MHZ" | ||||
|         elif "360MHZ" in choices: | ||||
|             cpu_frequency = "360MHZ" | ||||
|         else: | ||||
|             cpu_frequency = choices[-1] | ||||
|         config[CONF_CPU_FREQUENCY] = cpu_frequency | ||||
| @@ -289,11 +291,8 @@ def add_extra_build_file(filename: str, path: str) -> bool: | ||||
|  | ||||
| def _format_framework_arduino_version(ver: cv.Version) -> str: | ||||
|     # format the given arduino (https://github.com/espressif/arduino-esp32/releases) version to | ||||
|     # a PIO platformio/framework-arduinoespressif32 value | ||||
|     # List of package versions: https://api.registry.platformio.org/v3/packages/platformio/tool/framework-arduinoespressif32 | ||||
|     if ver <= cv.Version(1, 0, 3): | ||||
|         return f"~2.{ver.major}{ver.minor:02d}{ver.patch:02d}.0" | ||||
|     return f"~3.{ver.major}{ver.minor:02d}{ver.patch:02d}.0" | ||||
|     # a PIO pioarduino/framework-arduinoespressif32 value | ||||
|     return f"pioarduino/framework-arduinoespressif32@https://github.com/espressif/arduino-esp32/releases/download/{str(ver)}/esp32-{str(ver)}.zip" | ||||
|  | ||||
|  | ||||
| def _format_framework_espidf_version( | ||||
| @@ -317,12 +316,10 @@ def _format_framework_espidf_version( | ||||
|  | ||||
| # The default/recommended arduino framework version | ||||
| #  - https://github.com/espressif/arduino-esp32/releases | ||||
| #  - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-arduinoespressif32 | ||||
| RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(2, 0, 5) | ||||
| # The platformio/espressif32 version to use for arduino frameworks | ||||
| #  - https://github.com/platformio/platform-espressif32/releases | ||||
| #  - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif32 | ||||
| ARDUINO_PLATFORM_VERSION = cv.Version(5, 4, 0) | ||||
| RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(3, 1, 3) | ||||
| # The platform-espressif32 version to use for arduino frameworks | ||||
| #  - https://github.com/pioarduino/platform-espressif32/releases | ||||
| ARDUINO_PLATFORM_VERSION = cv.Version(53, 3, 13) | ||||
|  | ||||
| # The default/recommended esp-idf framework version | ||||
| #  - https://github.com/espressif/esp-idf/releases | ||||
| @@ -365,8 +362,8 @@ SUPPORTED_PIOARDUINO_ESP_IDF_5X = [ | ||||
| def _arduino_check_versions(value): | ||||
|     value = value.copy() | ||||
|     lookups = { | ||||
|         "dev": (cv.Version(2, 1, 0), "https://github.com/espressif/arduino-esp32.git"), | ||||
|         "latest": (cv.Version(2, 0, 9), None), | ||||
|         "dev": (cv.Version(3, 1, 3), "https://github.com/espressif/arduino-esp32.git"), | ||||
|         "latest": (cv.Version(3, 1, 3), None), | ||||
|         "recommended": (RECOMMENDED_ARDUINO_FRAMEWORK_VERSION, None), | ||||
|     } | ||||
|  | ||||
| @@ -388,6 +385,10 @@ def _arduino_check_versions(value): | ||||
|         CONF_PLATFORM_VERSION, _parse_platform_version(str(ARDUINO_PLATFORM_VERSION)) | ||||
|     ) | ||||
|  | ||||
|     if value[CONF_SOURCE].startswith("http"): | ||||
|         # prefix is necessary or platformio will complain with a cryptic error | ||||
|         value[CONF_SOURCE] = f"framework-arduinoespressif32@{value[CONF_SOURCE]}" | ||||
|  | ||||
|     if version != RECOMMENDED_ARDUINO_FRAMEWORK_VERSION: | ||||
|         _LOGGER.warning( | ||||
|             "The selected Arduino framework version is not the recommended one. " | ||||
| @@ -829,10 +830,7 @@ async def to_code(config): | ||||
|         cg.add_platformio_option("framework", "arduino") | ||||
|         cg.add_build_flag("-DUSE_ARDUINO") | ||||
|         cg.add_build_flag("-DUSE_ESP32_FRAMEWORK_ARDUINO") | ||||
|         cg.add_platformio_option( | ||||
|             "platform_packages", | ||||
|             [f"platformio/framework-arduinoespressif32@{conf[CONF_SOURCE]}"], | ||||
|         ) | ||||
|         cg.add_platformio_option("platform_packages", [conf[CONF_SOURCE]]) | ||||
|  | ||||
|         if CONF_PARTITIONS in config: | ||||
|             cg.add_platformio_option("board_build.partitions", config[CONF_PARTITIONS]) | ||||
|   | ||||
| @@ -324,23 +324,69 @@ void ESP32BLE::loop() { | ||||
|       } | ||||
|       case BLEEvent::GAP: { | ||||
|         esp_gap_ble_cb_event_t gap_event = ble_event->event_.gap.gap_event; | ||||
|         if (gap_event == ESP_GAP_BLE_SCAN_RESULT_EVT) { | ||||
|           // Use the new scan event handler - no memcpy! | ||||
|           for (auto *scan_handler : this->gap_scan_event_handlers_) { | ||||
|             scan_handler->gap_scan_event_handler(ble_event->scan_result()); | ||||
|           } | ||||
|         } else if (gap_event == ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT || | ||||
|                    gap_event == ESP_GAP_BLE_SCAN_START_COMPLETE_EVT || | ||||
|                    gap_event == ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT) { | ||||
|           // All three scan complete events have the same structure with just status | ||||
|           // The scan_complete struct matches ESP-IDF's layout exactly, so this reinterpret_cast is safe | ||||
|           // This is verified at compile-time by static_assert checks in ble_event.h | ||||
|           // The struct already contains our copy of the status (copied in BLEEvent constructor) | ||||
|           ESP_LOGV(TAG, "gap_event_handler - %d", gap_event); | ||||
|           for (auto *gap_handler : this->gap_event_handlers_) { | ||||
|             gap_handler->gap_event_handler( | ||||
|                 gap_event, reinterpret_cast<esp_ble_gap_cb_param_t *>(&ble_event->event_.gap.scan_complete)); | ||||
|           } | ||||
|         switch (gap_event) { | ||||
|           case ESP_GAP_BLE_SCAN_RESULT_EVT: | ||||
|             // Use the new scan event handler - no memcpy! | ||||
|             for (auto *scan_handler : this->gap_scan_event_handlers_) { | ||||
|               scan_handler->gap_scan_event_handler(ble_event->scan_result()); | ||||
|             } | ||||
|             break; | ||||
|  | ||||
|           // Scan complete events | ||||
|           case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: | ||||
|           case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: | ||||
|           case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: | ||||
|             // All three scan complete events have the same structure with just status | ||||
|             // The scan_complete struct matches ESP-IDF's layout exactly, so this reinterpret_cast is safe | ||||
|             // This is verified at compile-time by static_assert checks in ble_event.h | ||||
|             // The struct already contains our copy of the status (copied in BLEEvent constructor) | ||||
|             ESP_LOGV(TAG, "gap_event_handler - %d", gap_event); | ||||
|             for (auto *gap_handler : this->gap_event_handlers_) { | ||||
|               gap_handler->gap_event_handler( | ||||
|                   gap_event, reinterpret_cast<esp_ble_gap_cb_param_t *>(&ble_event->event_.gap.scan_complete)); | ||||
|             } | ||||
|             break; | ||||
|  | ||||
|           // Advertising complete events | ||||
|           case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: | ||||
|           case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT: | ||||
|           case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: | ||||
|           case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: | ||||
|           case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: | ||||
|             // All advertising complete events have the same structure with just status | ||||
|             ESP_LOGV(TAG, "gap_event_handler - %d", gap_event); | ||||
|             for (auto *gap_handler : this->gap_event_handlers_) { | ||||
|               gap_handler->gap_event_handler( | ||||
|                   gap_event, reinterpret_cast<esp_ble_gap_cb_param_t *>(&ble_event->event_.gap.adv_complete)); | ||||
|             } | ||||
|             break; | ||||
|  | ||||
|           // RSSI complete event | ||||
|           case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT: | ||||
|             ESP_LOGV(TAG, "gap_event_handler - %d", gap_event); | ||||
|             for (auto *gap_handler : this->gap_event_handlers_) { | ||||
|               gap_handler->gap_event_handler( | ||||
|                   gap_event, reinterpret_cast<esp_ble_gap_cb_param_t *>(&ble_event->event_.gap.read_rssi_complete)); | ||||
|             } | ||||
|             break; | ||||
|  | ||||
|           // Security events | ||||
|           case ESP_GAP_BLE_AUTH_CMPL_EVT: | ||||
|           case ESP_GAP_BLE_SEC_REQ_EVT: | ||||
|           case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: | ||||
|           case ESP_GAP_BLE_PASSKEY_REQ_EVT: | ||||
|           case ESP_GAP_BLE_NC_REQ_EVT: | ||||
|             ESP_LOGV(TAG, "gap_event_handler - %d", gap_event); | ||||
|             for (auto *gap_handler : this->gap_event_handlers_) { | ||||
|               gap_handler->gap_event_handler( | ||||
|                   gap_event, reinterpret_cast<esp_ble_gap_cb_param_t *>(&ble_event->event_.gap.security)); | ||||
|             } | ||||
|             break; | ||||
|  | ||||
|           default: | ||||
|             // Unknown/unhandled event | ||||
|             ESP_LOGW(TAG, "Unhandled GAP event type in loop: %d", gap_event); | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
| @@ -399,11 +445,26 @@ template void enqueue_ble_event(esp_gattc_cb_event_t, esp_gatt_if_t, esp_ble_gat | ||||
|  | ||||
| void ESP32BLE::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { | ||||
|   switch (event) { | ||||
|     // Only queue the 4 GAP events we actually handle | ||||
|     // Queue GAP events that components need to handle | ||||
|     // Scanning events - used by esp32_ble_tracker | ||||
|     case ESP_GAP_BLE_SCAN_RESULT_EVT: | ||||
|     case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: | ||||
|     case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: | ||||
|     case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: | ||||
|     // Advertising events - used by esp32_ble_beacon and esp32_ble server | ||||
|     case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: | ||||
|     case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT: | ||||
|     case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: | ||||
|     case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: | ||||
|     case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: | ||||
|     // Connection events - used by ble_client | ||||
|     case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT: | ||||
|     // Security events - used by ble_client and bluetooth_proxy | ||||
|     case ESP_GAP_BLE_AUTH_CMPL_EVT: | ||||
|     case ESP_GAP_BLE_SEC_REQ_EVT: | ||||
|     case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: | ||||
|     case ESP_GAP_BLE_PASSKEY_REQ_EVT: | ||||
|     case ESP_GAP_BLE_NC_REQ_EVT: | ||||
|       enqueue_ble_event(event, param); | ||||
|       return; | ||||
|  | ||||
|   | ||||
| @@ -34,6 +34,41 @@ static_assert(offsetof(esp_ble_gap_cb_param_t, scan_stop_cmpl.status) == | ||||
|                   offsetof(esp_ble_gap_cb_param_t, scan_stop_cmpl), | ||||
|               "status must be first member of scan_stop_cmpl"); | ||||
|  | ||||
| // Compile-time verification for advertising complete events | ||||
| static_assert(sizeof(esp_ble_gap_cb_param_t::ble_adv_data_cmpl_evt_param) == sizeof(esp_bt_status_t), | ||||
|               "ESP-IDF adv_data_cmpl structure has unexpected size"); | ||||
| static_assert(sizeof(esp_ble_gap_cb_param_t::ble_scan_rsp_data_cmpl_evt_param) == sizeof(esp_bt_status_t), | ||||
|               "ESP-IDF scan_rsp_data_cmpl structure has unexpected size"); | ||||
| static_assert(sizeof(esp_ble_gap_cb_param_t::ble_adv_data_raw_cmpl_evt_param) == sizeof(esp_bt_status_t), | ||||
|               "ESP-IDF adv_data_raw_cmpl structure has unexpected size"); | ||||
| static_assert(sizeof(esp_ble_gap_cb_param_t::ble_adv_start_cmpl_evt_param) == sizeof(esp_bt_status_t), | ||||
|               "ESP-IDF adv_start_cmpl structure has unexpected size"); | ||||
| static_assert(sizeof(esp_ble_gap_cb_param_t::ble_adv_stop_cmpl_evt_param) == sizeof(esp_bt_status_t), | ||||
|               "ESP-IDF adv_stop_cmpl structure has unexpected size"); | ||||
|  | ||||
| // Verify the status field is at offset 0 for advertising events | ||||
| static_assert(offsetof(esp_ble_gap_cb_param_t, adv_data_cmpl.status) == offsetof(esp_ble_gap_cb_param_t, adv_data_cmpl), | ||||
|               "status must be first member of adv_data_cmpl"); | ||||
| static_assert(offsetof(esp_ble_gap_cb_param_t, scan_rsp_data_cmpl.status) == | ||||
|                   offsetof(esp_ble_gap_cb_param_t, scan_rsp_data_cmpl), | ||||
|               "status must be first member of scan_rsp_data_cmpl"); | ||||
| static_assert(offsetof(esp_ble_gap_cb_param_t, adv_data_raw_cmpl.status) == | ||||
|                   offsetof(esp_ble_gap_cb_param_t, adv_data_raw_cmpl), | ||||
|               "status must be first member of adv_data_raw_cmpl"); | ||||
| static_assert(offsetof(esp_ble_gap_cb_param_t, adv_start_cmpl.status) == | ||||
|                   offsetof(esp_ble_gap_cb_param_t, adv_start_cmpl), | ||||
|               "status must be first member of adv_start_cmpl"); | ||||
| static_assert(offsetof(esp_ble_gap_cb_param_t, adv_stop_cmpl.status) == offsetof(esp_ble_gap_cb_param_t, adv_stop_cmpl), | ||||
|               "status must be first member of adv_stop_cmpl"); | ||||
|  | ||||
| // Compile-time verification for RSSI complete event structure | ||||
| static_assert(offsetof(esp_ble_gap_cb_param_t, read_rssi_cmpl.status) == 0, | ||||
|               "status must be first member of read_rssi_cmpl"); | ||||
| static_assert(offsetof(esp_ble_gap_cb_param_t, read_rssi_cmpl.rssi) == sizeof(esp_bt_status_t), | ||||
|               "rssi must immediately follow status in read_rssi_cmpl"); | ||||
| static_assert(offsetof(esp_ble_gap_cb_param_t, read_rssi_cmpl.remote_addr) == sizeof(esp_bt_status_t) + sizeof(int8_t), | ||||
|               "remote_addr must follow rssi in read_rssi_cmpl"); | ||||
|  | ||||
| // Received GAP, GATTC and GATTS events are only queued, and get processed in the main loop(). | ||||
| // This class stores each event with minimal memory usage. | ||||
| // GAP events (99% of traffic) don't have the vector overhead. | ||||
| @@ -147,12 +182,28 @@ class BLEEvent { | ||||
|     struct gap_event { | ||||
|       esp_gap_ble_cb_event_t gap_event; | ||||
|       union { | ||||
|         BLEScanResult scan_result;  // 73 bytes | ||||
|         BLEScanResult scan_result;  // 73 bytes - Used by: esp32_ble_tracker | ||||
|         // This matches ESP-IDF's scan complete event structures | ||||
|         // All three (scan_param_cmpl, scan_start_cmpl, scan_stop_cmpl) have identical layout | ||||
|         // Used by: esp32_ble_tracker | ||||
|         struct { | ||||
|           esp_bt_status_t status; | ||||
|         } scan_complete;  // 1 byte | ||||
|         // Advertising complete events all have same structure | ||||
|         // Used by: esp32_ble_beacon, esp32_ble server components | ||||
|         struct { | ||||
|           esp_bt_status_t status; | ||||
|         } adv_complete;  // 1 byte - for ADV_DATA_SET, SCAN_RSP_DATA_SET, ADV_DATA_RAW_SET, ADV_START, ADV_STOP | ||||
|         // RSSI complete event | ||||
|         // Used by: ble_client (ble_rssi_sensor component) | ||||
|         struct { | ||||
|           esp_bt_status_t status; | ||||
|           int8_t rssi; | ||||
|           esp_bd_addr_t remote_addr; | ||||
|         } read_rssi_complete;  // 8 bytes | ||||
|         // Security events - we store the full security union | ||||
|         // Used by: ble_client (automation), bluetooth_proxy, esp32_ble_client | ||||
|         esp_ble_sec_t security;  // Variable size, but fits within scan_result size | ||||
|       }; | ||||
|     } gap;  // 80 bytes total | ||||
|  | ||||
| @@ -180,6 +231,11 @@ class BLEEvent { | ||||
|   esp_gap_ble_cb_event_t gap_event_type() const { return event_.gap.gap_event; } | ||||
|   const BLEScanResult &scan_result() const { return event_.gap.scan_result; } | ||||
|   esp_bt_status_t scan_complete_status() const { return event_.gap.scan_complete.status; } | ||||
|   esp_bt_status_t adv_complete_status() const { return event_.gap.adv_complete.status; } | ||||
|   const esp_ble_gap_cb_param_t::ble_read_rssi_cmpl_evt_param &read_rssi_complete() const { | ||||
|     return event_.gap.read_rssi_complete; | ||||
|   } | ||||
|   const esp_ble_sec_t &security() const { return event_.gap.security; } | ||||
|  | ||||
|  private: | ||||
|   // Initialize GAP event data | ||||
| @@ -215,8 +271,47 @@ class BLEEvent { | ||||
|         this->event_.gap.scan_complete.status = p->scan_stop_cmpl.status; | ||||
|         break; | ||||
|  | ||||
|       // Advertising complete events - all have same structure with just status | ||||
|       // Used by: esp32_ble_beacon, esp32_ble server components | ||||
|       case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: | ||||
|         this->event_.gap.adv_complete.status = p->adv_data_cmpl.status; | ||||
|         break; | ||||
|       case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT: | ||||
|         this->event_.gap.adv_complete.status = p->scan_rsp_data_cmpl.status; | ||||
|         break; | ||||
|       case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:  // Used by: esp32_ble_beacon | ||||
|         this->event_.gap.adv_complete.status = p->adv_data_raw_cmpl.status; | ||||
|         break; | ||||
|       case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:  // Used by: esp32_ble_beacon | ||||
|         this->event_.gap.adv_complete.status = p->adv_start_cmpl.status; | ||||
|         break; | ||||
|       case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:  // Used by: esp32_ble_beacon | ||||
|         this->event_.gap.adv_complete.status = p->adv_stop_cmpl.status; | ||||
|         break; | ||||
|  | ||||
|       // RSSI complete event | ||||
|       // Used by: ble_client (ble_rssi_sensor) | ||||
|       case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT: | ||||
|         this->event_.gap.read_rssi_complete.status = p->read_rssi_cmpl.status; | ||||
|         this->event_.gap.read_rssi_complete.rssi = p->read_rssi_cmpl.rssi; | ||||
|         memcpy(this->event_.gap.read_rssi_complete.remote_addr, p->read_rssi_cmpl.remote_addr, sizeof(esp_bd_addr_t)); | ||||
|         break; | ||||
|  | ||||
|       // Security events - copy the entire security union | ||||
|       // Used by: ble_client, bluetooth_proxy, esp32_ble_client | ||||
|       case ESP_GAP_BLE_AUTH_CMPL_EVT:      // Used by: bluetooth_proxy, esp32_ble_client | ||||
|       case ESP_GAP_BLE_SEC_REQ_EVT:        // Used by: esp32_ble_client | ||||
|       case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:  // Used by: ble_client automation | ||||
|       case ESP_GAP_BLE_PASSKEY_REQ_EVT:    // Used by: ble_client automation | ||||
|       case ESP_GAP_BLE_NC_REQ_EVT:         // Used by: ble_client automation | ||||
|         memcpy(&this->event_.gap.security, &p->ble_security, sizeof(esp_ble_sec_t)); | ||||
|         break; | ||||
|  | ||||
|       default: | ||||
|         // We only handle 4 GAP event types, others are dropped | ||||
|         // We only store data for GAP events that components currently use | ||||
|         // Unknown events still get queued and logged in ble.cpp:375 as | ||||
|         // "Unhandled GAP event type in loop" - this helps identify new events | ||||
|         // that components might need in the future | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
| @@ -295,6 +390,12 @@ class BLEEvent { | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // Verify the gap_event union hasn't grown beyond expected size | ||||
| static_assert(sizeof(BLEEvent::gap_event) <= 80, "gap_event union has grown beyond 80 bytes"); | ||||
|  | ||||
| // Verify esp_ble_sec_t fits within our union | ||||
| static_assert(sizeof(esp_ble_sec_t) <= 73, "esp_ble_sec_t is larger than BLEScanResult"); | ||||
|  | ||||
| // BLEEvent total size: 84 bytes (80 byte union + 1 byte type + 3 bytes padding) | ||||
|  | ||||
| }  // namespace esp32_ble | ||||
|   | ||||
| @@ -3,7 +3,7 @@ import esphome.config_validation as cv | ||||
| from esphome.const import CONF_ID, CONF_MODE, CONF_PORT | ||||
|  | ||||
| CODEOWNERS = ["@ayufan"] | ||||
| DEPENDENCIES = ["esp32_camera"] | ||||
| DEPENDENCIES = ["esp32_camera", "network"] | ||||
| MULTI_CONF = True | ||||
|  | ||||
| esp32_camera_web_server_ns = cg.esphome_ns.namespace("esp32_camera_web_server") | ||||
|   | ||||
| @@ -1,48 +1,8 @@ | ||||
| import esphome.codegen as cg | ||||
| from esphome.components import esp32 | ||||
| import esphome.config_validation as cv | ||||
| from esphome.const import KEY_CORE, KEY_FRAMEWORK_VERSION | ||||
| from esphome.core import CORE | ||||
|  | ||||
| CODEOWNERS = ["@jesserockz"] | ||||
|  | ||||
| RMT_TX_CHANNELS = { | ||||
|     esp32.const.VARIANT_ESP32: [0, 1, 2, 3, 4, 5, 6, 7], | ||||
|     esp32.const.VARIANT_ESP32S2: [0, 1, 2, 3], | ||||
|     esp32.const.VARIANT_ESP32S3: [0, 1, 2, 3], | ||||
|     esp32.const.VARIANT_ESP32C3: [0, 1], | ||||
|     esp32.const.VARIANT_ESP32C6: [0, 1], | ||||
|     esp32.const.VARIANT_ESP32H2: [0, 1], | ||||
| } | ||||
|  | ||||
| RMT_RX_CHANNELS = { | ||||
|     esp32.const.VARIANT_ESP32: [0, 1, 2, 3, 4, 5, 6, 7], | ||||
|     esp32.const.VARIANT_ESP32S2: [0, 1, 2, 3], | ||||
|     esp32.const.VARIANT_ESP32S3: [4, 5, 6, 7], | ||||
|     esp32.const.VARIANT_ESP32C3: [2, 3], | ||||
|     esp32.const.VARIANT_ESP32C6: [2, 3], | ||||
|     esp32.const.VARIANT_ESP32H2: [2, 3], | ||||
| } | ||||
|  | ||||
| rmt_channel_t = cg.global_ns.enum("rmt_channel_t") | ||||
| RMT_CHANNEL_ENUMS = { | ||||
|     0: rmt_channel_t.RMT_CHANNEL_0, | ||||
|     1: rmt_channel_t.RMT_CHANNEL_1, | ||||
|     2: rmt_channel_t.RMT_CHANNEL_2, | ||||
|     3: rmt_channel_t.RMT_CHANNEL_3, | ||||
|     4: rmt_channel_t.RMT_CHANNEL_4, | ||||
|     5: rmt_channel_t.RMT_CHANNEL_5, | ||||
|     6: rmt_channel_t.RMT_CHANNEL_6, | ||||
|     7: rmt_channel_t.RMT_CHANNEL_7, | ||||
| } | ||||
|  | ||||
|  | ||||
| def use_new_rmt_driver(): | ||||
|     framework_version = CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] | ||||
|     if CORE.using_esp_idf and framework_version >= cv.Version(5, 0, 0): | ||||
|         return True | ||||
|     return False | ||||
|  | ||||
|  | ||||
| def validate_clock_resolution(): | ||||
|     def _validator(value): | ||||
| @@ -60,21 +20,3 @@ def validate_clock_resolution(): | ||||
|         return value | ||||
|  | ||||
|     return _validator | ||||
|  | ||||
|  | ||||
| def validate_rmt_channel(*, tx: bool): | ||||
|     rmt_channels = RMT_TX_CHANNELS if tx else RMT_RX_CHANNELS | ||||
|  | ||||
|     def _validator(value): | ||||
|         cv.only_on_esp32(value) | ||||
|         value = cv.int_(value) | ||||
|         variant = esp32.get_esp32_variant() | ||||
|         if variant not in rmt_channels: | ||||
|             raise cv.Invalid(f"ESP32 variant {variant} does not support RMT.") | ||||
|         if value not in rmt_channels[variant]: | ||||
|             raise cv.Invalid( | ||||
|                 f"RMT channel {value} does not support {'transmitting' if tx else 'receiving'} for ESP32 variant {variant}." | ||||
|             ) | ||||
|         return cv.enum(RMT_CHANNEL_ENUMS)(value) | ||||
|  | ||||
|     return _validator | ||||
|   | ||||
| @@ -42,7 +42,6 @@ void ESP32RMTLEDStripLightOutput::setup() { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   RAMAllocator<rmt_symbol_word_t> rmt_allocator(this->use_psram_ ? 0 : RAMAllocator<rmt_symbol_word_t>::ALLOC_INTERNAL); | ||||
|  | ||||
|   // 8 bits per byte, 1 rmt_symbol_word_t per bit + 1 rmt_symbol_word_t for reset | ||||
| @@ -79,36 +78,6 @@ void ESP32RMTLEDStripLightOutput::setup() { | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
| #else | ||||
|   RAMAllocator<rmt_item32_t> rmt_allocator(this->use_psram_ ? 0 : RAMAllocator<rmt_item32_t>::ALLOC_INTERNAL); | ||||
|  | ||||
|   // 8 bits per byte, 1 rmt_item32_t per bit + 1 rmt_item32_t for reset | ||||
|   this->rmt_buf_ = rmt_allocator.allocate(buffer_size * 8 + 1); | ||||
|  | ||||
|   rmt_config_t config; | ||||
|   memset(&config, 0, sizeof(config)); | ||||
|   config.channel = this->channel_; | ||||
|   config.rmt_mode = RMT_MODE_TX; | ||||
|   config.gpio_num = gpio_num_t(this->pin_); | ||||
|   config.mem_block_num = 1; | ||||
|   config.clk_div = RMT_CLK_DIV; | ||||
|   config.tx_config.loop_en = false; | ||||
|   config.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW; | ||||
|   config.tx_config.carrier_en = false; | ||||
|   config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW; | ||||
|   config.tx_config.idle_output_en = true; | ||||
|  | ||||
|   if (rmt_config(&config) != ESP_OK) { | ||||
|     ESP_LOGE(TAG, "Cannot initialize RMT!"); | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
|   if (rmt_driver_install(config.channel, 0, 0) != ESP_OK) { | ||||
|     ESP_LOGE(TAG, "Cannot install RMT driver!"); | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void ESP32RMTLEDStripLightOutput::set_led_params(uint32_t bit0_high, uint32_t bit0_low, uint32_t bit1_high, | ||||
| @@ -145,11 +114,7 @@ void ESP32RMTLEDStripLightOutput::write_state(light::LightState *state) { | ||||
|  | ||||
|   ESP_LOGVV(TAG, "Writing RGB values to bus"); | ||||
|  | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   esp_err_t error = rmt_tx_wait_all_done(this->channel_, 1000); | ||||
| #else | ||||
|   esp_err_t error = rmt_wait_tx_done(this->channel_, pdMS_TO_TICKS(1000)); | ||||
| #endif | ||||
|   if (error != ESP_OK) { | ||||
|     ESP_LOGE(TAG, "RMT TX timeout"); | ||||
|     this->status_set_warning(); | ||||
| @@ -162,11 +127,7 @@ void ESP32RMTLEDStripLightOutput::write_state(light::LightState *state) { | ||||
|   size_t size = 0; | ||||
|   size_t len = 0; | ||||
|   uint8_t *psrc = this->buf_; | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   rmt_symbol_word_t *pdest = this->rmt_buf_; | ||||
| #else | ||||
|   rmt_item32_t *pdest = this->rmt_buf_; | ||||
| #endif | ||||
|   while (size < buffer_size) { | ||||
|     uint8_t b = *psrc; | ||||
|     for (int i = 0; i < 8; i++) { | ||||
| @@ -184,15 +145,11 @@ void ESP32RMTLEDStripLightOutput::write_state(light::LightState *state) { | ||||
|     len++; | ||||
|   } | ||||
|  | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   rmt_transmit_config_t config; | ||||
|   memset(&config, 0, sizeof(config)); | ||||
|   config.loop_count = 0; | ||||
|   config.flags.eot_level = 0; | ||||
|   error = rmt_transmit(this->channel_, this->encoder_, this->rmt_buf_, len * sizeof(rmt_symbol_word_t), &config); | ||||
| #else | ||||
|   error = rmt_write_items(this->channel_, this->rmt_buf_, len, false); | ||||
| #endif | ||||
|   if (error != ESP_OK) { | ||||
|     ESP_LOGE(TAG, "RMT TX error"); | ||||
|     this->status_set_warning(); | ||||
| @@ -251,11 +208,7 @@ void ESP32RMTLEDStripLightOutput::dump_config() { | ||||
|                 "ESP32 RMT LED Strip:\n" | ||||
|                 "  Pin: %u", | ||||
|                 this->pin_); | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   ESP_LOGCONFIG(TAG, "  RMT Symbols: %" PRIu32, this->rmt_symbols_); | ||||
| #else | ||||
|   ESP_LOGCONFIG(TAG, "  Channel: %u", this->channel_); | ||||
| #endif | ||||
|   const char *rgb_order; | ||||
|   switch (this->rgb_order_) { | ||||
|     case ORDER_RGB: | ||||
|   | ||||
| @@ -11,12 +11,7 @@ | ||||
| #include <driver/gpio.h> | ||||
| #include <esp_err.h> | ||||
| #include <esp_idf_version.h> | ||||
|  | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
| #include <driver/rmt_tx.h> | ||||
| #else | ||||
| #include <driver/rmt.h> | ||||
| #endif | ||||
|  | ||||
| namespace esphome { | ||||
| namespace esp32_rmt_led_strip { | ||||
| @@ -61,11 +56,7 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight { | ||||
|                       uint32_t reset_time_high, uint32_t reset_time_low); | ||||
|  | ||||
|   void set_rgb_order(RGBOrder rgb_order) { this->rgb_order_ = rgb_order; } | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   void set_rmt_symbols(uint32_t rmt_symbols) { this->rmt_symbols_ = rmt_symbols; } | ||||
| #else | ||||
|   void set_rmt_channel(rmt_channel_t channel) { this->channel_ = channel; } | ||||
| #endif | ||||
|  | ||||
|   void clear_effect_data() override { | ||||
|     for (int i = 0; i < this->size(); i++) | ||||
| @@ -81,17 +72,11 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight { | ||||
|  | ||||
|   uint8_t *buf_{nullptr}; | ||||
|   uint8_t *effect_data_{nullptr}; | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   rmt_channel_handle_t channel_{nullptr}; | ||||
|   rmt_encoder_handle_t encoder_{nullptr}; | ||||
|   rmt_symbol_word_t *rmt_buf_{nullptr}; | ||||
|   rmt_symbol_word_t bit0_, bit1_, reset_; | ||||
|   uint32_t rmt_symbols_{48}; | ||||
| #else | ||||
|   rmt_item32_t *rmt_buf_{nullptr}; | ||||
|   rmt_item32_t bit0_, bit1_, reset_; | ||||
|   rmt_channel_t channel_{RMT_CHANNEL_0}; | ||||
| #endif | ||||
|  | ||||
|   uint8_t pin_; | ||||
|   uint16_t num_leds_; | ||||
|   | ||||
| @@ -3,7 +3,7 @@ import logging | ||||
|  | ||||
| from esphome import pins | ||||
| import esphome.codegen as cg | ||||
| from esphome.components import esp32, esp32_rmt, light | ||||
| from esphome.components import esp32, light | ||||
| import esphome.config_validation as cv | ||||
| from esphome.const import ( | ||||
|     CONF_CHIPSET, | ||||
| @@ -13,11 +13,9 @@ from esphome.const import ( | ||||
|     CONF_OUTPUT_ID, | ||||
|     CONF_PIN, | ||||
|     CONF_RGB_ORDER, | ||||
|     CONF_RMT_CHANNEL, | ||||
|     CONF_RMT_SYMBOLS, | ||||
|     CONF_USE_DMA, | ||||
| ) | ||||
| from esphome.core import CORE | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| @@ -69,53 +67,6 @@ CONF_RESET_HIGH = "reset_high" | ||||
| CONF_RESET_LOW = "reset_low" | ||||
|  | ||||
|  | ||||
| class OptionalForIDF5(cv.SplitDefault): | ||||
|     @property | ||||
|     def default(self): | ||||
|         if not esp32_rmt.use_new_rmt_driver(): | ||||
|             return cv.UNDEFINED | ||||
|         return super().default | ||||
|  | ||||
|     @default.setter | ||||
|     def default(self, value): | ||||
|         # Ignore default set from vol.Optional | ||||
|         pass | ||||
|  | ||||
|  | ||||
| def only_with_new_rmt_driver(obj): | ||||
|     if not esp32_rmt.use_new_rmt_driver(): | ||||
|         raise cv.Invalid( | ||||
|             "This feature is only available for the IDF framework version 5." | ||||
|         ) | ||||
|     return obj | ||||
|  | ||||
|  | ||||
| def not_with_new_rmt_driver(obj): | ||||
|     if esp32_rmt.use_new_rmt_driver(): | ||||
|         raise cv.Invalid( | ||||
|             "This feature is not available for the IDF framework version 5." | ||||
|         ) | ||||
|     return obj | ||||
|  | ||||
|  | ||||
| def final_validation(config): | ||||
|     if not esp32_rmt.use_new_rmt_driver(): | ||||
|         if CONF_RMT_CHANNEL not in config: | ||||
|             if CORE.using_esp_idf: | ||||
|                 raise cv.Invalid( | ||||
|                     "rmt_channel is a required option for IDF version < 5." | ||||
|                 ) | ||||
|             raise cv.Invalid( | ||||
|                 "rmt_channel is a required option for the Arduino framework." | ||||
|             ) | ||||
|         _LOGGER.warning( | ||||
|             "RMT_LED_STRIP support for IDF version < 5 is deprecated and will be removed soon." | ||||
|         ) | ||||
|  | ||||
|  | ||||
| FINAL_VALIDATE_SCHEMA = final_validation | ||||
|  | ||||
|  | ||||
| CONFIG_SCHEMA = cv.All( | ||||
|     light.ADDRESSABLE_LIGHT_SCHEMA.extend( | ||||
|         { | ||||
| @@ -123,20 +74,17 @@ CONFIG_SCHEMA = cv.All( | ||||
|             cv.Required(CONF_PIN): pins.internal_gpio_output_pin_number, | ||||
|             cv.Required(CONF_NUM_LEDS): cv.positive_not_null_int, | ||||
|             cv.Required(CONF_RGB_ORDER): cv.enum(RGB_ORDERS, upper=True), | ||||
|             cv.Optional(CONF_RMT_CHANNEL): cv.All( | ||||
|                 not_with_new_rmt_driver, esp32_rmt.validate_rmt_channel(tx=True) | ||||
|             ), | ||||
|             OptionalForIDF5( | ||||
|             cv.SplitDefault( | ||||
|                 CONF_RMT_SYMBOLS, | ||||
|                 esp32_idf=192, | ||||
|                 esp32_s2_idf=192, | ||||
|                 esp32_s3_idf=192, | ||||
|                 esp32_p4_idf=192, | ||||
|                 esp32_c3_idf=96, | ||||
|                 esp32_c5_idf=96, | ||||
|                 esp32_c6_idf=96, | ||||
|                 esp32_h2_idf=96, | ||||
|             ): cv.All(only_with_new_rmt_driver, cv.int_range(min=2)), | ||||
|                 esp32=192, | ||||
|                 esp32_s2=192, | ||||
|                 esp32_s3=192, | ||||
|                 esp32_p4=192, | ||||
|                 esp32_c3=96, | ||||
|                 esp32_c5=96, | ||||
|                 esp32_c6=96, | ||||
|                 esp32_h2=96, | ||||
|             ): cv.int_range(min=2), | ||||
|             cv.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds, | ||||
|             cv.Optional(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True), | ||||
|             cv.Optional(CONF_IS_RGBW, default=False): cv.boolean, | ||||
| @@ -145,7 +93,6 @@ CONFIG_SCHEMA = cv.All( | ||||
|                 esp32.only_on_variant( | ||||
|                     supported=[esp32.const.VARIANT_ESP32S3, esp32.const.VARIANT_ESP32P4] | ||||
|                 ), | ||||
|                 cv.only_with_esp_idf, | ||||
|                 cv.boolean, | ||||
|             ), | ||||
|             cv.Optional(CONF_USE_PSRAM, default=True): cv.boolean, | ||||
| @@ -218,15 +165,6 @@ async def to_code(config): | ||||
|     cg.add(var.set_is_rgbw(config[CONF_IS_RGBW])) | ||||
|     cg.add(var.set_is_wrgb(config[CONF_IS_WRGB])) | ||||
|     cg.add(var.set_use_psram(config[CONF_USE_PSRAM])) | ||||
|  | ||||
|     if esp32_rmt.use_new_rmt_driver(): | ||||
|         cg.add(var.set_rmt_symbols(config[CONF_RMT_SYMBOLS])) | ||||
|         if CONF_USE_DMA in config: | ||||
|             cg.add(var.set_use_dma(config[CONF_USE_DMA])) | ||||
|     else: | ||||
|         rmt_channel_t = cg.global_ns.enum("rmt_channel_t") | ||||
|         cg.add( | ||||
|             var.set_rmt_channel( | ||||
|                 getattr(rmt_channel_t, f"RMT_CHANNEL_{config[CONF_RMT_CHANNEL]}") | ||||
|             ) | ||||
|         ) | ||||
|     cg.add(var.set_rmt_symbols(config[CONF_RMT_SYMBOLS])) | ||||
|     if CONF_USE_DMA in config: | ||||
|         cg.add(var.set_use_dma(config[CONF_USE_DMA])) | ||||
|   | ||||
| @@ -106,7 +106,7 @@ void EthernetComponent::setup() { | ||||
|       .post_cb = nullptr, | ||||
|   }; | ||||
|  | ||||
| #if USE_ESP_IDF && (ESP_IDF_VERSION_MAJOR >= 5) | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(host, &devcfg); | ||||
| #else | ||||
|   spi_device_handle_t spi_handle = nullptr; | ||||
|   | ||||
| @@ -175,7 +175,7 @@ async def to_code(config): | ||||
|                 not config.get(CONF_VERIFY_SSL), | ||||
|             ) | ||||
|         else: | ||||
|             cg.add_library("WiFiClientSecure", None) | ||||
|             cg.add_library("NetworkClientSecure", None) | ||||
|             cg.add_library("HTTPClient", None) | ||||
|     if CORE.is_esp8266: | ||||
|         cg.add_library("ESP8266HTTPClient", None) | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
|  | ||||
| #if defined(USE_ESP32) || defined(USE_RP2040) | ||||
| #include <HTTPClient.h> | ||||
| #include <WiFiClient.h> | ||||
| #endif | ||||
| #ifdef USE_ESP8266 | ||||
| #include <ESP8266HTTPClient.h> | ||||
|   | ||||
| @@ -125,7 +125,7 @@ ErrorCode ArduinoI2CBus::readv(uint8_t address, ReadBuffer *buffers, size_t cnt) | ||||
|   size_t to_request = 0; | ||||
|   for (size_t i = 0; i < cnt; i++) | ||||
|     to_request += buffers[i].len; | ||||
|   size_t ret = wire_->requestFrom((int) address, (int) to_request, 1); | ||||
|   size_t ret = wire_->requestFrom(address, to_request, true); | ||||
|   if (ret != to_request) { | ||||
|     ESP_LOGVV(TAG, "RX %u from %02X failed with error %u", to_request, address, ret); | ||||
|     return ERROR_TIMEOUT; | ||||
|   | ||||
| @@ -9,7 +9,7 @@ namespace i2s_audio { | ||||
|  | ||||
| static const char *const TAG = "i2s_audio"; | ||||
|  | ||||
| #if defined(USE_ESP_IDF) && (ESP_IDF_VERSION_MAJOR >= 5) | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
| static const uint8_t I2S_NUM_MAX = SOC_I2S_NUM;  // because IDF 5+ took this away :( | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -114,7 +114,7 @@ async def to_code(config): | ||||
|         cg.add(var.set_external_dac_channels(2 if config[CONF_MODE] == "stereo" else 1)) | ||||
|         cg.add(var.set_i2s_comm_fmt_lsb(config[CONF_I2S_COMM_FMT] == "lsb")) | ||||
|  | ||||
|     cg.add_library("WiFiClientSecure", None) | ||||
|     cg.add_library("NetworkClientSecure", None) | ||||
|     cg.add_library("HTTPClient", None) | ||||
|     cg.add_library("esphome/ESP32-audioI2S", "2.3.0") | ||||
|     cg.add_build_flag("-DAUDIO_NO_SD_FS") | ||||
|   | ||||
| @@ -3,28 +3,16 @@ | ||||
|  | ||||
| #ifdef USE_ESP32 | ||||
|  | ||||
| #ifdef USE_ARDUINO | ||||
| #include <esp32-hal-ledc.h> | ||||
| #endif | ||||
| #include <driver/ledc.h> | ||||
|  | ||||
| #include <cinttypes> | ||||
|  | ||||
| #define CLOCK_FREQUENCY 80e6f | ||||
|  | ||||
| #ifdef USE_ARDUINO | ||||
| #ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK | ||||
| #undef CLOCK_FREQUENCY | ||||
| // starting with ESP32 Arduino 2.0.2, the 40MHz crystal is used as clock by default if supported | ||||
| #define CLOCK_FREQUENCY 40e6f | ||||
| #endif | ||||
| #else | ||||
| #ifdef SOC_LEDC_SUPPORT_APB_CLOCK | ||||
| #define DEFAULT_CLK LEDC_USE_APB_CLK | ||||
| #else | ||||
| #define DEFAULT_CLK LEDC_AUTO_CLK | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| static const uint8_t SETUP_ATTEMPT_COUNT_MAX = 5; | ||||
|  | ||||
| @@ -34,7 +22,6 @@ namespace ledc { | ||||
| static const char *const TAG = "ledc.output"; | ||||
|  | ||||
| static const int MAX_RES_BITS = LEDC_TIMER_BIT_MAX - 1; | ||||
| #ifdef USE_ESP_IDF | ||||
| #if SOC_LEDC_SUPPORT_HS_MODE | ||||
| // Only ESP32 has LEDC_HIGH_SPEED_MODE | ||||
| inline ledc_mode_t get_speed_mode(uint8_t channel) { return channel < 8 ? LEDC_HIGH_SPEED_MODE : LEDC_LOW_SPEED_MODE; } | ||||
| @@ -44,7 +31,6 @@ inline ledc_mode_t get_speed_mode(uint8_t channel) { return channel < 8 ? LEDC_H | ||||
| // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-reference/peripherals/ledc.html#functionality-overview | ||||
| inline ledc_mode_t get_speed_mode(uint8_t) { return LEDC_LOW_SPEED_MODE; } | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| float ledc_max_frequency_for_bit_depth(uint8_t bit_depth) { | ||||
|   return static_cast<float>(CLOCK_FREQUENCY) / static_cast<float>(1 << bit_depth); | ||||
| @@ -68,7 +54,6 @@ optional<uint8_t> ledc_bit_depth_for_frequency(float frequency) { | ||||
|   return {}; | ||||
| } | ||||
|  | ||||
| #ifdef USE_ESP_IDF | ||||
| esp_err_t configure_timer_frequency(ledc_mode_t speed_mode, ledc_timer_t timer_num, ledc_channel_t chan_num, | ||||
|                                     uint8_t channel, uint8_t &bit_depth, float frequency) { | ||||
|   bit_depth = *ledc_bit_depth_for_frequency(frequency); | ||||
| @@ -98,13 +83,10 @@ esp_err_t configure_timer_frequency(ledc_mode_t speed_mode, ledc_timer_t timer_n | ||||
|  | ||||
|   return init_result; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #ifdef USE_ESP_IDF | ||||
| constexpr int ledc_angle_to_htop(float angle, uint8_t bit_depth) { | ||||
|   return static_cast<int>(angle * ((1U << bit_depth) - 1) / 360.0f); | ||||
| } | ||||
| #endif  // USE_ESP_IDF | ||||
|  | ||||
| void LEDCOutput::write_state(float state) { | ||||
|   if (!this->initialized_) { | ||||
| @@ -120,10 +102,6 @@ void LEDCOutput::write_state(float state) { | ||||
|   const float duty_rounded = roundf(state * max_duty); | ||||
|   auto duty = static_cast<uint32_t>(duty_rounded); | ||||
|   ESP_LOGV(TAG, "Setting duty: %" PRIu32 " on channel %u", duty, this->channel_); | ||||
| #ifdef USE_ARDUINO | ||||
|   ledcWrite(this->channel_, duty); | ||||
| #endif | ||||
| #ifdef USE_ESP_IDF | ||||
|   auto speed_mode = get_speed_mode(this->channel_); | ||||
|   auto chan_num = static_cast<ledc_channel_t>(this->channel_ % 8); | ||||
|   int hpoint = ledc_angle_to_htop(this->phase_angle_, this->bit_depth_); | ||||
| @@ -135,18 +113,10 @@ void LEDCOutput::write_state(float state) { | ||||
|     ledc_set_duty_with_hpoint(speed_mode, chan_num, duty, hpoint); | ||||
|     ledc_update_duty(speed_mode, chan_num); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void LEDCOutput::setup() { | ||||
|   ESP_LOGCONFIG(TAG, "Running setup"); | ||||
| #ifdef USE_ARDUINO | ||||
|   this->update_frequency(this->frequency_); | ||||
|   this->turn_off(); | ||||
|   // Attach pin after setting default value | ||||
|   ledcAttachPin(this->pin_->get_pin(), this->channel_); | ||||
| #endif | ||||
| #ifdef USE_ESP_IDF | ||||
|   auto speed_mode = get_speed_mode(this->channel_); | ||||
|   auto timer_num = static_cast<ledc_timer_t>((this->channel_ % 8) / 2); | ||||
|   auto chan_num = static_cast<ledc_channel_t>(this->channel_ % 8); | ||||
| @@ -175,7 +145,6 @@ void LEDCOutput::setup() { | ||||
|   ledc_channel_config(&chan_conf); | ||||
|   this->initialized_ = true; | ||||
|   this->status_clear_error(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void LEDCOutput::dump_config() { | ||||
| @@ -208,38 +177,7 @@ void LEDCOutput::update_frequency(float frequency) { | ||||
|   } | ||||
|   this->bit_depth_ = bit_depth_opt.value_or(8); | ||||
|   this->frequency_ = frequency; | ||||
| #ifdef USE_ARDUINO | ||||
|   ESP_LOGV(TAG, "Using Arduino API - Trying to define channel, frequency and bit depth"); | ||||
|   u_int32_t configured_frequency = 0; | ||||
|  | ||||
|   // Configure LEDC channel, frequency and bit depth with fallback | ||||
|   int attempt_count_max = SETUP_ATTEMPT_COUNT_MAX; | ||||
|   while (attempt_count_max > 0 && configured_frequency == 0) { | ||||
|     ESP_LOGV(TAG, "Initializing channel %u with frequency %.1f and bit depth of %u", this->channel_, this->frequency_, | ||||
|              this->bit_depth_); | ||||
|     configured_frequency = ledcSetup(this->channel_, frequency, this->bit_depth_); | ||||
|     if (configured_frequency != 0) { | ||||
|       this->initialized_ = true; | ||||
|       this->status_clear_error(); | ||||
|       ESP_LOGV(TAG, "Configured frequency: %u with bit depth: %u", configured_frequency, this->bit_depth_); | ||||
|     } else { | ||||
|       ESP_LOGW(TAG, "Unable to initialize channel %u with frequency %.1f and bit depth of %u", this->channel_, | ||||
|                this->frequency_, this->bit_depth_); | ||||
|       // try again with a lower bit depth | ||||
|       this->bit_depth_--; | ||||
|     } | ||||
|     attempt_count_max--; | ||||
|   } | ||||
|  | ||||
|   if (configured_frequency == 0) { | ||||
|     ESP_LOGE(TAG, "Permanently failed to initialize channel %u with frequency %.1f and bit depth of %u", this->channel_, | ||||
|              this->frequency_, this->bit_depth_); | ||||
|     this->status_set_error(); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
| #endif  // USE_ARDUINO | ||||
| #ifdef USE_ESP_IDF | ||||
|   if (!this->initialized_) { | ||||
|     ESP_LOGW(TAG, "Not yet initialized"); | ||||
|     return; | ||||
| @@ -259,7 +197,7 @@ void LEDCOutput::update_frequency(float frequency) { | ||||
|   } | ||||
|  | ||||
|   this->status_clear_error(); | ||||
| #endif | ||||
|  | ||||
|   // re-apply duty | ||||
|   this->write_state(this->duty_); | ||||
| } | ||||
|   | ||||
| @@ -324,7 +324,10 @@ async def to_code(config): | ||||
|     if CORE.using_arduino: | ||||
|         if config[CONF_HARDWARE_UART] == USB_CDC: | ||||
|             cg.add_build_flag("-DARDUINO_USB_CDC_ON_BOOT=1") | ||||
|             if CORE.is_esp32 and get_esp32_variant() == VARIANT_ESP32C3: | ||||
|             if CORE.is_esp32 and get_esp32_variant() in ( | ||||
|                 VARIANT_ESP32C3, | ||||
|                 VARIANT_ESP32C6, | ||||
|             ): | ||||
|                 cg.add_build_flag("-DARDUINO_USB_MODE=1") | ||||
|  | ||||
|     if CORE.using_esp_idf: | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
| namespace esphome { | ||||
| namespace md5 { | ||||
|  | ||||
| #if defined(USE_ARDUINO) && !defined(USE_RP2040) | ||||
| #if defined(USE_ARDUINO) && !defined(USE_RP2040) && !defined(USE_ESP32) | ||||
| void MD5Digest::init() { | ||||
|   memset(this->digest_, 0, 16); | ||||
|   MD5Init(&this->ctx_); | ||||
| @@ -18,7 +18,7 @@ void MD5Digest::add(const uint8_t *data, size_t len) { MD5Update(&this->ctx_, da | ||||
| void MD5Digest::calculate() { MD5Final(this->digest_, &this->ctx_); } | ||||
| #endif  // USE_ARDUINO && !USE_RP2040 | ||||
|  | ||||
| #ifdef USE_ESP_IDF | ||||
| #ifdef USE_ESP32 | ||||
| void MD5Digest::init() { | ||||
|   memset(this->digest_, 0, 16); | ||||
|   esp_rom_md5_init(&this->ctx_); | ||||
| @@ -27,7 +27,7 @@ void MD5Digest::init() { | ||||
| void MD5Digest::add(const uint8_t *data, size_t len) { esp_rom_md5_update(&this->ctx_, data, len); } | ||||
|  | ||||
| void MD5Digest::calculate() { esp_rom_md5_final(this->digest_, &this->ctx_); } | ||||
| #endif  // USE_ESP_IDF | ||||
| #endif  // USE_ESP32 | ||||
|  | ||||
| #ifdef USE_RP2040 | ||||
| void MD5Digest::init() { | ||||
|   | ||||
| @@ -3,16 +3,11 @@ | ||||
| #include "esphome/core/defines.h" | ||||
| #ifdef USE_MD5 | ||||
|  | ||||
| #ifdef USE_ESP_IDF | ||||
| #ifdef USE_ESP32 | ||||
| #include "esp_rom_md5.h" | ||||
| #define MD5_CTX_TYPE md5_context_t | ||||
| #endif | ||||
|  | ||||
| #if defined(USE_ARDUINO) && defined(USE_ESP32) | ||||
| #include "rom/md5_hash.h" | ||||
| #define MD5_CTX_TYPE MD5Context | ||||
| #endif | ||||
|  | ||||
| #if defined(USE_ARDUINO) && defined(USE_ESP8266) | ||||
| #include <md5.h> | ||||
| #define MD5_CTX_TYPE md5_context_t | ||||
|   | ||||
| @@ -215,4 +215,7 @@ async def to_code(config): | ||||
|  | ||||
|     # https://github.com/Makuna/NeoPixelBus/blob/master/library.json | ||||
|     # Version Listed Here: https://registry.platformio.org/libraries/makuna/NeoPixelBus/versions | ||||
|     cg.add_library("makuna/NeoPixelBus", "2.7.3") | ||||
|     if CORE.is_esp32: | ||||
|         cg.add_library("makuna/NeoPixelBus", "2.8.0") | ||||
|     else: | ||||
|         cg.add_library("makuna/NeoPixelBus", "2.7.3") | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| #pragma once | ||||
|  | ||||
| #ifdef USE_ARDUINO | ||||
| #if defined(USE_ARDUINO) && !defined(CLANG_TIDY) | ||||
|  | ||||
| #include "esphome/core/color.h" | ||||
| #include "esphome/core/component.h" | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import esphome.codegen as cg | ||||
| from esphome.components.esp32 import add_idf_sdkconfig_option | ||||
| import esphome.config_validation as cv | ||||
| from esphome.const import CONF_ENABLE_IPV6, CONF_MIN_IPV6_ADDR_COUNT | ||||
| from esphome.core import CORE | ||||
| from esphome.core import CORE, coroutine_with_priority | ||||
|  | ||||
| CODEOWNERS = ["@esphome/core"] | ||||
| AUTO_LOAD = ["mdns"] | ||||
| @@ -36,8 +36,11 @@ CONFIG_SCHEMA = cv.Schema( | ||||
| ) | ||||
|  | ||||
|  | ||||
| @coroutine_with_priority(201.0) | ||||
| async def to_code(config): | ||||
|     cg.add_define("USE_NETWORK") | ||||
|     if CORE.using_arduino and CORE.is_esp32: | ||||
|         cg.add_library("Networking", None) | ||||
|     if (enable_ipv6 := config.get(CONF_ENABLE_IPV6, None)) is not None: | ||||
|         cg.add_define("USE_NETWORK_IPV6", enable_ipv6) | ||||
|         if enable_ipv6: | ||||
|   | ||||
| @@ -56,6 +56,7 @@ struct IPAddress { | ||||
|     IP_ADDR4(&ip_addr_, first, second, third, fourth); | ||||
|   } | ||||
|   IPAddress(const ip_addr_t *other_ip) { ip_addr_copy(ip_addr_, *other_ip); } | ||||
|   IPAddress(const char *in_address) { ipaddr_aton(in_address, &ip_addr_); } | ||||
|   IPAddress(const std::string &in_address) { ipaddr_aton(in_address.c_str(), &ip_addr_); } | ||||
|   IPAddress(ip4_addr_t *other_ip) { | ||||
|     memcpy((void *) &ip_addr_, (void *) other_ip, sizeof(ip4_addr_t)); | ||||
|   | ||||
| @@ -150,7 +150,7 @@ async def to_code(config): | ||||
|         cg.add_define("USE_NEXTION_TFT_UPLOAD") | ||||
|         cg.add(var.set_tft_url(config[CONF_TFT_URL])) | ||||
|         if CORE.is_esp32 and CORE.using_arduino: | ||||
|             cg.add_library("WiFiClientSecure", None) | ||||
|             cg.add_library("NetworkClientSecure", None) | ||||
|             cg.add_library("HTTPClient", None) | ||||
|         elif CORE.is_esp32 and CORE.using_esp_idf: | ||||
|             esp32.add_idf_sdkconfig_option("CONFIG_ESP_TLS_INSECURE", True) | ||||
|   | ||||
| @@ -224,7 +224,7 @@ void OnlineImage::loop() { | ||||
|     this->height_ = buffer_height_; | ||||
|     ESP_LOGD(TAG, "Image fully downloaded, read %zu bytes, width/height = %d/%d", this->downloader_->get_bytes_read(), | ||||
|              this->width_, this->height_); | ||||
|     ESP_LOGD(TAG, "Total time: %lds", ::time(nullptr) - this->start_time_); | ||||
|     ESP_LOGD(TAG, "Total time: %" PRIu32 "s", (uint32_t) (::time(nullptr) - this->start_time_)); | ||||
|     this->etag_ = this->downloader_->get_response_header(ETAG_HEADER_NAME); | ||||
|     this->last_modified_ = this->downloader_->get_response_header(LAST_MODIFIED_HEADER_NAME); | ||||
|     this->download_finished_callback_.call(false); | ||||
|   | ||||
| @@ -8,27 +8,6 @@ namespace remote_base { | ||||
|  | ||||
| static const char *const TAG = "remote_base"; | ||||
|  | ||||
| #if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR < 5 | ||||
| RemoteRMTChannel::RemoteRMTChannel(uint8_t mem_block_num) : mem_block_num_(mem_block_num) { | ||||
|   static rmt_channel_t next_rmt_channel = RMT_CHANNEL_0; | ||||
|   this->channel_ = next_rmt_channel; | ||||
|   next_rmt_channel = rmt_channel_t(int(next_rmt_channel) + mem_block_num); | ||||
| } | ||||
|  | ||||
| RemoteRMTChannel::RemoteRMTChannel(rmt_channel_t channel, uint8_t mem_block_num) | ||||
|     : channel_(channel), mem_block_num_(mem_block_num) {} | ||||
|  | ||||
| void RemoteRMTChannel::config_rmt(rmt_config_t &rmt) { | ||||
|   if (rmt_channel_t(int(this->channel_) + this->mem_block_num_) > RMT_CHANNEL_MAX) { | ||||
|     this->mem_block_num_ = int(RMT_CHANNEL_MAX) - int(this->channel_); | ||||
|     ESP_LOGW(TAG, "Not enough RMT memory blocks available, reduced to %i blocks.", this->mem_block_num_); | ||||
|   } | ||||
|   rmt.channel = this->channel_; | ||||
|   rmt.clk_div = this->clock_divider_; | ||||
|   rmt.mem_block_num = this->mem_block_num_; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /* RemoteReceiveData */ | ||||
|  | ||||
| bool RemoteReceiveData::peek_mark(uint32_t length, uint32_t offset) const { | ||||
|   | ||||
| @@ -8,10 +8,6 @@ | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/core/hal.h" | ||||
|  | ||||
| #if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR < 5 | ||||
| #include <driver/rmt.h> | ||||
| #endif | ||||
|  | ||||
| namespace esphome { | ||||
| namespace remote_base { | ||||
|  | ||||
| @@ -112,43 +108,21 @@ class RemoteComponentBase { | ||||
| #ifdef USE_ESP32 | ||||
| class RemoteRMTChannel { | ||||
|  public: | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   void set_clock_resolution(uint32_t clock_resolution) { this->clock_resolution_ = clock_resolution; } | ||||
|   void set_rmt_symbols(uint32_t rmt_symbols) { this->rmt_symbols_ = rmt_symbols; } | ||||
| #else | ||||
|   explicit RemoteRMTChannel(uint8_t mem_block_num = 1); | ||||
|   explicit RemoteRMTChannel(rmt_channel_t channel, uint8_t mem_block_num = 1); | ||||
|  | ||||
|   void config_rmt(rmt_config_t &rmt); | ||||
|   void set_clock_divider(uint8_t clock_divider) { this->clock_divider_ = clock_divider; } | ||||
| #endif | ||||
|  | ||||
|  protected: | ||||
|   uint32_t from_microseconds_(uint32_t us) { | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|     const uint32_t ticks_per_ten_us = this->clock_resolution_ / 100000u; | ||||
| #else | ||||
|     const uint32_t ticks_per_ten_us = 80000000u / this->clock_divider_ / 100000u; | ||||
| #endif | ||||
|     return us * ticks_per_ten_us / 10; | ||||
|   } | ||||
|   uint32_t to_microseconds_(uint32_t ticks) { | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|     const uint32_t ticks_per_ten_us = this->clock_resolution_ / 100000u; | ||||
| #else | ||||
|     const uint32_t ticks_per_ten_us = 80000000u / this->clock_divider_ / 100000u; | ||||
| #endif | ||||
|     return (ticks * 10) / ticks_per_ten_us; | ||||
|   } | ||||
|   RemoteComponentBase *remote_base_; | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   uint32_t clock_resolution_{1000000}; | ||||
|   uint32_t rmt_symbols_; | ||||
| #else | ||||
|   rmt_channel_t channel_{RMT_CHANNEL_0}; | ||||
|   uint8_t mem_block_num_; | ||||
|   uint8_t clock_divider_{80}; | ||||
| #endif | ||||
| }; | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -4,15 +4,12 @@ from esphome.components import esp32, esp32_rmt, remote_base | ||||
| import esphome.config_validation as cv | ||||
| from esphome.const import ( | ||||
|     CONF_BUFFER_SIZE, | ||||
|     CONF_CLOCK_DIVIDER, | ||||
|     CONF_CLOCK_RESOLUTION, | ||||
|     CONF_DUMP, | ||||
|     CONF_FILTER, | ||||
|     CONF_ID, | ||||
|     CONF_IDLE, | ||||
|     CONF_MEMORY_BLOCKS, | ||||
|     CONF_PIN, | ||||
|     CONF_RMT_CHANNEL, | ||||
|     CONF_RMT_SYMBOLS, | ||||
|     CONF_TOLERANCE, | ||||
|     CONF_TYPE, | ||||
| @@ -103,49 +100,36 @@ CONFIG_SCHEMA = remote_base.validate_triggers( | ||||
|                 cv.positive_time_period_microseconds, | ||||
|                 cv.Range(max=TimePeriod(microseconds=4294967295)), | ||||
|             ), | ||||
|             cv.SplitDefault(CONF_CLOCK_DIVIDER, esp32_arduino=80): cv.All( | ||||
|                 cv.only_on_esp32, | ||||
|                 cv.only_with_arduino, | ||||
|                 cv.int_range(min=1, max=255), | ||||
|             ), | ||||
|             cv.Optional(CONF_CLOCK_RESOLUTION): cv.All( | ||||
|                 cv.only_on_esp32, | ||||
|                 cv.only_with_esp_idf, | ||||
|                 esp32_rmt.validate_clock_resolution(), | ||||
|             ), | ||||
|             cv.Optional(CONF_IDLE, default="10ms"): cv.All( | ||||
|                 cv.positive_time_period_microseconds, | ||||
|                 cv.Range(max=TimePeriod(microseconds=4294967295)), | ||||
|             ), | ||||
|             cv.SplitDefault(CONF_MEMORY_BLOCKS, esp32_arduino=3): cv.All( | ||||
|                 cv.only_with_arduino, cv.int_range(min=1, max=8) | ||||
|             ), | ||||
|             cv.Optional(CONF_RMT_CHANNEL): cv.All( | ||||
|                 cv.only_with_arduino, esp32_rmt.validate_rmt_channel(tx=False) | ||||
|             ), | ||||
|             cv.SplitDefault( | ||||
|                 CONF_RMT_SYMBOLS, | ||||
|                 esp32_idf=192, | ||||
|                 esp32_s2_idf=192, | ||||
|                 esp32_s3_idf=192, | ||||
|                 esp32_p4_idf=192, | ||||
|                 esp32_c3_idf=96, | ||||
|                 esp32_c5_idf=96, | ||||
|                 esp32_c6_idf=96, | ||||
|                 esp32_h2_idf=96, | ||||
|             ): cv.All(cv.only_with_esp_idf, cv.int_range(min=2)), | ||||
|                 esp32=192, | ||||
|                 esp32_s2=192, | ||||
|                 esp32_s3=192, | ||||
|                 esp32_p4=192, | ||||
|                 esp32_c3=96, | ||||
|                 esp32_c5=96, | ||||
|                 esp32_c6=96, | ||||
|                 esp32_h2=96, | ||||
|             ): cv.All(cv.only_on_esp32, cv.int_range(min=2)), | ||||
|             cv.Optional(CONF_FILTER_SYMBOLS): cv.All( | ||||
|                 cv.only_with_esp_idf, cv.int_range(min=0) | ||||
|                 cv.only_on_esp32, cv.int_range(min=0) | ||||
|             ), | ||||
|             cv.SplitDefault( | ||||
|                 CONF_RECEIVE_SYMBOLS, | ||||
|                 esp32_idf=192, | ||||
|             ): cv.All(cv.only_with_esp_idf, cv.int_range(min=2)), | ||||
|                 esp32=192, | ||||
|             ): cv.All(cv.only_on_esp32, cv.int_range(min=2)), | ||||
|             cv.Optional(CONF_USE_DMA): cv.All( | ||||
|                 esp32.only_on_variant( | ||||
|                     supported=[esp32.const.VARIANT_ESP32S3, esp32.const.VARIANT_ESP32P4] | ||||
|                 ), | ||||
|                 cv.only_with_esp_idf, | ||||
|                 cv.boolean, | ||||
|             ), | ||||
|         } | ||||
| @@ -156,24 +140,15 @@ CONFIG_SCHEMA = remote_base.validate_triggers( | ||||
| async def to_code(config): | ||||
|     pin = await cg.gpio_pin_expression(config[CONF_PIN]) | ||||
|     if CORE.is_esp32: | ||||
|         if esp32_rmt.use_new_rmt_driver(): | ||||
|             var = cg.new_Pvariable(config[CONF_ID], pin) | ||||
|             cg.add(var.set_rmt_symbols(config[CONF_RMT_SYMBOLS])) | ||||
|             cg.add(var.set_receive_symbols(config[CONF_RECEIVE_SYMBOLS])) | ||||
|             if CONF_USE_DMA in config: | ||||
|                 cg.add(var.set_with_dma(config[CONF_USE_DMA])) | ||||
|             if CONF_CLOCK_RESOLUTION in config: | ||||
|                 cg.add(var.set_clock_resolution(config[CONF_CLOCK_RESOLUTION])) | ||||
|             if CONF_FILTER_SYMBOLS in config: | ||||
|                 cg.add(var.set_filter_symbols(config[CONF_FILTER_SYMBOLS])) | ||||
|         else: | ||||
|             if (rmt_channel := config.get(CONF_RMT_CHANNEL, None)) is not None: | ||||
|                 var = cg.new_Pvariable( | ||||
|                     config[CONF_ID], pin, rmt_channel, config[CONF_MEMORY_BLOCKS] | ||||
|                 ) | ||||
|             else: | ||||
|                 var = cg.new_Pvariable(config[CONF_ID], pin, config[CONF_MEMORY_BLOCKS]) | ||||
|             cg.add(var.set_clock_divider(config[CONF_CLOCK_DIVIDER])) | ||||
|         var = cg.new_Pvariable(config[CONF_ID], pin) | ||||
|         cg.add(var.set_rmt_symbols(config[CONF_RMT_SYMBOLS])) | ||||
|         cg.add(var.set_receive_symbols(config[CONF_RECEIVE_SYMBOLS])) | ||||
|         if CONF_USE_DMA in config: | ||||
|             cg.add(var.set_with_dma(config[CONF_USE_DMA])) | ||||
|         if CONF_CLOCK_RESOLUTION in config: | ||||
|             cg.add(var.set_clock_resolution(config[CONF_CLOCK_RESOLUTION])) | ||||
|         if CONF_FILTER_SYMBOLS in config: | ||||
|             cg.add(var.set_filter_symbols(config[CONF_FILTER_SYMBOLS])) | ||||
|     else: | ||||
|         var = cg.new_Pvariable(config[CONF_ID], pin) | ||||
|  | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  | ||||
| #include <cinttypes> | ||||
|  | ||||
| #if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR >= 5 | ||||
| #if defined(USE_ESP32) | ||||
| #include <driver/rmt_rx.h> | ||||
| #endif | ||||
|  | ||||
| @@ -29,7 +29,7 @@ struct RemoteReceiverComponentStore { | ||||
|   uint32_t filter_us{10}; | ||||
|   ISRInternalGPIOPin pin; | ||||
| }; | ||||
| #elif defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR >= 5 | ||||
| #elif defined(USE_ESP32) | ||||
| struct RemoteReceiverComponentStore { | ||||
|   /// Stores RMT symbols and rx done event data | ||||
|   volatile uint8_t *buffer{nullptr}; | ||||
| @@ -55,21 +55,13 @@ class RemoteReceiverComponent : public remote_base::RemoteReceiverBase, | ||||
|  | ||||
| { | ||||
|  public: | ||||
| #if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR < 5 | ||||
|   RemoteReceiverComponent(InternalGPIOPin *pin, uint8_t mem_block_num = 1) | ||||
|       : RemoteReceiverBase(pin), remote_base::RemoteRMTChannel(mem_block_num) {} | ||||
|  | ||||
|   RemoteReceiverComponent(InternalGPIOPin *pin, rmt_channel_t channel, uint8_t mem_block_num = 1) | ||||
|       : RemoteReceiverBase(pin), remote_base::RemoteRMTChannel(channel, mem_block_num) {} | ||||
| #else | ||||
|   RemoteReceiverComponent(InternalGPIOPin *pin) : RemoteReceiverBase(pin) {} | ||||
| #endif | ||||
|   void setup() override; | ||||
|   void dump_config() override; | ||||
|   void loop() override; | ||||
|   float get_setup_priority() const override { return setup_priority::DATA; } | ||||
|  | ||||
| #if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR >= 5 | ||||
| #ifdef USE_ESP32 | ||||
|   void set_filter_symbols(uint32_t filter_symbols) { this->filter_symbols_ = filter_symbols; } | ||||
|   void set_receive_symbols(uint32_t receive_symbols) { this->receive_symbols_ = receive_symbols; } | ||||
|   void set_with_dma(bool with_dma) { this->with_dma_ = with_dma; } | ||||
| @@ -80,21 +72,16 @@ class RemoteReceiverComponent : public remote_base::RemoteReceiverBase, | ||||
|  | ||||
|  protected: | ||||
| #ifdef USE_ESP32 | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   void decode_rmt_(rmt_symbol_word_t *item, size_t item_count); | ||||
|   rmt_channel_handle_t channel_{NULL}; | ||||
|   uint32_t filter_symbols_{0}; | ||||
|   uint32_t receive_symbols_{0}; | ||||
|   bool with_dma_{false}; | ||||
| #else | ||||
|   void decode_rmt_(rmt_item32_t *item, size_t item_count); | ||||
|   RingbufHandle_t ringbuf_; | ||||
| #endif | ||||
|   esp_err_t error_code_{ESP_OK}; | ||||
|   std::string error_string_{""}; | ||||
| #endif | ||||
|  | ||||
| #if defined(USE_ESP8266) || defined(USE_LIBRETINY) || (defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR >= 5) | ||||
| #if defined(USE_ESP8266) || defined(USE_LIBRETINY) || defined(USE_ESP32) | ||||
|   RemoteReceiverComponentStore store_; | ||||
|   HighFrequencyLoopRequester high_freq_; | ||||
| #endif | ||||
|   | ||||
| @@ -14,7 +14,6 @@ static const uint32_t RMT_CLK_FREQ = 32000000; | ||||
| static const uint32_t RMT_CLK_FREQ = 80000000; | ||||
| #endif | ||||
|  | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
| static bool IRAM_ATTR HOT rmt_callback(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *event, void *arg) { | ||||
|   RemoteReceiverComponentStore *store = (RemoteReceiverComponentStore *) arg; | ||||
|   rmt_rx_done_event_data_t *event_buffer = (rmt_rx_done_event_data_t *) (store->buffer + store->buffer_write); | ||||
| @@ -37,11 +36,9 @@ static bool IRAM_ATTR HOT rmt_callback(rmt_channel_handle_t channel, const rmt_r | ||||
|   store->buffer_write = next_write; | ||||
|   return false; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| void RemoteReceiverComponent::setup() { | ||||
|   ESP_LOGCONFIG(TAG, "Running setup"); | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   rmt_rx_channel_config_t channel; | ||||
|   memset(&channel, 0, sizeof(channel)); | ||||
|   channel.clk_src = RMT_CLK_SRC_DEFAULT; | ||||
| @@ -105,62 +102,11 @@ void RemoteReceiverComponent::setup() { | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
| #else | ||||
|   this->pin_->setup(); | ||||
|   rmt_config_t rmt{}; | ||||
|   this->config_rmt(rmt); | ||||
|   rmt.gpio_num = gpio_num_t(this->pin_->get_pin()); | ||||
|   rmt.rmt_mode = RMT_MODE_RX; | ||||
|   if (this->filter_us_ == 0) { | ||||
|     rmt.rx_config.filter_en = false; | ||||
|   } else { | ||||
|     rmt.rx_config.filter_en = true; | ||||
|     rmt.rx_config.filter_ticks_thresh = static_cast<uint8_t>( | ||||
|         std::min(this->from_microseconds_(this->filter_us_) * this->clock_divider_, (uint32_t) 255)); | ||||
|   } | ||||
|   rmt.rx_config.idle_threshold = | ||||
|       static_cast<uint16_t>(std::min(this->from_microseconds_(this->idle_us_), (uint32_t) 65535)); | ||||
|  | ||||
|   esp_err_t error = rmt_config(&rmt); | ||||
|   if (error != ESP_OK) { | ||||
|     this->error_code_ = error; | ||||
|     this->error_string_ = "in rmt_config"; | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   error = rmt_driver_install(this->channel_, this->buffer_size_, 0); | ||||
|   if (error != ESP_OK) { | ||||
|     this->error_code_ = error; | ||||
|     if (error == ESP_ERR_INVALID_STATE) { | ||||
|       this->error_string_ = str_sprintf("RMT channel %i is already in use by another component", this->channel_); | ||||
|     } else { | ||||
|       this->error_string_ = "in rmt_driver_install"; | ||||
|     } | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
|   error = rmt_get_ringbuf_handle(this->channel_, &this->ringbuf_); | ||||
|   if (error != ESP_OK) { | ||||
|     this->error_code_ = error; | ||||
|     this->error_string_ = "in rmt_get_ringbuf_handle"; | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
|   error = rmt_rx_start(this->channel_, true); | ||||
|   if (error != ESP_OK) { | ||||
|     this->error_code_ = error; | ||||
|     this->error_string_ = "in rmt_rx_start"; | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void RemoteReceiverComponent::dump_config() { | ||||
|   ESP_LOGCONFIG(TAG, "Remote Receiver:"); | ||||
|   LOG_PIN("  Pin: ", this->pin_); | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   ESP_LOGCONFIG(TAG, | ||||
|                 "  Clock resolution: %" PRIu32 " hz\n" | ||||
|                 "  RMT symbols: %" PRIu32 "\n" | ||||
| @@ -172,22 +118,6 @@ void RemoteReceiverComponent::dump_config() { | ||||
|                 this->clock_resolution_, this->rmt_symbols_, this->filter_symbols_, this->receive_symbols_, | ||||
|                 this->tolerance_, (this->tolerance_mode_ == remote_base::TOLERANCE_MODE_TIME) ? " us" : "%", | ||||
|                 this->filter_us_, this->idle_us_); | ||||
| #else | ||||
|   if (this->pin_->digital_read()) { | ||||
|     ESP_LOGW(TAG, "Remote Receiver Signal starts with a HIGH value. Usually this means you have to " | ||||
|                   "invert the signal using 'inverted: True' in the pin schema!"); | ||||
|   } | ||||
|   ESP_LOGCONFIG(TAG, | ||||
|                 "  Channel: %d\n" | ||||
|                 "  RMT memory blocks: %d\n" | ||||
|                 "  Clock divider: %u\n" | ||||
|                 "  Tolerance: %" PRIu32 "%s\n" | ||||
|                 "  Filter out pulses shorter than: %" PRIu32 " us\n" | ||||
|                 "  Signal is done after %" PRIu32 " us of no changes", | ||||
|                 this->channel_, this->mem_block_num_, this->clock_divider_, this->tolerance_, | ||||
|                 (this->tolerance_mode_ == remote_base::TOLERANCE_MODE_TIME) ? " us" : "%", this->filter_us_, | ||||
|                 this->idle_us_); | ||||
| #endif | ||||
|   if (this->is_failed()) { | ||||
|     ESP_LOGE(TAG, "Configuring RMT driver failed: %s (%s)", esp_err_to_name(this->error_code_), | ||||
|              this->error_string_.c_str()); | ||||
| @@ -195,7 +125,6 @@ void RemoteReceiverComponent::dump_config() { | ||||
| } | ||||
|  | ||||
| void RemoteReceiverComponent::loop() { | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   if (this->store_.error != ESP_OK) { | ||||
|     ESP_LOGE(TAG, "Receive error"); | ||||
|     this->error_code_ = this->store_.error; | ||||
| @@ -221,25 +150,9 @@ void RemoteReceiverComponent::loop() { | ||||
|       this->call_listeners_dumpers_(); | ||||
|     } | ||||
|   } | ||||
| #else | ||||
|   size_t len = 0; | ||||
|   auto *item = (rmt_item32_t *) xRingbufferReceive(this->ringbuf_, &len, 0); | ||||
|   if (item != nullptr) { | ||||
|     this->decode_rmt_(item, len / sizeof(rmt_item32_t)); | ||||
|     vRingbufferReturnItem(this->ringbuf_, item); | ||||
|  | ||||
|     if (!this->temp_.empty()) { | ||||
|       this->call_listeners_dumpers_(); | ||||
|     } | ||||
|   } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
| void RemoteReceiverComponent::decode_rmt_(rmt_symbol_word_t *item, size_t item_count) { | ||||
| #else | ||||
| void RemoteReceiverComponent::decode_rmt_(rmt_item32_t *item, size_t item_count) { | ||||
| #endif | ||||
|   bool prev_level = false; | ||||
|   bool idle_level = false; | ||||
|   uint32_t prev_length = 0; | ||||
|   | ||||
| @@ -4,14 +4,12 @@ from esphome.components import esp32, esp32_rmt, remote_base | ||||
| import esphome.config_validation as cv | ||||
| from esphome.const import ( | ||||
|     CONF_CARRIER_DUTY_PERCENT, | ||||
|     CONF_CLOCK_DIVIDER, | ||||
|     CONF_CLOCK_RESOLUTION, | ||||
|     CONF_ID, | ||||
|     CONF_INVERTED, | ||||
|     CONF_MODE, | ||||
|     CONF_OPEN_DRAIN, | ||||
|     CONF_PIN, | ||||
|     CONF_RMT_CHANNEL, | ||||
|     CONF_RMT_SYMBOLS, | ||||
|     CONF_USE_DMA, | ||||
| ) | ||||
| @@ -38,34 +36,26 @@ CONFIG_SCHEMA = cv.Schema( | ||||
|         ), | ||||
|         cv.Optional(CONF_CLOCK_RESOLUTION): cv.All( | ||||
|             cv.only_on_esp32, | ||||
|             cv.only_with_esp_idf, | ||||
|             esp32_rmt.validate_clock_resolution(), | ||||
|         ), | ||||
|         cv.Optional(CONF_CLOCK_DIVIDER): cv.All( | ||||
|             cv.only_on_esp32, cv.only_with_arduino, cv.int_range(min=1, max=255) | ||||
|         ), | ||||
|         cv.Optional(CONF_EOT_LEVEL): cv.All(cv.only_with_esp_idf, cv.boolean), | ||||
|         cv.Optional(CONF_EOT_LEVEL): cv.All(cv.only_on_esp32, cv.boolean), | ||||
|         cv.Optional(CONF_USE_DMA): cv.All( | ||||
|             esp32.only_on_variant( | ||||
|                 supported=[esp32.const.VARIANT_ESP32S3, esp32.const.VARIANT_ESP32P4] | ||||
|             ), | ||||
|             cv.only_with_esp_idf, | ||||
|             cv.boolean, | ||||
|         ), | ||||
|         cv.SplitDefault( | ||||
|             CONF_RMT_SYMBOLS, | ||||
|             esp32_idf=64, | ||||
|             esp32_s2_idf=64, | ||||
|             esp32_s3_idf=48, | ||||
|             esp32_p4_idf=48, | ||||
|             esp32_c3_idf=48, | ||||
|             esp32_c5_idf=48, | ||||
|             esp32_c6_idf=48, | ||||
|             esp32_h2_idf=48, | ||||
|         ): cv.All(cv.only_with_esp_idf, cv.int_range(min=2)), | ||||
|         cv.Optional(CONF_RMT_CHANNEL): cv.All( | ||||
|             cv.only_with_arduino, esp32_rmt.validate_rmt_channel(tx=True) | ||||
|         ), | ||||
|             esp32=64, | ||||
|             esp32_s2=64, | ||||
|             esp32_s3=48, | ||||
|             esp32_p4=48, | ||||
|             esp32_c3=48, | ||||
|             esp32_c5=48, | ||||
|             esp32_c6=48, | ||||
|             esp32_h2=48, | ||||
|         ): cv.All(cv.only_on_esp32, cv.int_range(min=2)), | ||||
|         cv.Optional(CONF_ON_TRANSMIT): automation.validate_automation(single=True), | ||||
|         cv.Optional(CONF_ON_COMPLETE): automation.validate_automation(single=True), | ||||
|     } | ||||
| @@ -75,30 +65,21 @@ CONFIG_SCHEMA = cv.Schema( | ||||
| async def to_code(config): | ||||
|     pin = await cg.gpio_pin_expression(config[CONF_PIN]) | ||||
|     if CORE.is_esp32: | ||||
|         if esp32_rmt.use_new_rmt_driver(): | ||||
|             var = cg.new_Pvariable(config[CONF_ID], pin) | ||||
|             cg.add(var.set_rmt_symbols(config[CONF_RMT_SYMBOLS])) | ||||
|             if CONF_CLOCK_RESOLUTION in config: | ||||
|                 cg.add(var.set_clock_resolution(config[CONF_CLOCK_RESOLUTION])) | ||||
|             if CONF_USE_DMA in config: | ||||
|                 cg.add(var.set_with_dma(config[CONF_USE_DMA])) | ||||
|             if CONF_EOT_LEVEL in config: | ||||
|                 cg.add(var.set_eot_level(config[CONF_EOT_LEVEL])) | ||||
|             else: | ||||
|                 cg.add( | ||||
|                     var.set_eot_level( | ||||
|                         config[CONF_PIN][CONF_MODE][CONF_OPEN_DRAIN] | ||||
|                         or config[CONF_PIN][CONF_INVERTED] | ||||
|                     ) | ||||
|                 ) | ||||
|         var = cg.new_Pvariable(config[CONF_ID], pin) | ||||
|         cg.add(var.set_rmt_symbols(config[CONF_RMT_SYMBOLS])) | ||||
|         if CONF_CLOCK_RESOLUTION in config: | ||||
|             cg.add(var.set_clock_resolution(config[CONF_CLOCK_RESOLUTION])) | ||||
|         if CONF_USE_DMA in config: | ||||
|             cg.add(var.set_with_dma(config[CONF_USE_DMA])) | ||||
|         if CONF_EOT_LEVEL in config: | ||||
|             cg.add(var.set_eot_level(config[CONF_EOT_LEVEL])) | ||||
|         else: | ||||
|             if (rmt_channel := config.get(CONF_RMT_CHANNEL, None)) is not None: | ||||
|                 var = cg.new_Pvariable(config[CONF_ID], pin, rmt_channel) | ||||
|             else: | ||||
|                 var = cg.new_Pvariable(config[CONF_ID], pin) | ||||
|             if CONF_CLOCK_DIVIDER in config: | ||||
|                 cg.add(var.set_clock_divider(config[CONF_CLOCK_DIVIDER])) | ||||
|  | ||||
|             cg.add( | ||||
|                 var.set_eot_level( | ||||
|                     config[CONF_PIN][CONF_MODE][CONF_OPEN_DRAIN] | ||||
|                     or config[CONF_PIN][CONF_INVERTED] | ||||
|                 ) | ||||
|             ) | ||||
|     else: | ||||
|         var = cg.new_Pvariable(config[CONF_ID], pin) | ||||
|     await cg.register_component(var, config) | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| #if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR >= 5 | ||||
| #if defined(USE_ESP32) | ||||
| #include <driver/rmt_tx.h> | ||||
| #endif | ||||
|  | ||||
| @@ -20,15 +20,7 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase, | ||||
| #endif | ||||
| { | ||||
|  public: | ||||
| #if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR < 5 | ||||
|   RemoteTransmitterComponent(InternalGPIOPin *pin, uint8_t mem_block_num = 1) | ||||
|       : remote_base::RemoteTransmitterBase(pin), remote_base::RemoteRMTChannel(mem_block_num) {} | ||||
|  | ||||
|   RemoteTransmitterComponent(InternalGPIOPin *pin, rmt_channel_t channel, uint8_t mem_block_num = 1) | ||||
|       : remote_base::RemoteTransmitterBase(pin), remote_base::RemoteRMTChannel(channel, mem_block_num) {} | ||||
| #else | ||||
|   explicit RemoteTransmitterComponent(InternalGPIOPin *pin) : remote_base::RemoteTransmitterBase(pin) {} | ||||
| #endif | ||||
|   void setup() override; | ||||
|  | ||||
|   void dump_config() override; | ||||
| @@ -38,7 +30,7 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase, | ||||
|  | ||||
|   void set_carrier_duty_percent(uint8_t carrier_duty_percent) { this->carrier_duty_percent_ = carrier_duty_percent; } | ||||
|  | ||||
| #if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR >= 5 | ||||
| #if defined(USE_ESP32) | ||||
|   void set_with_dma(bool with_dma) { this->with_dma_ = with_dma; } | ||||
|   void set_eot_level(bool eot_level) { this->eot_level_ = eot_level; } | ||||
|   void digital_write(bool value); | ||||
| @@ -65,15 +57,11 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase, | ||||
|  | ||||
|   uint32_t current_carrier_frequency_{38000}; | ||||
|   bool initialized_{false}; | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   std::vector<rmt_symbol_word_t> rmt_temp_; | ||||
|   bool with_dma_{false}; | ||||
|   bool eot_level_{false}; | ||||
|   rmt_channel_handle_t channel_{NULL}; | ||||
|   rmt_encoder_handle_t encoder_{NULL}; | ||||
| #else | ||||
|   std::vector<rmt_item32_t> rmt_temp_; | ||||
| #endif | ||||
|   esp_err_t error_code_{ESP_OK}; | ||||
|   std::string error_string_{""}; | ||||
|   bool inverted_{false}; | ||||
|   | ||||
| @@ -18,18 +18,10 @@ void RemoteTransmitterComponent::setup() { | ||||
|  | ||||
| void RemoteTransmitterComponent::dump_config() { | ||||
|   ESP_LOGCONFIG(TAG, "Remote Transmitter:"); | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   ESP_LOGCONFIG(TAG, | ||||
|                 "  Clock resolution: %" PRIu32 " hz\n" | ||||
|                 "  RMT symbols: %" PRIu32, | ||||
|                 this->clock_resolution_, this->rmt_symbols_); | ||||
| #else | ||||
|   ESP_LOGCONFIG(TAG, | ||||
|                 "  Channel: %d\n" | ||||
|                 "  RMT memory blocks: %d\n" | ||||
|                 "  Clock divider: %u", | ||||
|                 this->channel_, this->mem_block_num_, this->clock_divider_); | ||||
| #endif | ||||
|   LOG_PIN("  Pin: ", this->pin_); | ||||
|  | ||||
|   if (this->current_carrier_frequency_ != 0 && this->carrier_duty_percent_ != 100) { | ||||
| @@ -42,7 +34,6 @@ void RemoteTransmitterComponent::dump_config() { | ||||
|   } | ||||
| } | ||||
|  | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
| void RemoteTransmitterComponent::digital_write(bool value) { | ||||
|   rmt_symbol_word_t symbol = { | ||||
|       .duration0 = 1, | ||||
| @@ -65,10 +56,8 @@ void RemoteTransmitterComponent::digital_write(bool value) { | ||||
|     this->status_set_warning(); | ||||
|   } | ||||
| } | ||||
| #endif | ||||
|  | ||||
| void RemoteTransmitterComponent::configure_rmt_() { | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   esp_err_t error; | ||||
|  | ||||
|   if (!this->initialized_) { | ||||
| @@ -140,54 +129,6 @@ void RemoteTransmitterComponent::configure_rmt_() { | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
| #else | ||||
|   rmt_config_t c{}; | ||||
|  | ||||
|   this->config_rmt(c); | ||||
|   c.rmt_mode = RMT_MODE_TX; | ||||
|   c.gpio_num = gpio_num_t(this->pin_->get_pin()); | ||||
|   c.tx_config.loop_en = false; | ||||
|  | ||||
|   if (this->current_carrier_frequency_ == 0 || this->carrier_duty_percent_ == 100) { | ||||
|     c.tx_config.carrier_en = false; | ||||
|   } else { | ||||
|     c.tx_config.carrier_en = true; | ||||
|     c.tx_config.carrier_freq_hz = this->current_carrier_frequency_; | ||||
|     c.tx_config.carrier_duty_percent = this->carrier_duty_percent_; | ||||
|   } | ||||
|  | ||||
|   c.tx_config.idle_output_en = true; | ||||
|   if (!this->inverted_) { | ||||
|     c.tx_config.carrier_level = RMT_CARRIER_LEVEL_HIGH; | ||||
|     c.tx_config.idle_level = RMT_IDLE_LEVEL_LOW; | ||||
|   } else { | ||||
|     c.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW; | ||||
|     c.tx_config.idle_level = RMT_IDLE_LEVEL_HIGH; | ||||
|   } | ||||
|  | ||||
|   esp_err_t error = rmt_config(&c); | ||||
|   if (error != ESP_OK) { | ||||
|     this->error_code_ = error; | ||||
|     this->error_string_ = "in rmt_config"; | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   if (!this->initialized_) { | ||||
|     error = rmt_driver_install(this->channel_, 0, 0); | ||||
|     if (error != ESP_OK) { | ||||
|       this->error_code_ = error; | ||||
|       if (error == ESP_ERR_INVALID_STATE) { | ||||
|         this->error_string_ = str_sprintf("RMT channel %i is already in use by another component", this->channel_); | ||||
|       } else { | ||||
|         this->error_string_ = "in rmt_driver_install"; | ||||
|       } | ||||
|       this->mark_failed(); | ||||
|       return; | ||||
|     } | ||||
|     this->initialized_ = true; | ||||
|   } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t send_wait) { | ||||
| @@ -202,11 +143,7 @@ void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t sen | ||||
|   this->rmt_temp_.clear(); | ||||
|   this->rmt_temp_.reserve((this->temp_.get_data().size() + 1) / 2); | ||||
|   uint32_t rmt_i = 0; | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   rmt_symbol_word_t rmt_item; | ||||
| #else | ||||
|   rmt_item32_t rmt_item; | ||||
| #endif | ||||
|  | ||||
|   for (int32_t val : this->temp_.get_data()) { | ||||
|     bool level = val >= 0; | ||||
| @@ -241,7 +178,6 @@ void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t sen | ||||
|     return; | ||||
|   } | ||||
|   this->transmit_trigger_->trigger(); | ||||
| #if ESP_IDF_VERSION_MAJOR >= 5 | ||||
|   for (uint32_t i = 0; i < send_times; i++) { | ||||
|     rmt_transmit_config_t config; | ||||
|     memset(&config, 0, sizeof(config)); | ||||
| @@ -263,19 +199,6 @@ void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t sen | ||||
|     if (i + 1 < send_times) | ||||
|       delayMicroseconds(send_wait); | ||||
|   } | ||||
| #else | ||||
|   for (uint32_t i = 0; i < send_times; i++) { | ||||
|     esp_err_t error = rmt_write_items(this->channel_, this->rmt_temp_.data(), this->rmt_temp_.size(), true); | ||||
|     if (error != ESP_OK) { | ||||
|       ESP_LOGW(TAG, "rmt_write_items failed: %s", esp_err_to_name(error)); | ||||
|       this->status_set_warning(); | ||||
|     } else { | ||||
|       this->status_clear_warning(); | ||||
|     } | ||||
|     if (i + 1 < send_times) | ||||
|       delayMicroseconds(send_wait); | ||||
|   } | ||||
| #endif | ||||
|   this->complete_trigger_->trigger(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| #include "sntp_component.h" | ||||
| #include "esphome/core/log.h" | ||||
|  | ||||
| #ifdef USE_ESP_IDF | ||||
| #ifdef USE_ESP32 | ||||
| #include "esp_sntp.h" | ||||
| #elif USE_ESP8266 | ||||
| #include "sntp.h" | ||||
| @@ -16,7 +16,7 @@ static const char *const TAG = "sntp"; | ||||
|  | ||||
| void SNTPComponent::setup() { | ||||
|   ESP_LOGCONFIG(TAG, "Running setup"); | ||||
| #if defined(USE_ESP_IDF) | ||||
| #if defined(USE_ESP32) | ||||
|   if (esp_sntp_enabled()) { | ||||
|     esp_sntp_stop(); | ||||
|   } | ||||
| @@ -46,7 +46,7 @@ void SNTPComponent::dump_config() { | ||||
|   } | ||||
| } | ||||
| void SNTPComponent::update() { | ||||
| #if !defined(USE_ESP_IDF) | ||||
| #if !defined(USE_ESP32) | ||||
|   // force resync | ||||
|   if (sntp_enabled()) { | ||||
|     sntp_stop(); | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| #include <algorithm> | ||||
| #include <utility> | ||||
| #ifdef USE_WIFI_WPA2_EAP | ||||
| #include <esp_wpa2.h> | ||||
| #include <esp_eap_client.h> | ||||
| #endif | ||||
|  | ||||
| #ifdef USE_WIFI_AP | ||||
| @@ -228,43 +228,43 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) { | ||||
|   if (ap.get_eap().has_value()) { | ||||
|     // note: all certificates and keys have to be null terminated. Lengths are appended by +1 to include \0. | ||||
|     EAPAuth eap = ap.get_eap().value(); | ||||
|     err = esp_wifi_sta_wpa2_ent_set_identity((uint8_t *) eap.identity.c_str(), eap.identity.length()); | ||||
|     err = esp_eap_client_set_identity((uint8_t *) eap.identity.c_str(), eap.identity.length()); | ||||
|     if (err != ESP_OK) { | ||||
|       ESP_LOGV(TAG, "esp_wifi_sta_wpa2_ent_set_identity failed! %d", err); | ||||
|       ESP_LOGV(TAG, "esp_eap_client_set_identity failed! %d", err); | ||||
|     } | ||||
|     int ca_cert_len = strlen(eap.ca_cert); | ||||
|     int client_cert_len = strlen(eap.client_cert); | ||||
|     int client_key_len = strlen(eap.client_key); | ||||
|     if (ca_cert_len) { | ||||
|       err = esp_wifi_sta_wpa2_ent_set_ca_cert((uint8_t *) eap.ca_cert, ca_cert_len + 1); | ||||
|       err = esp_eap_client_set_ca_cert((uint8_t *) eap.ca_cert, ca_cert_len + 1); | ||||
|       if (err != ESP_OK) { | ||||
|         ESP_LOGV(TAG, "esp_wifi_sta_wpa2_ent_set_ca_cert failed! %d", err); | ||||
|         ESP_LOGV(TAG, "esp_eap_client_set_ca_cert failed! %d", err); | ||||
|       } | ||||
|     } | ||||
|     // workout what type of EAP this is | ||||
|     // validation is not required as the config tool has already validated it | ||||
|     if (client_cert_len && client_key_len) { | ||||
|       // if we have certs, this must be EAP-TLS | ||||
|       err = esp_wifi_sta_wpa2_ent_set_cert_key((uint8_t *) eap.client_cert, client_cert_len + 1, | ||||
|                                                (uint8_t *) eap.client_key, client_key_len + 1, | ||||
|                                                (uint8_t *) eap.password.c_str(), strlen(eap.password.c_str())); | ||||
|       err = esp_eap_client_set_certificate_and_key((uint8_t *) eap.client_cert, client_cert_len + 1, | ||||
|                                                    (uint8_t *) eap.client_key, client_key_len + 1, | ||||
|                                                    (uint8_t *) eap.password.c_str(), strlen(eap.password.c_str())); | ||||
|       if (err != ESP_OK) { | ||||
|         ESP_LOGV(TAG, "esp_wifi_sta_wpa2_ent_set_cert_key failed! %d", err); | ||||
|         ESP_LOGV(TAG, "esp_eap_client_set_certificate_and_key failed! %d", err); | ||||
|       } | ||||
|     } else { | ||||
|       // in the absence of certs, assume this is username/password based | ||||
|       err = esp_wifi_sta_wpa2_ent_set_username((uint8_t *) eap.username.c_str(), eap.username.length()); | ||||
|       err = esp_eap_client_set_username((uint8_t *) eap.username.c_str(), eap.username.length()); | ||||
|       if (err != ESP_OK) { | ||||
|         ESP_LOGV(TAG, "esp_wifi_sta_wpa2_ent_set_username failed! %d", err); | ||||
|         ESP_LOGV(TAG, "esp_eap_client_set_username failed! %d", err); | ||||
|       } | ||||
|       err = esp_wifi_sta_wpa2_ent_set_password((uint8_t *) eap.password.c_str(), eap.password.length()); | ||||
|       err = esp_eap_client_set_password((uint8_t *) eap.password.c_str(), eap.password.length()); | ||||
|       if (err != ESP_OK) { | ||||
|         ESP_LOGV(TAG, "esp_wifi_sta_wpa2_ent_set_password failed! %d", err); | ||||
|         ESP_LOGV(TAG, "esp_eap_client_set_password failed! %d", err); | ||||
|       } | ||||
|     } | ||||
|     err = esp_wifi_sta_wpa2_ent_enable(); | ||||
|     err = esp_wifi_sta_enterprise_enable(); | ||||
|     if (err != ESP_OK) { | ||||
|       ESP_LOGV(TAG, "esp_wifi_sta_wpa2_ent_enable failed! %d", err); | ||||
|       ESP_LOGV(TAG, "esp_wifi_sta_enterprise_enable failed! %d", err); | ||||
|     } | ||||
|   } | ||||
| #endif  // USE_WIFI_WPA2_EAP | ||||
| @@ -552,7 +552,7 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ | ||||
|       ESP_LOGV(TAG, "Event: Connected ssid='%s' bssid=" LOG_SECRET("%s") " channel=%u, authmode=%s", buf, | ||||
|                format_mac_addr(it.bssid).c_str(), it.channel, get_auth_mode_str(it.authmode)); | ||||
| #if USE_NETWORK_IPV6 | ||||
|       this->set_timeout(100, [] { WiFi.enableIpV6(); }); | ||||
|       this->set_timeout(100, [] { WiFi.enableIPv6(); }); | ||||
| #endif /* USE_NETWORK_IPV6 */ | ||||
|  | ||||
|       break; | ||||
| @@ -662,12 +662,7 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ | ||||
| } | ||||
|  | ||||
| WiFiSTAConnectStatus WiFiComponent::wifi_sta_connect_status_() { | ||||
| #if USE_ARDUINO_VERSION_CODE < VERSION_CODE(3, 1, 0) | ||||
|   const auto status = WiFiClass::status(); | ||||
| #else | ||||
|   const auto status = WiFi.status(); | ||||
| #endif | ||||
|  | ||||
|   if (status == WL_CONNECT_FAILED || status == WL_CONNECTION_LOST) { | ||||
|     return WiFiSTAConnectStatus::ERROR_CONNECT_FAILED; | ||||
|   } | ||||
|   | ||||
| @@ -149,7 +149,7 @@ | ||||
| #define USE_WIFI_11KV_SUPPORT | ||||
|  | ||||
| #ifdef USE_ARDUINO | ||||
| #define USE_ARDUINO_VERSION_CODE VERSION_CODE(2, 0, 5) | ||||
| #define USE_ARDUINO_VERSION_CODE VERSION_CODE(3, 1, 3) | ||||
| #define USE_ETHERNET | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -34,7 +34,6 @@ build_flags = | ||||
| [common] | ||||
| lib_deps = | ||||
|     esphome/noise-c@0.1.4                  ; api | ||||
|     makuna/NeoPixelBus@2.7.3               ; neopixelbus | ||||
|     improv/Improv@1.2.4                    ; improv_serial / esp32_improv | ||||
|     bblanchon/ArduinoJson@6.18.5           ; json | ||||
|     wjtje/qr-code-generator-library@1.7.0  ; qr_code | ||||
| @@ -101,6 +100,7 @@ lib_deps = | ||||
|     ESP8266WiFi                           ; wifi (Arduino built-in) | ||||
|     Update                                ; ota (Arduino built-in) | ||||
|     ESP32Async/ESPAsyncTCP@2.0.0          ; async_tcp | ||||
|     makuna/NeoPixelBus@2.7.3              ; neopixelbus | ||||
|     ESP8266HTTPClient                     ; http_request (Arduino built-in) | ||||
|     ESP8266mDNS                           ; mdns (Arduino built-in) | ||||
|     DNSServer                             ; captive_portal (Arduino built-in) | ||||
| @@ -118,23 +118,26 @@ extra_scripts = post:esphome/components/esp8266/post_build.py.script | ||||
| ; This are common settings for the ESP32 (all variants) using Arduino. | ||||
| [common:esp32-arduino] | ||||
| extends = common:arduino | ||||
| platform = platformio/espressif32@5.4.0 | ||||
| platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.13/platform-espressif32.zip | ||||
| platform_packages = | ||||
|     platformio/framework-arduinoespressif32@~3.20005.0 | ||||
|     pioarduino/framework-arduinoespressif32@https://github.com/espressif/arduino-esp32/releases/download/3.1.3/esp32-3.1.3.zip | ||||
|  | ||||
| framework = arduino | ||||
| lib_deps = | ||||
|     ; order matters with lib-deps; some of the libs in common:arduino.lib_deps | ||||
|     ; don't declare built-in libraries as dependencies, so they have to be declared first | ||||
|     FS                                   ; web_server_base (Arduino built-in) | ||||
|     Networking                           ; wifi,web_server_base,ethernet (Arduino built-in) | ||||
|     WiFi                                 ; wifi,web_server_base,ethernet (Arduino built-in) | ||||
|     Update                               ; ota,web_server_base (Arduino built-in) | ||||
|     ${common:arduino.lib_deps} | ||||
|     ESP32Async/AsyncTCP@3.4.4            ; async_tcp | ||||
|     WiFiClientSecure                     ; http_request,nextion (Arduino built-in) | ||||
|     NetworkClientSecure                  ; http_request,nextion (Arduino built-in) | ||||
|     HTTPClient                           ; http_request,nextion (Arduino built-in) | ||||
|     ESPmDNS                              ; mdns (Arduino built-in) | ||||
|     ESP32 Async UDP                      ; captive_portal (Arduino built-in) | ||||
|     DNSServer                            ; captive_portal (Arduino built-in) | ||||
|     makuna/NeoPixelBus@2.8.0             ; neopixelbus | ||||
|     esphome/ESP32-audioI2S@2.3.0         ; i2s_audio | ||||
|     droscy/esp_wireguard@0.4.2           ; wireguard | ||||
|     esphome/esp-audio-libs@1.1.4         ; audio | ||||
|   | ||||
| @@ -13,7 +13,7 @@ platformio==6.1.18  # When updating platformio, also update /docker/Dockerfile | ||||
| esptool==4.8.1 | ||||
| click==8.1.7 | ||||
| esphome-dashboard==20250514.0 | ||||
| aioesphomeapi==32.2.3 | ||||
| aioesphomeapi==32.2.4 | ||||
| zeroconf==0.147.0 | ||||
| puremagic==1.29 | ||||
| ruamel.yaml==0.18.14 # dashboard_import | ||||
|   | ||||
| @@ -5,7 +5,7 @@ pyupgrade==3.20.0  # also change in .pre-commit-config.yaml when updating | ||||
| pre-commit | ||||
|  | ||||
| # Unit tests | ||||
| pytest==8.4.0 | ||||
| pytest==8.4.1 | ||||
| pytest-cov==6.2.1 | ||||
| pytest-mock==3.14.1 | ||||
| pytest-asyncio==1.0.0 | ||||
|   | ||||
| @@ -6,7 +6,6 @@ light: | ||||
|     rgb_order: GRB | ||||
|     num_leds: 256 | ||||
|     pin: ${pin} | ||||
|     rmt_channel: 0 | ||||
|  | ||||
| display: | ||||
|   - platform: addressable_light | ||||
|   | ||||
| @@ -1,8 +0,0 @@ | ||||
| <<: !include common.yaml | ||||
|  | ||||
| esp32_ble_tracker: | ||||
|   max_connections: 3 | ||||
|  | ||||
| bluetooth_proxy: | ||||
|   active: true | ||||
|   connection_slots: 2 | ||||
| @@ -8,7 +8,6 @@ light: | ||||
|     rgb_order: GRB | ||||
|     num_leds: 256 | ||||
|     pin: ${pin} | ||||
|     rmt_channel: 0 | ||||
|     effects: | ||||
|       - e131: | ||||
|           universe: 1 | ||||
|   | ||||
| @@ -32,3 +32,7 @@ esp32_camera_web_server: | ||||
|     mode: stream | ||||
|   - port: 8081 | ||||
|     mode: snapshot | ||||
|  | ||||
| wifi: | ||||
|   ssid: MySSID | ||||
|   password: password1 | ||||
|   | ||||
| @@ -1,18 +0,0 @@ | ||||
| light: | ||||
|   - platform: esp32_rmt_led_strip | ||||
|     id: led_strip1 | ||||
|     pin: ${pin1} | ||||
|     num_leds: 60 | ||||
|     rmt_channel: 0 | ||||
|     rgb_order: GRB | ||||
|     chipset: ws2812 | ||||
|   - platform: esp32_rmt_led_strip | ||||
|     id: led_strip2 | ||||
|     pin: ${pin2} | ||||
|     num_leds: 60 | ||||
|     rmt_channel: 1 | ||||
|     rgb_order: RGB | ||||
|     bit0_high: 100us | ||||
|     bit0_low: 100us | ||||
|     bit1_high: 100us | ||||
|     bit1_low: 100us | ||||
| @@ -3,4 +3,4 @@ substitutions: | ||||
|   pin2: GPIO14 | ||||
|  | ||||
| packages: | ||||
|   common: !include common-ard.yaml | ||||
|   common: !include common.yaml | ||||
|   | ||||
| @@ -3,4 +3,4 @@ substitutions: | ||||
|   pin2: GPIO4 | ||||
|  | ||||
| packages: | ||||
|   common: !include common-ard.yaml | ||||
|   common: !include common.yaml | ||||
|   | ||||
| @@ -3,4 +3,4 @@ substitutions: | ||||
|   pin2: GPIO4 | ||||
|  | ||||
| packages: | ||||
|   common: !include common-idf.yaml | ||||
|   common: !include common.yaml | ||||
|   | ||||
| @@ -3,4 +3,4 @@ substitutions: | ||||
|   pin2: GPIO14 | ||||
|  | ||||
| packages: | ||||
|   common: !include common-idf.yaml | ||||
|   common: !include common.yaml | ||||
|   | ||||
| @@ -3,7 +3,7 @@ substitutions: | ||||
|   pin2: GPIO4 | ||||
|  | ||||
| packages: | ||||
|   common: !include common-idf.yaml | ||||
|   common: !include common.yaml | ||||
|  | ||||
| light: | ||||
|   - id: !extend led_strip1 | ||||
|   | ||||
| @@ -1,5 +1 @@ | ||||
| <<: !include common.yaml | ||||
|  | ||||
| esp32: | ||||
|   framework: | ||||
|     version: 2.0.9 | ||||
|   | ||||
| @@ -5,7 +5,6 @@ light: | ||||
|     chipset: ws2812 | ||||
|     num_leds: 256 | ||||
|     rgb_order: GRB | ||||
|     rmt_channel: 1 | ||||
|     pin: ${pin} | ||||
|   - platform: partition | ||||
|     name: Partition Light | ||||
|   | ||||
| @@ -1,14 +0,0 @@ | ||||
| remote_receiver: | ||||
|   - id: rcvr | ||||
|     pin: ${pin} | ||||
|     rmt_channel: ${rmt_channel} | ||||
|     dump: all | ||||
|     tolerance: 25% | ||||
|     <<: !include common-actions.yaml | ||||
|  | ||||
| binary_sensor: | ||||
|   - platform: remote_receiver | ||||
|     name: Panasonic Remote Input | ||||
|     panasonic: | ||||
|       address: 0x4004 | ||||
|       command: 0x100BCBD | ||||
| @@ -1,6 +1,9 @@ | ||||
| substitutions: | ||||
|   pin: GPIO2 | ||||
|   rmt_channel: "2" | ||||
|   clock_resolution: "2000000" | ||||
|   filter_symbols: "2" | ||||
|   receive_symbols: "4" | ||||
|   rmt_symbols: "64" | ||||
|  | ||||
| packages: | ||||
|   common: !include esp32-common-ard.yaml | ||||
|   common: !include esp32-common.yaml | ||||
|   | ||||
| @@ -1,6 +1,9 @@ | ||||
| substitutions: | ||||
|   pin: GPIO2 | ||||
|   rmt_channel: "2" | ||||
|   clock_resolution: "2000000" | ||||
|   filter_symbols: "2" | ||||
|   receive_symbols: "4" | ||||
|   rmt_symbols: "64" | ||||
|  | ||||
| packages: | ||||
|   common: !include esp32-common-ard.yaml | ||||
|   common: !include esp32-common.yaml | ||||
|   | ||||
| @@ -6,4 +6,4 @@ substitutions: | ||||
|   rmt_symbols: "64" | ||||
|  | ||||
| packages: | ||||
|   common: !include esp32-common-idf.yaml | ||||
|   common: !include esp32-common.yaml | ||||
|   | ||||
| @@ -6,4 +6,4 @@ substitutions: | ||||
|   rmt_symbols: "64" | ||||
|  | ||||
| packages: | ||||
|   common: !include esp32-common-idf.yaml | ||||
|   common: !include esp32-common.yaml | ||||
|   | ||||
| @@ -6,7 +6,7 @@ substitutions: | ||||
|   rmt_symbols: "64" | ||||
|  | ||||
| packages: | ||||
|   common: !include esp32-common-idf.yaml | ||||
|   common: !include esp32-common.yaml | ||||
|  | ||||
| remote_receiver: | ||||
|   - id: !extend rcvr | ||||
|   | ||||
| @@ -1,8 +0,0 @@ | ||||
| remote_transmitter: | ||||
|   - id: xmitr | ||||
|     pin: ${pin} | ||||
|     rmt_channel: ${rmt_channel} | ||||
|     carrier_duty_percent: 50% | ||||
|  | ||||
| packages: | ||||
|   buttons: !include common-buttons.yaml | ||||
| @@ -1,6 +1,7 @@ | ||||
| substitutions: | ||||
|   pin: GPIO2 | ||||
|   rmt_channel: "2" | ||||
|   clock_resolution: "2000000" | ||||
|   rmt_symbols: "64" | ||||
|  | ||||
| packages: | ||||
|   common: !include esp32-common-ard.yaml | ||||
|   common: !include esp32-common.yaml | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| substitutions: | ||||
|   pin: GPIO2 | ||||
|   rmt_channel: "1" | ||||
|   clock_resolution: "2000000" | ||||
|   rmt_symbols: "64" | ||||
|  | ||||
| packages: | ||||
|   common: !include esp32-common-ard.yaml | ||||
|   common: !include esp32-common.yaml | ||||
|   | ||||
| @@ -4,4 +4,4 @@ substitutions: | ||||
|   rmt_symbols: "64" | ||||
|  | ||||
| packages: | ||||
|   common: !include esp32-common-idf.yaml | ||||
|   common: !include esp32-common.yaml | ||||
|   | ||||
| @@ -4,4 +4,4 @@ substitutions: | ||||
|   rmt_symbols: "64" | ||||
|  | ||||
| packages: | ||||
|   common: !include esp32-common-idf.yaml | ||||
|   common: !include esp32-common.yaml | ||||
|   | ||||
| @@ -4,7 +4,7 @@ substitutions: | ||||
|   rmt_symbols: "64" | ||||
|  | ||||
| packages: | ||||
|   common: !include esp32-common-idf.yaml | ||||
|   common: !include esp32-common.yaml | ||||
|  | ||||
| remote_transmitter: | ||||
|   - id: !extend xmitr | ||||
|   | ||||
| @@ -12,6 +12,5 @@ light: | ||||
|     rgb_order: GRB | ||||
|     num_leds: 256 | ||||
|     pin: 2 | ||||
|     rmt_channel: 0 | ||||
|     effects: | ||||
|       - wled: | ||||
|   | ||||
| @@ -12,6 +12,5 @@ light: | ||||
|     rgb_order: GRB | ||||
|     num_leds: 256 | ||||
|     pin: 2 | ||||
|     rmt_channel: 0 | ||||
|     effects: | ||||
|       - wled: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user