TFT SIO communication (tft_regs.mo)

Started by a1ex, November 26, 2017, 03:51:30 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

a1ex

Some notes after looking into this.

QEMU logs: zip

How I've got them:

make -C ../magic-lantern/60D_install_qemu
./run_canon_fw.sh 60D,firmware="boot=1" -d debugmsg,io
# same for 600D, 650D, 700D, 70D

In ML menu, selected Display -> Advanced -> Orientation -> Normal/Mirror/Reverse, then copied the console output. Had to silence a few things in QEMU to get clean logs. The important lines are those like this:

[  DisplayMgr:ff0611b4 ] (82:02) SIO [3]:0xf01d


60D, 600D:

[ GuiMainTask:ff325714 ] (04:03) -->Mirror start
[  DisplayMgr:ff0611b4 ] (82:02) SIO [0]:0x1000
[  DisplayMgr:ff0611b4 ] (82:02) SIO [1]:0xbe01
[  DisplayMgr:ff0611b4 ] (82:02) SIO [2]:0xe401
[  DisplayMgr:ff0611b4 ] (82:02) SIO [3]:0xf01d
[ GuiMainTask:ff325774 ] (04:03) -->Normal start
[  DisplayMgr:ff0611b4 ] (82:02) SIO [0]:0x1001
[  DisplayMgr:ff0611b4 ] (82:02) SIO [1]:0xbe01
[  DisplayMgr:ff0611b4 ] (82:02) SIO [2]:0xe401
[  DisplayMgr:ff0611b4 ] (82:02) SIO [3]:0xf01d
[ GuiMainTask:ff325744 ] (04:03) -->Reverse start
[  DisplayMgr:ff0611b4 ] (82:02) SIO [0]:0x1000
[  DisplayMgr:ff0611b4 ] (82:02) SIO [1]:0xbe01
[  DisplayMgr:ff0611b4 ] (82:02) SIO [2]:0xe401
[  DisplayMgr:ff0611b4 ] (82:02) SIO [3]:0xf09d


700D, 650D:

cat 700D-*.log | grep -E "DisplayMgr.*SIO|-->"
[ GuiMainTask:ff4d91bc ] (04:03) -->Mirror start
[  DisplayMgr:ff128980 ] (82:01) SIO [0]:0x36
[  DisplayMgr:ff128980 ] (82:01) SIO [1]:0x140
[ GuiMainTask:ff4d921c ] (04:03) -->Normal start
[  DisplayMgr:ff128980 ] (82:01) SIO [0]:0x36
[  DisplayMgr:ff128980 ] (82:01) SIO [1]:0x100
[ GuiMainTask:ff4d91ec ] (04:03) -->Reverse start
[  DisplayMgr:ff128980 ] (82:01) SIO [0]:0x36
[  DisplayMgr:ff128980 ] (82:01) SIO [1]:0x1c0


70D (EOS M matches this):

cat 70D-*.log | grep -E "DisplayMgr.*SIO|-->"
[ GuiMainTask:ff504660 ] (04:03) -->Mirror start
[  DisplayMgr:ff134c18 ] (82:02) SIO [0]:0x602
[ GuiMainTask:ff5046c0 ] (04:03) -->Normal start
[  DisplayMgr:ff134c18 ] (82:02) SIO [0]:0x600
[ GuiMainTask:ff504690 ] (04:03) -->Reverse start
[  DisplayMgr:ff134c18 ] (82:02) SIO [0]:0x606


Experimental code (don't click me):

static void run_test()
{
    msleep(3000);

    #ifdef CONFIG_5D3_113
    void (*lcd_sio_init)() = (void *) 0xFF12D284;
    void (*lcd_sio_write)(uint32_t * data, int size) = (void *) 0xFF12D1E0;
    void (*lcd_sio_finish)(void * sio_obj) = (void *) 0xFF13BDC8;
    void ** p_lcd_sio_obj = (void **) 0x246F0;
    #endif
    // 650D 104: FF127E88, FF127D88, FF13B868, 23C48.
    // 700D 115: FF128A28, FF128928, FF13C420, 23C58.

    printf("LCD sio start\n");
    lcd_sio_init();
    lcd_sio_write((uint32_t[]) { 0x36, 0x140 }, 2);
    lcd_sio_finish(*p_lcd_sio_obj);
    printf("LCD sio finish\n");
}


5D3: the above code turns off the screen, but leaves the backlight on.
650D: wip
700D: ?

SIO initialization sequences are different (likely different TFT controllers). 650D and 700D are identical.

5D3 has an interesting SIO sequence when display brightness is set to Auto.


11949> DisplayMgr:ff12d238:82:02: SIO [0]:0x34
11981> DisplayMgr:ff12d238:82:02: SIO [1]:0x1700
119B5> DisplayMgr:ff12d238:82:02: SIO [2]:0x1808
119E9> DisplayMgr:ff12d238:82:02: SIO [3]:0x1960
11A1C> DisplayMgr:ff12d238:82:02: SIO [4]:0x35


Hypothesis: high byte is TFT register address, low byte is value (similar to ADTG, CMOS, audio).

5D3: register 0x19 appears to be gamma correction (0-63). The remaining two bits cause some flicker in saturated blue (?!)

Register 0 is set to 0x34 on TftDeepStanby; 0x35 brings back the image.


    for (int i = 0; i < 64; i++)
    {
        lcd_sio_init();
        lcd_sio_write((uint32_t[]) { 0x34, 0x1900 | (i + (rand() & 3) * 64), 0x35 }, 3);
        lcd_sio_finish(*p_lcd_sio_obj);
        msleep(50);
    }


The search space appears small (256 registers, 256 possible values), so let's brute-force it:

    for (int reg = 0; reg < 0x100; reg++)
    {
        for (int val = 0; val < 0x100; val++)
        {
            bmp_printf(FONT_LARGE, 50, 50, "%02x: %02x", reg, val);
            lcd_sio_init();
            lcd_sio_write((uint32_t[]) { 0x34, (reg << 8) | val, 0x35 }, 3);
            lcd_sio_finish(*p_lcd_sio_obj);
            msleep(50);
        }

        /* restore the display back to working condition */
        enter_play_mode();
        exit_play_qr_mode();
    }


Documenting other registers (either on 5D3 or on other models) is welcome. Other than trial and error, I don't have a better way to analyze them.

Other registers present (found with { 0x34, rand() & 0xFFFF, 0x35 }, but not written down):
- color adjusments (temperature?)
- mirroring, flipping
- half resolution
- scaling, translation (both H and V)

So far, the image gets back to normal when switching the display mode (such as going into Canon menu).

dfort

Quote from: a1ex on November 26, 2017, 03:51:30 PM
700D: ?

Works!


Here is the console output. Screenshot doesn't show the image flipped.



Found the stubs for EOSM with the exception of the p_lcd_sio_obj:
    #ifdef CONFIG_EOSM_202
    void (*lcd_sio_init)() = (void *) 0xFF12909C;
    void (*lcd_sio_write)(uint32_t * data, int size) = (void *) 0xFF128F9C;
    void (*lcd_sio_finish)(void * sio_obj) = (void *) 0xFF13B454;
    void ** p_lcd_sio_obj = (void **) 0x?????;
    #endif

    // 650D 104: FF127E88, FF127D88, FF13B868, 23C48.
    // 700D 115: FF128A28, FF128928, FF13C420, 23C58.
    // EOSM 202: FF12909C, FF128F9C, FF13B454, ?????.


a1ex

My values for EOS M are:


    if (is_camera("EOSM", "2.0.2"))
    {
        /* TFT Command start ... TFT Command end */
        tft_sio_init    = (void *) 0xFF12906C;
        tft_sio_write   = (void *) 0xFF128F6C;
        tft_sio_finish  = (void *) 0xFF13B30C;
        p_tft_sio_obj   = (void **)   0x3EAF0;
    }


Added all the above stuff into a module: tft_regs. Please try it, find the missing stubs and document the registers for your camera model (they are model-specific).

BTW - 5D3 has NormalDisplay, MirrorDisplay and ReverseDisplay. The first two are working, but only for the bitmap overlay (not for the LiveView image). Not usable for the original request.

dfort

Really?

So much for my stub hunting instincts. I'm just doing pattern matching and you can actually make sense of this stuff. Those EOSM addresses make no sense to me, they break with the pattern established on the other cameras.

Speaking of other cameras, I made a 650D build for our friend Walter to try out. It should work the same as the 700D.

I'm not testing the 5D3 because there are more experienced people than me working on that but on the EOSM the addresses supplied by a1ex are causing the LiveView to freeze, or on occasion doing something like this--usually after booting up a fresh build:



My addresses simply black out the screen. In both cases it requires a battery pull. One time I did get crash log with a1ex's stubs:

[67698789] run_test: NULL PTR (0,e1a00000)
pc=19980218 lr=  143e80 stack=1dd9d8+0x8000
entry=a2890(143e80)
e1a00000 e59ff014 e59ff014 e59ff014
e59ff014 e1a00000 e59ff010 e59ff010

Magic Lantern version : Nightly.2017Nov26.EOSM202
Mercurial changeset   : ef46234b628a+ (LiveView_flip-wip) tip
Built on 2017-11-26 18:59:44 UTC by rosiefort@RosieFoComputer.
Free Memory  : 166K + 3479K


I can't get the brute-force code to work because the camera freezes up after printing "00:00"

Still can't wrap my head around how you came up with the value for p_tft_sio_obj.

a1ex

Oops - my disassembly for EOS M was still on 1.0.6...

Values for 2.0.2: FF12909C, FF128F9C, FF13B454, 3E690. The last one is the argument passed to the one before it.

For some reason, tft_sio_init does not return the SerialIO object it has created - rather, it stores that in a global variable (3E690). When cleaning up, tft_sio_finish expects the SerialIO object passed as argument.

dfort

Quote from: a1ex on November 26, 2017, 09:56:34 PM
Oops - my disassembly for EOS M was still on 1.0.6...

Ha ha -- Made my day.

I'm still not sure how you came up with 3E690 for p_lcd_sio_obj but the current state for EOSM is that it goes to black screen when running the test code to flip the LCD image. This time it isn't a hard crash requiring a battery pull. Switching to the Canon menu brings the camera back to life.

I also ran the brute-force code on the 700D and it showed a lot of information on the screen and eventually peters out. It runs longer in photo mode outside of live view than it does in live view mode so I shot one of the most boring videos ever. First pass is plain photo mode second pass is in photo LiveView mode. Hope this is of some value.



[EDIT] This video was made before the tft_regs modules was pushed to Bitbucket but the module works pretty much the same as the code from the first post--only with better control over the registers. Register 00 apparenly inverses the LCD colors thus the strange look of the posted video.

[EDIT 2] Playing around some more with the new module. Having a wild ride on the EOSM. Some very interesting things going on with the LCD.

reddeercity

Quote from: a1ex on November 26, 2017, 03:51:30 PM
- color adjusments (temperature?)
- flipping
- half resolution
- scaling, translation (both H and V)
Interesting , I came across the same thing with the Digic IV/5D2 experimenting with the registries on the adtg_gui build I use in my 3.5k/UHD developments thread
It's easy , mainly use cmos[1] , cmos[2] , ADTG1 & or  ADTG2 depending if in crop mode or not plus same others I can't remember right now .
What was most interesting was the different Pixel binding (and maybe line skipping not sure) that I found if I recall it was 3x5 or 3x6 or more not sure .
First image is as it came from the mlv raw (1250x1856) , Second is 3x5 from mlvproducer (2082x1856)and the third I resized the Vertical to 4096x1856 , which looks like the right aspect ratio 

Sorry I when off topic a little bit  :) just thought it was of interest



dfort

Found the key to flipping the display on the EOSM using the tft_regs module. Not just the overlays but the image too. Posted it on the EOSM topic.

a1ex

Quote from: dfort on November 27, 2017, 03:30:20 AM
the most boring videos ever

Okay, in this case, register 0 is not restored by going to PLAY mode and back (and I don't know how to read the original values either, to restore them). If 0 reverses the colors, the display should be back to normal when testing the other registers.

Can you start the scan from register 1? I'd expect the flip/mirror controls to show up in the video (register 1 on 700D).

dfort

I did a scan of register 1 on the 700D but it didn't appear to do anything. I'm not quite understanding the notes. According to the module description:

QuoteMirror/flip registers:
...
650D, 700D: register 0x01, mask 0xC0

Yet the code that worked on the 700D was this:

    lcd_sio_init();
    lcd_sio_write((uint32_t[]) { 0x36, 0x140 }, 2);
    lcd_sio_finish(*p_lcd_sio_obj);


Not sure which registers I need to use to get the same thing happening with the module:

/* send a SIO command sequence to TFT controller */
static void tft_command(uint32_t * buffer, int size)
{
    /* there is a call to take_semaphore in tft_sio_init and give_semaphore in tft_sio_finish */
    /* so it's probably thread-safe (todo: test) */
    tft_sio_init();
    tft_sio_write(buffer, size);
    tft_sio_finish(*p_tft_sio_obj);
}


The tft_regs module appears to be working miracles on the EOSM but on the 700D the main thing I found was that some registers invert the colors on the screen and require a camera restart to get out of it.

Quote from: a1ex on November 26, 2017, 03:51:30 PM
Documenting other registers (either on 5D3 or on other models) is welcome. Other than trial and error, I don't have a better way to analyze them.

How do you want it documented?

I also don't mind looking for stubs on other cameras but:

Quote from: dfort on November 26, 2017, 09:14:02 PMStill can't wrap my head around how you came up with the value for p_tft_sio_obj.

a1ex

700D: try this for tft_set_reg:

tft_command((uint32_t[]) { 0x36, (reg << 8) | val }, 2);


In other words, register 0 set to value 0x36, then the tested register set to the tested value. Maybe it matters.

Also start the outer brute-forcing loop from 1, not from 0 (for int reg = 1 ...).

Maybe only one of these two tricks is needed, maybe both, not sure.

Quote
How do you want it documented?

The flip/mirror register is documented in the README. The gamma correction register is documented in first post. Something similar would be nice for the other registers (even if it's just a description of what they do, not the exact meaning).

Examples for a similar brute forcing effort (with a much larger search space): http://magiclantern.wikia.com/wiki/Register_Map/Brute_Force

Examples of MMIO register documentations for various devices in the camera: http://magiclantern.wikia.com/wiki/Register_Map

QuoteStill can't wrap my head around how you came up with the value for p_tft_sio_obj.

EOS M: 0x3E650 + 0x40:

ROM:FF12A76C                 LDR     R4, =0x3E650
...
ROM:FF12A7DC                 LDR     R0, [R4,#0x40]
ROM:FF12A7E0                 BL      sub_FF13B454

dfort

Now that I get it, here are a couple more platforms:

5D3 123: FF12C950, FF12C8AC, FF13BE8C, 23C48
5D3 134: FF12C958, FF12C8B4, FF13BE94, 23C48


Yep, 5D3.134 is working:



That's register 0x2 set to value 0x2. The module seems to be portable so I uploaded a version that includes 5D3.123/134 support to my Bitbucket downloads page.

I'll play around with that code on the 700D and maybe look into finding the stubs for other cameras--maybe the 7D?

[EDIT] Found stubs for 7D:
7D 203: FF070114, FF070068, FF07F8F4, 21D0

dfort

Quote from: a1ex on November 27, 2017, 06:44:32 PM
700D: try this for tft_set_reg:

tft_command((uint32_t[]) { 0x36, (reg << 8) | val }, 2);


In other words, register 0 set to value 0x36, then the tested register set to the tested value. Maybe it matters.

Also start the outer brute-forcing loop from 1, not from 0 (for int reg = 1 ...).

Maybe only one of these two tricks is needed, maybe both, not sure.

Tried each one individually and combined but it looks like there are lots of combinations that cause the inverse video (reverse colors) on the 700D. Once it does that it needs a restart.

One thing that is an issue with some cameras is that the value is applied immediately instead of after hitting the SET button. On the 7D it is hard to get to the flip/mirror on Register 0x6 because several of the values simply blank out the display. Once that happens it seems that the module doesn't function properly until you bring up the Canon menu or in some cases the camera needs a restart.

Walter Schulz

650D:

Register 0x0, 0x2:
Value
0X1: ? (blank screen, recovers when button pressed)
0X10: ? (blank screen, recovers when button pressed)
0x21: Invert colours

Register 0x1: No visible action for any value

a1ex

Might be helpful to know the default value for the register you are changing. I don't know how to read them, but you can find them in a startup log.

For example, 7D register 6:

GuiLockTas:ff0700c8:82:01:8: SIO [6]:0x690


If the image goes bad, try dialing the default value blindly (for example, to set the above, select register 6, move the cursor like this: 00, then press the up key 9 times). I find it unlikely to require a display refresh if you are only changing one register; display refresh may be needed when changing more registers, and one of them puts the controller in some invalid configuration (and you don't know which one). But if you are only trying one register at a time - just keep scrolling until the image gets back.

From startup logs, 700D and 650D (they are identical regarding TFT SIO) don't seem to follow the same register/value pattern. Their high byte is:

- always 0 at the beginning of each sequence, and also every now and then in the middle, but never seen any adjacent zeros
- 1 most of the time, also on adjacent positions, for example:


DisplayMgr:ff128980:82:01: SIO [0]:0xd1
DisplayMgr:ff128980:82:01: SIO [1]:0x114
DisplayMgr:ff128980:82:01: SIO [2]:0x11d
DisplayMgr:ff128980:82:01: SIO [3]:0x123
DisplayMgr:ff128980:82:01: SIO [4]:0x144
DisplayMgr:ff128980:82:01: SIO [5]:0x153
DisplayMgr:ff128980:82:01: SIO [6]:0x19a
DisplayMgr:ff128980:82:01: SIO [7]:0xc7
DisplayMgr:ff128980:82:01: SIO [8]:0x100
DisplayMgr:ff128980:82:01: SIO [9]:0x153
DisplayMgr:ff128980:82:01: SIO [10]:0x153
...


- 0x2* in some special cases (such as changing brightness), but these use a different chip select (GPIO, -d debugmsg,io in qemu), so they are talking to a different device:

DisplayMgr:ff128ca0:82:03: CalcBrightness = 92(DEC)
DisplayMgr:ff128cb8:82:03: CommandBrightness = 0x265c
DisplayMgr:000c5cf0:00:00: *** register_interrupt(0x0, 0x84, 0xff13c07c, 0x5), from ff13c228
DisplayMgr:ff1288dc:82:01: SIO [0]:0x265c
DisplayMgr:000c5cf0:00:00: *** register_interrupt(0x0, 0x84, 0xff13c07c, 0x5), from ff13c228
DisplayMgr:ff1288dc:82:01: SIO [0]:0x2492
**INTERRUP:ff127cb8:82:01: WaitTimerCallBack 120
DisplayMgr:ff1288dc:82:01: SIO [0]:0x2030


Hypothesis: 0x00rr might be register address, 0x01vv might be value (and if there are more values, register may get auto-incremented). Our sequence 0x36, 0x140 might be interpreted as "set register 0x36 to value 0x40".

That means:

/* should have no effect, no matter how many times you call it */
tft_command((uint32_t[]) { rand() & 0xFF }, 1);

/* should set register "reg" to value "val" */
tft_command((uint32_t[]) { reg, 0x100 | val }, 2);


Can you check these two sequences?

dfort

Tried the various suggestions and was going to shoot a video to show what is going on with the 700D but I started looking for stubs for other cameras and didn't stop until I found the addresses for all of the supported cameras -- and then I went on to find stubs for some of the not yet fully supported cameras like the 100D, 70D and even the EOSM2. Made a pull request and updated the tft_regs module on my downloads page. Of course I'm not able to test out the various platforms so testers are needed. (Hope no cameras get bricked.)

So, until I get around to making a video here are brief descriptions of what I see on the 700D running Brute-force all registers with the variations on the tft_command function:

tft_command((uint32_t[]) { (reg << 8) | val }, 1);

This is in the current version of the module. Right away on register 0x0 it goes into inverse colors and stays that way until it gets to register 0x2 then it goes black. Note that every time it reaches value 0xff the screen flashes even when the screen is black. Once early into the run the screen returned to normal for a brief time but it went by too fast for me to note the register it was on. I waited until I was pretty sure the full run was finished to see if the image would return but it never did.

tft_command((uint32_t[]) { 0x36, (reg << 8) | val }, 2);

This was suggested on an earlier post along with changing to different starting values and skipping the beginning registers that may be putting the camera into inverse colors mode. Starting with register 0x0 it goes into inverse colors but when it runs through register 0x1 it shows color changes and halfway through the image mirrors and flips in inverse colors and continues to show color changes. When it hits register 0x2 it goes black and stays there like in the previous test.

/* should have no effect, no matter how many times you call it */
tft_command((uint32_t[]) { rand() & 0xFF }, 1);


It actually does have an effect. It varies between normal, black and inverse colors. I don't see any color changes or image mirroring/flipping but I do see the counter incrementing when the LCD shows a normal or inverse color screen. Of course this code gives random calls so there's no point reporting on what register does what.

/* should set register "reg" to value "val" */
tft_command((uint32_t[]) { reg, 0x100 | val }, 2);


With this code register 0x0 looks normal, register 0x1 goes black, 0x2 returns to normal and it pretty much stays there, no image mirroring/flipping and no color changes until it hits register 0x21 when it goes into inverse colors. Image mirroring/flipping finally shows up when it hits register 0x36 but it stays in inverse video and doesn't show any color changes through the remainder of the run. Camera restart is needed, simply switching to the Canon menu doesn't restore the LCD to normal. Note that this is the only time that I was able to see something on the LCD through the entire run.

One thing worth noting is I can sometimes see when it hits value 0xff it flashes "No image" on the LCD. This means that it goes to playback mode each time. Shooting a photo and doing another run shows the saved image file on the screen every time the value hits 0xff.

So overall this wouldn't make an interesting video though I still might shoot something showing either the 5D3, 7D or EOSM because those cameras do give you a wild ride as it runs through the various registers.

By the way, I did try that trick with moving the cursor when setting registers and values. Learned that back when we were playing around with the various preferred raw buffers in the 10bit/12bit topic, something like that. Anyway, running a Brute-force on register 0x36 did result in color changes and image mirroring/flipping without going to inverse colors using that last version of the tft_command function but going back to the current version of the tft_command function it went black and then to inverse video when running Brute-force on that same register. Tried changing just the value but it kept going to a black screen and recovering by switching to the Canon menu seemed to kill the effect the module had on changing the register values.

IDA_ML

I am sorry to interfere but could you, guys, possibly explain with a few words what you are doing and what does this effort aim at?  Is it useful for porting crop recording to the 7D for example? I apologize for the dumb question but I am totally lost in this thread.  I know, "TFT" stands for "thin film technology", SIO probably means "silicon monoxide" but then, ... that's it.

Walter Schulz

SIO
https://en.wikipedia.org/wiki/Serial_communication
Popular: I²C, SPI (both linked in wiki article)

Very short explanation what devs are doing in https://mobile.twitter.com/autoexec_bin/status/934876760893685761

Possible short term solution for bringing the whole set of mirror/flip options to cams not yet supported by the method used now.
Long term use? This is reverse engineering ... gaining knowledge, explore the unknown, having fun.

IDA_ML

Thanks Walter, I understand now.  Indeed, reading from a flipped screen is a lot of fun!  We used to do this when we were kids :-))).

DeafEyeJedi

Honestly in all this is indeed quite bad ass and will be quite useful for those that want to use extended viewfinders (mirror/flip options) hence the reason for this tat_regs module. Hopefully 3rd party companies are watching this thread in hopes for marketing purposes. At least I would buy such a product.

Some time ago if I remember correctly a user in here requested for this similar feature to have a mirror/flip option for his DSLR kit (was that you @reddeercity? lol) though correct me if I'm wrong, ha!
5D3.113 | 5D3.123 | EOSM.203 | 7D.203 | 70D.112 | 100D.101 | EOSM2.* | 50D.109

a1ex

Gamma correction: might be useful to make the screen more readable in sunlight.

Color calibration: was requested before. There are LOTS of registers for color adjustments.

Position fine-tuning: when you look at the screen from an angle, might be helpful (most models have it - IMAGE_POSITION; done with a different method; no idea if the feature is actually working on all of them).

Inverted display colors: was requested, already done on DIGIC 4 models, but the image also gets recorded that way (IMAGE_EFFECTS on the feature matrix). This investigation would allow inverting the display colors without affecting the recorded image.

Better astro color theme?

If any of the above sounds useful, please grab the tft_regs module (either from dfort's repository, or compile from source) and document the registers for your camera model. They are not the same.

Another experiment that I'd find useful: record a RAW video, with manual exposure and little or no ambient light, of the camera screen, while brute-forcing the color adjustment / gamma correction registers. Best done with a color target on the screen (a static image in PLAY mode is enough), but the exact choice is not critical (just something that displays many colors should be enough). That should help finding out what exactly these registers are adjusting (recovering the curves). Be sure to save a screenshot of the static image used during the test (Debug menu).




TFT: used the naming from Canon strings, so others looking at the disassembly would know exactly what we are adjusting.

SIO: again Canon naming; also referred as SerialIO; the low-level protocol is probably SPI, but we are just calling a high-level function to change these values. The same communication interface is used for MPU messages, ADTG/CMOS registers, RTC (real-time clock), serial flash and maybe others.

This sends a bunch of data to some device (probably the LCD controller or something else in the display hardware); we are trying to find what these numbers mean (some may be registers, some may be values, and they are generally not the same across camera models), and since the search space is small, brute forcing and documenting what you see is a reasonable option. We don't have any docs on this device (no idea how it even looks like on the PCB) - we just have the numbers used by Canon code during camera startup (from their debug messages).

dfort

Cool, it can do a lot more than just flip the screen but let's get back to that on the 700D because it was one of the first things we got right, even before a1ex created the module. The code to flip the screen was this:

lcd_sio_write((uint32_t[]) { 0x36, 0x140 }, 2);

The function name changed to make it match the disassembly strings and variables added to explore all of the registers but with the latest code we tried:

/* should set register "reg" to value "val" */
tft_command((uint32_t[]) { reg, 0x100 | val }, 2);


I was finally able to flip the screen with register 0x36 and value 0x40. Looking at the code it seems that the value that was actually passed was 0x140, right? Going back to way the function is currently coded in the module:

tft_command((uint32_t[]) { (reg << 8) | val }, 1);

After setting the register to 0x36, anything I enter in the value field results in an LCD blackout. In addition, the value field in the module only goes up to 0xff so the value can't be set to 0x140.

Running Brute-force all registers on the 700D puts it in an inverse video state early in the run so I thought why not start with register 0x30. Part of my logic was because on the EOSM register 0x06 does the screen mirroring/flipping and on the 700D it is register 0x36 so maybe there is a 0x30 offset between the cameras?

for (int reg = 48; reg < 0x100; reg++)

(48 dec. = 0x30 hex.)

That, along with:

tft_command((uint32_t[]) { reg, 0x100 | val }, 2);

I was able to run a Brute-force all registers on the 700D without the LCD going black or into inverse video. Albeit the brute-force run was not all that interesting to watch because only a few registers at the beginning did anything with the display.

Walter Schulz

Would be fine to have a downloadable file to test all registers with value 2. Haven't found a way to make 650D's screen flip yet. Tried a lot of registers, though.

dfort

Hi Walter, I just uploaded special builds for 650D and 700D since these cameras seem to be different than all the others.

I did say that the latest module I uploaded supports all the other cameras, right?  :D

As always, on my Bitbucket downloads page. Limited time offer.

Walter Schulz

Thanks! 650D with register 0x36 works. Values differ a lot.

0x1


0x40


0x80


Incrementing values to 0xC0 -> Screen orientation normal
Then up to 0x0 -> Upside down again as in 0x1


Having some fun with 7D. Dfort, have you tried register 0x10 with incrementing/decrementing values?