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

Generated on Thu Aug 7 16:19:01 2008 for elphel by  doxygen 1.5.1