G7X battery 4th terminal for communication - Hotwire! Hardware Mods, Accessories and Insights - CHDK Forum supplierdeeply

G7X battery 4th terminal for communication

  • 13 Replies
  • 6936 Views
G7X battery 4th terminal for communication
« on: 28 / December / 2020, 09:22:04 »
Advertisements
Hi all,


So I've noticed that the batteries for my G7X cameras have 4 terminals instead of 3. Applying a piece of tape over this it gives a battery communication error indicating that there is some communication going on between the camera and battery over this terminal. If this could be used as a serial input/output terminal it could be very useful for many things such as for my StereoSync project https://chdk.setepontos.com/index.php?topic=14195


I did some searching on this forum all I came across was this post: https://chdk.setepontos.com/index.php?topic=13451.msg137584#msg137584


Unfortunately my digital oscilloscope is currently broken so I just probed them with my analog scope for now, the result is attached. Scale is 0.1ms and 2V
Each bit is about 20us in length. The camera seems to transmit many packets (with different bits each time) for about a second before displaying the battery communication error.


I will try and borrow a digital oscilloscope soon or set it up with a logic analyzer to see what communication is going on here. Perhaps it could be 1-Wire serial protocol?


Any ideas of how to go about reading and writing to this pin with CHDK?
« Last Edit: 28 / December / 2020, 09:24:58 by Recyclojunk64 »

*

Offline reyalp

  • ******
  • 14082
Re: G7X battery 4th terminal for communication
« Reply #1 on: 28 / December / 2020, 14:46:23 »
You can find various things related to the the battery authentication in the the firmware (the string are relatively obvious), but it's an area we've mostly avoided for reasons discussed here https://chdk.setepontos.com/index.php?topic=12542.msg130630#msg130630 I believe third party sellers have now widely bypassed the battery validation for that generation of camera, so possibly less relevant now.

Note on some cameras at least one battery related task runs on the Omar core: https://chdk.setepontos.com/index.php?topic=11316.msg142038#msg142038

I'm not clear why you need this rather than one of the existing inputs, I guess you're expecting / hoping for some kind of 2 way communication? FWIW, on g7x you should be able to do that with HDMI power control and hot plug detect. Alternately, the HDMI interface also includes i2c if you want to reverse engineer that. I'd expect that to be a lot of work to repurpose for general communication, but it would be broadly useful and potentially applicable to many cameras if you figured it out.

Or you could include a pi zero in your rig and control it all with PTP :)
Don't forget what the H stands for.

Re: G7X battery 4th terminal for communication
« Reply #2 on: 28 / December / 2020, 23:09:03 »
Thanks, yep after 2 way communication. I started looking into this before I found out about the HDMI power control output which could also work. I guess the advantage of this is that everything is nicely self contained into a dummy battery without cables plugged into the side (which would force the cameras to be spaced out more depending on how small the HDMI connector is). And the bitrate will be faster and more reliable as it is presumably a proper serial port rather than bitbanging with interrupts as with the HDMI power control and hot plug detect (or what I was doing before with the battery temp terminal and AF LED).

However the disadvantage is that only a few cameras have this 4th terminal, whereas all of the non-ancient ones have mini/micro HDMI. Do you know if the HDMI power control output and the hot plug detect input can work on all of the HDMI cameras or only the newer ones? If it can also work for S100 and S110 then that would make this a more attractive option than putting in the work to get the battery 4th terminal communication working but only being able to use it on the G7X and M series cameras.

HDMI I2C sounds like a good idea I will have a look into that and start another thread if make any progress with it.

As for PTP it could possibly work as well if I used another input for syncing the shutters, though the HDMI does sound like a better idea at this point.

*

Offline reyalp

  • ******
  • 14082
Re: G7X battery 4th terminal for communication
« Reply #3 on: 29 / December / 2020, 01:18:29 »
Do you know if the HDMI power control output and the hot plug detect input can work on all of the HDMI cameras or only the newer ones?
Not all cameras are able to control the HDMI power out. Those with CAM_REMOTE_HDMI_POWER_OVERRIDE definitely can, but most models haven't been tested, and we don't currently have an automated way to detect which ones can. Some discussion of models which are known to be able to do it or not in
https://chdk.setepontos.com/index.php?topic=13451.msg139364#msg139364
https://chdk.setepontos.com/index.php?topic=13451.msg139575#msg139575
Quote
If it can also work for S100 and S110 then that would make this a more attractive option than putting in the work to get the battery 4th terminal communication working but only being able to use it on the G7X and M series cameras.
From the thread above s110 doesn't seem to have HDMI power control, at least not with the simply named function that we use on the other cameras

Note CAM_REMOTE_HDMI_POWER_OVERRIDE doesn't directly refer to the ability to control HDMI power: These cameras turn off HDMI power in rec mode, so need it forced on to use HPD remote. However, there could be cameras which can control the power but don't automatically turn it off in rec.

Quote
As for PTP it could possibly work as well if I used another input for syncing the shutters, though the HDMI does sound like a better idea at this point.
You can do both PTP and hardware remote trigger on USB with usb_force_active and a custom cable but having them separate is certainly simpler.

One other caution: The latency of the non-USB inputs has not been tested that I know of. I'd guess analog AV is likely similar to USB, since it's likely just a simple GPIO, but it requires a much trickier custom connector. HDMI stuff is potentially a lot more complicated, since my impression is the entire HDMI interface is controlled over i2c.
Don't forget what the H stands for.


Re: G7X battery 4th terminal for communication
« Reply #4 on: 29 / December / 2020, 04:34:45 »
One other caution: The latency of the non-USB inputs has not been tested that I know of. I'd guess analog AV is likely similar to USB, since it's likely just a simple GPIO, but it requires a much trickier custom connector. HDMI stuff is potentially a lot more complicated, since my impression is the entire HDMI interface is controlled over i2c.


If there are latency issues with the HDMI power out then that would be a problem. I will do some experimentation with this once I get a micro HDMI connector for it but doesn't sound very promising at the moment. Especially if it does not work with the S110 cameras as well.


The HDMI I2C option looks the most appealing at the moment especially with its other use cases, I might have a go at getting the I2C output working on one of my old S100 cameras in case I brick it and if it works hopefully the I2C functions will be similar to the G7X camera.

Re: G7X battery 4th terminal for communication
« Reply #5 on: 29 / December / 2020, 10:29:50 »
Looks like the I2C on the HDMI connector is done through the HDMI chip, at least for the S100 camera which has an ADV7521NK chip. So it's probably not as straightforward as I was hoping.
According to https://www.analog.com/en/products/adv7521nk.html#product-overview the I2C is done with "On-chip MPU w/ I2C® master performs EDID reading operations" so this would require not only hacking the I2C going to this chip but also getting the on chip MPU here to forward other packets to it's I2C master. Even if possible it might still have latency issues.


I haven't checked what HDMI chip the G7X has in it, I just took the back cover off and it looks like much more disassembly is required to access the mainboard. Even if it is different then that would mean that the same solution is not likely applicable to all HDMI cameras.


Looks like my best options are the HDMI power output if I measure the latency low enough, the battery 4th terminal which I will probably have a go at, or the fall back is a Pi Zero with PTP and a low latency input.


*

Offline c_joerg

  • *****
  • 1248
Re: G7X battery 4th terminal for communication
« Reply #6 on: 29 / December / 2020, 11:25:34 »
AF LED
This is what i'm doing to control an external device. Is not very reliable.
Unfortunately, my cameras do not support HDMI control.
I still hope for another solution....
M100 100a, M3 121a, G9x II (1.00c), 2*G1x (101a,100e), S110 (103a), SX50 (100c), SX230 (101a), S45,
Flickr https://www.flickr.com/photos/136329431@N06/albums
YouTube https://www.youtube.com/channel/UCrTH0tHy9OYTVDzWIvXEMlw/videos?shelf_id=0&view=0&sort=dd

Re: G7X battery 4th terminal for communication
« Reply #7 on: 18 / April / 2021, 10:37:57 »
Edit: Now using a G7X Mark II for testing from here on (updated to 110b firmware)

I've done some tests with the HDMI 5V out, including modifying some of the assembly code for the low level functions that control the HDMI power out. Results were unusual, seems like there is both control of the DC-DC converter and maybe something that shorts the output as well for faster response. However I could not get a rise time of less than 4ms and fall time of less than 1ms (but sometimes much slower) which will be unsuitable for SteroSync communication. I'll probably make a separate thread for this with the results and scope screenshots in case it is useful later on.

HDMI I2C and CEC I think will be difficult to reverse engineer (and not sure if even possible as they are probably handled by the HDMI IC) but I will likely revisit them also later on when I get more time and have more knowledge about the firmware and SRE in general. My goal is to have StereoSync work with multiple communication methods which can be selected depending upon what the camera supports and what the user wants.

For now though I've moved back on to trying to get the battery 4th terminal working for communication, since I think it is more likely to be achievable than anything on HDMI and more reliable and elegant than CHDKPTP with a Raspi 0 and USB hubs. My stereo rig will be using external batteries and so I will need to disable the battery warning message anyway the G7X mk II still gives the message with the temp sensor terminal covered unlike the G7X mk I), I could probably could have it display the warning to the user just once and then remember the result or something like that, or maybe make it work like the G7X mk I. Just for now I have disabled it by overwriting the result of a function that checks if the camera has had the battery replaced since last startup.

I have found many interesting functions that are called with CreateController_FW. I couldn't find any info on the forum or wiki about this, or any uses in the CHDK source. Is there any knowledge about it? And what would be the best way to modify a function called with this? I could possibly copy the hook system for CreateTask in boot.c and patch CreateController_FW to create the hooks similarly, or I could start from task_Startup and modify each function working its way down until the CreateController_FW is called and have it load the modified function instead?
« Last Edit: 05 / May / 2021, 07:10:19 by Recyclojunk64 »


*

Offline reyalp

  • ******
  • 14082
Re: G7X battery 4th terminal for communication
« Reply #8 on: 18 / April / 2021, 16:01:06 »
Just for now I have disabled it by overwriting the result of a function that checks if the camera has had the battery replaced since last startup.
FWIW, there are some logical events related to this, search for "Bat" in the levent table.

Quote
I have found many interesting functions that are called with CreateController_FW.
Funny, I was just recently digging in this area and thinking about writing some of it up. Some related information in https://chdk.setepontos.com/index.php?topic=13522.20 and https://chdk.setepontos.com/index.php?topic=6560.msg104282#msg104282

Basics:
A "controller" is a function that receives events (from PostLogicalEventToUI etc). Controllers have a "z order" so (probably) the one on top sees events first and the return value determines whether the ones further up the stack see it. The event ID is in r1.

The events 0x800 - 0x803 seem related to creation / destruction / z order changes

I recently added some ghidra scripts which will label levent related calls for you (though not yet event IDs in controller functions) https://chdk.setepontos.com/index.php?topic=13718.msg145519#msg145519

One potentially very useful thing about controllers is they are allocated from UI memory (see https://chdk.setepontos.com/index.php?topic=11246.0)
On modern cameras (around dryos r43 and later) UI memory is allocated and freed through function pointers in the firmware data segment (factory mode sets this to just be malloc / free instead of using a separate pool).
This means it should be relatively straightforward to hook the UI memory malloc function, check if the LR is in CreateController, and if so jump to your own version of create controller that installs a custom controller. Or to log when /where specific controllers are created.

The controller structure varies by camera (including within the same dryos version  >:() but the first element appears to always be the function pointer.

edit:
Quote
I could possibly copy the hook system for CreateTask in boot.c and patch CreateController_FW to create the hooks similarly
See a above for a possible method of hooking. You can't follow the approach from CreateTask because CreateController_FW is in ROM. You could use cache hacks (some examples in https://chdk.setepontos.com/index.php?topic=14052.msg145308#msg145308)

You could also modify the controller structures in memory after they are created.
« Last Edit: 18 / April / 2021, 20:04:38 by reyalp »
Don't forget what the H stands for.

Re: G7X battery 4th terminal for communication
« Reply #9 on: 02 / May / 2021, 11:10:45 »
Thanks for the explanations, I have dug through the firmware a bit more and tried some more things, including hooking the controller functions, though I haven't had success yet with getting output on the 4th terminal but I haven't given up hope just yet.

The Ghidra scripts have been pretty helpful thanks, I've been updating from SVN and running new ones as they appear except for the MZRM ones which I still need to generate the handler list for first if I need to look into the Zico core which I guess is just for the GPU so probably not at this stage.

I got the controller functions hooked  through a custom ui_mallloc function which runs a custom CreateController function that hooks the desired controller functions as suggested. It does work to modify the controller functions (tested by illuminating the AF LED) and has been useful for testing what sections of different controller functions do by skipping those sections and seeing what happens. CreateController hooks below in case they are helpful to anyone else (addresses correct for g7x2 110b)

Code: [Select]

void __attribute__((naked,noinline)) task_Startup_my() {
    asm volatile (
...

            "    bl      sub_e0425886\n" // various initilizations including for ui_malloc
            // ui_malloc hook
            "    ldr     r4, =0x0000cb64\n" // +
            "    ldr     r0, =ui_malloc_default_my\n" // +
            "    str     r0, [r4, #4]\n" // +
            "    bl      sub_e005b33e_my\n"     // -> taskcreate_physw
...
    );
}


...



//0xe0371e68
void  __attribute__((naked,noinline)) ui_malloc_default_my() {
    asm volatile(
            // hooks first, r1 input is not used in ui_malloc_default
       
            // hook CreateController function
            "    ldr     r1, =CreateController+0x1c\n"  // + function to hook + offset in fuction where lr will be (just after ui_malloc)
            "    cmp     r1, lr\n"                      // + check if ui_malloc has been called from the function to hook
            "    beq     CreateController_my\n"         // + return immediately to alternative function
           
            //capdis -f=chdk -s=0xe0371e69 -e=0xe0371ea9 -stubs PRIMARY.BIN 0xe0000000
            "    push    {r3, r4, r5, r6, r7, lr}\n"
            "    mov     r6, r0\n"
            "    ldr     r5, =0x0000cb64\n"
            "    ldrb    r0, [r5]\n"
            "    lsls    r0, r0, #0x1f\n"
            "    beq     loc_e0371e7e\n"
            "    movs    r2, #0x6c\n"
            "    movs    r0, #0\n"
            "    ldr     r1, =0xe0371f18\n" //  *"UiMemory.c"
            "    bl      sub_dffc96f4\n"
            "loc_e0371e7e:\n"
            "    ldr     r0, [r5]\n"
            "    mov     r1, r6\n"
            "    bl      sub_e037e604\n"
            "    movs    r4, r0\n"
            "    bne     loc_e0371ea6\n"
            "    ldr     r0, [r5]\n"
            "    mov     r1, sp\n"
            "    bl      sub_e037e60c\n"
            "    ldr     r2, [sp]\n"
            "    mov     r1, r6\n"
            "    ldr     r0, =0xe0371f24\n" //  *"Size: %ld, MaxRegion: %ld\n"
            "    bl      sub_e037e664\n"
            "    movs    r2, #0x71\n"
            "    movs    r0, #0\n"
            "    ldr     r1, =0xe0371f18\n" //  *"UiMemory.c"
            "    bl      sub_dffc96f4\n"
            "loc_e0371ea6:\n"
            "    mov     r0, r4\n"
            "    pop     {r3, r4, r5, r6, r7, pc}\n"
    );
}



//0xe0371490
void  __attribute__((naked,noinline)) CreateController_my() {
    asm volatile(
            //capdis -f=chdk -s=0xe0371491 -e=0xe0371515 -stubs PRIMARY.BIN 0xe0000000
//             "    push.w  {r4, r5, r6, r7, r8, lr}\n" // - already done from original CreateController function
//             "    mov     r7, r0\n"                   // -
//             "    ldr     r5, =0x0000c518\n"          // -
//             "    movs    r6, #0\n"                   // -
//             "    mov     r8, r1\n"                   // -
//             "    ldrb    r0, [r5]\n"                 // -
//             "    lsls    r0, r0, #0x1f\n"            // -
//             "    beq     loc_e03714a6\n"             // -
           
            // hook BattAuthController function
            "    ldr     r0, =BattAuthController\n"     // + controller function to hook
            "    cmp     r0, r7\n"                      // + check if we are creating that controller here
            "    it      eq\n"                          // + EQ block
            "    ldreq   r7, =BattAuthController_my\n"  // + alternate controller function to create instead
//             "    beq     loc_e03714a6\n"                // + continue at ui_malloc
           
            //hook more controller functions here simmilarly
           
            "    b       loc_e03714a6\n" // + continue at ui_malloc (replaces beq from above)
            "loc_e03714a2:\n"
            "    movs    r0, #0x11\n"
            "    b       loc_e037134a\n" //  return
            "loc_e03714a6:\n"
            "    movs    r0, #0x28\n"
            "    bl      sub_e0371f08\n" // ui_malloc
            "    ldr     r1, =0x0001d4c0\n"
            "    mov     r4, r0\n"
            "    ldr     r0, [r5]\n"
            "    mov.w   r3, #0x288\n"
            "    ldr     r2, =0xe037173c\n" //  *"CtrlMan.c"
            "    bl      sub_dffca338\n"
            "    cbz     r0, loc_e03714c6\n"
            "    mov     r0, r4\n"
            "    bl      sub_e0371f0e\n"
            "    b       loc_e03714a2\n"
            "loc_e03714c6:\n"
            "    ldr     r0, [r5, #0xc]\n"
            "    cbz     r0, loc_e03714cc\n"
            "    mov     r6, r0\n"
            "loc_e03714cc:\n"
            "    str     r7, [r4]\n"
            "    strd    r8, r0, [r4, #4]\n"
            "    movs    r0, #0x19\n"
            "    str     r0, [r4, #0xc]\n"
            "    movs    r1, #0x19\n"
            "    ldr     r0, [r5, #0x14]\n"
            "    str     r0, [r4, #0x10]\n"
            "    movs    r0, #0\n"
            "    str     r0, [r4, #0x18]\n"
            "    str     r0, [r4, #0x1c]\n"
            "    str     r0, [r4, #0x20]\n"
            "    ldr     r0, [r5, #0x1c]\n"
            "    str     r0, [r4, #0x24]\n"
            "    adds    r0, r0, #1\n"
            "    str     r0, [r5, #0x1c]\n"
            "    ldr     r0, =0xe03713bd\n"
            "    str     r0, [r4, #0x14]\n"
            "    mov     r0, r4\n"
            "    bl      sub_e03713f4\n"
            "    ldr     r0, [r5]\n"
            "    bl      sub_dffcad46\n"
            "    movs    r3, #0\n"
            "    movw    r1, #0x803\n"
            "    mov     r2, r3\n"
            "    mov     r0, r4\n"
            "    bl      sub_e0371330\n"
            "    mov     r1, r4\n"
            "    mov     r0, r6\n"
            "    bl      sub_e03719b8\n"
            "    mov     r0, r4\n"
//             "    b       loc_e037134a\n" // - return (right below now rather than very far above)
            //capdis -f=chdk -s=0xe037134b -c=1 -stubs PRIMARY.BIN 0xe0000000
            "loc_e037134a:\n"
            "    pop.w   {r4, r5, r6, r7, r8, pc}\n"
    );
}




I also came across some strings just now in the firmware starting with N5fluid, any idea what that might refer to? Such as "N5fluid12Battery_baseE" and "N5fluid16FL_TimerReceiverE"


 

Related Topics