packages/web/353/php_top/sync.php

Go to the documentation of this file.
00001 <?php
00002 /*!***************************************************************************
00003 *! FILE NAME  : sync.php
00004 *! DESCRIPTION: sync boards detection /setup
00005 *! Copyright (C) 2008 Elphel, Inc
00006 *! -----------------------------------------------------------------------------**
00007 *!
00008 *!  This program is free software: you can redistribute it and/or modify
00009 *!  it under the terms of the GNU General Public License as published by
00010 *!  the Free Software Foundation, either version 3 of the License, or
00011 *!  (at your option) any later version.
00012 *!
00013 *!  This program is distributed in the hope that it will be useful,
00014 *!  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 *!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 *!  GNU General Public License for more details.
00017 *!
00018 *!  You should have received a copy of the GNU General Public License
00019 *!  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00020 *! -----------------------------------------------------------------------------**
00021 *!  $Log: sync.php,v $
00022 *!  Revision 1.1.1.1  2008/11/27 20:04:03  elphel
00023 *!
00024 *!
00025 *!  Revision 1.6  2008/03/25 07:38:43  elphel
00026 *!  just troubleshooting
00027 *!
00028 *!  Revision 1.5  2008/03/22 04:43:03  elphel
00029 *!  few minor changes
00030 *!
00031 *!  Revision 1.4  2008/03/21 01:20:19  elphel
00032 *!  forces to use "role=sync" if no board is detected (so malfunctioning board will cause an error)
00033 *!
00034 *!  Revision 1.3  2008/03/21 01:10:34  elphel
00035 *!  mode it work in "self" mode even if no sync board is detected.
00036 *!
00037 *!  Revision 1.2  2008/03/20 22:33:23  elphel
00038 *!  control fof inter-cameras synchronization using 10369, 10371 boards
00039 *!
00040 *!  Revision 1.1  2008/03/17 17:44:39  elphel
00041 *!  started sync.php to setup synchronization (10369/10371 boards)
00042 *!
00043 *!
00044 */
00045 
00046 require 'i2c.inc';
00047 function _returnXML($xml,$rslt=0) {
00048     $sxml=$xml->asXML();
00049     header("Content-Type: text/xml");
00050     header("Content-Length: ".strlen($sxml)."\n");
00051     header("Pragma: no-cache\n");
00052     printf($sxml);
00053     exit($rslt);
00054 }
00056 //bits can not be 0 - bit 0 is used by i2c
00057 $xmlsyncstr = <<<XML
00058 <?xml version='1.0'?>
00059 <models>
00060  <m10369>
00061   <external>
00062    <in>
00063     <bit>10</bit>
00064     <polarity>0</polarity>
00065    </in>
00066    <out>
00067     <bit>11</bit>
00068     <polarity>0</polarity>
00069    </out>
00070   </external>
00071   <internal>
00072    <in>
00073     <bit>8</bit>
00074     <polarity>0</polarity>
00075    </in>
00076    <out>
00077     <bit>9</bit>
00078     <polarity>0</polarity>
00079    </out>
00080   </internal>
00081  </m10369>
00082  <m10371>
00083   <internal>
00084    <in>
00085     <bit>8</bit>
00086     <polarity>0</polarity>
00087    </in>
00088    <out>
00089     <bit>9</bit>
00090     <polarity>1</polarity>
00091    </out>
00092   </internal>
00093  </m10371>
00094 </models>
00095 XML;
00096    $self_only=false;
00097    $xmlsync = new SimpleXMLElement($xmlsyncstr);
00098    $s=exec("bootblocktool -x SERNO");
00099    $try_master=5;
00100    $try_master1=5+("0x".substr($s,11,1))+("0x".substr($s,10,1)); //randomize
00101    $busbits=array ( );
00102    $channel="self";
00103    $xml = new SimpleXMLElement("<?xml version='1.0' standalone='yes'?><sync/>");
00104    if (($_GET["channel"]=="self") || ($_GET["role"]=="self") || ($_GET["self"])) {
00105      $_GET["channel"]="self"; 
00106      $_GET["role"]="self"; 
00107      $self_only=true;
00108    }
00109    if (!$self_only) {
00110      $id_str=i2c_read256b();
00111      if ($id_str=="") {
00112        if ($_GET["role"]!="self") {
00113          $xml->addChild ('error','No sync capable board detected, use "role=self" for the onboard timer');
00114          _returnXML($xml,-1);
00115         }
00116         $xml->addChild ('board','none');
00117         $self_only=true;
00118      } else {
00119        $zero=strpos($id_str,chr(0));
00120        if ($zero!==false) $id_str=substr($id_str,0, $zero);
00121        if (substr($id_str,0,5)!="<?xml") {
00122          if ($_GET["role"]!="self") {
00123            $xml->addChild ('error','Corrupted sync board ID in the EEPROM, use "role=self" for the onboard timer');
00124            _returnXML($xml,-1);
00125          }
00126          $xml->addChild ('board','unidentified');
00127          $self_only=true;
00128        }
00129      }
00130    }
00131    if (!$self_only) {
00132      $xml_id = new SimpleXMLElement($id_str);
00133      $model=(string) $xml_id->model;
00134      $xml->addChild ('board',$model);
00135      $xml->addChild ('revision',(string) $xml_id->rev);
00136      $xml->addChild ('serial',(string) $xml_id->serial);
00137      $v= $xmlsync->{'m'.$model}->external->in->bit;       if ($v!==NULL) $busbits["external"]["in" ]["bit"]     = (integer) $v;
00138      $v= $xmlsync->{'m'.$model}->external->in->polarity;  if ($v!==NULL) $busbits["external"]["in" ]["polarity"]= (integer) $v;
00139      $v= $xmlsync->{'m'.$model}->external->out->bit;      if ($v!==NULL) $busbits["external"]["out"]["bit"]     = (integer) $v;
00140      $v= $xmlsync->{'m'.$model}->external->out->polarity; if ($v!==NULL) $busbits["external"]["out"]["polarity"]= (integer) $v;
00141      $v= $xmlsync->{'m'.$model}->internal->in->bit;       if ($v!==NULL) $busbits["internal"]["in" ]["bit"]     = (integer) $v;
00142      $v= $xmlsync->{'m'.$model}->internal->in->polarity;  if ($v!==NULL) $busbits["internal"]["in" ]["polarity"]= (integer) $v;
00143      $v= $xmlsync->{'m'.$model}->internal->out->bit;      if ($v!==NULL) $busbits["internal"]["out"]["bit"]     = (integer) $v;
00144      $v= $xmlsync->{'m'.$model}->internal->out->polarity; if ($v!==NULL) $busbits["internal"]["out"]["polarity"]= (integer) $v;
00145      if ($_GET["init"]!==NULL) {
00146        $xml->addChild ('initialize');
00147        if ($busbits["external"]["out"]>0) {
00148          $data=(2-$busbits["external"]["out" ]["polarity"])<<(2*$busbits["external"]["out" ]["bit"]);
00149          elphel_fpga_write(0x70,$data);
00150          $xml->initialize->addChild ('external_out',sprintf("0x%x",$data));
00151        }
00152        if ($busbits["external"]["in" ]>0) {
00153          $data=3<<(2*$busbits["external"]["in" ]["bit"]);
00154          elphel_fpga_write(0x70,$data);
00155          $xml->initialize->addChild ('external_in',sprintf("0x%x",$data));
00156        }
00157        if ($busbits["internal"]["out"]>0) {
00158          $data=(2-$busbits["internal"]["out" ]["polarity"])<<(2*$busbits["internal"]["out"]["bit"]);
00159          elphel_fpga_write(0x70,$data);
00160          $xml->initialize->addChild ('internal_out',sprintf("0x%x",$data));
00161        }
00162        if ($busbits["internal"]["in" ]>0) {
00163          $data=3<<(2*$busbits["internal"]["in" ]["bit"]);
00164          elphel_fpga_write(0x70,3<<(2*$busbits["internal"]["in" ]["bit"]));
00165          $xml->initialize->addChild ('internal_in',sprintf("0x%x",$data));
00166        }
00167      }
00168      $channel=(($_GET["channel"]=="external") || ($_GET["external"]))?"external":"internal";
00169      $xml->addChild ('channel',$channel);
00170      if ($busbits[$channel]["in" ]==0) {
00171         $xml->addChild ('error',sprintf("Channel %s is not implemented",$channel));
00172        _returnXML($xml,-1);
00173      }
00174    } else {
00175      $_GET["role"]="self";
00176    }
00177    $master=0;
00178 
00179    switch ($_GET["role"]) {
00180      case "master":
00181        $master=1;
00182      case "slave":
00183      case "self":
00184      case "":
00185       $role=$_GET["role"];
00186       break;
00187      case "detect":
00188       if ($busbits[$channel]["out" ]==0) $role="slave";
00189       else {
00190         elphel_fpga_write(0x70,0x8000000); 
00191         elphel_fpga_write(0x70,(2-$busbits[$channel]["out" ]["polarity"])<<(2*$busbits[$channel]["out"]["bit"])); //turn off
00192         $master=((elphel_fpga_read(0x70)>>$busbits[$channel]["in" ]["bit"]) ^ $busbits[$channel]["in" ]["polarity"]) & 1;
00193         for ($i=0; ($i< $try_master) && ($master>0); $i++) {
00194           elphel_fpga_write(0x70,(1+$busbits[$channel]["out" ]["polarity"])<<(2*$busbits[$channel]["out"]["bit"])); //turn on
00195           $master &= ~((elphel_fpga_read(0x70)>>$busbits[$channel]["in" ]["bit"]) ^ $busbits[$channel]["in" ]["polarity"] );
00196           elphel_fpga_write(0x70,(2-$busbits[$channel]["out" ]["polarity"])<<(2*$busbits[$channel]["out"]["bit"])); //turn off
00197           for ($j=0;($j<rand(0,$try_master1)) && ($master>0);$j++) {
00198              elphel_fpga_write(0x70,(2-$busbits[$channel]["out" ]["polarity"])<<(2*$busbits[$channel]["out"]["bit"])); //turn off
00199              $master &= ((elphel_fpga_read(0x70)>>$busbits[$channel]["in" ]["bit"]) ^ $busbits[$channel]["in" ]["polarity"] );
00200           }
00201           if ($master==0) break;
00202         }
00203         $role=$master?"master":"slave";
00204       }
00205       break;
00206      default:
00207        $xml->addChild ('error',sprintf("Unknown role: %s",$_GET["role"]));
00208        _returnXML($xml,-1);
00209    }
00210    $xml->addChild ('role',$role);
00211    $trigger_parms=array();
00212    $sensor_clk=elphel_get_P_value(ELPHEL_CLK_SENSOR); 
00213    if ($_GET["pdelay"]!==NULL)    $trigger_parms["TRIG_DELAY"]= (integer) $_GET["pdelay"];
00214    if ($_GET["delay"]!==NULL)     $trigger_parms["TRIG_DELAY"]= (integer) ($_GET["delay"]*$sensor_clk);
00215    if ($_GET["fps"]!==NULL) {
00216      if      ($_GET["fps"]=="single")    $trigger_parms["TRIG_PERIOD"]= 1;
00217      else if ($_GET["fps"]=="stop")      $trigger_parms["TRIG_PERIOD"]= 0; 
00218      else if ($_GET["fps"]>0)            $trigger_parms["TRIG_PERIOD"]= (integer) ($sensor_clk/$_GET["fps"]);
00219      else                                $trigger_parms["TRIG_PERIOD"]= 0; 
00220 
00221    }
00223    switch ($role) {
00224      case "self":
00225         $trigger_parms["TRIG_CONDITION"]= 0;
00226       break;
00227      case "master":
00228      case "slave":
00229         $trigger_parms["TRIG_CONDITION"]= (2+$busbits[$channel]["in" ]["polarity"])<< (2*$busbits[$channel]["in"]["bit"]);
00230       break;
00231    }
00233    switch ($role) {
00234      case "master":
00235         $trigger_parms["TRIG_OUT"]= (2+$busbits[$channel]["out" ]["polarity"])<< (2*$busbits[$channel]["out"]["bit"]);
00236         elphel_fpga_write(0x70,0xc000000); 
00237       break;
00238      case "slave":
00239      case "self":
00240         $trigger_parms["TRIG_OUT"]= 0;
00241         elphel_fpga_write(0x70,0x8000000); 
00242       break;
00243    }
00244    $xml->addChild ('trigger');
00245    foreach ($trigger_parms as $key=>$value) {
00246      $xml->trigger->addChild ($key,$value);
00247      $xml->trigger->addChild ($key."_HEX",sprintf("0x%x",$value));
00248    }
00249    elphel_set_P_arr($trigger_parms);
00250 //   if (($role!="") && (count($trigger_parms)>0)){
00253    if (count($trigger_parms)>0){
00255      elphel_trigger();
00256      $xml->trigger->addChild ('programmed',1);
00257    } else {
00258      $xml->trigger->addChild ('programmed',0);
00259    }
00260    $current_trigger=elphel_get_P_arr(Array("TRIG_DELAY"=>0,"TRIG_PERIOD"=>0,"TRIG_CONDITION"=>0,"TRIG_OUT"=>0));
00261    foreach ($current_trigger as $key=>$value) {
00262      $xml->trigger->addChild ($key,$value);
00263      $xml->trigger->addChild ($key."_HEX",sprintf("0x%x",$value));
00264    }
00265    _returnXML($xml,-0);
00266 ?>

Generated on Fri Nov 28 00:06:25 2008 for elphel by  doxygen 1.5.1