STM32N6 JPEG encoder fails for any image width ≠ 800 (e.g., 480, 960) — IDMAEN auto-cleared, raw data dumped
- April 22, 2026
- 0 replies
- 83 views
Hi ST Community,
I'm facing a critical and reproducible hardware JPEG encoding issue on the STM32N6. The JPEG encoder only works correctly when the image width is exactly 800 pixels. Any other width I've tested — including 480, 960, and 960x480 — causes the hardware to fail in exactly the same way. Height variations do not affect the outcome; the problem is solely tied to the row width.
Environment:
-
MCU: STM32N657xx (STM32N6-DK board)
-
Firmware Package: STM32Cube FW_N6 V1.3.0
-
IDE: STM32CubeIDE
-
Image Format: RGB565 input → YCbCr 4:2:0 subsampling, Quality 75.
Issue Summary:
When the image width is 800, JPEG encoding completes successfully and produces a valid compressed JPEG stream. When the width is 480, 960, or any other tested value ≠ 800, the hardware encoder aborts input processing early (after ~14 input chunks for 960 width) and subsequently dumps a massive amount of uncompressed raw data into the output buffer. The output DMA fills the entire buffer in a single transfer, and no valid JPEG data is produced.
Debugging Evidence:
I've instrumented the encode_dma.c driver to log JPEG peripheral registers at each callback. Here are the key observations from a failing 960×960 run (identical behavior occurs for 480 width):
-
IDMAEN Bit Auto-Cleared by Hardware:
During normal operation, CR (Control Register) is 0x00001001. When the failure occurs (at Input Chunk #14 for 960 width), CR becomes 0x00000801. This shows that the IDMAEN (Input DMA Enable) bit is automatically cleared by the JPEG hardware.text[Input Chunk #13] -> GetDataCallback: CR=0x00001001 (IDMAEN = 1) [Input Chunk #14] -> DataReadyCallback: CR=0x00000801 (IDMAEN = 0)
-
OFNEF (Output FIFO Not Empty) Stuck High:
The SR (Status Register) consistently shows OFNEF = 1 (SR = 0x00000096 or 0x86) even early in the encoding process, indicating that the output FIFO is not being drained normally. -
Abnormal Callback Sequence:
The expected sequence is [Input Chunk #N] → [GetDataCallback] → [DataReadyCallback]. During failure, [Input Chunk #14] is followed directly by [DataReadyCallback], skipping the expected [GetDataCallback]. This confirms the input flow was aborted by hardware. -
Massive Raw Data Dump:
After IDMAEN is cleared, DataReadyCallback reports an OutDataLength equal to the entire output buffer size (e.g., 1,843,200 bytes for 960×960). The buffer fills immediately and output pauses.
Observations Across Different Widths:
| 800 × 480 | :white_heavy_check_mark: Success (valid JPEG) |
| 800 × 800 | :white_heavy_check_mark: Success |
| 800 × 960 | :white_heavy_check_mark: Success |
| 480 × 480 | :cross_mark: Fails with same symptoms |
| 960 × 480 | :cross_mark: Fails with same symptoms |
| 960 × 960 | :cross_mark: Fails with same symptoms |
Questions:
-
Why does the JPEG encoder hardware exhibit this strict width dependency? Both 480 and 960 are multiples of 16, satisfying the 4:2:0 MCU alignment requirements.
-
What internal condition causes the hardware to clear IDMAEN and abort input processing?
-
Are there any known errata or configuration constraints (e.g., FIFO thresholds, AXI burst alignment) that could explain this behavior?
-
Could this be related to the internal RGB-to-YCbCr conversion library (jpeg_utils.c) generating incompatible data layouts for non‑800 widths?
I have attached a full debug log comparing a successful 800×800 run with a failing 960×960 run, including register dumps. Any guidance or insights would be greatly appreciated.
Thank you,
LinYuan
