Commit 6ca736b9 authored by Mikhail Karpenko's avatar Mikhail Karpenko

Add unmodified 103697.php script for crosspoint switch control

parent 2000e7a4
VERILOGDIR= $(DESTDIR)/usr/local/verilog
INSTALLDIR= $(DESTDIR)/usr/local/bin
WWW_PAGES = $(DESTDIR)/www/pages
SCRIPTPATH= py393sata
OWN = -o root -g root
......@@ -8,6 +9,7 @@ INSTMODE = 0755
DOCMODE = 0644
PYTHON_EXE = $(SCRIPTPATH)/*.py
PHP_EXE = $(SCRIPTPATH)/*.php
FPGA_BITFILES = x393_sata.bit
all:
......@@ -16,9 +18,11 @@ install:
@echo "make install in x393sata"
$(INSTALL) $(OWN) -d $(VERILOGDIR)
$(INSTALL) $(OWN) -d $(INSTALLDIR)
$(INSTALL) $(OWN) -d $(WWW_PAGES)
$(INSTALL) $(OWN) -m $(INSTMODE) $(PYTHON_EXE) $(INSTALLDIR)
$(INSTALL) $(OWN) -m $(DOCMODE) $(FPGA_BITFILES) $(VERILOGDIR)
$(INSTALL) $(OWN) -m $(INSTMODE) $(PHP_EXE) $(WWW_PAGES)
clean:
@echo "make clean in x393sata"
\ No newline at end of file
<?php
/*!*******************************************************************************
*! FILE NAME : x393_vsc330x.php
*! DESCRIPTION: web interface for VSC3304 crosspoint switch in 393 camera
*! Copyright (C) 2012 - 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/>.
*! -----------------------------------------------------------------------------**
*/
require 'i2c.inc';
include 'show_source.inc';
$debug=false;
$BUS=1; // 1 - 10369, 0 - 10359 (sensor)
$slaveAddrVCS3312= 0x2d;
$i2c_Page_Connection= 0x00; // When written to $i2c_CurrentPage, makes registers 0..0xf control corresponding output (0..0xf) source (input number)
// bit 4 (+0x10) - turn output off, bits 3:0 - source
$i2c_Page_InputISE= 0x10; // When written to $i2c_CurrentPage, makes registers 0..0xf control corresponding input (0..0xf) ISE (equalization):
// Bits 5:4 ISE short: 0 - off, 1 - minimal, 2 - moderate, 3 - maximal; bits 3:2 ISE medium, bits 1:0 ISE Long time constant
$i2c_Page_InputState= 0x11; // When written to $i2c_CurrentPage, makes registers 0..0xf control corresponding input (0..0xf) enable, polarity and termination (default 6)
// Bit 2 (+4) Terminate to VDD ( 0 - connect, 1 - do not connect) - dedicated (0..7) inputs only
// Bit 1 (+2) Input power (0 - on, 1 - off)
// Bit 0 (+1) Invert signal at input
///$i2c_InputStateData= 0x04; // terminated,enabled, not inverted
$i2c_InputStateData= 0x00; // terminated,disabled, not inverted
$i2c_Page_InputLOS= 0x12; // When written to $i2c_CurrentPage, makes registers 0..0xf control corresponding input (0..0xf) LOS (loss of signal) threshold
// Bits 2:0 - level in mV for dedicated(bidirectional) inputs: 0,1,6,7 - unused, 2 - 150(170), 3 - 200(230), 4 - 250(280), 5 - 300(330)
$i2c_Page_OutputPreLong= 0x20; // When written to $i2c_CurrentPage, makes registers 0..0xf control corresponding output (0..0xf) long time constant pre-emphasis
// Bits 6:3 Pre-Emphasis level (0x0 - off, 0x1 - min, 0xf - max - 0..6dB), bits 2:0 - Pre-emphasis decay (0x0 - fastest, 0x7 - slowest) in 500..1500 ps range
$i2c_Page_OutputPreShort= 0x21; // When written to $i2c_CurrentPage, makes registers 0..0xf control corresponding output (0..0xf) short time constant pre-emphasis
// Bits 6:3 Pre-Emphasis level (0x0 - off, 0x1 - min, 0xf - max - 0..6dB), bits 2:0 - Pre-emphasis decay (0x0 - fastest, 0x7 - slowest) in 30..500 ps range
$i2c_Page_OutputLevel= 0x22; // When written to $i2c_CurrentPage, makes registers 0..0xf control corresponding output (0..0xf) short time constant pre-emphasis
// Bits 3:0 - peak-to-peak 0,1,0xe,0xf - unused, 0x2-405mV,0x3-425V,0x4-455mV,0x5-485mV,0x6-520mV,0x7-555mV,0x8-605mV,0x9-655mV,0xa-720mV,0xb-790mV,0xc-890mV,0xd-990mV (+3.3VDC required)
// bit 4 (+0x10) - for 8-15 used as inputs only: terminate inputs 8..15 to VDDIO-0.7V
$i2c_Page_OutputState= 0x23; // When written to $i2c_CurrentPage, makes registers 0..0xf control corresponding output (0..0xf) OOB signaling and output polarity
// bits 4:1 - operation mode: 0xa - inverted, 0x5 - normal, 0x0 - suppressed
// bit 0 - OOB control: 1 - enable LOS forwarding, 0 - ignore LOS
$i2c_Page_ChannelStatus= 0xf0; // When written to $i2c_CurrentPage, makes registers 0..0xf monitor corresponding input (0..0xf) LOS status
// bit 0 - LOS status: 1 - LOS detected (loss of signal), 0 - signal present (input has to be enabled, otherwise 0 is read)
// when reading from address 0x10 of this page:
// bit 0 - value of STAT0
// bit 1 - value of STAT1
$i2c_Page_Status0Configure=0x80; // When written to $i2c_CurrentPage, makes registers 0..0xf control selected input LOS to be OR-ed to STAT0 output pin (and bit)
// bit 0 : 1 - OR this input channel LOS status to STAT0
$i2c_Page_Status1Configure=0x81; // When written to $i2c_CurrentPage, makes registers 0..0xf control selected input LOS to be OR-ed to STAT1 output pin (and bit)
// bit 0 : 1 - OR this input channel LOS status to STAT1
$i2c_GlobalConnection= 0x50; // Bit 4 (+0x10) - disable all outputs, bits 3:0 - input number to connect to all outputs
$i2c_GlobalInputISE= 0x51; // Bits 5:4 ISE short: 0 - off, 1 - minimal, 2 - moderate, 3 - maximal; bits 3:2 ISE medium, bits 1:0 ISE Long time constant
$i2c_GlobalInputState= 0x52; // Bit 2 (+4) - terminate input to VDD (0..7 only) 0-connect, 1 Normal; Bit 1 (+2) Input power off (0 - On, 1 - Off) bit0 (+1): Input polarity: 1 - inverted, 0 - normal
$i2c_GlobalInputLOS= 0x53; // Bits 2:0 - level in mV for dedicated(bidirectional) inputs: 0,1,6,7 - unused, 2 - 150(170), 3 - 200(230), 4 - 250(280), 5 - 300(330)
$i2c_GlobalOutputPreLong= 0x54; // Bits 6:3 Pre-Emphasis level (0x0 - off, 0x1 - min, 0xf - max - 0..6dB), bits 2:0 - Pre-emphasis decay (0x0 - fastest, 0x7 - slowest) in 500..1500 ps range
$i2c_GlobalOutputPreShort= 0x55; // Bits 6:3 Pre-Emphasis level (0x0 - off, 0x1 - min, 0xf - max - 0..6dB), bits 2:0 - Pre-emphasis decay (0x0 - fastest, 0x7 - slowest) in 30..500 ps range
$i2c_GlobalOutputLevel= 0x56; // Bits 3:0 - peak-to-peak 0,1,0xe,0xf - unused, 0x2-405mV,0x3-425V,0x4-455mV,0x5-485mV,0x6-520mV,0x7-555mV,0x8-605mV,0x9-655mV,0xa-720mV,0xb-790mV,0xc-890mV,0xd-990mV (+3.3VDC required)
// bit 4 (+0x10) terminate inputs 8..15 to VDDIO-0.7V
$i2c_GlobalOutputState= 0x57; // +1 (bit 0) - LOS, +0x15 - inverted, 0xa0 - normal, +0 - "Common mode" ?
$i2c_GlobalOutputStateData=0x0b; // No inversion, enable OOB forwarding on all channels
$i2c_Status0= 0x58; // Bit 0 - selected for Status0 chanel LOS on
$i2c_Status1= 0x59; // Bit 0 - selected for Status1 chanel LOS on // Which channel LOS to show on Status1 output/bit
$i2c_CoreConfiguration= 0x75;
$i2c_CoreConfigurationData= 0x18; // default 0x18 - 0x10 - leftEn, 0x8 - rightEn, 0x4 - DNU, 0x2 - BufferForceOn, 0x1 - Config polarity
$i2c_CoreConfigurationDataF=0x19; // default with inverted Config polarity (freeze update)
$i2c_SlaveAddress= 0x78; // programmed only, not hardwired
$i2c_InterfaceMode= 0x79;
$i2c_InterfaceModeData= 0x02; // i2c (1 - 4-wire)
$i2c_SoftwareReset= 0x7a;
$i2c_SoftwareResetData= 0x10; // to reset, 0 - normal
$i2c_CurrentPage= 0x7f;
$connections=array(); // pairs, first index< second
$channels=array(
array('in'=>10, 'out'=> 3, 'name'=>'host1', 'connector'=> 1),
array('in'=> 3, 'out'=>10, 'name'=>'host2', 'connector'=> 2),
array('in'=> 0, 'out'=> 5, 'name'=>'host3', 'connector'=> 3),
array('in'=> 4, 'out'=> 4, 'name'=>'host4', 'connector'=> 4),
array('in'=> 9, 'out'=> 0, 'name'=>'host5', 'connector'=> 5),
array('in'=> 7, 'out'=> 9, 'name'=>'host6', 'connector'=> 6),
array('in'=>11, 'out'=> 1, 'name'=>'ssd1', 'connector'=> 7),
array('in'=> 8, 'out'=> 6, 'name'=>'ssd2', 'connector'=> 8),
array('in'=> 5, 'out'=>11, 'name'=>'ssd3', 'connector'=> 9),
array('in'=> 2, 'out'=> 2, 'name'=>'ssd4', 'connector'=>10),
array('in'=> 1, 'out'=> 8, 'name'=>'ssd5', 'connector'=>11));
//echo "<pre>\n";
$numHosts=6;
if (count($_GET)==0){
showUsage();
exit (0);
}
$debug= isset($_GET['debug']);
$init= !isset($_GET['noinit']); // default - on
$dry= isset($_GET['dry']); // dry run, no actual programming over i2c
$error=false;
$port_ise = array(); //-1=>'','','','','','','','','','','','',''); // -1(all),0..11
$port_input_state= array(); //-1=>'','','','','','','','','','','','',''); // -1(all),0..11
$port_los= array(); //-1=>'','','','','','','','','','','','',''); // -1(all),0..11
$port_pre_long= array(); //-1=>'','','','','','','','','','','','',''); // -1(all),0..11
$port_pre_short= array(); //-1=>'','','','','','','','','','','','',''); // -1(all),0..11
$port_out_level= array(); //-1=>'','','','','','','','','','','','',''); // -1(all),0..11
$port_out_state= array(); //-1=>'','','','','','','','','','','','',''); // -1(all),0..11
$port_channel_status=array(); // read only - 1 - LOS
$port_channel_input= array(); // read current connections (number of input or "-1" - disabled
if ($init) {
$port_ise[-1]= array('short'=>0,'medium'=>0,'long'=>0);
// $port_input_state[-1]= array('terminate'=>1,'invert'=>0); // change to no termination?
$port_input_state[-1]= array('terminate'=>0,'invert'=>0); // change to no termination?
$port_los[-1]= array('level'=>4); // 250 mv
$port_pre_long[-1]= array('level'=>0,'decay'=>0);
$port_pre_short[-1]= array('level'=>0,'decay'=>0);
$port_out_level[-1]= array('level'=>6);
$port_out_state[-1]= array('mode'=>5,'oob'=>1);
}
$SA=$slaveAddrVCS3312<<8;
foreach ($_GET as $cmdkey=>$value) {
if (strpos($key,":" )>=0){
$command=strtok($cmdkey,":");
$key= strtok(":");
} else {
$command="";
$key=$cmdkey;
}
$port= parsePort($key);
$inPort= parseInPort($key);
$outPort= parseOutPort($key);
if ($debug) {
echo "<!--$command:$key=$value -->\n";
}
switch (strtoupper($command)) {
// case '':
case 'S':
case 'STATE':
echo <<<EOT
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>SATA Multiplexer Current State</title>
</head>
<body>
EOT;
readCurrentState(); // outputs comments, so <head> should be before it
showCurrentStateHTML();
echo "</body>\n";
exit(0);
case 'CONNECTION':
case 'CON':
case 'C':
$pair=array($port,parsePort($value));
sort($pair);
// print_r($pair);
if (($pair[0]>=0) &&
($pair[0]<$numHosts) &&
($pair[1]>=$numHosts) &&
($pair[1]<count($channels))) {
// remove duplicate IO-s
$duplicateIO=false;
foreach ($connections as $connection) if (($connection[0]==$pair[0]) || ($connection[1]==$pair[1])){
$duplicateIO=true;
break;
}
if (!$duplicateIO) $connections[count($connections)]=$pair;
else {
echo "Duplicate connection for ".$key.": \n";
print_r($pair);
echo "Current connections:\n";
print_r($connections);
}
}
break;
case 'ISE':
$aval=getMultiVals($value);
if (count($aval)!=3) {
echo "Value for the ISE (input signal equalization) command is expected to be short_value:medium_value:long_value, got >$value<\n";
$error =true;
exit (1);
}
$this_ise=array('short'=>$aval[0],'medium'=>$aval[1],'long'=>$aval[2]);
if (($inPort>=-1) && ($port<12)) $port_ise[$inPort]=$this_ise;
else {
echo "Invalid input port index=$inPort\n";
$error =true;
exit (1);
}
if ($debug) {
}
break;
case 'IN_STATE':
$aval=getMultiVals($value);
if (count($aval)!=2) {
echo "Value for the IN_STATE (input state) command is expected to be terminate_to_VCC:invert, got >$value<\n";
$error =true;
exit (1);
}
$this_input_state=array('terminate'=>$aval[0],'invert'=>$aval[1]);
if (($inPort>=-1) && ($port<12)) $port_input_state[$inPort]=$this_input_state;
else {
echo "Invalid input port index=$inPort\n";
$error =true;
exit (1);
}
if ($debug) {
}
break;
case 'LOS':
$aval=getMultiVals($value);
if ((count($aval)!=1) || ($aval[0]<0) || ($aval[0]>7)) {
echo "Value for the LOS (loss of signal) command is expected to be a 0..7 integer, got >$value<\n";
$error =true;
exit (1);
}
if (($inPort>=-1) && ($inPort<12)) $port_los[$inPort]=array('level'=>$aval[0]);
else {
echo "Invalid input port index=$inPort\n";
$error =true;
exit (1);
}
if ($debug) {
}
break;
case 'PRE_LONG':
$aval=getMultiVals($value);
if (count($aval)!=2) {
echo "Value for the PE_LONG (output pre-emphasis long time constant) command is expected to be pre_emphasis_level[0..15]:pre_emphasis_decay[0..7], got >$value<\n";
$error =true;
exit (1);
}
$this_pre_long=array('level'=>$aval[0],'decay'=>$aval[1]);
if (($outPort>=-1) && ($outPort<12)) $port_pre_long[$outPort]=$this_pre_long;
else {
echo "Invalid output port index=$outPort\n";
$error =true;
exit (1);
}
if ($debug) {
}
break;
case 'PRE_SHORT':
$aval=getMultiVals($value);
if (count($aval)!=2) {
echo "Value for the PE_SHORT (output pre-emphasis short time constant) command is expected to be pre_emphasis_level[0..15]:pre_emphasis_decay[0..7], got >$value<\n";
$error =true;
exit (1);
}
$this_pre_short=array('level'=>$aval[0],'decay'=>$aval[1]);
if (($outPort>=-1) && ($outPort<12)) $port_pre_short[$outPort]=$this_pre_short;
else {
echo "Invalid output port index=$outPort\n";
$error =true;
exit (1);
}
if ($debug) {
}
break;
//$port_out_level= array(-1=>array('level'=>6), '','','','','','','','','','','',''); // -1(all),0..11
case 'OUT_LEVEL':
$aval=getMultiVals($value);
if ((count($aval)!=1) || ($aval[0]<0) || ($aval[0]>15)) {
echo "Value for the OUT_LEVEL (output signal level) command is expected to be 0..15 value, got >$value<\n";
$error =true;
exit (1);
}
$this_out_level=array('level'=>$aval[0]);
if (($outPort>=-1) && ($outPort<12)) $port_out_level[$outPort]=$this_out_level;
else {
echo "Invalid output port index=$outPort\n";
$error =true;
exit (1);
}
if ($debug) {
}
break;
//$port_out_state= array(-1=>array('mode'=>5,'oob'=>1),'','','','','','','','','','','',''); // -1(all),0..11
case 'OUT_STATE':
$aval=getMultiVals($value);
if (count($aval)!=2) {
echo "Value for the OUT_STATE (output state) command is expected to be mode(10-inverted,5-normal,0-common mode):oob_forwarding, got >$value<\n";
$error =true;
exit (1);
}
$this_out_state=array('mode'=>$aval[0],'oob'=>$aval[1]);
if (($outPort>=-1) && ($outPort<12)) $port_out_state[$outPort]=$this_out_state;
else {
echo "Invalid output port index=$outPort\n";
$error =true;
exit (1);
}
if ($debug) {
}
break;
/*
*/
//$port_input_state
}
}
//print_r($connections);
//echo "</pre>\n";
if (isset($_GET['list']))listSettings();
$activeOutputs=array(false,false,false,false, false,false,false,false, false,false,false,false);
$activeInputs= array(false,false,false,false, false,false,false,false, false,false,false,false);
foreach ($connections as $connection){
$activeOutputs[$channels[$connection[0]]['out']]=true;
$activeOutputs[$channels[$connection[1]]['out']]=true;
$activeInputs [$channels[$connection[0]]['in']]= true;
$activeInputs [$channels[$connection[1]]['in']]= true;
}
if ($debug) {
echo "<!-- activeOutputs:\n";
print_r($activeOutputs);
echo "\nactiveInputs:\n";
print_r($activeInputs);
echo "\nISE (input signal equalization):\n";
print_r($port_ise);
echo "\nInput state:\n";
print_r($port_input_state);
echo "\nLOS (loss of signal thershold):\n";
print_r($port_los);
echo "\nPre-emphasis long:\n";
print_r($port_pre_long);
echo "\nPre-emphasis short:\n";
print_r($port_pre_short);
echo "\nOutput level:\n";
print_r($port_out_level);
echo "\nOutput state:\n";
print_r($port_out_state);
echo "-->\n";
}
//exit (0);
$outputLevel=6; // 520mV
if ($debug) echo '<!-- setting i2c mode (writing 0x'.dechex($i2c_InterfaceModeData).' to 0x'.dechex($SA | $i2c_InterfaceMode).' -->'."\n";
i2c_send_or_die($i2c_InterfaceMode,$i2c_InterfaceModeData); // set i2c mode
// turn off immediate configuration:
if ($debug) echo '<!-- freezing updates (writing 0x'.dechex($i2c_CoreConfigurationDataF).' to 0x'.dechex($SA | $i2c_CoreConfiguration).' -->'."\n";
i2c_send_or_die($i2c_CoreConfiguration,$i2c_CoreConfigurationDataF); // freeze updates
// program ISE
if ($debug) echo "<!-- program ISE -->\n";
if (isGlobalSet($port_ise)){
i2c_send_or_die( $i2c_GlobalInputISE,data_ise(-1));
}
if (isIndividualSet($port_ise)) {
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_InputISE);
for($index=0;$index<12;$index++) if (isset($port_ise[$index])){
i2c_send_or_die($index,data_ise($index));
}
}
// program InputState (program termination for inputs 8-11 during programming output
if ($debug) echo "<!-- program InputState -->\n";
$dflt_is=0;
if (isGlobalSet($port_input_state)){
$dflt_is=data_input_state(-1); // default may be specified even w/o init - it will apply to polarity and termination,
// for inputs that will be programmed anyway, not cause write to global register.
/// if ($init) i2c_send_or_die( $i2c_GlobalInputState,$dflt_is); // will disable all ports - resets current connection
}
// here we have to scan all inputs, disable/enable only in $init mode
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_InputState); // select page 0x11 ($i2c_Page_InputState)
$shared_input_termination=array();
for ($index=0;$index<12;$index++) {
$powerOn=$activeInputs[$index] || isset($port_input_state[$index]); // programming input implies it is on
$data=$dflt_is;
if (isset($port_input_state[$index])) $data=data_input_state($index);
$data&=5; // removing poweroff
if (!$powerOn) $data |=2;
// if (isGlobalSet($port_input_state) || $powerOn){
if ($init || $powerOn){
i2c_send_or_die($index, $data); // do not turn off in non-init mode
if ($index>=8) $shared_input_termination[$index]=(($data&4)==0); // true - terminate
}
}
if ($debug) echo "<!-- program LOS -->\n";
// program LOS
if (isGlobalSet($port_los)){
i2c_send_or_die( $i2c_GlobalInputLOS,data_port_los(-1));
}
if (isIndividualSet($port_los)) {
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_InputLOS);
for($index=0;$index<12;$index++) if (isset($port_los[$index])){
i2c_send_or_die($index,data_port_los($index));
}
}
if ($debug) echo "<!-- program pre-emphasis (long) -->\n";
// program pre-emphasis (long)
if (isGlobalSet($port_pre_long)){
i2c_send_or_die( $i2c_GlobalOutputPreLong,data_pre_long(-1));
}
if (isIndividualSet($port_pre_long)) {
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_OutputPreLong);
for($index=0;$index<12;$index++) if (isset($port_pre_long[$index])){
i2c_send_or_die($index,data_pre_long($index));
}
}
if ($debug) echo "<!-- program pre-emphasis (short) -->\n";
// if ($debug) {echo '<!-- port_pre_short'; print_r($port_pre_short); echo "-->\n";}
// program pre-emphasis (short)
if (isGlobalSet($port_pre_short)){
i2c_send_or_die( $i2c_GlobalOutputPreShort,data_pre_short(-1));
}
if (isIndividualSet($port_pre_short)) {
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_OutputPreShort);
for($index=0;$index<12;$index++) if (isset($port_pre_short[$index])){
i2c_send_or_die($index,data_pre_short($index));
}
}
// program output level and shared inputs (8..11) termination
if ($debug) echo "<!-- program output level -->\n";
// if ($debug) {echo '<!-- port_out_level'; print_r($port_out_level); echo "-->\n";}
if (isGlobalSet($port_out_level)){
i2c_send_or_die( $i2c_GlobalOutputLevel,data_out_level(-1));
}
if (isIndividualSet($port_out_level) ||
isset($shared_input_termination[ 8]) ||
isset($shared_input_termination[ 9]) ||
isset($shared_input_termination[10]) ||
isset($shared_input_termination[11])) {
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_OutputLevel);
for($index=0;$index<12;$index++) if (isset($port_out_level[$index])){
i2c_send_or_die($index,data_out_level($index));
}
// extra input termination
if ($debug) echo "<!-- program shared inputs termination -->\n";
for($index=8;$index<12;$index++) if (isset($shared_input_termination[$index])){
i2c_send_or_die($index+4,$shared_input_termination[$index]?0x10:0);
}
}
if ($debug) echo "<!-- program output state -->\n";
// program Output State
if (isGlobalSet($port_out_state)){
i2c_send_or_die( $i2c_GlobalOutputState,data_out_state(-1));
}
if (isIndividualSet($port_out_state)) {
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_OutputState);
for($index=0;$index<12;$index++) if (isset($port_out_state[$index])){
i2c_send_or_die($index,data_out_state($index));
}
}
if ($debug) echo "<!-- program connections($init) -->\n";
programConnections($init); // in init mode will disable unused outputs
if ($debug) echo '<!-- re-enabling updates (writing 0x'.dechex($i2c_CoreConfigurationData).' to 0x'.dechex($SA | $i2c_CoreConfiguration).' -->'."\n";
i2c_send_or_die( $i2c_CoreConfiguration,$i2c_CoreConfigurationData); // re-enable updates
exit(0);
function showUsage(){
$script_name=trim($_SERVER['SCRIPT_NAME'],'/');
$prefix_url='http://'.$_SERVER['SERVER_ADDR'].$_SERVER['SCRIPT_NAME'];
echo <<<EOT
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Usage of 103697A SATA multiplexer control interface ($script_name)</title>
</head>
<h2>Usage of $script_name:</h2>
<h3>Commands w/o parameters</h3>
<ul>
<li><i>list</i> - show settings to be programmed</li>
<li><i>debug</i> - output all I<sup>2</sup>C commands as HTML comments (visible with "view source")</li>
<li><i>dry</i> - "dry run" - simulation only, no I<sup>2</sup>C commands are sent to the device</li>
<li><i>noinit</i> - update only what is specified, do not disable unused i/o</li>
<li><i>state</i> - show current programmed state of the multiplexer</li>
<li><i><a href="$prefix_url?source">source</a></i> - show program source code (no other actions)</li>
</ul>
<h3>Commands with parameters</h3>
<p>All commands with parameters have format:</p>
<p><b>command:port=value</b>, where port can be specified in one of the following ways:</p>
<ul>
<li><i>numeric</i> - 0..11 specify I/O ports as specified for the VSC3312, "-1" means "all" (apply to all ports, lower precedence than specific ports)</li>
<li><i>J&lt;number&gt;</i> - using connector reference designators as on 103697A circuit diagram (i.e.J3, J10)</li>
<li><i>host&lt;number&gt;</i> - where number=1..6, with host1...host5 being 10353 (camera) boards and host6 - extrenal eSATA port</li>
<li><i>ssd&lt;number&gt;</i> - where number=1..5, with ssd1...ssd4 being SSD directly inserted into the 103697A board and ssd5 - optional extra one connected with a cable</li>
<li><i>global</i> or <i>all</i> - apply to all ports (not valid for "connection" command).</ul>
<br/>
<h4>connection:port1=port2<br/>c:port1=port2</h4>
<p>Connect two ports. The order of the ports is arbitrary, but one has be one of the hosts, and the other - one of the SSD. If <i>noinit</i> does not appear in the url, all unused inputs and outputs will be disabled to reduce power consumption.</p>
<br/>
<h4>ise:port=short_value:medium_value:long_value</h4>
<p>Configure ISE (input signal equalization) levels for short, medium and long time constants. Each value is in the range 0..3 (0- off, 1 - minimal, 2 - moderate, 3 - maximal)</p>
<br/>
<h4>in_state:port=terminate:invert</h4>
<p>Configure input port state. "terminate" (terminate input to VCC) can bne either 0 (off) or 1 (on), "invert" (also 0/1) control inversion of the input siognal polarity</p>
<br/>
<h4>los:port=level</h4>
<p>Configure input LOS (loss of signal) thershold level</p>
<table border="1">
<tr><th>level</th><th>threshold</th></tr>
<tr><td>0</td><td>---</td></tr>
<tr><td>1</td><td>---</td></tr>
<tr><td>2</td><td>150 mV</td></tr>
<tr><td>3</td><td>200 mV</td></tr>
<tr><td>4</td><td>250 mV</td></tr>
<tr><td>5</td><td>300 mV</td></tr>
<tr><td>6</td><td>---</td></tr>
<tr><td>7</td><td>---</td></tr>
</table>
<br/>
<h4>pre_long:port=level:decay</h4>
<p>Output pre-emphasis with 0.5ns-1.5ns decay, where. 4-bit level controls pre-emphasis amount from 0 (off) to 15 (6db), and decay - 3-bit decay, 0 corresponds to fastest (0.5ns) and 15 - slowest one (1.5ns).</p>
<br/>
<h4>pre_short:port=level:decay</h4>
<p>Output pre-emphasis with 0.03 ns-0.5 ns decay, where. 4-bit level controls pre-emphasis amount from 0 (off) to 15 (6db), and decay - 3-bit decay, 0 corresponds to fastest (0.03ns) and 15 - slowest one (0.5ns).</p>
<br/>
<h4>out_level:port=level</h4>
<p>Programs output power level - peak-to-peak differentioal voltage. These values have to be reduced when pre-emphasis is used as the actual signal adds the levels.</p>
<table border="1">
<tr><th>level</th><th>output voltage</th></tr>
<tr><td> 0</td><td>---</td></tr>
<tr><td> 1</td><td>---</td></tr>
<tr><td> 2</td><td>405 mV</td></tr>
<tr><td> 3</td><td>425 mV</td></tr>
<tr><td> 4</td><td>455 mV</td></tr>
<tr><td> 5</td><td>485 mV</td></tr>
<tr><td> 6</td><td>520 mv</td></tr>
<tr><td> 7</td><td>555 mv</td></tr>
<tr><td> 8</td><td>605 mv</td></tr>
<tr><td> 9</td><td>655 mv</td></tr>
<tr><td>10</td><td>720 mv</td></tr>
<tr><td>11</td><td>790 mv</td></tr>
<tr><td>12</td><td>890 mv</td></tr>
<tr><td>13</td><td>990 mv (no avail. in 103697A)</td></tr>
<tr><td>14</td><td>---</td></tr>
<tr><td>15</td><td>---</td></tr>
</table>
<br/>
<h4>out_state:port=mode:oob_forwarding</h4>
<p>Controls output inversion and OOB forwarding.'oob' of 1 enables, 0 - disables OOB forwarding and 'mode' can be one of</p>
<table border="1">
<tr><th>mode</th><th>Descrtiption</th></tr>
<tr><td>0</td><td>disabled</td></tr>
<tr><td>5</td><td>non-inverted</td></tr>
<tr><td>10</td><td>inverted</td></tr>
</table>
EOT;
}
function readCurrentState(){
global $debug, $i2c_InterfaceMode,$i2c_InterfaceModeData,$SA;
global $i2c_CurrentPage,$activeInputs,$activeOutputs;
global $port_ise,$port_input_state,$port_los,$port_pre_long,$port_pre_short,$port_out_level;
global $port_out_state,$port_channel_status,$port_channel_input;
global $i2c_Page_InputISE, $i2c_Page_InputState,$i2c_Page_InputLOS,$i2c_Page_OutputPreLong,$i2c_Page_OutputPreShort;
global $i2c_Page_OutputLevel, $i2c_Page_OutputState,$i2c_Page_ChannelStatus,$i2c_Page_Connection;
if ($debug) echo '<!-- setting i2c mode (writing 0x'.dechex($i2c_InterfaceModeData).' to 0x'.dechex($SA | $i2c_InterfaceMode).' -->'."\n";
i2c_send_or_die($i2c_InterfaceMode,$i2c_InterfaceModeData); // set i2c mode
// Read ISE
if ($debug) echo "<!-- reading ISE -->\n";
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_InputISE);
for($index=0;$index<12;$index++) {
$data=i2c_get_or_die($index);
if ($debug) echo "<!-- [".$index."] => ".$data." -->\n";
$port_ise[$index]=array(
'short'=>($data>>4)&3,
'medium'=>($data>>2)&3,
'long'=>($data)&3);
}
// Read InputState (program termination for inputs 8-11 during programming output
if ($debug) echo "<!-- read InputState -->\n";
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_InputState); // select page 0x11 ($i2c_Page_InputState)
for ($index=0;$index<12;$index++) {
$data=i2c_get_or_die($index);
if ($debug) echo "<!-- [".$index."] => ".$data." -->\n";
$activeInputs[$index]=($data & 2) == 0;
$port_input_state[$index]= array(
'terminate'=>((($data>>2)&1)==0)?1:0,
'invert'=> ($data )&1);
}
// read LOS
if ($debug) echo "<!-- read LOS -->\n";
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_InputLOS);
for($index=0;$index<12;$index++) {
$data=i2c_get_or_die($index);
if ($debug) echo "<!-- [".$index."] => ".$data." -->\n";
$port_los[$index]= array('level'=>$data);
}
// read pre-emphasis (long)
if ($debug) echo "<!-- read pre-emphasis (long) -->\n";
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_OutputPreLong);
for($index=0;$index<12;$index++) {
$data=i2c_get_or_die($index);
if ($debug) echo "<!-- [".$index."] => ".$data." -->\n";
$port_pre_long[$index]= array(
'level'=>($data>>3)&0x0f,
'decay'=> $data & 7);
}
// read pre-emphasis (short)
if ($debug) echo "<!-- read pre-emphasis (short) -->\n";
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_OutputPreShort);
for($index=0;$index<12;$index++) {
$data=i2c_get_or_die($index);
if ($debug) echo "<!-- [".$index."] => ".$data." -->\n";
$port_pre_short[$index]= array(
'level'=>($data>>3)&0x0f,
'decay'=> $data & 7);
}
// program output level and shared inputs (8..11) termination
if ($debug) echo "<!-- read output level -->\n";
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_OutputLevel);
for($index=0;$index<12;$index++) {
$data=i2c_get_or_die($index);
if ($debug) echo "<!-- [".$index."] => ".$data." -->\n";
$port_out_level[$index]= array(
'level'=>$data& 0x0f);
if ($index>=8){
$data=i2c_get_or_die($index+4);
if ($debug) echo "<!-- [".($index+4)."] => ".$data." -->\n";
$port_input_state[$index]['terminate']=(($data & 0x10)==0)?0:1;
}
}
// read Output State
if ($debug) echo "<!-- read output state -->\n";
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_OutputState);
for($index=0;$index<12;$index++) {
$data=i2c_get_or_die($index);
if ($debug) echo "<!-- [".$index."] => ".$data." -->\n";
$port_out_state[$index]= array(
'mode'=>($data>>1)& 0x0f,
'oob'=> $data & 1);
}
// read Channel Status
if ($debug) echo "<!-- read channel status -->\n";
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_ChannelStatus);
for($index=0;$index<12;$index++) {
$data=i2c_get_or_die($index);
if ($debug) echo "<!-- [".$index."] => ".$data." -->\n";
$port_channel_status[$index]= array(
'los'=> $data & 1);
}
// Read connections
if ($debug) echo "<!-- read connections -->\n";
i2c_send_or_die($i2c_CurrentPage,$i2c_Page_Connection);
for($index=0;$index<12;$index++) {
$data=i2c_get_or_die($index);
if ($debug) echo "<!-- [".$index."] => ".$data." -->\n";
$port_channel_input[$index]= array(
'input'=> (($data & 0x10)==0)?($data & 0x0f):-1);
$activeOutputs[$index]=($data & 0x10)==0;
}
}
// TODO: add XML version
function values_los_dedicated($index){
$values =array(
'invalid', // 0
'invalid', // 1
'150 mV', // 2
'200 mV', // 3
'250 mV', // 4