packages/web/353/php_top/i2c.inc

Go to the documentation of this file.
00001 <?php
00002 /*!***************************************************************************
00003 *! FILE NAME  : i2c.inc
00004 *! DESCRIPTION: Provides functions to read/write over i2c buses in the camera,
00005 *!              low-level R/W and additionally:
00006 *!              Setting per-slave protection mask,
00007 *!              Synchronizing system clock with a "CMOS" one
00008 *!              Reading from/writing to EEPROM memory
00009 *! Copyright (C) 2008 Elphel, Inc
00010 *! -----------------------------------------------------------------------------**
00011 *!
00012 *!  This program is free software: you can redistribute it and/or modify
00013 *!  it under the terms of the GNU General Public License as published by
00014 *!  the Free Software Foundation, either version 3 of the License, or
00015 *!  (at your option) any later version.
00016 *!
00017 *!  This program is distributed in the hope that it will be useful,
00018 *!  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 *!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 *!  GNU General Public License for more details.
00021 *!
00022 *!  You should have received a copy of the GNU General Public License
00023 *!  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00024 *! -----------------------------------------------------------------------------**
00025 *!  $Log: i2c.inc,v $
00026 *!  Revision 1.1.1.1  2008/11/27 20:04:03  elphel
00027 *!
00028 *!
00029 *!  Revision 1.3  2008/10/04 16:09:04  elphel
00030 *!  updating FPGA time with system time from CMOS
00031 *!
00032 *!  Revision 1.2  2008/06/04 20:26:23  elphel
00033 *!  includes SMBus operations, needed to activate USB on the 10369A board
00034 *!
00035 *!  Revision 1.2  2008/03/16 01:24:09  elphel
00036 *!  Added i2c speed control interface
00037 *!
00038 *!  Revision 1.1  2008/03/15 23:05:18  elphel
00039 *!  split i2c.php into i2c.php and i2c.inc (to be used from other scripts)
00040 *!
00041 *!
00042 */
00043 
00044 function i2c_ctl($bus,$data="") { 
00045    $size=6; // bytes per bus
00046    $data=trim($data);
00047    if ($data!="") {
00048      $darr=explode(":",$data);
00049      $i2cctl  = fopen('/dev/xi2cctl', 'w');
00050      for ($i=0; ($i<$size) && ($i<count($darr)); $i++) if ($darr[$i]!=""){
00051        fseek ($i2cctl, $bus*$size+$i) ;
00052        fwrite($i2cctl, chr($darr[$i]+0), 1);
00053      }
00054      fclose($i2cctl);
00055    }
00056    $i2cctl  = fopen('/dev/xi2cctl', 'r');
00057    fseek ($i2cctl, $bus*$size) ;
00058    $data = fread($i2cctl, $size);
00059    fclose($i2cctl);
00060    $xml = new SimpleXMLElement("<?xml version='1.0'?><i2cctl/>");
00061            $xml->addChild ('scl_high',ord($data[0]));
00062            $xml->addChild ('scl_low', ord($data[1]));
00063            $xml->addChild ('slave2master', ord($data[2]));
00064            $xml->addChild ('master2slave', ord($data[3]));
00065            $xml->addChild ('filter_sda',   ord($data[4]));
00066            $xml->addChild ('filter_scl',   ord($data[5]));
00067 //           $data=$xml->asXML();
00068    return $xml;
00069 
00070 } // end of i2c_ctl()
00071 
00072 function i2c_send($width,$bus,$a,$d,$raw=0) { //$a<0 - use raw read/write
00073    $w=($width==16)?2:1;
00074    $i2c_fn='/dev/xi2c'.($raw?'raw':(($w==2)?'16':'8')).(($bus==0)?'':'_aux');
00075    $i2c  = fopen($i2c_fn, 'w');
00076    fseek ($i2c, $w*$a) ;
00077    if ($w==1)    $res=fwrite($i2c, chr ($d));
00078    else          $res=fwrite($i2c, chr (floor($d/256)).chr ($d-256*floor($d/256)));
00079    fclose($i2c);
00080    return $res;
00081 } // end of i2c_send()
00082 
00083 function smbus_send($a,$d) { // d - array
00084    $i2c_fn='/dev/xi2c8_aux';
00085    $i2c  = fopen($i2c_fn, 'w');
00086    fseek ($i2c, $a) ;
00087    $cmd=chr(count($d));
00088    foreach ($d as $b) $cmd.=chr($b);
00089 //   var_dump($cmd);
00090    $res=fwrite($i2c, $cmd);
00091    fclose($i2c);
00092    return $res;
00093 } // end of i2c_send()
00094 
00095 function i2c_receive($width,$bus,$a,$raw=0) {
00096    $w=($width==16)?2:1;
00097    $i2c_fn='/dev/xi2c'.($raw?'raw':(($w==2)?'16':'8')).(($bus==0)?'':'_aux');
00098    $i2c  = fopen($i2c_fn, 'r');
00099    fseek ($i2c, $w*$a) ;
00100    $data = fread($i2c, $w);
00101    fclose($i2c);
00102    if (strlen($data)<$w) return -1;
00103    $v=unpack(($w==1)?'C':'n1',$data);
00104    return $v[1];
00105 } // end of i2c_receive()
00106 
00107 function i2c_setprot ($bus,$slave,$bit,$value) { 
00108    $i2cprot  = fopen("/dev/xi2cenable", 'r+');
00109    fseek ($i2cprot,($bus*128)+($slave>>1));
00110    $data=ord(fread($i2cprot,1));
00111    if ($value) $data |= (1<<$bit);
00112    else $data &= ~(1<<$bit);
00113    fseek ($i2cprot,($bus*128)+($slave>>1));
00114    fwrite($i2cprot, chr ($data));
00115    fclose($i2cprot);
00116 } // end of i2c_setprot ()
00117 
00118 function i2c_getCMOSClock(){
00119    $i2c  = fopen('/dev/xi2c8_aux', 'r');
00120    fseek ($i2c, 0x5102) ; //seconds in clock on the 10369 board
00121    $data = fread($i2c, 7); //sec/min/hours/days/weekdays/century-months/years, BCD
00122    fclose($i2c);
00123    if (strlen($data)<7) return "error";
00124    $v=unpack('C*',$data);
00125    $d=array("sec"  =>($v[1]& 0xf)+ 10* (($v[1]>>4)& 0x7),
00126             "min"  =>($v[2]& 0xf)+ 10* (($v[2]>>4)& 0x7),
00127             "hrs"  =>($v[3]& 0xf)+ 10* (($v[3]>>4)& 0x3),
00128             "day"  =>($v[4]& 0xf)+ 10* (($v[4]>>4)& 0x3),
00129             "wday" => $v[5]& 0x7,
00130             "month"=>($v[6]& 0xf)+ 10* (($v[6]>>4)& 0x1),
00131             "year" =>($v[7]& 0xf)+ 10* (($v[7]>>4)& 0xf) + (($v[6] & 0x80)?2000:1900)
00132            );
00133    exec("date -s ".sprintf("%02d%02d%02d%02d%04d.%02d",$d["month"],$d["day"],$d["hrs"],$d["min"],$d["year"],$d["sec"]),$out,$ret);
00134    if ($ret==0) {
00135       elphel_set_fpga_time(time()+0.0);
00136    }
00137    return $ret;
00138 } // end of i2c_getCMOSClock()
00139 
00140 function i2c_bcd($v) {
00141   $d=intval($v,10);
00142   return $d + 6*floor($d/10);
00143 } // end of i2c_bcd($v)
00144 
00145 function i2c_setCMOSClock(){
00146  $ts=time();
00147  $data=chr(i2c_bcd(gmdate("s",$ts))).
00148        chr(i2c_bcd(gmdate("i",$ts))).
00149        chr(i2c_bcd(gmdate("H",$ts))).
00150        chr(i2c_bcd(gmdate("d",$ts))).
00151        chr(i2c_bcd(gmdate("w",$ts))).
00152        chr(i2c_bcd(gmdate("m",$ts))+ ((intval(gmdate("Y",$ts),10)>=2000)?0x80:0)).
00153        chr(i2c_bcd(gmdate("y",$ts)));
00154    $i2c  = fopen('/dev/xi2c8_aux', 'w');
00155    fseek ($i2c, 0x5102) ; //seconds in clock on the 10369 board
00156    $written= fwrite($i2c, $data);
00157    fclose($i2c);
00158    if ($written < strlen($data)) return "error";
00159    return "OK";
00160 } // end of i2c_setCMOSClock()
00161 
00162 function i2c_read256b($slave=0xa0) { //will read 256 bytes from slave (address is 8-bit, includes r/~w)
00163    $i2c  = fopen('/dev/xi2c8_aux', 'r');
00164    fseek ($i2c, $slave*128) ; //256 per slave, but slave are only even
00165    $data = fread($i2c, 256);  // full 256 bytes
00166    fclose($i2c);
00167    return $data;
00168 } // end of i2c_read256b ()
00169 
00170 //this EEPROM writes only 4 bytes sequentionally (only 2 LSBs are incremented)
00171 function i2c_write256b($data, $slave=0xa0) { //will write up to 256 bytes $data to slave (address is 8-bit, includes r/~w). EEPROM should be un-protected
00172    $maxretries=200; //measured - 19
00173    if (!is_string($data)) return -1;
00174    if (strlen($data)>256) return -2;
00175    if (strlen($data)<256) $data.=chr(0);
00176    $i2c  = fopen('/dev/xi2c8_aux', 'w');
00177    $len=0;
00178    for ($i=0;$i<strlen($data); $i+=4) {
00179      for ($retry=0; $retry< $maxretries; $retry++) {
00180        fseek ($i2c, $slave*128+$i) ; //256 per slave, but slave are only even
00181        $rslt=fwrite($i2c, substr($data,$i,4));
00182        if ($rslt>0) break;
00183      }
00184      if ($rslt<=0) {
00185       $len=$rslt;
00186       break;
00187      }
00188      $len+=$rslt;
00189    }
00190    fclose($i2c);
00191    return $len;
00192 } // end of i2c_write256b ()
00193 ?>

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