Fix TC358743 HDMI capture colors and CSI-stall recovery on rev 1.3 - #2
Draft
DatanoiseTV wants to merge 2 commits into
Draft
Fix TC358743 HDMI capture colors and CSI-stall recovery on rev 1.3#2DatanoiseTV wants to merge 2 commits into
DatanoiseTV wants to merge 2 commits into
Conversation
On rev 1.3 silicon the TC358743 keeps a locked HDMI input (TMDS+SYNC in SYS_STATUS) while the P4 MIPI CSI-2 bridge stalls independently: the RX FIFO fills, no line packets arrive, and DMA completions stop. The old recovery path treated every frame timeout as HDMI loss and dropped HPD, which forced the attached PC to re-enumerate the display on each stall - a visible reconnect/mode-change storm on the host. Split recovery by what actually failed: - capture_hw_csi_rekick(): non-destructive path for the "TC locked but CSI stalled" case. Stops esp_cam, re-applies the CSI bridge config, restarts, and re-issues the TC's CSI-2 TX start WITHOUT touching HPD/EDID/TMDS, so the source never re-enumerates. - capture_hw_csi_full_reinit(): escalation for a wedged D-PHY. esp_cam stop/start does not reset the D-PHY receiver; only a full teardown and recreate of the esp_cam CSI controller + ISP processor does. Destroys and rebuilds the stack, then re-issues the TC CSI start, still without cycling HPD. handle_csi_timeout() now checks SYS_STATUS: while the input is locked it re-kicks (throttled by HDMI_RECOVER_CSI_REKICK_COOLDOWN_US), and after CSI_REKICK_ATTEMPTS_BEFORE_REINIT consecutive failed re-kicks escalates to the full D-PHY reinit. Only a genuine loss of lock falls back to the HPD-cycling capture_hw_hdmi_recover(). The esp_cam creation/destruction is refactored into s_csi_stack_create()/s_csi_stack_destroy() so both init and the D-PHY reinit share one code path. A frame-buffer hex dump (raw CSI word and encoder input) is added behind CONFIG_P4KVM_TC358743_ADV_DEBUG for diagnosing byte-order and stall issues.
On rev 1.3 silicon the TC358743 lands its YUV422 stream luma-first ([Y,C,Y,C] in memory, confirmed via the raw framebuffer hex dump) while the P4 JPEG encoder consumes chroma-first. Without a reorder the luma and chroma bytes are interleave-swapped, producing 2-pixel vertical stripes and wrong colours on solid fills. Enable the CSI bridge's byte_swap_en, which swaps the two bytes of each 16-bit YUV422 element in the DMA write path - a free hardware de- interleave, no extra pass and no measured fps cost (28 fps sustained). This supersedes the disabled BitScrambler reorder path; update the CAPTURE_NEEDS_REORDER comment in capture_priv.h to reflect that the reorder is now done by the byte swap rather than being unnecessary.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings up TC358743 HDMI-to-CSI capture on rev 1.3 silicon (DCDZ-H2C module). Two independent defects, one commit each. Stacked on
feat/video-hid-webui-overhaul.1. YUV422 luma/chroma order (
byte_swap_en)The TC358743 lands its YUV422 stream luma-first (
[Y,C,Y,C]in memory, confirmed via a raw framebuffer hex dump) while the P4 JPEG encoder consumes chroma-first. The bytes were interleave-swapped, giving 2-pixel vertical stripes and wrong colours on solid fills.Fix: enable the CSI bridge's
byte_swap_en, which swaps the two bytes of each 16-bit YUV422 element in the DMA write path. Free hardware de-interleave, no extra pass, no fps cost (28 fps sustained). Supersedes the disabled BitScrambler reorder path (measured ~28 MB/s, far too slow for 30 fps).2. CSI-stall recovery without HDMI re-enumeration
On rev 1.3 the TC358743 keeps a locked HDMI input (TMDS+SYNC in
SYS_STATUS) while the P4 MIPI CSI-2 bridge stalls independently (RX FIFO fills, no line packets, DMA completions stop). The old recovery path treated every frame timeout as HDMI loss and dropped HPD, forcing the attached PC to re-enumerate the display on each stall — a visible reconnect/mode-change storm on the host.Recovery is now split by what actually failed:
capture_hw_csi_rekick()— non-destructive path for "TC locked, CSI stalled". Restarts esp_cam and re-issues the TC CSI-2 TX start without touching HPD/EDID/TMDS, so the source never re-enumerates. Throttled by a cooldown.capture_hw_csi_full_reinit()— escalation for a wedged D-PHY.esp_camstop/start does not reset the D-PHY receiver; only a full teardown/recreate of the esp_cam CSI controller + ISP processor does. Rebuilds the stack, then re-issues the TC CSI start, still without cycling HPD.handle_csi_timeout()checksSYS_STATUS: while locked it re-kicks; after N consecutive failed re-kicks it escalates to the full D-PHY reinit; only a genuine loss of lock falls back to the HPD-cycling recover. The esp_cam create/destroy is refactored into shareds_csi_stack_create()/s_csi_stack_destroy()helpers. A framebuffer hex dump (raw CSI word + encoder input) is added behindCONFIG_P4KVM_TC358743_ADV_DEBUGfor byte-order/stall diagnosis.Testing
Verified on hardware (ESP32-P4 rev 1.3 + TC358743, PC HDMI source): correct colours, stable capture over 2+ minutes across host sleep/wake, 28 fps at 4.28 Mb/s over the live MJPEG stream. Full IDF v6.0 build passes.
Known residual
A faint +8px horizontal echo remains on high-contrast text (81/370 text rows; luma full-res, no shear, colours correct). Under investigation; not a regression from this change and does not block the colour/stability fixes.