...
 
Commits (53)
......@@ -21,18 +21,33 @@
<builder arguments="web-393" command="${workspace_loc:/elphel-web-393/scripts/run_bitbake.sh}" enableCleanBuild="false" enabledIncrementalBuild="true" id="org.eclipse.cdt.build.core.settings.default.builder.365026764" incrementalBuildTarget="-c install -f" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder" />
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.785882741" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs" />
<tool id="org.eclipse.cdt.build.core.settings.holder.982996495" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.772251241" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__arm__=1" />
</option>
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.8554647" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType" />
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.480226500" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.994702313" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__arm__=1" />
</option>
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1347472659" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType" />
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.1686385332" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.1940520547" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__arm__=1" />
</option>
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.716913472" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType" />
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.559915258" name="LLVM bytecode assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.1625690961" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__arm__=1" />
</option>
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1886099197" languageId="org.eclipse.cdt.managedbuilder.llvm.ui.llvmAssembly" languageName="LLVM bytecode assembly" sourceContentType="org.eclipse.cdt.managedbuilder.llvm.ui.llvmAssemblySource" superClass="org.eclipse.cdt.build.core.settings.holder.inType" />
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.1960214219" name="UPC" superClass="org.eclipse.cdt.build.core.settings.holder">
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.1302332589" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__arm__=1" />
</option>
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1593701683" languageId="org.eclipse.cdt.core.parser.upc.upc" languageName="UPC" sourceContentType="org.eclipse.cdt.core.parser.upc.upcSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType" />
</tool>
</toolChain>
......@@ -60,4 +75,5 @@
<resource resourceType="PROJECT" workspacePath="/elphel-web-393" />
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets" />
</cproject>
\ No newline at end of file
......@@ -2,8 +2,10 @@ DOCUMENTROOT=$(DESTDIR)/www/pages
OWN = -o root -g root
INSTDOCS = 0644
INSTALL = install
DOCS= index.html \
index.php
DOCS= img.html \
index.html \
index.php \
mjpeg.html
all:
@echo "make all in src"
......
<html>
<head>
<style>
body {
margin: 0px;
}
#cnv_div {
border: 0px solid red;
}
#display{
height: 100%;
}
</style>
</head>
<body>
<div id='cnv_div'></div>
<script src="js/elphel.js"></script>
<script src="js/UTIF.js"></script>
<script src="js/jquery-3.1.1.js"></script>
<script src="js/jcanvas.js"></script>
<script src="js/exif.js"></script>
<script src="js/jquery-jp4.js"></script>
<script>
const IMGSRV_PORT0 = 2323;
const params = new URLSearchParams(location.search);
const port = params.get('port') || 0;
const refresh = params.get('refresh') || 5;
if (params.get('port')===null){
let s = "";
if (location.search===""){
s = "?port="+port;
}else{
s = location.search+"&port="+port;
}
window.history.pushState('', '', location.pathname+s);
}
let imgsrv_port = IMGSRV_PORT0 + parseInt(port);
let t1 = $("#cnv_div").jp4({src:"http://"+location.host+":"+imgsrv_port+"/img",width:1600,fast:true,lowres:2,debug:false,refresh:true});
</script>
</body>
</html>
\ No newline at end of file
This diff is collapsed.
<html>
<head>
<style>
body {
margin: 0px;
}
canvas {
height: 100%;
border: 0px solid red;
}
</style>
</head>
<body>
<canvas id='cnv'></canvas>
<script>
const IMGSRV_PORT0 = 2323;
const params = new URLSearchParams(location.search);
const port = params.get('port') || 0;
const refresh = params.get('refresh') || 5;
if (params.get('port')===null){
let s = "";
if (location.search===""){
s = "?port="+port;
}else{
s = location.search+"&port="+port;
}
window.history.pushState('', '', location.pathname+s);
}
let imgsrv_port = IMGSRV_PORT0 + parseInt(port);
let cnv = document.getElementById('cnv');
let ctx = cnv.getContext('2d');
let img = new Image();
img.onload = function() {
canvas_resize();
refreshCanvas();
};
img.src = location.origin+":"+imgsrv_port+"/mimg";
window.addEventListener("resize", ()=>{
canvas_resize();
});
///////////////////////////////////////////////////////////////////////////////////
function canvas_resize(){
ctx.canvas.width = img.width;
ctx.canvas.height = img.height;
}
window.setInterval("refreshCanvas()", refresh);
function refreshCanvas(){
try{
ctx.drawImage(img,0,0,ctx.canvas.width,ctx.canvas.height);
}catch(err){
img.src = location.origin+":2323/mimg";
}
};
</script>
</body>
</html>
\ No newline at end of file
......@@ -7,6 +7,7 @@ DOCS= jp4-canvas.html \
LIBS= elphel.js \
exif.js \
UTIF.js \
jquery-jp4.js \
jcanvas.js \
webworker.js
......
This diff is collapsed.
......@@ -129,13 +129,13 @@ var Elphel = {
* @lowres - valid values: 1 (not scaled), 2, 4, 8 (lowest resolution)
*
*/
reorderBlocksJP4_lowres: function(pixels,width,height,format="JP4",mosaic=[["Gr","R"],["B" ,"Gb"]],lowres){
//reorderBlocksJP4_lowres: function(pixels,width,height,format="JP4",mosaic=[["Gr","R"],["B" ,"Gb"]],lowres){
reorderBlocksJP4_lowres: async function(pixels,width,height,format="JP4",mosaic=[["Gr","R"],["B" ,"Gb"]],lowres){
// the output image is 1/4 because demosaicing = 4 single color channel pixels are put into 1 rgb pixel
var oPixels = new Uint8Array(pixels.length/4);
// check
if ((lowres!=1)&&(lowres!=2)&&(lowres!=4)&&(lowres!=8)){
if (![1,2,4,8].includes(lowres)){
lowres = 4;
}
......@@ -692,4 +692,4 @@ var Elphel = {
console.log("Test message from elphel.js: ok");
}
}
\ No newline at end of file
}
......@@ -44,10 +44,26 @@ $port0 = 2323;
$pointers = elphel_get_circbuf_pointers(intval($port)-$port0,1);
$pointer = $pointers[count($pointers)-1]['circbuf_pointer'];
$contents = file_get_contents("http://$ip:$port/$rel");
$acao = "*";
$ct = "image/jpeg";
// pass some headers from file_get_contents
// $http_response_header is auto populated
foreach($http_response_header as $h){
$hv = explode(":",$h);
if ($hv[0]=="Access-Control-Allow-Origin"){
$acao = trim($hv[1]);
}else if ($hv[0]=="Content-Type"){
$ct = trim($hv[1]);
}
}
// allow CORS
header('Access-Control-Allow-Origin: *');
header('Content-type:image/jpeg');
echo file_get_contents("http://$ip:$port/$pointer/$rel");
header("Access-Control-Allow-Origin: $acao");
header("Content-Type: $ct");
echo $contents;
//echo file_get_contents("http://$ip:$port/$rel");
die();
......
......@@ -7,15 +7,16 @@
<body>
<table>
<tr>
<td><div id='test1'></div></td>
<td><div id='test2'></div></td>
<td valign='top'><div id='test1'></div></td>
<td valign='top'><div id='test2'></div></td>
</tr>
<tr>
<td><div id='test3'></div></td>
<td><div id='test4'></div></td>
<td valign='top'><div id='test3'></div></td>
<td valign='top'><div id='test4'></div></td>
</tr>
</table>
<script src="js/elphel.js"></script>
<script src="js/UTIF.js"></script>
<script src="js/jquery-3.1.1.js"></script>
<script src="js/jcanvas.js"></script>
<script src="js/exif.js"></script>
......
......@@ -26,10 +26,10 @@
*/
$(function(){
var t1 = $("#test1").jp4({ip:"127.0.0.1",port:2323,width:600,fast:true,lowres:4});
var t2 = $("#test2").jp4({ip:"127.0.0.1",port:2324,width:600,fast:true,lowres:4});
var t3 = $("#test3").jp4({ip:"127.0.0.1",port:2325,width:600,fast:true,lowres:4});
var t4 = $("#test4").jp4({ip:"127.0.0.1",port:2326,width:600,fast:true,lowres:4});
let t1 = $("#test1").jp4({src:"http://"+location.host+":"+2323+"/img",width:600,fast:true,lowres:4,debug:false,refresh:false});
let t2 = $("#test2").jp4({src:"http://"+location.host+":"+2324+"/img",width:600,fast:true,lowres:4,debug:false,refresh:false});
let t3 = $("#test3").jp4({src:"http://"+location.host+":"+2325+"/img",width:600,fast:true,lowres:4,debug:false,refresh:false});
let t4 = $("#test4").jp4({src:"http://"+location.host+":"+2326+"/img",width:600,fast:true,lowres:4,debug:false,refresh:false});
});
This diff is collapsed.
importScripts('elphel.js');
self.onmessage = function(e) {
var W = e.data.width;
var H = e.data.height;
var Mosaic = e.data.mosaic;
var Format = e.data.format;
var settings = e.data.settings;
var Pixels = new Uint8Array(e.data.pixels);
if (settings.lowres==0){
var reorderedPixels = Elphel.Pixels.reorderBlocksJPx(Pixels,W,H,Format,Mosaic,settings.fast);
//reorder first then downscale
if (settings.fast){
W = W/2;
H = H/2;
onmessage = async (e) => {
let W = e.data.width;
let H = e.data.height;
let Mosaic = e.data.mosaic;
let Format = e.data.format;
let settings = e.data.settings;
let Pixels = new Uint8Array(e.data.pixels);
let reorderedPixels;
if (settings.lowres==0){
reorderedPixels = Elphel.Pixels.reorderBlocksJPx(Pixels,W,H,Format,Mosaic,settings.fast);
//reorder first then downscale
if (settings.fast){
W = W/2;
H = H/2;
}
}else{
reorderedPixels = await Elphel.Pixels.reorderBlocksJP4_lowres(Pixels,W,H,Format,Mosaic,settings.lowres);
W = W/2;
H = H/2;
}
}else{
var reorderedPixels = Elphel.Pixels.reorderBlocksJP4_lowres(Pixels,W,H,Format,Mosaic,settings.lowres);
W = W/2;
H = H/2;
}
Elphel.Pixels.applySaturation(reorderedPixels,W,H,2);
postMessage({
width: W,
height: H,
pixels: reorderedPixels.buffer
},[reorderedPixels.buffer]);
Elphel.Pixels.applySaturation(reorderedPixels,W,H,2);
//Elphel.test();
this.close();
postMessage({
width: W,
height: H,
pixels: reorderedPixels.buffer
},[reorderedPixels.buffer]);
};
\ No newline at end of file
//Elphel.test();
this.close();
};
......@@ -8,6 +8,7 @@
<script src="../js/jquery-3.1.1.js"></script>
<script src="../js/jcanvas.js"></script>
<script src="../js/exif.js"></script>
<script src="../js/UTIF.js"></script>
<script src="../js/jquery-jp4.js"></script>
<script type='text/javascript' src='jp4-viewer.js'></script>
......
......@@ -27,7 +27,7 @@ function parseURL(){
$(function(){
$.ajax({
url: "http://192.168.0.9:2323",
url: location.host+":2323",
success: function(){
console.log("success");
}
......@@ -54,6 +54,8 @@ function handleImage(e) {
reader.onload = function(event){
//$("#smallimage").attr("src",event.target.result);
console.log("File loaded");
$("#jp4view").html("");
var view = $("<div>",{id:"img"});
......@@ -63,7 +65,7 @@ function handleImage(e) {
//console.log(SETTINGS.width);
view.jp4({image:myimg, fromhtmlinput: true, width:SETTINGS.width,fast:true, lowres:SETTINGS.quality, webworker_path:"../js"});
view.jp4({src:myimg, fromhtmlinput: true, width:SETTINGS.width,fast:true, lowres:SETTINGS.quality, webworker_path:"../js"});
//view.jp4({image:"test.jp4", input: false, width:1200,fast:true, lowres:1});
$("#jp4view").append(view);
......
DOCUMENTROOT=$(DESTDIR)/www/pages/multicam
DOCUMENTROOTZIP=$(DESTDIR)/www/pages/js/zip
OWN = -o root -g root
INSTDOCS = 0644
INSTALL = install
......@@ -7,6 +8,11 @@ DOCS= index.html \
multicam.css \
multicam.php
ZIPDOCS= zip/deflate.js \
zip/inflate.js \
zip/z-worker.js \
zip/zip.js
all:
@echo "make all in src"
......@@ -14,6 +20,8 @@ install:
@echo "make install in src"
$(INSTALL) $(OWN) -d $(DOCUMENTROOT)
$(INSTALL) $(OWN) -m $(INSTDOCS) $(DOCS) $(DOCUMENTROOT)
$(INSTALL) $(OWN) -d $(DOCUMENTROOTZIP)
$(INSTALL) $(OWN) -m $(INSTDOCS) $(ZIPDOCS) $(DOCUMENTROOTZIP)
clean:
@echo "make clean in src"
......@@ -7,6 +7,7 @@
<script src="../js/jquery-3.1.1.js"></script>
<script src="../js/elphel.js"></script>
<script src="../js/jcanvas.js"></script>
<script src="../js/UTIF.js"></script>
<script src="../js/exif.js"></script>
<script src="../js/jquery-jp4.js"></script>
<script src="../js/zip/zip.js"></script>
......
......@@ -477,8 +477,9 @@ function refresh_previews(){
//console.log("preview does not exist");
var jp4prev = elem.find(".port_preview[index="+j+"]");
var preview = jp4prev.jp4({
ip: cam.ip,
port: cam.ports[j].port,
//ip: cam.ip,
//port: cam.ports[j].port,
src: "http://"+cam.ip+":"+cam.ports[j].port+"/img",
width: 200,
fast: true,
lowres:4,
......@@ -774,7 +775,17 @@ function snapshot_find_latest_ts(ptrs){
var total_ports = 0;
for(var i=0;i<ptrs.length;i++){
total_ports += $(ptrs[i]).find('port').length;
let port_counter = 0;
let ports = $(ptrs[i]).find('port');
for(p of ports){
let sensors = $(p).attr("sensor").replace(/\s/g,'').split(",");
if (!sensors.every(v => v==='none')){
port_counter++;
}
}
total_ports += port_counter;
}
var ts = [];
......
This diff is collapsed.
This diff is collapsed.
/* jshint worker:true */
(function main(global) {
"use strict";
if (global.zWorkerInitialized)
throw new Error('z-worker.js should be run only once');
global.zWorkerInitialized = true;
addEventListener("message", function(event) {
var message = event.data, type = message.type, sn = message.sn;
var handler = handlers[type];
if (handler) {
try {
handler(message);
} catch (e) {
onError(type, sn, e);
}
}
//for debug
//postMessage({type: 'echo', originalType: type, sn: sn});
});
var handlers = {
importScripts: doImportScripts,
newTask: newTask,
append: processData,
flush: processData,
};
// deflater/inflater tasks indexed by serial numbers
var tasks = {};
function doImportScripts(msg) {
if (msg.scripts && msg.scripts.length > 0)
importScripts.apply(undefined, msg.scripts);
postMessage({type: 'importScripts'});
}
function newTask(msg) {
var CodecClass = global[msg.codecClass];
var sn = msg.sn;
if (tasks[sn])
throw Error('duplicated sn');
tasks[sn] = {
codec: new CodecClass(msg.options),
crcInput: msg.crcType === 'input',
crcOutput: msg.crcType === 'output',
crc: new Crc32(),
};
postMessage({type: 'newTask', sn: sn});
}
// performance may not be supported
var now = global.performance ? global.performance.now.bind(global.performance) : Date.now;
function processData(msg) {
var sn = msg.sn, type = msg.type, input = msg.data;
var task = tasks[sn];
// allow creating codec on first append
if (!task && msg.codecClass) {
newTask(msg);
task = tasks[sn];
}
var isAppend = type === 'append';
var start = now();
var output;
if (isAppend) {
try {
output = task.codec.append(input, function onprogress(loaded) {
postMessage({type: 'progress', sn: sn, loaded: loaded});
});
} catch (e) {
delete tasks[sn];
throw e;
}
} else {
delete tasks[sn];
output = task.codec.flush();
}
var codecTime = now() - start;
start = now();
if (input && task.crcInput)
task.crc.append(input);
if (output && task.crcOutput)
task.crc.append(output);
var crcTime = now() - start;
var rmsg = {type: type, sn: sn, codecTime: codecTime, crcTime: crcTime};
var transferables = [];
if (output) {
rmsg.data = output;
transferables.push(output.buffer);
}
if (!isAppend && (task.crcInput || task.crcOutput))
rmsg.crc = task.crc.get();
// posting a message with transferables will fail on IE10
try {
postMessage(rmsg, transferables);
} catch(ex) {
postMessage(rmsg); // retry without transferables
}
}
function onError(type, sn, e) {
var msg = {
type: type,
sn: sn,
error: formatError(e)
};
postMessage(msg);
}
function formatError(e) {
return { message: e.message, stack: e.stack };
}
// Crc32 code copied from file zip.js
function Crc32() {
this.crc = -1;
}
Crc32.prototype.append = function append(data) {
var crc = this.crc | 0, table = this.table;
for (var offset = 0, len = data.length | 0; offset < len; offset++)
crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF];
this.crc = crc;
};
Crc32.prototype.get = function get() {
return ~this.crc;
};
Crc32.prototype.table = (function() {
var i, j, t, table = []; // Uint32Array is actually slower than []
for (i = 0; i < 256; i++) {
t = i;
for (j = 0; j < 8; j++)
if (t & 1)
t = (t >>> 1) ^ 0xEDB88320;
else
t = t >>> 1;
table[i] = t;
}
return table;
})();
// "no-op" codec
function NOOP() {}
global.NOOP = NOOP;
NOOP.prototype.append = function append(bytes, onprogress) {
return bytes;
};
NOOP.prototype.flush = function flush() {};
})(this);
This diff is collapsed.
......@@ -50,8 +50,9 @@ $(function(){
});
display_object = $("#display-panel").jp4({
ip:"127.0.0.1",
port:2323,
//ip:location.host,
//port:2323,
src: "http://"+location.host+":2323/img",
width:600,
fast:true,
lowres:0,
......
......@@ -18,7 +18,9 @@ PHP_SCRIPTS=i2c.php \
phpinfo.php \
raw.php \
snapfull.php \
tuneseq.php
test_sensors.php \
tuneseq.php \
utils.php
PHPINCLUDES=i2c_include.php \
show_source_include.php \
......
......@@ -317,4 +317,18 @@ function get_raw_dev()
return $raw_devices;
}
/** Get a list of detected sensors (no mux). Readimg from sysfs. */
function get_sensors(){
$sensors = array('none','none','none','none');
$path = "/sys/devices/soc0/elphel393-detect_sensors@0";
for($i=0;$i<count($sensors);$i++){
$s = "$path/sensor{$i}0";
if (is_file($s)){
$c = trim(file_get_contents($s));
$sensors[$i] = $c;
}
}
return $sensors;
}
?>
<html>
<head>
<style>
body {
margin: 0px;
}
canvas {
height: 100%;
border: 0px solid red;
}
</style>
</head>
<body>
<canvas id='cnv'></canvas>
<script>
const IMGSRV_PORT0 = 2323;
const params = new URLSearchParams(location.search);
const port = params.get('port') || 0;
if (params.get('port')===null){
let s = "";
if (location.search===""){
s = "?port="+port;
}else{
s = location.search+"&port="+port;
}
window.history.pushState('', '', location.pathname+s);
}
let imgsrv_port = IMGSRV_PORT0 + parseInt(port);
let cnv = document.getElementById('cnv');
let ctx = cnv.getContext('2d');
let img = new Image();
img.onload = function() {
canvas_resize();
refreshCanvas();
};
img.src = location.origin+":"+imgsrv_port+"/mimg";
window.addEventListener("resize", ()=>{
canvas_resize();
});
///////////////////////////////////////////////////////////////////////////////////
function canvas_resize(){
ctx.canvas.width = img.width;
ctx.canvas.height = img.height;
}
window.setInterval("refreshCanvas()", 5);
function refreshCanvas(){
try{
ctx.drawImage(img,0,0,ctx.canvas.width,ctx.canvas.height);
}catch(err){
img.src = location.origin+":2323/mimg";
}
};
</script>
</body>
</html>
\ No newline at end of file
......@@ -501,7 +501,21 @@ $prefix_url='http://'.$_SERVER['SERVER_ADDR'].$_SERVER['SCRIPT_NAME'];
</ul>
<p>Each parameter on a generated page has a "tooltip" - if you hover a mouse pointer over it's name it will show short description of the parameter.</p>
<h4> Changing parameters with the HTTP GET method</h4>
<p>If "&immediate" is added the the URL, the program will apply parameteres (those that have values specified) without opening any forms. If the parameter <b>showseq</b> is specified and positive, the HTML page will show the sequence of parameter application, if it is ommitted or less or equal to 0, the request will generate an XML response with the previous parameter values (before application of the new ones). You may specify different program-ahead values and/or multiple settings for the same parameters - program-ahead values are separated from the parameter values with "*", multiple value/program-ahead pairs for the same parameter are separated with ":". Non-specified program-ahead is currently set to 3.</p>
<p>If "&immediate" is added the the URL, the program will apply parameteres (those that have values specified)
without opening any forms. If the parameter <b>showseq</b> is specified and positive, the HTML page will show
the sequence of parameter application, if it is ommitted or less or equal to 0, the request will generate
an XML response with the previous parameter values (before application of the new ones). You may specify
different program-ahead values and/or multiple settings for the same parameters - program-ahead values
are separated from the parameter values with "*", multiple value/program-ahead pairs for the same parameter
are separated with ":". Non-specified program-ahead is currently set to 3.</p>
<p>It is possible to simultaneously apply the same parameter to all (or some) ports, not just the one specified by
"sensor_port=x". Port selection can be set as a hex digit:
<ul>
<li>attached to the value after "!" sign: <b>&amp;key=value!ports</b> or with ahead parameter <b>&amp;key=value*ahead!ports</b> (<span style='color:red;font-weight:bold'>order of <i>value, ahead and ports</i> is important</span>)</li>
<li>by adding parameter preceded by an asterisk: <b>&amp;key=value&amp;*key=ports</b></li>
</ul>
<b><i>Note:</i></b> 'broadcast' parameters set with port selection are applied with FRAMEPAIR_FORCE_NEWPROC modifier
(other parameters are not!), so the actions caused by the parameter will be performed even if the value is not changed.</p>
USAGE;
}
......@@ -898,7 +912,7 @@ function applyPost($todo,$noFinalWait=false) {
elphel_set_P_arr ( $GLOBALS [sensor_port], $params, $frame_zero + $since, ELPHEL_CONST_FRAMEPAIR_FORCE_NEWPROC, $bcast );
} else {
// echo "elphel_set_P_arr(" . $GLOBALS [sensor_port] . ", " . print_r ( $params, 1 ) . ", " . ($frame_zero + $since) . ", ELPHEL_CONST_FRAMEPAIR_FORCE_NEWPROC)\n";
elphel_set_P_arr ( $GLOBALS [sensor_port], $params, $frame_zero + $since, ELPHEL_CONST_FRAMEPAIR_FORCE_NEWPROC ); // / Are these flags needed?
elphel_set_P_arr ( $GLOBALS [sensor_port], $params, $frame_zero + $since, ELPHEL_CONST_FRAMEPAIR_FORCE_NEWPROC ); // / Are these flags needed?- YES!
}
}
}
......@@ -1119,8 +1133,10 @@ function parseGetNames() {
}
$port_mask = 0;
if (strpos($value,"!")!==FALSE) {
$port_mask = myval(substr($value,strpos($value,"!")+1),16);
$value = substr($value,strpos($value,"!")+1);
$port_mask = myval(substr($value,strpos($value,"!")+1),16); // string after '!' - hex port mask
// $value = substr($value,strpos($value,"!")+1);
// Old bug above?
$value = substr($value,0, strpos($value,"!")); // string before "!" - parameter value
}
if (isset($_GET["*$key"])) {
......
<?php
/**
* @copyright Copyright (C) 2020 Elphel, Inc.
* SPDX-License-Identifier: GPL-3.0-or-later
*
* @author Oleg Dzhimiev <oleg@elphel.com>
* @brief Test sensors at all 10393 ports
*/
include "include/elphel_functions_include.php";
$PORT_BASE = 2323;
$SENSOR_NONE = 'none';
$SENSOR_MT9P006 = "mt9p006";
function apply_def_settings($port,$pars){
global $PORT_BASE;
$parsForMD5=array(
'QUALITY' => 96,
'WOI_WIDTH' => 2592,
'WOI_HEIGHT' => 1936,
'SENSOR_RUN' => 2,
'COMPRESSOR_RUN' => 2,
'GAINR' => 0x20000,
'GAING' => 0x20000,
'GAINB' => 0x20000,
'GAINGB' => 0x20000,
'COLOR' => 0,
'AUTOEXP_ON' => 0,
'WB_EN' => 0,
'GAIN_MIN' => 0x10000,
'GAIN_MAX' => 0x10000,
'TESTSENSOR' => 0x10008,
'EXPOS' => 10000
);
for($i=0;$i<2;$i++){
elphel_set_P_arr($port,$parsForMD5);
$thisFrame = elphel_get_frame($port);
elphel_wait_frame_abs($port,$thisFrame+3);
}
}
function run_test_mt9p006($port){
global $PORT_BASE;
$ref_md5sum = "e1f8f6c37d1d7ddd233a821338f812e5";
$p = $PORT_BASE + $port;
$test_status = "ok";
$ahead = 3;
$parsForMD5=array(
'QUALITY' => 96,
'WOI_WIDTH' => 2592,
'WOI_HEIGHT' => 1936,
'SENSOR_RUN' => 2,
'COMPRESSOR_RUN' => 2,
'GAINR' => 0x20000,
'GAING' => 0x20000,
'GAINB' => 0x20000,
'GAINGB' => 0x20000,
'COLOR' => 0,
'AUTOEXP_ON' => 0,
'WB_EN' => 0,
'GAIN_MIN' => 0x10000,
'GAIN_MAX' => 0x10000,
'TESTSENSOR' => 0x10008,
'EXPOS' => 10000
);
// save pars to restore later
$parsSaved = elphel_get_P_arr($port,$parsForMD5);
// Spectr's cheating - double initialization
for($i=0;$i<2;$i++){
elphel_set_P_arr($port,$parsForMD5);
$thisFrame = elphel_get_frame($port);
elphel_wait_frame_abs($port,$thisFrame+$ahead);
}
for($i=0;$i<3;$i++){
$md5sum = md5(file_get_contents("http://127.0.0.1:$p/noexif/next/wait/img"));
if ($md5sum!=$ref_md5sum){
print("md5sum($i) does not match reference ($ref_md5sum): $md5sum\n");
$test_status = "fail";
}else{
print("md5sum($i) $md5sum ok\n");
}
}
// restore saved pars
elphel_set_P_arr($port,$parsSaved);
print("RESULT: $test_status\n");
}
if (isset($_SERVER['SERVER_ADDR'])){
print("<pre>");
}
$sensors = get_sensors();
foreach($sensors as $i => $sensor){
print("Testing port $i:\n");
switch($sensor){
case $SENSOR_MT9P006:
run_test_mt9p006($i);
break;
case $SENSOR_NONE:
print("WARNING: No sensor attached to port $i. Test skipped.\n");
break;
default:
print("WARNING: Unsupported sensor '$sensor'. Test skipped.\n");
}
}
print("Done\n");
?>
<?php
/**
* @copyright Copyright (C) 2020 Elphel, Inc.
* SPDX-License-Identifier: GPL-3.0-or-later
*
* @author Oleg Dzhimiev <oleg@elphel.com>
* @brief Access info or perform actions using GET requests
*/
include "include/elphel_functions_include.php";
$cmd = "donothing";
if (isset($_GET['cmd']))
$cmd = $_GET['cmd'];
else if (isset($argv[1]))
$cmd = $argv[1];
// allow CORS
header('Access-Control-Allow-Origin: *');
switch($cmd){
case "sensors":
print(cmd_sensors());
break;
case "time":
cmd_time();
break;
default:
print("OK");
}
function cmd_sensors(){
$p0 = 2323;
$sensors = get_sensors();
$res = "\t<camera ip='".$_SERVER['SERVER_ADDR']."'>\n";
foreach($sensors as $i => $sensor){
$p = $p0+$i;
$res .= "\t\t<port index='$i' port='$p'>$sensor</port>\n";
}
$res .= "\t</camera>\n";
return wrap_into_xml($res);
}
function get_formatted_ts($ts){
$ts_s = substr($ts,0,10);
$ts_ms = substr($ts,11);
$ts_formatted = date("Y-m-d H:i:s.$ts_ms",$ts_s);
return $ts_formatted;
}
function cmd_time(){
date_default_timezone_set('UTC');
exec("date +%s.%3N",$ots);
$t = elphel_get_fpga_time();
$tsys = $ots[0];
print("Camera time (fpga): $t (".get_formatted_ts($t).")\n");
print("Camera time (sys): $tsys (".get_formatted_ts($tsys).")\n");
if (isset($_GET['ts'])){
// ts is in ms
$ts_s = substr($_GET['ts'],0,10);
$ts_ms = substr($_GET['ts'],11);
$ts_formatted = get_formatted_ts($_GET['ts']);
print("Your (browser) time: $ts_s.$ts_ms ($ts_formatted)\n");
if (isset($_GET['apply'])||(abs($ts_s-$t)>24*3600)){
elphel_set_fpga_time($_GET['ts']/1000);
exec("date -s '$ts_formatted'");
exec("hwclock --systohc");
print("Timestamps differ by more than 24h. Camera and fpga time updated.\n");
}
}
}
function wrap_into_xml($s){
$xml = "<?xml version='1.0' standalone='yes'?>\n";
$xml .= "<Document>\n";
$xml .= $s;
$xml .= "</Document>\n";
return $xml;
}
?>
......@@ -34,14 +34,18 @@ $BKP_DIR = "/etc/elphel393";
# update files
# file, expertise level, nand partition, size - see http://wiki.elphel.com/index.php?title=NAND_flash_boot_rootfs
# partitions are also listed in the device tree
# WARNING: DO NOT CHANGE
# e[3]s for flash_erase are now calculated from sysfs and depend on the device tree
# WARNING: TRY NOT TO CHANGE
$UPDATE_LIST = array(
array(0,"boot.bin", "/dev/mtd0","0 2"),
array(0,"u-boot-dtb.img","/dev/mtd1","0 8"),
array(0,"devicetree.dtb","/dev/mtd2","0 8"),
array(0,"uImage", "/dev/mtd3","0 128"),
array(1,"rootfs.tar.gz", "",""),
array(0,"rootfs.ubi", "/dev/mtd4","0 2048","-s 2048 -O 2048"),
//array(0,"rootfs.ubi", "/dev/mtd4","0 2048","-s 2048 -O 2048"),
array(0,"rootfs.ubi", "/dev/mtd4","0 2560","-s 512 -O 512"),
array(1,"rootfs.ubifs", "/dev/mtd4","/dev/ubi_ctrl -m 4","ubiupdatevol /dev/ubi0_0"),
);
......@@ -137,6 +141,21 @@ function backup_note(){
print("<b>NOTE</b>: If flashing rootfs, please download a backup copy of <a href='$base?cmd=backup'>/etc/elphel393</a><br/>");
}
// $defaults are not used yet. No need
function get_flash_erase_args($dev, $defaults){
$mtd_device = explode("/",$dev)[2];
$mtd_sysfs_path = "/sys/class/mtd/$mtd_device";
$mtd_size = intval(file_get_contents("$mtd_sysfs_path/size"));
$mtd_erasesize = intval(file_get_contents("$mtd_sysfs_path/erasesize"));
$mtd_size_blocks = intval($mtd_size/$mtd_erasesize);
$mtd_erase_start = 0;
$res = "$mtd_erase_start $mtd_size_blocks";
return $res;
}
function nandflash($list){
global $UPDATE_DIR;
global $FLASH_LOG;
......@@ -149,12 +168,16 @@ function nandflash($list){
if ($e[0]==0){
if ($e[1]!="rootfs.ubi"){
exec("flash_unlock ${e[2]} >> $FLASH_LOG");
exec("flash_erase ${e[2]} ${e[3]} >> $FLASH_LOG");
exec("nandwrite -n ${e[2]} -p $UPDATE_DIR/${e[1]} >> $FLASH_LOG");
$flash_erase_args = get_flash_erase_args($e[2],$e[3]);
exec("flash_erase ${e[2]} $flash_erase_args >> $FLASH_LOG");
// -n - write without ecc
//exec("nandwrite -n ${e[2]} -p $UPDATE_DIR/${e[1]} >> $FLASH_LOG");
exec("nandwrite ${e[2]} -p $UPDATE_DIR/${e[1]} >> $FLASH_LOG");
}else{
if (!is_dir($NAND_PATH)) {
exec("flash_unlock ${e[2]} >> $FLASH_LOG");
exec("flash_erase ${e[2]} ${e[3]} >> $FLASH_LOG");
$flash_erase_args = get_flash_erase_args($e[2],$e[3]);
exec("flash_erase ${e[2]} $flash_erase_args >> $FLASH_LOG");
exec("ubiformat ${e[2]} -f $UPDATE_DIR/${e[1]} ${e[4]} >> $FLASH_LOG");
}else{
rootfs_warning_note();
......