Synchronizing two SX40s - page 2 - Hotwire! Hardware Mods, Accessories and Insights - CHDK Forum supplierdeeply

Synchronizing two SX40s

  • 33 Replies
  • 7107 Views
Re: Synchronizing two SX40s
« Reply #10 on: 07 / March / 2014, 02:25:32 »
Advertisements
Quote
To do something equivalent to USB remote using key inputs, you'd want to read the MMIO addresses for the keys directly.  _GetKbdState may do this for you, or provide you with the addresses in disassembly.

Ok thanks, so I tried out GetKbdState by adding this to the end of wrappers.c
Code: [Select]
int GetKbdState(int ch) {
return _GetKbdState(ch);
}
and then printed the output of GetKbdState in gui_osd.c (just to see what it gave out)
Code: [Select]
   if ((conf.show_temp == 6) || (conf.show_temp == 5))
//        draw_ad("KEY", GetKbdState(0x00010000), yofst++);
        draw_ad("KEY", GetKbdState(KEY_ZOOM_ASSIST), yofst++);
by trying both of those draw_ad(... out seperately. (draw_ad is the same as draw_temp but without the degrees symbol) It printed out a value flickering between 0 and 1 in both cases, and the camera didn't seem to like it very much; it alternated between alt and normal mode, hardly responded to any button presses, did other random stuff and then eventually crashed. Not that eager to disassemble the firmware really.

For easy reference, the values out of kbd.c are here
Code: [Select]
static KeyMap keymap[] = {

{ 0, KEY_ZOOM_IN      ,0x00000060 }, // 2 bits used, 4 values (0x00000060)
{ 0, KEY_ZOOM_IN      ,0x00000020 }, // 2 bits used, 4 values (0x00000060)
{ 0, KEY_ZOOM_IN      ,0x00000040 }, // 2 bits used, 4 values (0x00000060)
{ 0, KEY_ZOOM_OUT      ,0x00000180 }, // 2 bits used, 4 values (0x00000180)
{ 0, KEY_ZOOM_OUT      ,0x00000080 }, // 2 bits used, 4 values (0x00000180)
{ 0, KEY_ZOOM_OUT      ,0x00000100 }, // 2 bits used, 4 values (0x00000180)
    { 0, KEY_UP              ,0x00000400 }, // Found @0xff434aec, levent 0x04
    { 0, KEY_DOWN            ,0x00000800 }, // Found @0xff434af4, levent 0x05
    { 0, KEY_LEFT            ,0x00001000 }, // Found @0xff434afc, levent 0x06
    { 0, KEY_RIGHT           ,0x00002000 }, // Found @0xff434b04, levent 0x07
    { 0, KEY_SET             ,0x00004000 }, // Found @0xff434b0c, levent 0x08
{ 0, KEY_VIDEO           ,0x00008000 },
{ 0, KEY_ZOOM_ASSIST     ,0x00010000 },
    { 0, KEY_DISPLAY         ,0x00020000 }, // Found @0xff434b24, levent 0x0a
    { 0, KEY_MENU            ,0x00040000 }, // Found @0xff434b2c, levent 0x09
{ 0, KEY_ERASE      ,0x00080000 },
{ 0, KEY_FLASH           ,0x00400000 },
{ 0, KEY_PRINT      ,0x00800000 },

    { 2, KEY_POWER           ,0x00000800 }, // Found @0xff434b8c, levent 0x100
    { 2, KEY_PLAYBACK        ,0x00001000 }, // Found @0xff434b94, levent 0x101
    { 2, KEY_SHOOT_FULL      ,0x0000c000 }, // Found @0xff434bac, levent 0x01
    { 2, KEY_SHOOT_FULL_ONLY ,0x00008000 }, // Found @0xff434bac, levent 0x01
    { 2, KEY_SHOOT_HALF      ,0x00004000 }, // Found @0xff434ba4, levent 0x00

{ 0, 0, 0 }
};

The response time isn't that important as the sync isn't relying on it. What will happen is the master camera will flash its AF LED (connected via a photodiode to the battery temp input) to signal the slave camera to take the photo at the same time. So each camera may have a different modified CHDK on it.

Quote
I probably missed it, but why are you trying to do this?
It's so that I don't have to have an external remote switch, I can use the shutter button to take a photo. If it works, I may end up using the same setup with my D20's. Saves building a complex (and waterproof in the case of the D20) remote which also decreases the portability of the rig.

EDIT: Clearly I have no idea of what I'm doing, I did also try *(short*)0xff434b24 and *(short*)0x00020000 (and also long) and they printed values, which didn't change.
« Last Edit: 07 / March / 2014, 04:05:04 by Recyclojunk64 »

Re: Synchronizing two SX40s
« Reply #11 on: 07 / March / 2014, 09:23:51 »
It's so that I don't have to have an external remote switch, I can use the shutter button to take a photo.
I just have to ask.  Doesn't the pressing the shutter button normally take a photo? 

I'm still not sure I'm following everything you want to do, but rather than messing with the USB remote code,  why not just hack the kbd.c code to check the incoming photosensor and poke the half-press and full-press MMIO bits directly?
Ported :   A1200    SD940   G10    Powershot N    G16

Re: Synchronizing two SX40s
« Reply #12 on: 07 / March / 2014, 10:05:35 »
Quote
I just have to ask.  Doesn't the pressing the shutter button normally take a photo?  ... why not just hack the kbd.c code to check the incoming photosensor and poke the half-press and full-press MMIO bits directly?
Yes of course, but it's not going to be highly synchronised to 0.3ms like on my D20's :)

Basically what I eventually want is for me to just be interfacing with the master camera, and the slave will copy its every move with highly synchronized precision. Without any external remote. So other than the stereo-viewfinder (which I haven't yet built either) and the slave camera to the left, you'd forget you were even using a stereo rig.
Of course I know the above is never going to happen completely; I'll still have to manually check that options in the canon menu are in sync, but zooming, focusing, exposure metering and photo-taking will be properly synchronised between the cameras. And I do realise that even these will take some time for me to implement.

I still haven't really figured out the earlier problem with monitoring the button presses, but as the sync isn't relying on the response time of the button press, I could modify the continuous loop to be not-so-continuous and to be able to read the shutter press the conventional way. But this would be my last resort though. And I'd still have the problem of masking the shutter from the camera, but not from CHDK.

I've searched through the forum a bit but with my very limited coding knowledge I just can't seem to work out how to monitor the shutter button directly. In fact, all I really need to do while _wait_until_remote_button_is_released( is waiting is to monitor for a change in the keys that are pressed (when the full-press is released).

Re: Synchronizing two SX40s
« Reply #13 on: 07 / March / 2014, 11:02:59 »
In fact, all I really need to do while _wait_until_remote_button_is_released( is waiting is to monitor for a change in the keys that are pressed (when the full-press is released).
My suggestion would be to implement the communication protocol between cameras such that when the first camera wants to shoot,  it sends a command to the slave saying "get ready to shoot".  The slave then goes through the shooting process and stops at wait_until_remote_button_is_released.   On the next transition of the communications line to the remote,  its shoot continues.    On the master side,  the camera sends the "get ready" message, pauses for a few hundred milliseconds, and then starts its shoot sequence.  When it gets to wait_until_remote_button_is_released it toggles the AF LED on and continues. 

Is that basically what you are thinking?
Ported :   A1200    SD940   G10    Powershot N    G16


Re: Synchronizing two SX40s
« Reply #14 on: 07 / March / 2014, 11:52:32 »
Quote
On the master side,  the camera sends the "get ready" message, pauses for a few hundred milliseconds, and then starts its shoot sequence

Yeah that's basically what I thought of doing the other day, but I figured I might as well remove the few-hundred-milliseconds shutter delay and instead make it take the photo when the full-press button is released. As sometimes I will need to accurately time my shots and a lengthy shutter delay is going to get annoying. But I might as well implement this for now though. And later on probably leave it as a menu option to use when I don't need a precisely timed shot (which I probably won't need most of the time)

So I'd be ok to use something like msleep(200); ?

Also how would I go about using GetKbdState or something similar in usb_remote.c to get info from the shutter button full-press?

*

Offline reyalp

  • ******
  • 13447
Re: Synchronizing two SX40s
« Reply #15 on: 07 / March / 2014, 23:56:39 »
Ok thanks, so I tried out GetKbdState by adding this to the end of wrappers.c
Code: [Select]
int GetKbdState(int ch) {
return _GetKbdState(ch);
}

_GetKbdState expects a pointer to an array of 3 ints (normally physw_status, but you should be able to use your own).

 (didn't read the rest of the post)
Don't forget what the H stands for.

Re: Synchronizing two SX40s
« Reply #16 on: 08 / March / 2014, 12:31:42 »
OK thanks now I realise how _GetKbdState works (before I thought it just returns something based on some input address). So now that I've also learned what a pointer is and how to use them I tried the following:

kbd.c
Code: [Select]
static long kbd_new_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
static long kbd_prev_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
static long kbd_mod_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
extern void _GetKbdState(long*);
//Added by me
long kbd_exp[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
int *kbd_address_pointer = &kbd_exp[0];

gui_osd.c (top)
Code: [Select]
extern void _GetKbdState(long*);
extern int kbd_address_pointer;
extern long kbd_exp[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };

gui_osd in void gui_osd_draw_temp
Code: [Select]
_GetKbdState(kbd_exp);
   if ((conf.show_temp == 6) || (conf.show_temp == 5))
        draw_ad("KEY", kbd_exp[0], yofst++);
        draw_ad("KEY", kbd_exp[1], yofst++);
        draw_ad("KEY", kbd_exp[2], yofst++);

But unfortunately it doesn't compile:
Code: [Select]
...
>> Entering to platform/sx40hs
kbd.c -> kbd.o
kbd.c:19:28: warning: initialization from incompatible pointer type
main.o lib.o wrappers.o kbd.o shooting.o -> libplatform.a
<< Leaving platform/sx40hs
>> Entering to platform/sx40hs/sub/100f
../../../../core/gui_osd.c -> gui_osd.thm.o
../../../../core/gui_osd.c:31:13: warning: 'kbd_exp' initialized and declared 'extern'
boot.o stubs_min.o stubs_auto.o stubs_entry.o stubs_entry_2.o capt_seq.o movie_rec.o filewrite.o main.thm.o gui_draw.thm.o memmgmt.thm.o gui.thm.o kbd_process.thm.o conf.thm.o gui_osd.thm.o raw.thm.o shot_histogram.thm.o shooting.thm.o camera_info.thm.o remotecap.thm.o bin_compat.h -> libplatformsub.a
<< Leaving platform/sx40hs/sub/100f
>> Entering to core
entry.S -> entry.o
-> main.elf
../platform/sx40hs/libplatform.a(kbd.o):(.data+0x24): multiple definition of `kbd_exp'
../platform/sx40hs/sub/100f/libplatformsub.a(gui_osd.thm.o):(.data+0x4): first defined here
collect2: ld returned 1 exit status
make[1]: *** [main.elf] Error 1
make: *** [all-recursive] Error 1
Any idea of what I might have done wrong?

Re: Synchronizing two SX40s
« Reply #17 on: 08 / March / 2014, 13:11:44 »
Quote
Any idea of what I might have done wrong?
Well, for starters.

Code: [Select]
long kbd_exp[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
int *kbd_address_pointer = &kbd_exp[0];
long *kbd_address_pointer = &kbd_exp[0];

Quote
Code: [Select]
extern long kbd_exp[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
extern long kbd_exp[3] ;

Not sure what the rest of the code is trying to do so I have no comments on that. At a minimum your bracketing is wrong.
Ported :   A1200    SD940   G10    Powershot N    G16


*

Offline reyalp

  • ******
  • 13447
Re: Synchronizing two SX40s
« Reply #18 on: 08 / March / 2014, 17:17:22 »
../../../../core/gui_osd.c:31:13: warning: 'kbd_exp' initialized and declared 'extern'
This tells you where the error is, you've initialized it in both kbd.c and gui_osd.c. If you are using an extern, that means the real variable should be somewhere else. You don't need a global for this anyway, you could just declare it where you are going to use it and pass it to GetKbdState();. Or you could put a function in kbd.c that just extracts the particular bits you are interested in. But I don't really understand what you are trying to accomplish here, so it's hard to say what the correct approach would be.

Another thing, you should not call firmware functions like _GetKbdState directly from core code, because it won't have correct ARM/Thumb interworking (you may get away with it in a lot of cases, but don't rely on it). To use it form thumb code, you should make a wrapper in ARM code (the stuff under platform, in generic or  for your particular camera), e.g.

void GetKbdState(long *state) {
_GetKbdState(state);
}
Don't forget what the H stands for.

Re: Synchronizing two SX40s
« Reply #19 on: 09 / March / 2014, 00:15:43 »
Well it compiled and printed out, well, something...

It was also very buggy (camera would freeze on half-press and crash often, few of the buttons worked properly)

kbd_exp[0] printed out a value that changed when a button was pressed, and also changed whenever it wanted to randomly
kbd_exp[1] and [2] were 2 and 64512 respectively.

So I tried something about kbd_read_keys_r2

So now, in wrappers.c (generic):
Code: [Select]
void GetKbdState(long *state) {
_GetKbdState(state);
}

void kbd_read_keys_r2(long *state) {
_kbd_read_keys_r2(state);
}
and processed by these in gui_osd.c (just to print them so I can see what they are)
   GetKbdState(kbd_exp);
   kbd_read_keys_r2(kbd_exp);
But the output was the same as GetKbdState on it's own, except that kbd_exp[2] is now 807468032

Quote
Another thing, you should not call firmware functions like _GetKbdState directly from core code, because it won't have correct ARM/Thumb interworking (you may get away with it in a lot of cases, but don't rely on it). To use it form thumb code, you should make a wrapper in ARM code (the stuff under platform, in generic or  for your particular camera), e.g.

void GetKbdState(long *state) {
_GetKbdState(state);
}
About the functions with an underscore in front, are these the functions that are defined in functions_by_address.csv? When they're listed in there, they don't have the underscore (but some of them do though), does it get added later when compiling? Or are these functions defined elsewhere instead?

 

Related Topics