From 1517eda13ecae0c28918b570da9d2b759eafe52d Mon Sep 17 00:00:00 2001 From: Ashley Strahle Date: Wed, 1 Jul 2026 06:11:28 +0000 Subject: [PATCH] add CONFIG_BT_ENABLED to sdkconfig.h for proper BT RF calibration; patch NimBLEDevice.cpp to skip controller init if already done by Arduino framework --- pre_build.py | 96 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 4 deletions(-) diff --git a/pre_build.py b/pre_build.py index e232cc2..327f000 100644 --- a/pre_build.py +++ b/pre_build.py @@ -70,9 +70,8 @@ def patch_sdkconfig_bt(): content = f.read() defines = { - # Do NOT set CONFIG_BT_ENABLED here — that forces the Arduino - # framework to pre-init the BT controller at startup, which - # conflicts with USB. NimBLEDevice::init() handles its own init. + "CONFIG_BT_ENABLED": 1, + "CONFIG_BT_NIMBLE_ENABLED": 1, "CONFIG_BTDM_CTRL_MODE_BLE_ONLY": 1, "CONFIG_BT_NIMBLE_MAX_CONNECTIONS": 1, "CONFIG_BT_NIMBLE_TASK_STACK_SIZE": 6144, @@ -161,6 +160,95 @@ def patch_nimconfig(): print("nimconfig.h patched successfully") +def patch_nimble_device(): + # Find NimBLEDevice.cpp in the NimBLE-Arduino library + search_dirs = [ + os.path.join(os.getcwd(), ".pio", "libdeps"), + os.path.expanduser("~/.platformio/lib"), + ] + for env_dir in ["esp32s3", ""]: + candidate = os.path.join( + os.getcwd(), ".pio", "libdeps", + env_dir, "NimBLE-Arduino", "src", "NimBLEDevice.cpp" + ) if env_dir else "" + if candidate and os.path.exists(candidate): + dev_path = candidate + break + else: + dev_path = None + for base in search_dirs: + if not os.path.exists(base): + continue + for root, _dirs, files in os.walk(base): + if "NimBLEDevice.cpp" in files: + dev_path = os.path.join(root, "NimBLEDevice.cpp") + break + if dev_path: + break + + if not dev_path: + print("WARNING: NimBLEDevice.cpp not found, skipping controller init patch") + return + + print(f"Patching {dev_path} to handle double BT controller init") + + with open(dev_path, 'r') as f: + content = f.read() + + # Replace the ESP_ERROR_CHECK(esp_bt_controller_init) block to handle + # ESP_ERR_INVALID_STATE (already initialized by Arduino framework when CONFIG_BT_ENABLED) + old_block = ( + ' ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg));\n' + ' ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE));\n' + ' ESP_ERROR_CHECK(esp_nimble_hci_init());' + ) + new_block = ( + ' if (esp_bt_controller_init(&bt_cfg) == ESP_OK) {\n' + ' ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE));\n' + ' }\n' + ' ESP_ERROR_CHECK(esp_nimble_hci_init());' + ) + + if old_block in content: + content = content.replace(old_block, new_block) + with open(dev_path, 'w') as f: + f.write(content) + print(" Patched esp_bt_controller_init to skip if already initialized") + else: + # Try alternative indentation (1 tab = 8 spaces) + old_block_alt = old_block.replace(' ', '\t') + new_block_alt = new_block.replace(' ', '\t') + if old_block_alt in content: + content = content.replace(old_block_alt, new_block_alt) + with open(dev_path, 'w') as f: + f.write(content) + print(" Patched (tab-indented) esp_bt_controller_init") + else: + # Try with partial indentation + patterns = [ + (r'(\s*)ESP_ERROR_CHECK\(esp_bt_controller_init\(&bt_cfg\)\);\s*\n' + r'\1ESP_ERROR_CHECK\(esp_bt_controller_enable\(ESP_BT_MODE_BLE\)\);\s*\n' + r'\1ESP_ERROR_CHECK\(esp_nimble_hci_init\(\)\);'), + ] + for pattern in patterns: + replacement = ( + r'\1if (esp_bt_controller_init(&bt_cfg) == ESP_OK) {\n' + r'\1 ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE));\n' + r'\1}\n' + r'\1ESP_ERROR_CHECK(esp_nimble_hci_init());' + ) + new_content = re.sub(pattern, replacement, content) + if new_content != content: + content = new_content + with open(dev_path, 'w') as f: + f.write(content) + print(" Patched esp_bt_controller_init (regex)") + break + else: + print(" WARNING: Could not find esp_bt_controller_init pattern in NimBLEDevice.cpp") + + patch_usb_ids() patch_sdkconfig_bt() -patch_nimconfig() \ No newline at end of file +patch_nimconfig() +patch_nimble_device() \ No newline at end of file