refactor(driver_spi): refactor header styles of spi sct part on soc and lowlevel
Closes IDF-10583, IDF-10584, IDF-10585, IDF-10586, and IDF-13725
See merge request espressif/esp-idf!51676
fix(nimble): Send Prepare Write Request before Execute Write in write long with zero-length data
Closes BLERP-2813
See merge request espressif/esp-idf!48832
Migrate the MCP server extension to the shared esp-pylib library:
- replace raw stderr prints with esp_pylib.logger.log (note/err)
- route informational logs to stderr via set_info_stream so stdout
stays reserved for the MCP JSON-RPC transport
- enumerate connected devices via esp_pylib.serial_ports.get_port_names
- stub the new imports in the mcp_ext unit tests
Co-authored-by: Cursor <cursoragent@cursor.com>
Add a `monitor_device` MCP tool that lets an AI agent run a scripted,
non-interactive `esp-idf-monitor` session against a flashed device and
get back a short status plus a log file path, instead of raw serial
output inline.
Under the hood:
- The agent supplies a plain-text command body (expect/send/sleep/reset/
exit/comments). `assemble_monitor_script_from_agent_commands()` frames
it into a script the monitor's non-interactive command mode can
consume via stdin: it appends `exit` if the agent didn't already end
with one, and rewrites every bare `expect <regex>` into `expect
--timeout <timeout_sec> <regex>` via `_monitor_normalize_expect_line()`
(an already-bounded `expect --timeout ...` line is left untouched so
the monitor itself reports a bad value). A leading `reset` is not
prepended - the monitor already resets the chip when it opens the
port - and any `reset` the agent wrote is left in place.
`_monitor_parse_sleep_duration()` extracts each `sleep <n>` duration.
The effective timeout is the sum of every bounded expect duration
plus every sleep duration. Scripts whose sum exceeds
`MONITOR_MAX_SCRIPT_SEC` are rejected. If the script has neither
expect nor sleep (for example only `send`), `timeout_sec` is used so
the process still has a kill bound.
- `monitor_device()` runs `python -m esp_idf_monitor` via
`subprocess.run(..., input=script, timeout=2 * effective_timeout)`.
`no_reset` is forwarded as `--no-reset` so the connection reset can be
skipped; an explicit `-p` is forwarded when a port is given. Extra
arguments match `idf.py monitor` where a build exists: baud (`baud`
tool arg, else `monitor_baud` from `project_description.json`),
toolchain prefix, `--target`/`--revision`, coredump/panic decode, and
ELF files with the app ELF first. The 2x hard timeout is a safety net
independent of the script's own `expect --timeout`/`exit` logic; on
`TimeoutExpired` the process is killed but any output already captured
is preserved and logged. `decode_stream()` normalizes that captured
output, which can be `bytes` on the timeout path even though the
process otherwise runs in text mode.
- The monitor's exit code drives the reported status via
`_monitor_status()`, using `EXIT_EXPECT_TIMEOUT` and
`EXIT_SCRIPT_ERROR` from `esp_idf_monitor.base.constants`: 0 is
success, 110 means an `expect` pattern never showed up before its
`--timeout` elapsed, 2 means the monitor rejected the script (bad
syntax/timeout/regex), anything else is reported generically.
- Serial output and the monitor's own messages share one pipe
(`stderr=STDOUT`) so decoded panic backtraces stay next to the lines
that triggered them. `_save_monitor_output()` writes the full merge to
`<tempdir>/esp_idf_mcp_log/action_monitor/monitor_<timestamp>.log` and
reports a dedicated `Log file:` line. On non-zero exit or process
kill, a short tail of that same merge is also returned inline so the
agent has some failure context without a second file read. If the log
file can't be written, it falls back to inlining a truncated tail.
Closes https://github.com/espressif/esp-idf/issues/18757
Closes https://github.com/espressif/esp-idf/pull/18385
Co-authored-by: Cursor <cursoragent@cursor.com>
A 15 ms link with max_ce_len=0 sent one DLE PDU per event and capped
badge frames at ~17 KB/s. Request 7.5–15 ms and a long CE, and refill
the single CoC TX slot instead of treating EBUSY as a hard failure.
Move the cache profile counter type definitions to hal/cache_types.h so
that
esp_cache_cnt.h can use them without depending on the public soc header
soc/cache_periph.h (which CI rejects as non-public).
The remaining cache_periph.h header and its per-target cache_periph.c
sources
are moved from the soc component into the hal component, with the
sources
organized per target directory as usual for the hal component.
Removes the soc/cache_periph.h dependency from esp_cache_cnt.h and
hal/cache_ll.h by using hal/cache_periph.h instead.
Return GATT_INVALID_HANDLE instead of GATT_NOT_FOUND when Read Multiple
(Variable) response assembly fails, since 0x0A is not a valid ATT error
for these PDUs per Core Spec Vol 3 Part F.
Add function usb_dwc_hal_init_with_config() that takes a bitmap
of configuration flags.
Currently only FS/LS only flag is implemented, but the design
allows extension in the future.
spi_flash_mmap_page_num_init() passed a literal 128 while the ROM searches
Cache_Get_DROM_MMU_End() / 4 entries -- 256 on esp32c5, c6, h2 and s3 -- so
its free-page scan ran off the array and judged entries from stale heap bytes.
The refcount bump on the commit path indexes the same way, so a mapping placed
above entry 127 also writes past the array and corrupts the heap behind it.
esp32c61 and esp32h21 have the ROM mmap but never program the size and have no
soc/mmu.h to read it from, so they keep 128.