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

Synchronizing two SX40s

  • 33 Replies
  • 8268 Views
Re: Synchronizing two SX40s
« Reply #20 on: 09 / March / 2014, 00:26:28 »
Advertisements
kbd_exp[0] printed out a value that changed when a button was pressed, and also changed whenever it wanted to randomly
Normal - it's just telling you that some of the digital inputs it's watching are changing.

Quote
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?
functions_by_address.csv does not get used in the build in any way.  It's just there for reference.
Ported :   A1200    SD940   G10    Powershot N    G16

Re: Synchronizing two SX40s
« Reply #21 on: 09 / March / 2014, 00:47:25 »
Quote
functions_by_address.csv does not get used in the build in any way.  It's just there for reference.
Not sure why I said functions_by_address.csv, I meant in stubs_entry.S, where
NHSTUB(GetKbdState                            ,0xff057c04) //109
NHSTUB(kbd_read_keys_r2                       ,0xff05730c) //109
So where does the underscore prefix come in?

Quote
Normal - it's just telling you that some of the digital inputs it's watching are changing.
OK so it monitors other stuff aswell then. So if I extract the following I will be able to monitor an individual key? As in that the following values (and whatever else is monitored) are added together (when the corresponding key is pressed) and outputted at kbd_exp[0]?
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 }
};

However I still have the problem of it crashing and misbehaving, could this be because I am calling GetKbdState too often?

*

Offline reyalp

  • ******
  • 13749
Re: Synchronizing two SX40s
« Reply #22 on: 09 / March / 2014, 00:51:09 »
Well it compiled and printed out, well, something...
What are you actually trying to do?
Quote
It was also very buggy (camera would freeze on half-press and crash often, few of the buttons worked properly)
This could be due calling those functions in an unexpected way, but it's more likely there is just a bug in your changes.
Quote
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.
Each individual bit in those numbers represents the state of something. Some of those things are keys, others are things than change continuously.

This is a very roundabout way of getting something you can already see very easily.

The normal keyboard code uses the these functions to fill in physw_status. You could watch phsw_status to see how it changes when you press various keys. However, if you are looking for a normal key, it's already defined in the key map.
Quote
About the functions with an underscore in front, are these the functions that are defined in functions_by_address.csv?
No, they are from stubs_entry.S or stubs_entry_2.S.
Don't forget what the H stands for.

*

Offline reyalp

  • ******
  • 13749
Re: Synchronizing two SX40s
« Reply #23 on: 09 / March / 2014, 00:58:19 »
OK so it monitors other stuff aswell then. So if I extract the following I will be able to monitor an individual key? As in that the following values (and whatever else is monitored) are added together (when the corresponding key is pressed) and outputted at kbd_exp[0]?
The first number is the index in the array, so all the keys except the last four are in kbd_exp[0], while the remainder are in kbd_exp[2].

The second number is the CHDK identifier for the key

The third number defines the individual bits associated with the key. Usually if the bit is set, it means the key is NOT pressed.

KEY_SHOOT_FULL is special, it combines the bits of KEY_SHOOT_HALF and KEY_SHOOT_FULL_ONLY.

You can figure out if a specific key is pressed using bitwise operators.

Quote
However I still have the problem of it crashing and misbehaving, could this be because I am calling GetKbdState too often?
It's possible, but more likely you've just broken something else.

edit:
Looking at the disassembly, GetKbdState on this camera is relatively complicated compared to many cameras (which just read directly from some MMIOs), so it's quite possible it doesn't want to be called out of the normal kbd_task sequence.

It does read some MMIOs
0xC022F480
0xC022F484
0xC022F488
0xC022F48C
but the values get fiddled a bunch, so it's not immediately obvious how they correspond to physw_status bits.
If you want to monitor a single key, it's possible you could just poll these addresses directly.
« Last Edit: 09 / March / 2014, 01:09:25 by reyalp »
Don't forget what the H stands for.


Re: Synchronizing two SX40s
« Reply #24 on: 09 / March / 2014, 11:56:31 »
Quote
It does read some MMIOs
0xC022F480
0xC022F484
0xC022F488
0xC022F48C
but the values get fiddled a bunch, so it's not immediately obvious how they correspond to physw_status bits.
Thanks for those addresses. I printed all 128 individual bits on the OSD, to see which ones responded to buttons. Quite a few were random, and the rest didn't change. Except for two (the third and fourth bits of the first address) which changed as the jog-wheel was rotated. I am guessing that some of the seemingly random bits might be from multiplexing the keyboard?

Anyway as there's not much I can do with those outputs ATM, I tried making a modified version of kbd_is_key_pressed that calls my_kbd_read_keys for an up-to-date result
(in kbd.c)
Code: [Select]
long kbd_is_key_pressed_update(long key)
{
    my_kbd_read_keys(); //The only change here
int i;
for (i=0;keymap[i].hackkey;i++)
    {
if (keymap[i].hackkey == key)
        {
if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)
                return 1;
}
}
return 0;
}

and FWIW the OSD printing part:
Code: [Select]
draw_ad("ZA", kbd_is_key_pressed_update(KEY_ZOOM_ASSIST), yofst++); //When this is commented out it works normally
draw_ad("Disp", kbd_is_key_pressed(KEY_DISPLAY), yofst++);
draw_ad("SH", kbd_is_key_pressed(KEY_SHOOT_HALF), yofst++);
draw_ad("SF", kbd_is_key_pressed(KEY_SHOOT_FULL), yofst++);

It the outputs do change when the appropriate keys are pressed, but once again the camera behaves with a mind of its own. I turn it on, alt-mode flashes on and off a few times, it zooms in a bit then out again, and then the alt menu comes up. Happens in that order every time.

I wouldn't have though simply calling my_keyboard_read_keys() would cause so much trouble, as it's used anyway by CHDK right?

Re: Synchronizing two SX40s
« Reply #25 on: 09 / March / 2014, 12:06:16 »
I am guessing that some of the seemingly random bits might be from multiplexing the keyboard?
If the keypad was multiplexed then the standard CHDK code that  uses the keymap would not work.  As CHDK does in fact work on the SX40, this is clearly not the case.

I wouldn't have though simply calling my_keyboard_read_keys() would cause so much trouble, as it's used anyway by CHDK right?
Take a look at the first three lines of the function.  It's tracking key states and there is code before and after the function call that depends on that mechanism advancing once every time through.  When you add an additional call to my_keyboard_read_keys() you mess up the sequence.
« Last Edit: 09 / March / 2014, 12:15:36 by waterwingz »
Ported :   A1200    SD940   G10    Powershot N    G16

*

Offline reyalp

  • ******
  • 13749
Re: Synchronizing two SX40s
« Reply #26 on: 09 / March / 2014, 16:50:34 »
I am guessing that some of the seemingly random bits might be from multiplexing the keyboard?
If the keypad was multiplexed then the standard CHDK code that  uses the keymap would not work.  As CHDK does in fact work on the SX40, this is clearly not the case.
Not in this case, as I said, the sx40 GetKbdState does a lot more than just poll the MMIOs (unlike the say the d10 which basically just reads 3 and stuffs the values in physw_status), so if he's reading them directly it may well be that the values aren't easy to sort out, or some additional code has to be run to set up what you are reading.
Don't forget what the H stands for.

Re: Synchronizing two SX40s
« Reply #27 on: 12 / March / 2014, 12:36:43 »
Quote
Take a look at the first three lines of the function.  It's tracking key states and there is code before and after the function call that depends on that mechanism advancing once every time through.  When you add an additional call to my_keyboard_read_keys() you mess up the sequence.
Ahh yes of course. I completely forgot there would be two instances of this function running at the same time.

But before I can try out my make-shift fix for this (my_keyboard_read_keys will not be allowed to run during _wait_until_remote_button_is_released, but an identical version, my_keyboard_read_keys_alt, will be called then instead), I have run into the older problem of not being able to read the keys when they are masked from the camera.

kbd_process.c, in long kbd_process()
Code: [Select]
    if (kbd_is_key_pressed(KEY_SHOOT_FULL))
{
//        key_pressed = 0;
        kbd_key_release_all();         
        return 1;
}
    if (kbd_is_key_pressed(KEY_SHOOT_HALF))
{
//        key_pressed = 0;
        kbd_key_release_all();         
        return 1;
}

    if (kbd_is_key_pressed(KEY_ZOOM_ASSIST))
{
//        key_pressed = 0;
        kbd_key_release_all();         
        return 1;
}
All three of these keys are disabled this way, but KEY_ZOOM_ASSIST is the only one that's readable, the rest are always zero for some reason. I have tried different combinations of return and key_pressed. As far as I've checked, none of these should affect kbd_new_state which is where kbd_is_key_pressed reads it's keys from. So why would it not be reading them then? (I'm just printing out the values for now)
Oh of course, the OSD temperature values stop updating during halfpress. Note to admins: we really need a facepalm emoticon
« Last Edit: 12 / March / 2014, 23:26:51 by Recyclojunk64 »


Re: Synchronizing two SX40s
« Reply #28 on: 13 / March / 2014, 04:55:08 »
The make-shift fix I described earlier does indeed work (testing with the zoom assist button replacing the normal usb input). And I'm no longer having trouble masking the keys from the camera.

I've looked through usb_remote.c a fair bit, but I can't seem to figure out how to start the synchronised shooting process. EDIT Yeah I finally realised that wait_until_remote_button_is_released is run whenever the camera is shooting, regardless. So all I had to do was set usb_sync_wait to 1. /EDIT Basically I want to leave half-press untouched, but then on full-press the camera will start the synchronised shooting process (I've already taken care of what happens in wait_until_remote_button_is_released, where it will pause until full-press is released).

I've taken a look in capt_seq.c, the only other place I could find "wait_until_remote_button_is_released", but with my knowledge I might as well be looking at a machine punch card.
« Last Edit: 14 / March / 2014, 01:49:02 by Recyclojunk64 »

Re: Synchronizing two SX40s
« Reply #29 on: 14 / March / 2014, 10:37:29 »
Now comes the time to synchronise stuff between the cameras over the AF LED (I'm probably going to leave hacking the hot-shoe output for now, as I intend to use this same setup on my D20's and future S100 rig).

Quote

    What is the better approach to code a byte and send it over USB to CHDK.
    Should I use same pulse width and set USB to 5V for logic 1 and 0V for logic 0?
    Or is there any benefit working with the pulse width e.g. 60ms for logic 1 and 30 ms for logic 0?

Either can be made to work.  On newer cameras where task execution timing is not always consistent & repeatable,  I'd suggest the 60 mSec=1,  30 msec=0 approach will be easier to make robust.

That would mean a bitrate of maybe 10 bits s-1 , which to send for instance a 16 bit focus value will take way too long (imagine having a two second shutter lag :o ). And then there's also Ev (zoom values, Av and ISO can be sent when I change them). Is there anywhere I could put some code that would run every, say, 1 ms? Or any other ideas for sending data at a reasonable rate?

 

Related Topics