−Table of Contents
Camera controller
NOTE: this is a findings dump for now. It is unclear what is what, so there may be stuff pertaining to the h265 codec in here. Not sure how interwoven it is with the camera controller.
Known registers:
Address | Desc. |
---|---|
0xF0000800 | ??? (might not be strictly camera-related) |
0xF000081C | ??? address for some buffer |
0xF0000820 | ??? set to 0x400000 |
0xF0000828 | ??? set to same as F000081C |
0xF000082C | ??? set to 0x400000 |
0xF0008414 | ??? |
0xF0008420 | ??? |
0xF0008460 | ??? buffer? position? |
0xF0008468 | IRQ status/ack for IRQ 0x11 |
0xF000846C | ??? buffer? position? |
0xF0008470 | ??? buffer? position? |
0xF0008474 | ??? buffer? position? |
0xF0008478 | ??? IRQ enable flags?? |
0xF00084A4 | buffer address for incoming h265 data? |
0xF00084A8 | another buffer address? |
0xF00084AC | ??? buffer? position? |
0xF00084B0 | IRQ status/ack for IRQ 0x12 |
0xF00084B8 | ??? |
0xF0008800 | ??? |
0xF0008810 | ??? control reg? |
0xF0008814 | ??? |
0xF000881C+(N*8) | table N, bytes 0..3 (N=0..7) |
0xF0008820+(N*8) | table N, byte 4 |
0xF000886C | ??? |
0xF000887C+(N*8) | table N, bytes 0..3 (N=0..7) |
0xF0008880+(N*8) | table N, byte 4 |
0xF00088B4 | ??? (related to framerate?) (actually part of the tables above) |
0xF0008C00 | ??? |
0xF0008C04 | ??? weird value, timings? |
0xF0008C08 | Resolution? |
0xF0008C10 | ??? |
0xF0008C28 | ??? |
0xF0008C2C | ??? |
0xF0008C34 | ??? |
0xF0008C70 | IRQ status/ack for IRQ 0x10 |
0xF0008C74 | ??? related to IRQ 0x10? |
0xF0009000 | ??? control register? |
0xF0009004 | ??? vertical resolution? |
0xF0009008 | ??? |
0xF0009028 | IRQ disable/status/ack for IRQ 0x14 |
0xF0009030 | ??? (IRQ position?? think F0009508) |
0xF0009034 | ??? (IRQ position??) |
0xF0009038 | IRQ status/ack for IRQ 0x1D |
0xF0009040 | extra IRQ status/ack for IRQ 0x14 |
0xF0009044 | ??? |
Related IRQs:
IRQ | Desc. |
---|---|
0x10 | h264 decoding? |
0x11 | h264 encoding? |
0x14 | Camera event |
0x1D | ??? |
0xF0009028
IRQ disable, status and acknowledge, condensed into one register.
Bits 0-7 are the status flags. Bits 8-15 are the disable flags (ie. setting a bit to 1 disables the corresponding IRQ). Bits 16-23 are the acknowledge flags, ie. writing a 1 to a bit acknowledges the corresponding IRQ.
IRQ bit | Desc. |
---|---|
0 | Camera frame IRQ |
1 | ??? |
2 | ??? |
3 | ??? |
4 | ??? |
5 | ??? |
6 | ??? |
7 | ??? |
IRQ 1, 2 and 5 are unused by the stock firmware.
IRQ 0 fires between each camera frame. It can be synchonized to the display with register 0xF00094F8. TODO: not known if it marks the start or end of the camera VBlank; it is probably the end, ie. the start of a new camera frame.
These IRQ conditions are connected to IRQ 0x14.
Camera video format
The video data produced by the camera is YUV, encoded in a NV12-like interleaved format.
The data is split in chunks of 48 bytes. In each chunk, the first 16 bytes are Y values for a row of 16 pixels, the next 16 bytes are Y values for the next row (underneath the first row), the next 8 bytes are U values, and the last 8 bytes are V values. U/V value pairs are shared across blocks of 2×2 pixels.
Oddly, it seems that in each row, the values are stored backwards, and this regardless of the camera's mirror setting.
The camera can produce data in other formats, but it's not yet known how they work. Also unknown if the controller supports different encodings.
Camera timings
The camera VSync is generated by the SoC's camera controller, rather than by the camera itself. It seems that the pixel clock is also generated by the SoC, but the HREF signal (horizontal sync) is generated by the camera.
When the camera is active, its input clock (register 0xF0000038) is set to 24 MHz. The camera then divides that clock by 2. These settings are suitable for a framerate of 30 FPS at 640×480.
It is possible to reach 60 FPS at 640×480 by either doubling the input clock or changing the camera's clock divider to 1 (instead of 2), but doing so seems to produce a picture with weird colors. Possibly other settings need to be adjusted as well, like the exposure time, etc…
When the camera is inactive, the input clock is set to ~125.5 KHz, presumably to save energy.