Commit 877a89dd authored by Andrey Filippov's avatar Andrey Filippov

Porting i2c functionality to PHP scripts

parent 33c12313
DOCUMENTROOT=/www/pages DOCUMENTROOT=/www/pages
INCLUDES=$(DOCUMENTROOT)/include
OWN = -o root -g root OWN = -o root -g root
INSTDOCS = 0644 INSTDOCS = 0644
#INSTALL = install #INSTALL = install
...@@ -16,6 +17,8 @@ PHP_SCRIPTS=camvars.php \ ...@@ -16,6 +17,8 @@ PHP_SCRIPTS=camvars.php \
phpinfo.php \ phpinfo.php \
snapfull.php snapfull.php
PHPINCLUDES=i2c_include.php show_source_include.php
all: all:
@echo "make all in src" @echo "make all in src"
...@@ -25,8 +28,10 @@ all: ...@@ -25,8 +28,10 @@ all:
install: install:
@echo "make install in src" @echo "make install in src"
$(INSTALL) $(OWN) -d $(DESTDIR)$(DOCUMENTROOT) $(INSTALL) $(OWN) -d $(DESTDIR)$(DOCUMENTROOT)
$(INSTALL) $(OWN) -d $(DESTDIR)$(INCLUDES)
$(INSTALL) $(OWN) -m $(INSTDOCS) $(DOCS) $(DESTDIR)$(DOCUMENTROOT) $(INSTALL) $(OWN) -m $(INSTDOCS) $(DOCS) $(DESTDIR)$(DOCUMENTROOT)
$(INSTALL) $(OWN) -m $(INSTDOCS) $(PHP_SCRIPTS) $(DESTDIR)$(DOCUMENTROOT) $(INSTALL) $(OWN) -m $(INSTDOCS) $(PHP_SCRIPTS) $(DESTDIR)$(DOCUMENTROOT)
$(INSTALL) $(OWN) -m $(INSTDOCS) $(PHPINCLUDES) $(DESTDIR)$(INCLUDES)
$(INSTALL) $(OWN) -d $(DESTDIR)$(SYSCONFDIR) $(INSTALL) $(OWN) -d $(DESTDIR)$(SYSCONFDIR)
$(INSTALL) $(OWN) -d $(DESTDIR)$(CONFDIR) $(INSTALL) $(OWN) -d $(DESTDIR)$(CONFDIR)
$(INSTALL) $(OWN) -m $(INSTDOCS) -T autocampars.xml $(DESTDIR)$(CONFDIR)/autocampars0.xml $(INSTALL) $(OWN) -m $(INSTDOCS) -T autocampars.xml $(DESTDIR)$(CONFDIR)/autocampars0.xml
......
<?php
/*!***************************************************************************
*! FILE NAME : i2c.php
*! DESCRIPTION: Provides single byte/short r/w from/to the i2c
*! Setting per-slave protection mask,
*! Synchronizing system clock with a "CMOS" one
*! Reading from/writing to EEPROM memory
*! Copyright (C) 2008 Elphel, Inc
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: i2c.php,v $
*! Revision 1.7 2012/04/08 04:08:58 elphel
*! bug fix in temperature measurement
*!
*! Revision 1.6 2012/01/16 01:42:24 elphel
*! comments
*!
*! Revision 1.5 2011/12/22 05:35:11 elphel
*! Added "slow" option (for slow i2c devices) and reading the sensor board temperature
*!
*! Revision 1.4 2011/08/13 00:51:21 elphel
*! support for "granddaughter" board ID eeprom
*!
*! Revision 1.3 2011/01/18 17:38:34 dzhimiev
*! 1. added <len> record, passed through 'length'
*!
*! Revision 1.2 2010/08/10 21:11:40 elphel
*! added EEPROM support of the 10359 and 10338D boards.
*!
*! Revision 1.1.1.1 2008/11/27 20:04:03 elphel
*!
*!
*! Revision 1.8 2008/04/24 20:32:44 elphel
*! reverted, wrong edit
*!
*! Revision 1.7 2008/04/24 18:19:50 elphel
*! changed to absolute path to i2c.inc
*!
*! Revision 1.6 2008/03/16 01:24:09 elphel
*! Added i2c speed control interface
*!
*! Revision 1.5 2008/03/15 23:05:18 elphel
*! split i2c.php into i2c.php and i2c.inc (to be used from other scripts)
*!
*! Revision 1.4 2008/03/15 18:38:21 elphel
*! Implemented add-on boards EEPROM support
*!
*! Revision 1.3 2008/02/20 07:41:42 elphel
*! report error if the date is wrong
*!
*! Revision 1.2 2008/02/13 00:30:01 elphel
*! Added system time synchronization with "CMOS" clock
*!
*! Revision 1.1 2008/02/12 21:53:20 elphel
*! Modified I2c to support multiple buses, added raw access (no address registers) and per-slave protection bitmasks
*!
*!
*/
// In NC393: buses 0..3 - sensors(old bus=0), 4 - aux (old bus=1)
set_include_path(get_include_path() . PATH_SEPARATOR . '/www/pages/include');
require 'i2c_include.php';
$width=0;
$bus=0;
$adr=-1;
$data="";
$nopars=false;
$raw=0;
$wprot=-1;
$rprot=-1;
$rslt="";
$cmd="";
//
$model="";
$rev="";
$brand="Elphel";
$serial="";
$time="";
$port="";
$part="";
$baud="";
$sync="";
$slowbus0=-1; // extra microseconds for SCL low and SCL high
$EEPROM_bus0=false;
$EEPROM_chn=0; /// 0 - 10359/single 10338D, 1..3 - 10338D attached to the 10359
$application='';
$applicationMode='';
$sensor='';
$temperatureSA=0x30;
$temperarureDelay=1.0; // extra microseconds for SCL low/high (nominal 4, but works with 1)
$msg="<?xml version=\"1.0\"?>\n<i2c>\n";
if (count($_GET) == 0 ) {
$nopars=true;
} else {
$pars=array();
foreach($_GET as $key=>$value) {
switch($key) {
case "slow":
case "slowbus0":
$slowbus0=$value+0;
break;
case "cmd":
switch($value) {
case "fromCMOS":
$rslt=i2c_getCMOSClock()?"Set system time error (probably CMOS clock is not set)":("System clock is set to ".exec("date"));
break;
case "toCMOS":
$rslt=i2c_setCMOSClock();
break;
case "fromEEPROM":
case "toEEPROM":
case "fromEEPROM0":
case "toEEPROM0":
case "ctl":
$cmd=$value;
break;
}
break;
case "EEPROM_chn":
$EEPROM_chn=$value;
break;
case "app":
case "application":
$application=$value;
break;
case "mode":
case "application_mode":
$application_mode=$value;
break;
case "sensor":
$sensor=$value;
break;
case "port":
$port=$value;
break;
case "part":
$part=$value;
break;
case "baud":
$baud=$value;
break;
case "sync":
$sync=$value;
break;
case "model":
$model=$value;
break;
case "rev":
$rev=$value;
break;
case "serial":
$serial=$value;
break;
case "time": // seconds from 1970
$time=$value+0;
break;
case "raw":
$adr=($value+0) & ~0x7f;
$raw=1;
$width=8;
break;
case "width":
$width=$value+0;
break;
case "bus":
$bus=$value+0;
break;
case "adr":
$adr=$value+0;
break;
case "wp":
if ($value==0) $wprot=0;
else if ($value==1) $wprot=1;
break;
case "rp":
if ($value==0) $rprot=0;
else if ($value==1) $rprot=1;
break;
case "data":
$data=$value;
break;
case "length":
$length=$value+0;
break;
}
}
}
switch($cmd) {
case "fromEEPROM0":
$EEPROM_bus0=true; // and fall below
case "fromEEPROM":
$rslt=i2c_read256b(0xa0+($EEPROM_chn*($EEPROM_bus0?4:2)), $EEPROM_bus0?0:1);
$zero=strpos($rslt,chr(0));
if ($zero!==false) $rslt=substr($rslt,0, $zero);
if (substr($rslt,0,5)=="<?xml") {
$xml=simplexml_load_string($rslt);
// $temperatureSA=0x30;
// $temperarureDelay=1.0; // extra microseconds for SCL low/high (nominal 4, but works with 1)
// try reading sensor temperature (if available)
if ($EEPROM_bus0) {
$bus=0;
$sa=$temperatureSA+($EEPROM_chn*($EEPROM_bus0?4:2));
$data=i2c_receive_slow(16,$bus,$sa*128+5,0,$temperarureDelay);
if ($data>=0) { // <0 - i2c error - not implemented
$data= (($data & 0x1000)?-1:1)*($data&0xfff)/16.0;
$xml->addChild ('sensorTemperature',$data);
i2c_send_slow(8,$bus,$sa*128+8,3,0,$temperarureDelay); // set slow conversion, 1/16C resolution - for the next time
}
}
$xml_string=$xml->asXML();
header("Content-Type: text/xml");
header("Content-Length: ".strlen($xml_string)."\n");
header("Pragma: no-cache\n");
printf($xml_string);
exit (0);
}
break;
case "toEEPROM0":
$EEPROM_bus0=true; // and fall below
case "toEEPROM":
if ($wprot>=0) {
i2c_setprot ($EEPROM_bus0?0:1,0xa0+($EEPROM_chn*($EEPROM_bus0?4:2)),1,(1-$wprot));
}
if ($data=="") {
if ($model === "") {$rslt="model not specified"; break;}
if ($rev === "") {$rslt="rev not specified"; break;}
if ($serial === "") {$rslt="serial not specified"; break;}
if ($time === "") {$rslt="time not specified"; break;}
$xml = new SimpleXMLElement("<?xml version='1.0' standalone='yes'?><board/>");
if ($brand!='') $xml->addChild ('brand',$brand);
if ($model!='') $xml->addChild ('model',$model);
if ($rev!='') $xml->addChild ('rev', $rev);
if ($serial!='') $xml->addChild ('serial',$serial);
if ($time!='') $xml->addChild ('time',$time);
if ($application!="") $xml->addChild ('app',$application);
if ($application_mode!="") $xml->addChild ('mode',$application_mode);
if ($sensor!='') $xml->addChild ('sensor',$sensor);
if ($length!='') $xml->addChild ('len',$length);
if ($port!='') $xml->addChild ('port',$port);
if ($part!='') $xml->addChild ('part',$part);
if ($baud!='') $xml->addChild ('baud',$baud);
if ($sync!='') $xml->addChild ('sync',$sync);
$data=$xml->asXML();
}
if (strlen($data)>256) {
$rslt="data too long - ".strlen($data)." bytes, only 256 are permitted";
break;
}
$rslt="written ".i2c_write256b($data,0xa0+($EEPROM_chn*($EEPROM_bus0?4:2)),$EEPROM_bus0?0:1);
i2c_setprot ($EEPROM_bus0?0:1,0xa0+($EEPROM_chn*($EEPROM_bus0?4:2)),1,0);
break;
case "ctl":
if ($bus==="") {
$rslt="i2c bus number is not specified";
break;
}
$rslt=i2c_ctl($bus,$data)->asXML();
header("Content-Type: text/xml");
header("Content-Length: ".strlen($rslt)."\n");
header("Pragma: no-cache\n");
printf($rslt);
exit (0);
}
if ($rslt=="") {
if (($adr>=0) && (($width==8) || ($width==16))) {
$slave=($adr >> (($width==16)?8:7)) & 0xfe;
if ($wprot>=0) {
i2c_setprot ($bus,$slave,1,(1-$wprot));
}
if ($rprot>=0) {
i2c_setprot ($bus,$slave,0,(1-$rprot));
}
$msg.="<width>".$width."</width>\n";
$msg.="<bus>".$bus."</bus>\n";
$msg.="<slave>".(sprintf("0x%x",($adr>>(($width==8)?7:8)) & 0xfe ))."</slave>\n";
if (!$raw) {
$msg.="<adr>".$adr."</adr>\n";
$msg.="<hex_adr>".sprintf("0x%x",$adr)."</hex_adr>\n";
}
if ($data!="") { //! i2c write
$data+=0;
$msg.="<data>".$data."</data>\n";
$msg.="<wdata>".$data."</wdata>\n";
$msg.="<hex_data>".sprintf("0x%x",$data)."</hex_data>\n";
$rslt=($slowbus0>=0)? i2c_send_slow($width,$bus,$adr,$data,$raw,$slowbus0): i2c_send($width,$bus,$adr,$data,$raw);;
if (!($rslt>0)) $msg.="<error> \"i2c write error (".$rslt.")\"</error>\n";
} else { //!i2c read
$data=($slowbus0>=0)? i2c_receive_slow($width,$bus,$adr,$raw,$slowbus0):i2c_receive($width,$bus,$adr,$raw);
$msg.="<data>".$data."</data>\n";
$msg.="<rdata>".$data."</rdata>\n";
$msg.="<hex_data>".sprintf("0x%x",$data)."</hex_data>\n";
if ($data==-1) $msg.="<error> \"i2c read error\"</error>\n";
}
} else {
if (!$nopars) $msg.="<error>\"Address (adr or raw) or width are not specified or are not positive.\"</error>\n";
$msg.="<usage>\"open URL: i2c.php?width&#061;www&amp;bus&#061;bbb&amp;adr&#061;aaa&amp;data&#061;ddd\"</usage>\n";
}
} else {
$msg.="<result>\"".$rslt."\"</result>\n";
}
$msg.="</i2c>\n";
header("Content-Type: text/xml");
header("Content-Length: ".strlen($msg)."\n");
header("Pragma: no-cache\n");
printf($msg);
?>
<?php
/*!***************************************************************************
*! FILE NAME : i2c.inc
*! DESCRIPTION: Provides functions to read/write over i2c buses in the camera,
*! low-level R/W and additionally:
*! Setting per-slave protection mask,
*! Synchronizing system clock with a "CMOS" one
*! Reading from/writing to EEPROM memory
*! Copyright (C) 2008-2016 Elphel, Inc
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: i2c.inc,v $
*! Revision 1.4 2012/01/12 19:09:28 elphel
*! bug fix
*!
*! Revision 1.3 2011/12/22 05:35:11 elphel
*! Added "slow" option (for slow i2c devices) and reading the sensor board temperature
*!
*! Revision 1.2 2010/08/10 21:11:40 elphel
*! added EEPROM support of the 10359 and 10338D boards.
*!
*! Revision 1.1.1.1 2008/11/27 20:04:03 elphel
*!
*!
*! Revision 1.3 2008/10/04 16:09:04 elphel
*! updating FPGA time with system time from CMOS
*!
*! Revision 1.2 2008/06/04 20:26:23 elphel
*! includes SMBus operations, needed to activate USB on the 10369A board
*!
*! Revision 1.2 2008/03/16 01:24:09 elphel
*! Added i2c speed control interface
*!
*! Revision 1.1 2008/03/15 23:05:18 elphel
*! split i2c.php into i2c.php and i2c.inc (to be used from other scripts)
*!
*!
*/
//$i2c_slow_safe=array(3,4,2,2,7,7); /// sensor i2c delays are 2,2,1,1,7,7
// In NC393: buses 0..3 - sensors(old bus=0), 4 - aux (old bus=1)
/// NC393-fucnctions to read/write sensor ports
/// Reusing NC53 parameters: $width->$name, $raw ->
function i2c_send_sensor($name, ///< device class name (get all by "cat /sys/devices/soc0/elphel393-sensor-i2c@0/i2c_all")
$sensor_port, ///< sensor port :0..3
$ra, ///< register address
$data, ///< data to write
$sa7_offset=0) ///< slave address offset when there are multiple devices (2*sub-channel in 10359)
///< return true on success, false on failure
{ //$a<0 - use raw read/write
$path = '/sys/devices/soc0/elphel393-sensor-i2c@0/i2c'.strval($sensor_port);
$rslt = file_put_contents ($path, $name.' ' . strval($sa7_offset) . ' ' . strval($ra) . ' ' . strval($data));
return $rslt;
}
function i2c_receive_sensor($name, ///< device class name (get all by "cat /sys/devices/soc0/elphel393-sensor-i2c@0/i2c_all")
$sensor_port, ///< sensor port :0..3
$ra, ///< register address
$sa7_offset=0) ///< slave address offset when there are multiple devices (2*sub-channel in 10359)
///< @return read data or -1 on error
{
// Initiate read
$path = '/sys/devices/soc0/elphel393-sensor-i2c@0/i2c'.strval($sensor_port);
$rslt = file_put_contents ($path, $name.' ' . strval($sa7_offset) . ' ' . strval($ra) );
if (!$rslt)
return -1;
$rslt = file_get_contents ($path);
if ($rslt === false)
return -1;
return intval($rslt);
}
/** Read 256 bytes from device as a string */
function i2c_read256b_sensor($name, ///< device class name (get all by "cat /sys/devices/soc0/elphel393-sensor-i2c@0/i2c_all")
$sensor_port, ///< sensor port :0..3
$sa7_offset=0) ///< slave address offset when there are multiple devices (2*sub-channel in 10359)
///< @return read data string or partial (empty) string on error
{
$rslt = '';
for ($ra=0;$ra<256;$ra++){
if (($d = i2c_receive_sensor($name,$sensor_port,$ra,$sa7_offset))<0) break;
$rslt .= chr($d);
}
return $rslt;
}
/** Write string to device */
function i2c_write256b_sensor($data, ///< Sring to write
$name, ///< device class name (get all by "cat /sys/devices/soc0/elphel393-sensor-i2c@0/i2c_all")
$sensor_port, ///< sensor port :0..3
$sa7_offset=0) ///< slave address offset when there are multiple devices (2*sub-channel in 10359)
///< @return number of bytes written
{
$len = 0;
for ($ra=0;$ra<strlen($data);$ra++){
$b = ord(substr($data,$ra,1));
if (($d = i2c_send_sensor($name,$sensor_port,$ra,$b,$sa7_offset))<0) break;
usleep(10000);
$len ++;
}
return $len;
}
///sys/devices/soc0/elphel393-sensor-i2c@0# echo "mt9p006 8 9" > i2c3; cat i2c3
/*
cy22393: 0x69 1 1 100 kHz
sensor_temp: 0x18 1 2 100 kHz
sensor_eeprom: 0x50 1 1 100 kHz
pca9500_eeprom: 0x50 1 1 100 kHz
el10359_32: 0x8 1 4 500 kHz
el10359: 0x8 1 2 500 kHz
mt9p006: 0x48 1 2 500 kHz
mt9f002: 0x10 2 2 500 kHz
*/
function getSlowArray($usec=0){
if ($usec<0) $usec=0;
$SCL_low=3+(int) ($usec*8);
$SCL_high=4+(int) ($usec*8);
if ($SCL_low>254) $SCL_low=254;
if ($SCL_high>254) $SCL_high=254;
$i2c_slow_safe=array($SCL_low ,$SCL_high,2,2,7,7); /// sensor i2c delays are 2,2,1,1,7,7
return $i2c_slow_safe;
}
///Map i2c bus of 393 to "old" one
function i2c_bus353($bus){
if ($bus<4) return 0;
else return $bus-3;
}
function i2c_ctl($bus,$data="") { //!$data - string of decimal values separated by ":", empty - don't change
$size=6; // bytes per bus
$data=trim($data);
if ($data!="") {
$darr=explode(":",$data);
$i2cctl = fopen('/dev/xi2cctl', 'w');
for ($i=0; ($i<$size) && ($i<count($darr)); $i++) if ($darr[$i]!=""){
fseek ($i2cctl, i2c_bus353($bus)*$size+$i) ;
fwrite($i2cctl, chr($darr[$i]+0), 1);
}
fclose($i2cctl);
}
$i2cctl = fopen('/dev/xi2cctl', 'r');
fseek ($i2cctl, i2c_bus353($bus)*$size) ;
$data = fread($i2cctl, $size);
fclose($i2cctl);
$xml = new SimpleXMLElement("<?xml version='1.0'?><i2cctl/>");
$xml->addChild ('scl_high',ord($data[0]));
$xml->addChild ('scl_low', ord($data[1]));
$xml->addChild ('slave2master', ord($data[2]));
$xml->addChild ('master2slave', ord($data[3]));
$xml->addChild ('filter_sda', ord($data[4]));
$xml->addChild ('filter_scl', ord($data[5]));
// $data=$xml->asXML();
return $xml;
} // end of i2c_ctl()
function i2c_ctl_arr($bus,$darr=array()) { //!$data - 6-element array
$size=6; // bytes per bus
if (count($darr)>00) {
$i2cctl = fopen('/dev/xi2cctl', 'w');
for ($i=0; ($i<$size) && ($i<count($darr)); $i++) if ($darr[$i]!=""){
fseek ($i2cctl, i2c_bus353($bus)*$size+$i) ;
fwrite($i2cctl, chr($darr[$i]+0), 1);
}
fclose($i2cctl);
}
$i2cctl = fopen('/dev/xi2cctl', 'r');
fseek ($i2cctl, i2c_bus353($bus)*$size) ;
$data = fread($i2cctl, $size);
fclose($i2cctl);
for ($i=0;$i<$size; $i++) $darr[$i]=ord($data[$i]);
return $darr;
} // end of i2c_ctl()
function i2c_send($width, $bus, $a, $d, $raw = 0) { // $a<0 - use raw read/write
if ($bus < 4)
return i2c_send_sensor ( $width, $bus, $a, $d, $raw );
else
$bus = i2c_bus353 ( $bus );
$bus353 = i2c_bus353 ( $bus );
$w = ($width == 16) ? 2 : 1;
$i2c_fn = '/dev/xi2c' . ($raw ? 'raw' : (($w == 2) ? '16' : '8')) . (($bus == 0) ? '' : '_aux');
$i2c = fopen ( $i2c_fn, 'w' );
fseek ( $i2c, $w * $a );
if ($w == 1)
$res = fwrite ( $i2c, chr ( $d ) );
else
$res = fwrite ( $i2c, chr ( floor ( $d / 256 ) ) . chr ( $d - 256 * floor ( $d / 256 ) ) );
fclose ( $i2c );
return $res;
} // end of i2c_send()
function i2c_send_slow($width, $bus, $a, $d, $raw = 0, $extrausec = -1) { // $a<0 - use raw read/write
if ($bus < 4)
return i2c_send_sensor ( $width, $bus, $a, $d, $raw );
else
$bus = i2c_bus353 ( $bus );
if (($bus == 0) && ($extrausec >= 0)) {
$i2c_old_ctrl = i2c_ctl_arr ( 0 );
i2c_ctl_arr ( 0, getSlowArray ( $extrausec ) );
}
$w = ($width == 16) ? 2 : 1;
$i2c_fn = '/dev/xi2c' . ($raw ? 'raw' : (($w == 2) ? '16' : '8')) . (($bus == 0) ? '' : '_aux');
$i2c = fopen ( $i2c_fn, 'w' );
fseek ( $i2c, $w * $a );
if ($w == 1)
$res = fwrite ( $i2c, chr ( $d ) );
else
$res = fwrite ( $i2c, chr ( floor ( $d / 256 ) ) . chr ( $d - 256 * floor ( $d / 256 ) ) );
fclose ( $i2c );
if (($bus == 0) && ($extrausec >= 0)) {
i2c_ctl_arr ( 0, $i2c_old_ctrl ); // / restore old speed (not thread-safe)
}
return $res;
} // end of i2c_send()
function smbus_send($a, $d) { // d - array
$i2c_fn = '/dev/xi2c8_aux';
$i2c = fopen ( $i2c_fn, 'w' );
fseek ( $i2c, $a );
$cmd = chr ( count ( $d ) );
foreach ( $d as $b )
$cmd .= chr ( $b );
// var_dump($cmd);
$res = fwrite ( $i2c, $cmd );
fclose ( $i2c );
return $res;
} // end of i2c_send()
function i2c_receive($width, $bus, $a, $raw = 0) {
if ($bus < 4)
return i2c_receive_sensor ( $width, $bus, $a, $raw );
else
$bus = i2c_bus353 ( $bus );
$w = ($width == 16) ? 2 : 1;
$i2c_fn = '/dev/xi2c' . ($raw ? 'raw' : (($w == 2) ? '16' : '8')) . (($bus == 0) ? '' : '_aux');
$i2c = fopen ( $i2c_fn, 'r' );
fseek ( $i2c, $w * $a );
$data = fread ( $i2c, $w );
fclose ( $i2c );
if (strlen ( $data ) < $w)
return - 1;
$v = unpack ( ($w == 1) ? 'C' : 'n1', $data );
return $v [1];
} // end of i2c_receive()
function i2c_receive_slow($width, $bus, $a, $raw = 0, $extrausec = -1) {
if ($bus < 4)
return i2c_receive_sensor ( $width, $bus, $a, $raw );
else
$bus = i2c_bus353 ( $bus );
if (($bus == 0) && ($extrausec >= 0)) {
$i2c_old_ctrl = i2c_ctl_arr ( 0 );
i2c_ctl_arr ( 0, getSlowArray ( $extrausec ) );
}
$w = ($width == 16) ? 2 : 1;
$i2c_fn = '/dev/xi2c' . ($raw ? 'raw' : (($w == 2) ? '16' : '8')) . (($bus == 0) ? '' : '_aux');
$i2c = fopen ( $i2c_fn, 'r' );
fseek ( $i2c, $w * $a );
$data = fread ( $i2c, $w );
fclose ( $i2c );
if (strlen ( $data ) < $w)
return - 1;
$v = unpack ( ($w == 1) ? 'C' : 'n1', $data );
if ($bus == 0) {
i2c_ctl_arr ( 0, $i2c_old_ctrl ); // / restore old speed (not thread-safe)
}
return $v [1];
} // end of i2c_receive()
function i2c_setprot($bus, $slave, $bit, $value) { // !slave is MSB aligned, LSB==0)
$bus = i2c_bus353 ( $bus );
$i2cprot = fopen ( "/dev/xi2cenable", 'r+' );
fseek ( $i2cprot, ($bus * 128) + ($slave >> 1) );
$data = ord ( fread ( $i2cprot, 1 ) );
if ($value)
$data |= (1 << $bit);
else
$data &= ~ (1 << $bit);
fseek ( $i2cprot, ($bus * 128) + ($slave >> 1) );
fwrite ( $i2cprot, chr ( $data ) );
fclose ( $i2cprot );
} // end of i2c_setprot ()
function i2c_getCMOSClock() {
echo "**** FUNCTION NOT SUPPORTED in NC393 *****";
return - 1;
$i2c = fopen ( '/dev/xi2c8_aux', 'r' );
fseek ( $i2c, 0x5102 ); // seconds in clock on the 10369 board
$data = fread ( $i2c, 7 ); // sec/min/hours/days/weekdays/century-months/years, BCD
fclose ( $i2c );
if (strlen ( $data ) < 7)
return "error";
$v = unpack ( 'C*', $data );
$d = array (
"sec" => ($v [1] & 0xf) + 10 * (($v [1] >> 4) & 0x7),
"min" => ($v [2] & 0xf) + 10 * (($v [2] >> 4) & 0x7),
"hrs" => ($v [3] & 0xf) + 10 * (($v [3] >> 4) & 0x3),
"day" => ($v [4] & 0xf) + 10 * (($v [4] >> 4) & 0x3),
"wday" => $v [5] & 0x7,
"month" => ($v [6] & 0xf) + 10 * (($v [6] >> 4) & 0x1),
"year" => ($v [7] & 0xf) + 10 * (($v [7] >> 4) & 0xf) + (($v [6] & 0x80) ? 2000 : 1900)
);
exec ( "date -s " . sprintf ( "%02d%02d%02d%02d%04d.%02d", $d ["month"], $d ["day"], $d ["hrs"], $d ["min"], $d ["year"], $d ["sec"] ), $out, $ret );
if ($ret == 0) {
elphel_set_fpga_time ( time () + 0.0 );
}
return $ret;
} // end of i2c_getCMOSClock()
function i2c_bcd($v) {
$d=intval($v,10);
return $d + 6*floor($d/10);
} // end of i2c_bcd($v)
function i2c_setCMOSClock(){
$ts=time();
$data=chr(i2c_bcd(gmdate("s",$ts))).
chr(i2c_bcd(gmdate("i",$ts))).
chr(i2c_bcd(gmdate("H",$ts))).
chr(i2c_bcd(gmdate("d",$ts))).
chr(i2c_bcd(gmdate("w",$ts))).
chr(i2c_bcd(gmdate("m",$ts))+ ((intval(gmdate("Y",$ts),10)>=2000)?0x80:0)).
chr(i2c_bcd(gmdate("y",$ts)));
$i2c = fopen('/dev/xi2c8_aux', 'w');
fseek ($i2c, 0x5102) ; //seconds in clock on the 10369 board
$written= fwrite($i2c, $data);
fclose($i2c);
if ($written < strlen($data)) return "error";
return "OK";
} // end of i2c_setCMOSClock()
function i2c_read256b($slave=0xa0,$bus=1,$extrausec=0) { //will read 256 bytes from slave (address is 8-bit, includes r/~w)
if ($bus < 4)
return i2c_read256b_sensor ( $slave, $bus, $extrausec); // ($name, $sensor_port, $sa7_offset)
else
$bus = i2c_bus353 ( $bus );
if (($bus==0) && ($extrausec>=0)){
$i2c_old_ctrl= i2c_ctl_arr(0);
i2c_ctl_arr(0,getSlowArray($extrausec));
}
$i2c_fn='/dev/xi2c8'.(($bus==0)?'':'_aux');
$i2c = fopen($i2c_fn, 'r');
fseek ($i2c, $slave*128) ; //256 per slave, but slave are only even
$data = fread($i2c, 256); // full 256 bytes
fclose($i2c);
if (($bus==0) && ($extrausec>=0)){
i2c_ctl_arr(0,$i2c_old_ctrl); /// restore old speed (not thread-safe)
}
return $data;
} // end of i2c_read256b ()
//this EEPROM writes only 4 bytes sequentionally (only 2 LSBs are incremented)
function i2c_write256b($data, $slave=0xa0,$bus=1,$extrausec=0) { //will write up to 256 bytes $data to slave (address is 8-bit, includes r/~w). EEPROM should be un-protected
if ($bus < 4)
return i2c_write256b_sensor ($data, $slave, $bus, $extrausec); // ($data, $name, $sensor_port, $sa7_offset)
else
$bus = i2c_bus353 ( $bus );
if (($bus==0) && ($extrausec>=0)){
$i2c_old_ctrl= i2c_ctl_arr(0);
i2c_ctl_arr(0,getSlowArray($extrausec));
}
$maxretries=200; //measured - 19
if (!is_string($data)) return -1;
if (strlen($data)>256) return -2;
if (strlen($data)<256) $data.=chr(0);
$i2c_fn='/dev/xi2c8'.(($bus==0)?'':'_aux');
$i2c = fopen($i2c_fn, 'w');
$len=0;
for ($i=0;$i<strlen($data); $i+=4) {
for ($retry=0; $retry< $maxretries; $retry++) {
fseek ($i2c, $slave*128+$i) ; //256 per slave, but slave are only even
$rslt=fwrite($i2c, substr($data,$i,4));
if ($rslt>0) break;
}
if ($rslt<=0) {
$len=$rslt;
break;
}
$len+=$rslt;
}
fclose($i2c);
if (($bus==0) && ($extrausec>=0)){
i2c_ctl_arr(0,$i2c_old_ctrl); /// restore old speed (not thread-safe)
}
return $len;
} // end of i2c_write256b ()
?>
<?php
/*!***************************************************************************
*! FILE NAME : show_source.inc
*! DESCRIPTION: Outputs program source code if url has 'source' parameter.
*! Copyright (C) 2012 Elphel, Inc
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (array_key_exists('source',$_GET)) {
$source=file_get_contents ($_SERVER['SCRIPT_FILENAME']);
header("Content-Type: text/php");
header("Content-Length: ".strlen($source)."\n");
header("Pragma: no-cache\n");
echo $source;
exit(0);
}
if (array_key_exists('help',$_GET)) {
if (function_exists('_help')) {
_help();
exit(0);
}
}
if (count($_GET)==0) {
if (function_exists('_usage')) {
_usage();
exit(0);
}
}
?>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment