2026-04-22 12:00 AM - last edited on 2026-04-22 1:20 AM by Gyessine
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.
[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