(output_file, device_properties: ConfigParser)
| 329 | output_file.write("CONFIG_TINYUSB_RHPORT_FS=y\n") |
| 330 | |
| 331 | def write_bluetooth_variables(output_file, device_properties: ConfigParser): |
| 332 | idf_target = get_property_or_exit(device_properties, "hardware", "target").lower() |
| 333 | has_bluetooth = get_boolean_property_or_false(device_properties, "hardware", "bluetooth") |
| 334 | if has_bluetooth: |
| 335 | output_file.write("# Bluetooth (NimBLE)\n") |
| 336 | output_file.write("CONFIG_BT_ENABLED=y\n") |
| 337 | output_file.write("CONFIG_BT_NIMBLE_ENABLED=y\n") |
| 338 | if idf_target == "esp32p4": |
| 339 | output_file.write("CONFIG_BT_NIMBLE_TRANSPORT_UART=n\n") |
| 340 | output_file.write("CONFIG_ESP_HOSTED_ENABLE_BT_NIMBLE=y\n") |
| 341 | # Move NimBLE host buffers to SPIRAM when available, regardless of target. |
| 342 | # The default (INTERNAL) mode causes heap fragmentation after a disable+deinit |
| 343 | # cycle, preventing a subsequent nimble_port_init() from allocating its buffers |
| 344 | # ("hci inits failed" / rc=-1). EXTERNAL mode uses SPIRAM, which is much larger |
| 345 | # and does not suffer from the same fragmentation — enabling reliable re-init. |
| 346 | # Also frees significant internal RAM on memory-constrained targets (e.g. S3). |
| 347 | # Dependency: CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC (set by write_spiram_variables). |
| 348 | has_spiram = get_boolean_property_or_false(device_properties, "hardware", "spiRam") |
| 349 | if has_spiram: |
| 350 | output_file.write("CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y\n") |
| 351 | # Expand NimBLE's GAP device name buffer to match BLE_DEVICE_NAME_MAX. |
| 352 | # The default (31) is too short for some device names and leaves no headroom. |
| 353 | output_file.write("CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=64\n") |
| 354 | # Increase NimBLE host task stack from the 4096-byte default. |
| 355 | # GAP/GATT event processing + C++ frames push the default over the limit, |
| 356 | # causing stack-protection faults on events like BLE_GAP_EVENT_SUBSCRIBE. |
| 357 | output_file.write("CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8192\n") |
| 358 | # Persist bond/CCCD data to NVS so that bonds survive BLE disable+re-enable |
| 359 | # cycles (nimble_port_deinit clears RAM-only state). Without this, bonded peers |
| 360 | # (e.g. Windows HID host) lose their LTK match on re-enable and enter a |
| 361 | # rapid connect/disconnect/re-pair loop. |
| 362 | output_file.write("CONFIG_BT_NIMBLE_NVS_PERSIST=y\n") |
| 363 | |
| 364 | def write_usbhost_variables(output_file, device_properties: ConfigParser): |
| 365 | has_usbhost = get_boolean_property_or_false(device_properties, "hardware", "usbHostEnabled") |
no test coverage detected