thanks for reply, which release should I take?
From stable one or development trunk?
(A link would be great)
I just used SVN to get it
svn co https://tools.assembla.com/svn/chdk/trunk chdk .
Should I test with and without precision sync?
If you want to make sure that the sync is working properly and want to know how bad it is without precision sync, then yes. But the results aren't that important, I just wanted to know if anyone else had had the same problem as me, which is the case.
It would be interesting to know the value from this line ;
Code: [Select]
int std_period = _EngDrvRead(GPIO_VSYNC_MAX);
I was going to test it today but I forgot, I'll post the results tomorrow. And try out the HDMI output aswell
Well after a lot of trial-and-error, I have put together some quick-and-dirty code to synchronise the shutter between the two cameras. Basically, whenever the AF LED is on, the slave camera will half-press. If the LED turns off for less than 50ms (the off-time is 30ms), it will full-press, then take the photo when the LED turns off again (when full-press is released on the master). As half-press is still pressed of course, the LED will go back on almost immediately, and the slave won't have to refocus (until half-press on the master is released again).
in usb_remote.c . Note that the code for the master is commented out at the moment
#include "keyboard.h"
#define GPIO_VSYNC_UPDATE 0xC0F06000
#define GPIO_VSYNC_MAX 0xC0F06014
#define GPIO_VSYNC_CURRENT 0xC0F070C8 // microfunguy's value
//#define GPIO_VSYNC_CURRENT 0xC0F07008 // vnd's original value
void _wait_until_remote_button_is_released(void)
{
int tick;
//NOTE set to 1 because, well, you're not going to be turning it off anyway
if ( 1 /*( conf.remote_enable ) // menu : USB remote enabled - bracket everything in this function
&& ( conf.synch_enable ) // menu : Sync enabled - tells us to wait for USB to disconnect
&& ( usb_sync_wait )*/ ) // only sync when USB remote is active - don't trap normal shooting
{
usb_remote_status_led(1); // indicate to user we are waiting for remote button to release - this happens every time the camera takes a picture
tick = get_tick_count(); // timestamp so we don't hang here forever if something goes wrong
int std_period = _EngDrvRead(GPIO_VSYNC_MAX);
int sync_time = std_period * 3; // schedule the end of extended period at t = t(synch pulse) + sync_time
//NOTE For the master camera
/*
*((volatile int *) 0xc022c028) = 0x83dc00; //Turn AF LED off for 30 ms to signal slave
msleep(30); //LED is turned off anyway by the firmware about 20ms after _wait_until_remote_button_is_released starts
*((volatile int *) 0xc022c028) = 0x93d800; //Set AF LED on //address is for the S110
do
{
msleep(20);
} while( (kbd_is_key_pressed(KEY_SHOOT_FULL)) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
//
*((volatile int *) 0xc022c028) = 0x83dc00; //Set AF LED off //Address is for the S110
*/
//NOTE For the slave camera, Value of 100 works well, anything above about 300 will trigger if the battery temp terminal is not modified.
do
{ } while( (*(short*)0xc090004a < 100) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
int cur_cnt = *(volatile int*)(GPIO_VSYNC_CURRENT) & 0xffff; // get the counter state at the time of sync
int sync_period = sync_time - (std_period - cur_cnt);
if (std_period - cur_cnt < 10)
{
// too close to overflow, wait for the next period
sync_period -= std_period;
while ((*(volatile int*)(GPIO_VSYNC_CURRENT) & 0xffff) >= cur_cnt) {};
}
*(volatile int*)(GPIO_VSYNC_MAX) = sync_period; // write the length of the extended period to the register
*(volatile int*)(GPIO_VSYNC_UPDATE) = 1;
while (*(volatile int*)(GPIO_VSYNC_UPDATE)) {}; // wait until the new value is applied
//now we are at the beginning of extended period
//NOTE commented out because it caused problems with the S110
// *(volatile int*)(GPIO_VSYNC_MAX) = std_period; // back to standard timing on next period
*(volatile int*)(GPIO_VSYNC_UPDATE) = 1;
msleep(40);
sync_counter++ ;
usb_sync_wait = 0 ;
usb_remote_status_led(0); // alert the user that we are all done
}
}
in kbd_process.c, master code commented out again.
int wait_until_master_confirms = 0;
long kbd_process()
{
...
// auto iso shift
if (camera_info.state.is_shutter_half_press && kbd_is_key_pressed(conf.alt_mode_button))
return 0;
if (kbd_is_key_pressed(conf.alt_mode_button))
{
key_pressed = 1;
kbd_key_release_all();
return 1;
}
//NOTE for slave
if (*(short*)0xc090004a < 100)
{
if ((wait_until_master_confirms > 1) && (wait_until_master_confirms < 5))
{
kbd_key_press(KEY_SHOOT_FULL);
kbd_blocked = 1;
}
else
{
kbd_key_release(KEY_SHOOT_FULL);
kbd_key_press(KEY_SHOOT_HALF);
*((volatile int *) 0xc022c028) = 0x93d800; //Set AF LED on, address is for S110
wait_until_master_confirms = 0;
kbd_blocked = 1;
}
}
else
{
wait_until_master_confirms++;
if (wait_until_master_confirms > 5) //wait 50 ms to ensure this isn't a 30ms off pulse
{
*((volatile int *) 0xc022c028) = 0x83dc00;
if (wait_until_master_confirms == 6)
{
kbd_blocked = 0; //Only do this once or else it will interfere with alt mode keyboard masking
}
}
}
//NOTE for master
/*if (kbd_is_key_pressed(KEY_SHOOT_HALF))
{
*((volatile int *) 0xc022c028) = 0x93d800; //turns on the AF LED on the S110
}
else
{
*((volatile int *) 0xc022c028) = 0x83dc00;
}*/
#ifdef CAM_TOUCHSCREEN_UI
extern int ts_process_touch();
if (ts_process_touch())
{
gui_set_need_restore();
}
#endif
// deals with the rest
if ( !kbd_blocked || usb_remote_active )
{
// kbd_blocked = handle_usb_remote(); //Yes, this has been disabled, as it was causing problems I will have to find later
}
if (gui_kbd_process())
return 1;
action_stack_process_all();
return kbd_blocked;
}
It seems to work alright, and sync is very good, most shots were about 0.1ms apart. Sometimes the sync was out enough to be heard but only on occasion, not sure why just yet. The above code for the master may have problems reading the state of the full-press during sync, I had to do a complex rearrangement in kbd.c, but it would be easier to replace it with a 50ms or so delay. Not that I expect anyone will try the above modification just yet anyhow.
The next step will be to send settings over to the slave, such as ISO and aperture, and probably shutter-speed.