For 700D, define ENGIO_WRITE_FUNC and ENG_DRV_OUT_FUNC in adtg_gui.c (copy from stubs.S; they used to require fiddling, but I hope it's no longer the case), then select Advanced -> DIGIC registers.
Currently trying to sketch a walkthrough; here's the first draft (still editing).
Here's
another adtg_gui walkthrough for a different purpose; the basics are still valid.
Background:-
What are these registers? (TLDR: that's how the ARM CPU interacts with other peripherals - by writing to / reading from registers)
-
What are ADTG and CMOS registers? (TLDR: CMOS = sensor controller,
ADTG = ADC + timing generator, ENGIO = Canon's image processing engine)
For
changing the LiveView resolution, we are interested in:
- ENGIO registers 0xC0F06800/4 on D5, 0xC0F06084/8 on D4 (raw.c: raw_lv_get_resolution); these adjust the resolution of the captured raw buffer (it's the first set of registers we have to tweak, but it's not enough)
-
Video timer aka
FPS override (these are directly related to resolution; we did not know that at first, but found out later)
- CMOS registers (to select what image area to scan, and also the column binning factors)
- ADTG registers (line skipping factor and some others)
The number of registers is huge (overwhelming). Hundreds? No. Thousands. Many thousands. Address space covers millions of possible registers. We only understand
a tiny part of them. Don't be discouraged.
The logging code has noticeable overhead and may push LiveView beyond its limits. Be prepared to encounter crashes or corrupted images, and be prepared to search for workarounds. For example, on 5D3, I can switch from 50p to 25p with logging enabled, but not the other way around. Enabling logging in x5 mode gives corrupted frames, unless I reduce the FPS. There is an option named Force low FPS, just for that.
Let's start with some basics, for example
FPS override.
There are two timers: A and B. FPS is MainClock / timerA / timerB. MainClock is TG_FREQ_BASE in fps-engio.c (24MHz on 5D3, 32MHz on 100D). Browse the FPS override submenu in a few video modes, compute the FPS from timer values and make sure you understand the math before proceeding.
Now try changing FPS from adtg_gui. Timer A is 0xC0F06008, B is 0xC0F06014. Start from a low-FPS video mode (24/25p), turn off FPS override, enable ADTG registers, enable DIGIC
*) registers, select to show Image size regs only. Go to PLAY mode and back - the registers are identified only when Canon code changes them. Locate the two registers in the menu.
*) actually ENGIO - it wasn't clear to me when I wrote the module. I should rename it.
On 5D3, in 1080p25, you will see: C0F06008 = 0x1df01df, C0F06014 = 0x7cf. Do the math to get 25 FPS. Do not skip this step.
Now increase the value of timer B (e.g. 0x7df). Go to PLAY mode and back to apply the changes (they are only applied when Canon code changes these registers again). Notice the FPS value printed by ML on the top bar changed.
Do the same with timer A (for example, change it to 0x1ef01ef). Notice there are some more registers with the same value (0x1df01df or 0x1df). Update them too.
Level 1 complete - back to theory.
Timer A is
directly related to horizontal resolution. Timer B is directly related to vertical resolution. They are not the same, but if you increase one, you may also have to increase the FPS timers.
Now that we know how to adjust stuff, let's
find out what registers are relevant to image resolution. The first step is to look at the registers configured by Canon code,
save them to a log file and
compare them.
For example, let's compare 1080p25 with 720p50. On 5D3, the raw resolutions in these two modes (usable in mlv_lite) are 1920x1290 and 1920x672 (same resolution horizontally, different vertically). Full buffers (including black bars) are 2080x1318 and 2080x692 (edmac.mo -> Show EDMAC channels -> raw_write_chan in edmac-memcpy.c -> channel 4 on 5D3 and 18 on other models, or Debug -> Show console).
Unfortunately, on 5D3 I can only compare the ADTG/CMOS registers (without the DIGIC/ENGIO ones), as it locks up when trying to log the latter in 50p. It might work on other models, or it might not. We'll still get useful info out of this.
Step by step:
- select 720p50 in Canon menu
- enable ADTG Registers
- go to PLAY mode and back to get all the registers
- select Show -> Modified from now on (also displayed as "since HH:MM:SS")
- go to PLAY mode and back, make sure it shows nothing (if it does, repeat a few times)
- select 1080p25 in Canon menu
- go to ADTG registers menu and notice some registers appeared
- to double-check: go back to 720p50 and make sure it shows nothing
- back to 1080p25 and the registers should appear again
- select Advanced -> Log Registers Now (to save the modified registers to a log file)
That's the general procedure for "diff-ing" two video modes.
There are already a few dozens of registers, but you can ignore some of them:
- shutter blanking: that actually gives the shutter speed
- ADTG 8/9/a/b and 8882/4/6/8: ISO gains
- likely most other registers with "small" values
The interesting stuff:
- ADTG2[800c]: line skipping factor (2 in 1080p and 4 in 720p)
- ADTG2[8178, 8179, 82F8, 82F9, 8196, 8197]: likely related to vertical resolution (look them up in crop_rec source)
You may also diff the 1080p and x5 zoom modes - this should work with DIGIC registers as well, without locking up. There you'll notice registers 0xC0F06800/4 for adjusting the capture resolution, and many many others.
Finally, you can compare the x5 zoom with the regular photo mode. This may require some fiddling - I've got it working by using plain FPS override set to 10 fps to avoid image distortion, rather than adtg_gui's "Force low FPS" (which appears to interfere with photo mode).
Level 2 complete. You may now examine the differences between Canon video modes, look up the registers in
adtg_gui.c and make some guesses about their possible meaning.
TODO: logs.
Let's now try to
adjust the horizontal resolution. We've
already got some 20MB reserved for the raw buffer from Canon code, so we don't need to worry about memory yet. Let's start from some 1:1 crop mode (x5 zoom or something else).
Horizontal resolution is adjusted from the low halves of 0xC0F06800/4. First do the math for the current video mode (raw_lv_get_resolution). Enable ADTG Registers and DIGIC Registers to see them, then select "Show: Image size regs only" to find them faster, then go to PLAY mode and back to refresh all the registers. Select "Force low FPS" if the image is broken.
Examples:
5D3 1080p: [0xC0F06800] = 0x10017, [0xC0F06804] = 0x528011b => 2080x1319 (
column_factor = 8 for 5D3, 4 for 100D).
5D3 x5: [0xC0F06800] = 0x10017, [0xC0F06804] = 0x56601eb => 3744x1381.
Increase horizontal resolution in x5 by 1 step (8 pixels on 5D3) => change 0xC0F06804 to 0x56601ec. Go to PLAY mode and back to x5 to apply the change. Notice the image is "slightly" distorted (some sort of diagonal look). This is good!
Enable raw video (mlv_lite), set preview to Framing, set image resolution and aspect ratio to maximum.
Before the change: 3584x1320.
After: 3592x1320.
Level 3 complete. You have successfully increased the resolution in x5 mode by a whopping 8 pixels!
(the real-time preview is broken, don't know how to fix it yet, but the preview looks good with the Framing option, so the raw data is valid)
Still with me?