<head>
<title>Central Trigger System</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <link href="layout/base.css" rel="Stylesheet" type="text/css" />
- <script src="scripts/mootools-core-1.4.5.js" type="text/javascript"></script>
- <script src="scripts/cts.js" type="text/javascript"></script>
+ <link href="../layout/cts.css" rel="Stylesheet" type="text/css" />
+ <script src="../scripts/mootools-core-1.4.5.js" type="text/javascript"></script>
+ <script src="../scripts/cts.js" type="text/javascript"></script>
</head>
<body lang="en">
</div>
<div id="content-area">
+ <div class="warning-box" id="nameDB-match-warning">
+ The name database was created for another FPGA design (<span class="old-date"></span>). Please ensure, that the defined labels are still valid.<br />
+ The database can be found in <span class="path">web/htdocs/cts/names.json</span> in your daqtools-directory.
+ After verification set the <span class="path">cts-compiletime</span> property to <span class="new-date"></span> to stop this message from reappearing.
+ </div>
+
<div class="expandable expanded" id="itc-overview">
<div class="header"><span class="indicator"></span> Status overview</div>
<div class="content">
<div id="rate-plot-cotainer">
- <img src="layout/empty_plot.png" id="rate-plot" title="Click to switch between short and long plot interval" />
+ <img src="empty_plot.png" id="rate-plot" title="Click to switch between short and long plot interval" />
Click on the image to switch between short and long plotting intervals
</div>
<table id="overview-tab">
<td class="label">Design compiled</td>
<td class="value" id="trb_compiletime">n/a</td>
</tr>
+
+ <tr><td colspan="2"> </td></tr>
+
+ <tr class="alt">
+ <td class="label">Export Renaming Template</td>
+ <td class="value">
+ <a href="#" id="gui_export_name_template">to define setup specific names</a>
+ </td>
+ </tr>
+<!--
<tr class="alt">
<td class="label">TD FSM Limit (debug only):</td>
<td class="value">
interpret="var f=function(x){return (x.trim() == '' || x.match(/disabled|off/)) ? 0xffff : (isNaN(parseInt(x))?0:parseInt(x))}; f" />
</td>
</tr>
+-->
</table>
</div>
<div class="right">
</div>
</div>
</div>
+
+ <div id="win-nameDB" class="window">
+ <div class="header">
+ <div class="tools"><a href="javascript:window.location.reload()">close and reload</a></div>
+ <div class="title">Export NameDB template</div>
+ </div>
+
+ <div class="content">
+ <p>
+ You can change the name of most IO-related ports by copying the template from below
+ into a text file and placing it under <span class="path">web/htdocs/cts/names.json</span>
+ in your daqtools-directory. Ensure that the file is NOT executable (chmod -x names.json).
+ Then reload the page.
+ </p>
+ <p>If you omit any value, the GUI uses the default value send by
+ the CTS tool. If a <span class="path">cts-compiletime</span> option is included in the file, the
+ GUI warns you, when it connects to a different hardware version (which could have a
+ different IO mapping - Those change cannot be tracked automatically). It is, hence, highly recommended
+ to use this security measure !!!
+ </p>
+
+ <pre class="template"></pre>
+ </div>
+ </div>
+
+
+
</body>
</html>
\ No newline at end of file
return fallback ? fallback : id;
}
-
+
var CTS = new Class({
Implements: [Events],
defs: null,
autoCommitInhibit: false,
+ nameDB: {},
currentData: {},
dataUpdateConstantFor: 0,
dataUpdateActive: true,
- initialize: function(defs) {
+ initialize: function(defs, nameDB) {
this.defs = defs;
+ if (nameDB) {
+ this.nameDB = nameDB;
+ if (nameDB['cts-compiletime'] && this.nameDB['cts-compiletime'] != this.defs.properties.trb_compiletime) {
+ $$('#nameDB-match-warning .old-date').set('text', timestamp2Date(this.nameDB['cts-compiletime']) + ' - ' +this.nameDB['cts-compiletime']);
+ $$('#nameDB-match-warning .new-date').set('text', this.defs.properties.trb_compiletime);
+ $('nameDB-match-warning').setStyle('display', 'block');
+ }
+ }
this.monitorPrefix = 'monitor-' + this.defs.server.port + '/';
this.renderTriggerChannels();
},
readRegisters: function(regs, callback, formated) {
- var opts = {'onFailure':xhrFailure, 'url': 'cts.pl?' + (formated ? "format" : "read") + ',' + Array.from(regs).join(",")};
+ var opts = {'onFailure':requestFailure, 'url': '/cts/cts.pl?' + (formated ? "format" : "read") + ',' + Array.from(regs).join(",")};
if (callback) {
opts['onSuccess'] = callback;
return (new Request.JSON(opts)).send();
var arrValues = [];
Object.each(values, function(v,r) {arrValues.push(r); arrValues.push(v)});
(new Request.JSON({
- url: 'cts.pl?write,' + arrValues.join(','),
+ url: '/cts/cts.pl?write,' + arrValues.join(','),
onSuccess: function(json, text) {
console.log(json)
console.log(text)
else alert("An unknown error occured while writing register");
}
},
- onFailure: xhrFailure
+ onFailure: requestFailure
})).send();
},
onFailure: function(xhr) {
window.clearTimeout(manualTimeout);
- //xhrFailure(xhr);
+ //requestFailure(xhr);
this.dataUpdate.delay(1000, this);
dup.addClass('error').set('text', 'Update failed').setStyle('display', 'block');
$('status-indicator').set('class', 'error');
}.bind(this));
},
+/**
+ * Translate Names, such as channel assignments into user-overrideable values.
+ */
+
+ translateName: function(category, key, def) {
+ if (this.nameDB[category] == undefined)
+ this.nameDB[category] = {};
+
+ if (this.nameDB[category][key] == undefined)
+ this.nameDB[category][key] = def;
+
+ return def;
+ },
+
/**
* Creates all active elements of the Trigger Input Configuration
* section. It is called by the class' constructor and hence
new Element('td', {'class': 'source'})
.adopt(
- new Element('select', {'class': 'text autocommit autoupdate', 'slice': areg + '.input'}).adopt(
- Object.values(en).map(function (r) {
- return new Element('option', {'value': r, 'text': r})
- })
+ new Element('select', {'class': 'text autocommit autoupdate', 'slice': areg + '.input'})
+ .adopt(
+ Object.values(en).map(function (r) {
+ return new Element('option', {'value': r, 'text': this.translateName('addon-input-multiplexer', r, r)})
+ }, this)
)
),
$('itc-tab') // + (i / 8).toInt())
.adopt(
new Element('tr', {'class': i%2?'':'alt', 'flashgroup': 'itc-' + i})
- .adopt([
+ .adopt([
new Element('td', {'text': i, 'class': 'channel'}),
new Element('td', {'class': 'enable'})
.adopt(
new Element('input', {'type': 'checkbox', 'id': 'itc-enable'+i, 'class': 'autocommit autoupdate', 'slice': 'trg_channel_mask.mask[' + i + ']'})
),
- new Element('td', {'class': 'edge'})
+ new Element('td', {'class': 'edge'})
.adopt(
edgeType = new Element('select', {'type': 'checkbox', 'class': 'autocommit autoupdate', 'slice': 'trg_channel_mask.edge[' + i + ']'})
.adopt([
new Element('option', {'value': '1', 'text': 'R. Edge'})
])
),
-
- itc = new Element('td', {'class': 'assign', 'text': this.defs.properties.itc_assignments[i]}),
+
+ itc = new Element('td', {'class': 'assign', 'text': (this.defs.properties['trg_periph_itc_base'] == i) ? '' : this.translateName('itc-names', 'itc-' + i, this.defs.properties.itc_assignments[i])}),
new Element('td', {'class': 'type'})
.adopt(
ddType = new Element('select', {'class': 'autocommit autoupdate autoupdate-value', 'slice': '_trg_trigger_types' + (i < 8 ? '0' : '1') + '.type' + i})
),
-
+
assertedRate = new Element('td', {'class': 'rate autorate', 'slice': 'trg_channel_asserted_cnt' + i + '.value', 'text': 'n/a', 'id': 'itc-asserted-rate' + i}),
edgeRate = new Element('td', {'class': 'rate autorate', 'slice': 'trg_channel_edge_cnt' + i + '.value', 'text': 'n/a', 'id': 'itc-edge-rate' + i})
])
);
- if (this.defs.properties['trg_periph_itc_base'] == i) {
- itc.set('html', '').adopt([
- new Element('span', {'html': 'Trigger from FPGA: '}),
- new Element('sub', {'text': '4'})
- ]);
- for(var j=3; j>=0; j--)
- itc.adopt(new Element('input', {'type': 'checkbox', 'class': 'autocommit autoupdate', 'slice': 'trg_periph_config.mask[' + j + ']'}));
-
- itc.adopt(new Element('sub', {'text': '1'}));
- }
+ if (this.defs.properties['trg_periph_itc_base'] == i) {
+ itc.set('html', '').adopt([
+ new Element('span', {'html': 'Trigger from FPGA: '}),
+ new Element('sub', {'text': '4'})
+ ]);
+ for(var j=3; j>=0; j--)
+ itc.adopt(new Element('input', {'type': 'checkbox', 'class': 'autocommit autoupdate', 'slice': 'trg_periph_config.mask[' + j + ']'}));
+
+ itc.adopt(new Element('sub', {'text': '1'}));
+ }
for(var j=0; j < 16; j++)
ddType.adopt(new Element('option', {'value': j, 'text': this.defs.registers['_trg_trigger_types' + (i < 8 ? '0' : '1')]._defs['type' + i].enum[j]}));
},
renderCTSDetails: function() {
- $('trb_compiletime').set('text', new Date(this.defs.properties.trb_compiletime * 1000 - new Date().getTimezoneOffset() * 60000).toGMTString().replace('GMT', ''));
+ $('trb_compiletime').set('text', timestamp2Date(this.defs.properties.trb_compiletime));
$('trb_endpoint').set('text', "0x" + this.defs.properties.trb_endpoint.toString(16));
$('trb_daqopserver').set('text', this.defs.properties.daqopserver);
},
}
});
-function xhrFailure(xhr){
- console.log(xhr);
- var m = xhr.responseText.match(/<pre>([\s\S]*)<\/pre>/im);
+function timestamp2Date(ts) {
+ return new Date(ts * 1000 - new Date().getTimezoneOffset() * 60000).toGMTString().replace('GMT', '');
+}
+
+
+function requestFailure(obj){
+ console.log(obj);
+
+ var text = (obj.responseText) ? obj.responseText : obj;
+ var m = text.match(/<pre>([\s\S]*)<\/pre>/im);
- if (m) {
+ if (obj.responseText && m) {
text = m[1];
m = text.match(/^\s*-+ More[\w\s]+ -+\s+(.+)$/im)
if (m) text = m[1];
alert("Server send error response:\n"+text.trim());
+ } else {
+ alert("An unknown error while contacting the sever. Did you open this file locally? Did the connection or server crash?\nHint:\n" + text);
}
-
-
-
- else alert("An unknown error while contacting the sever. Did you open this file locally? Did the connection or server crash?");
}
var cts;
-(new Request.JSON({'url': 'cts.pl?init',
- 'onSuccess': function(json) {cts = new CTS(json)},
- 'onFailure': xhrFailure})).send();
+function loadCTS(nameDB) {
+ if (typeOf(nameDB) != 'object')
+ nameDB = {};
+ (new Request.JSON({'url': 'cts.pl?init',
+ 'onSuccess': function(json) {cts = new CTS(json, nameDB)},
+ 'onFailure': requestFailure,
+ 'onError': requestFailure})).send();
+}
+
+(new Request.JSON({'url': 'names.json',
+ 'onSuccess': loadCTS,
+ 'onFailure': loadCTS,
+ 'onError': loadCTS})).send();
+
function countToTime(val) {return (1.0*val / cts.defs.properties.cts_clock_frq * 1e9).toFixed(0);}
function countToFreq(val) {return formatFreq (1 / (val / cts.defs.properties.cts_clock_frq)); }
function timeToCount(val) {return (parseNum(val) / 1.0e9 * cts.defs.properties.cts_clock_frq).round();}
});
});
-function id(x) {return x;}
\ No newline at end of file
+function id(x) {return x;}
+
+
+function prettyJSON(obj, indent=""){
+ if (obj && obj.toJSON) obj = obj.toJSON();
+
+ switch (typeOf(obj)){
+ case 'string':
+ return '"' + obj.replace(/[\x00-\x1f\\"]/g, escape) + '"';
+ case 'array':
+ return '[' + obj.map(JSON.encode).clean() + ']';
+ case 'object': case 'hash':
+ var string = [];
+ Object.each(obj, function(value, key){
+ var json = prettyJSON(value, indent + ' ');
+ if (json) string.push(prettyJSON(key) + ': ' + json);
+ });
+
+ return string ? ('{\n' + indent + " " + string.join(",\n " + indent) + "\n" + indent + '}') : "{}";
+ case 'number': case 'boolean': return '' + obj;
+ case 'null': return 'null';
+ }
+
+ return null;
+};
+
+
+window.addEvent('domready', function() {
+ $('gui_export_name_template').addEvent('click', function(e) {
+ e.stop();
+ cts.nameDB['cts-compiletime'] = cts.defs.properties.trb_compiletime;
+ $$('#win-nameDB .template')[0].set('text', prettyJSON(cts.nameDB));
+ $('win-nameDB').fade('hide').setStyle('display', 'block').fade('in');
+ });
+});
+
+
+