1 /*=================================================================================================== 2 usb_sync.c 3 - platform dependent code related to USB remote precision sync / button release 4 5 ===================================================================================================*/ 6 7 #include "camera.h" 8 #include "clock.h" 9 #include "modes.h" 10 #include "conf.h" 11 #include "usb_remote.h" 12 #include "script_api.h" 13 #include "shooting.h" 14 15 /*=================================================================================================== 16 Variables 17 ===================================================================================================*/ 18 19 extern int usb_sync_wait_flag ; 20 extern int usb_remote_active; 21 #ifdef USB_REMOTE_DEBUGGING 22 int sync_counter=0; 23 #endif 24 25 /*--------------------------------------------------------------------------------------------------------- 26 27 force_usb_state() 28 29 - causes camera to think the USB port is active ( i.e. 5V on the +V input pin) 30 - enables the simultaneous use of the USB port for PTP communications and USB remote precision sync 31 32 ---------------------------------------------------------------------------------------------------------*/ 33 34 int forced_usb_port = 0 ; 35 36 int force_usb_state(int state) 37 { 38 forced_usb_port = state ; 39 #ifdef CAM_ALLOWS_USB_PORT_FORCING 40 return 1 ; 41 #else 42 return 0 ; 43 #endif 44 } 45 46 47 /*--------------------------------------------------------------------------------------------------------- 48 49 get_remote_state() 50 51 - return state of current remote input 52 ---------------------------------------------------------------------------------------------------------*/ 53 54 int get_remote_state() 55 { 56 #ifdef CAM_REMOTE_MULTICHANNEL 57 switch(conf.remote_input_channel) 58 { 59 case REMOTE_INPUT_USB: 60 return get_usb_bit(); 61 #ifdef CAM_REMOTE_HDMI_HPD 62 case REMOTE_INPUT_HDMI_HPD: 63 return get_hdmi_hpd_bit(); 64 #endif 65 #ifdef CAM_REMOTE_ANALOG_AV 66 case REMOTE_INPUT_ANALOG_AV: 67 return get_analog_av_bit(); 68 #endif 69 #ifdef CAM_REMOTE_AtoD_CHANNEL 70 case REMOTE_INPUT_AD_CHANNEL: 71 return (GetAdChValue(CAM_REMOTE_AtoD_CHANNEL) < CAM_REMOTE_AtoD_THRESHOLD) ? 1 : 0; 72 #endif 73 } 74 return 0; 75 #else // not CAM_REMOTE_MULTICHANNEL 76 return( get_usb_bit() ); 77 #endif 78 } 79 80 /*--------------------------------------------------------------------------------------------------------- 81 82 wait_until_remote_button_is released() 83 84 - called from capt_seq.c after all focus, exposure and flash things have been setup 85 - if enabled, waits for a USB 1->0 transition to allow accurate sync between cameras connected in parrallel 86 87 ---------------------------------------------------------------------------------------------------------*/ 88 89 #define GPIO_VSYNC_UPDATE 0xC0F06000 90 #define GPIO_VSYNC_MAX 0xC0F06014 91 // note : GPIO_VSYNC_CURRENT is camera dependent and define in platform_camera.h 92 93 void _wait_until_remote_button_is_released(void) 94 { 95 int tick; 96 97 // hook for script to block processing just prior to exposure start 98 libscriptapi->shoot_hook(SCRIPT_SHOOT_HOOK_SHOOT); 99 100 if ( usb_sync_wait_flag ) // flag set when something wants the current shot to be sync'd 101 { 102 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 103 tick = get_tick_count(); // timestamp so we don't hang here forever if something goes wrong 104 105 #ifdef CAM_REMOTE_USES_PRECISION_SYNC 106 107 int std_period = EngDrvRead(GPIO_VSYNC_MAX); 108 109 do { } while( get_remote_state() && ((int)get_tick_count()-tick < DELAY_TIMEOUT)); 110 111 int cur_cnt = *(volatile int*)(GPIO_VSYNC_CURRENT) & 0xffff; // get the counter state at the time of sync 112 113 int sync_period = std_period * 2 + cur_cnt; // schedule the end of extended period at t = t(synch pulse) + sync_time 114 115 if (std_period - cur_cnt < 10) // if too close to overflow, wait for the next period 116 { 117 sync_period -= (std_period - cur_cnt); 118 while ((*(volatile int*)(GPIO_VSYNC_CURRENT) & 0xffff) >= cur_cnt) {}; 119 } 120 121 *(volatile int*)(GPIO_VSYNC_MAX) = sync_period; // write the length of the extended period to the register 122 *(volatile int*)(GPIO_VSYNC_UPDATE) = 1; 123 124 while (*(volatile int*)(GPIO_VSYNC_UPDATE)) {}; // wait until the new value is applied 125 126 //now we are at the beginning of extended period 127 128 *(volatile int*)(GPIO_VSYNC_MAX) = std_period; // back to standard timing on next period 129 *(volatile int*)(GPIO_VSYNC_UPDATE) = 1; 130 131 /* on s95 the std_period is 0x110 132 1. if the shooting starts with GPIO_VSYNC_CURRENT value between 0 and 0xe1, it starts immediately 133 2. if the shooting starts with value between 0xe1 and 0x110 (end of period), it waits for the next period 134 135 now we want to go for the case 2 136 msleep(40) should get us there, the timing is not critical and with sleep we give the camera a chance 137 to run the delayed low prio tasks now 138 */ 139 140 msleep(40); 141 142 // now we are in the second half of the extended period, shooting can start, it will wait for the end of the period 143 144 #else // CAM_REMOTE_USES_PRECISION_SYNC 145 // delay until USB state goes to "Off" or timeout 146 147 do { } while( get_remote_state() && ((int)get_tick_count()-tick < DELAY_TIMEOUT)); 148 149 // add a sync calibration delay if requested 150 151 if ( conf.synch_delay_enable && conf.synch_delay_value>0 ) kbd_synch_delay( conf.synch_delay_value ); 152 153 #endif 154 #ifdef USB_REMOTE_DEBUGGING 155 sync_counter++ ; 156 #endif 157 usb_sync_wait_flag = 0 ; 158 usb_remote_status_led(0); // alert the user that we are all done 159 } 160 161 }