Incorrect values read when trying to get a JPEG

  1. Where did you get the camera module(s)?
    Two identical cameras from Arducam web site

  2. Model number of the product(s)?
    3MP-NoIR 10th anniversary edition, SKU B0435

  3. What hardware/platform were you working on?
    Custom board with ATmega32U4, 8 MHz SPI

  4. Instructions you have followed. (link/manual/etc.)
    Mega SPI Camera Series Application Note (very incomplete, registers missing), source code from Arducam’s GitHub (mainly ArducamCamera.c)

  5. Problems you were having?
    Trying to get a JPEG I get always the same absurd size (8390520, greater than 8 MB), and the data is not a valid JPEG.

  6. What help do you need?
    Proper register table for this camera, point if something is missing in my code
    I will read later also raw RGB values (format 2): How are these values returned, RGB565? Little endian or big endian?

My code:

// Init camera
SingleWrite(CAM_REG_SENSOR_RESET, CAM_SENSOR_RESET_ENABLE_MASK); // 0x07, (1 << 6)
SingleWrite(CAM_REG_FORMAT, FORMAT_JPEG); // 0x20, 1
SingleWrite(CAM_REG_IMAGE_QUALITY, JPEG_QUALITY_LOW); // 0x2A, 2
SingleWrite(CAM_REG_CAPTURE_RESOLUTION, RESOLUTION_1600X1200); // 0x21, 6
// Read some values, all OK
const uint8_t Sensor = SingleRead(CAM_REG_SENSOR_ID); // 0x40, returns 0x84 (3 Mp v2)
const uint8_t Year = SingleRead(CAM_REG_YEAR_ID); // 0x41, returns 23
const uint8_t Month = SingleRead(CAM_REG_MONTH_ID); // 0x42, returns 4
const uint8_t Day = SingleRead(CAM_REG_DAY_ID); // 0x43, returns 12
// Take snapshot
SingleWrite(CAM_REG_SENSOR_RESET, CAM_SENSOR_RESET_CLEAR_MASK); // 0x07, (1 << 7)
SingleWrite(CAM_REG_FIFO_CONTROL, FIFO_CONTROL_CLEAR_MASK); // 0x04, (1 << 0)
SingleWrite(CAM_REG_FIFO_CONTROL, FIFO_CONTROL_START_MASK); // 0x04, (1 << 1)
// Wait capture
while ((SingleRead(CAM_REG_SENSOR_STATE) & CAM_SENSOR_STATE_DONE_MASK) == 0); // 0x44, (1 << 2)
// Read data length
const uint32_t LengthLow = SingleRead(CAM_REG_FIFO_SIZE_LOW); // 0x45
const uint32_t LengthMid = SingleRead(CAM_REG_FIFO_SIZE_MID); // 0x46
const uint32_t LengthHigh = SingleRead(CAM_REG_FIFO_SIZE_HIGH); // 0x47
const uint32_t Length = LengthLow | (LengthMid << 8) | (LengthHigh << 16);

Surprise! Here Length is always 8390520 (0x800778), greater than the FIFO size (8 MB) and too big for a JPG.

When I read these bytes the content is not a JPEG. The first 48 bytes are:
D4 93 DC B4 DC D5 E4 F5 E4 F5 E5 15 E5 15 E5 15
E4 F5 E4 F5 E4 F5 EC F5 EC F5 ED 16 ED 15 ED 36
F5 57 F5 57 ED 56 ED 56 ED 57 F5 77 F5 77 F5 77

I found the problem: waiting for I2C completion is your friend, specially after changing image format.

IMHO the MEGA documentation (specially register list) is incomplete and poor.