/cvi/apps/RedPitaya/sockserv/daq.c |
---|
0,0 → 1,447 |
#include <stdlib.h> |
#include <stdio.h> |
#include <signal.h> |
#include <time.h> |
#include <string.h> |
#include <sys/types.h> |
#include <sys/time.h> |
#include <ctype.h> |
#include <unistd.h> |
#ifdef MRP |
#include "redpitaya/rp.h" |
#else |
#include "calib.h" |
#endif |
#include "fpga_osc.h" |
#define TRUE -1 |
#define FALSE 0 |
int timer_out; struct sigaction oact; |
int ctrl_c=0; |
void SigInt (int sig) { |
ctrl_c = 1; |
} |
void timerast (signumber, code, context) int signumber, code; struct sigcontext context; { |
fprintf(stderr, "Timeout\n"); |
timer_out = TRUE; |
} |
void tmlnk (tout) int tout; { |
struct sigaction act; |
struct itimerval tdelay; |
act.sa_handler = timerast; |
sigemptyset (&act.sa_mask); |
act.sa_flags = 0; |
tdelay.it_value.tv_sec = tout / 100; |
tdelay.it_value.tv_usec = 10000 * (tout % 100); |
tdelay.it_interval.tv_sec = 0; |
tdelay.it_interval.tv_usec = 0; |
if (sigaction (SIGALRM, &act, &oact) < 0) |
{ |
perror ("sigaction(tmlnk)"); |
exit (EXIT_FAILURE); |
} |
if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0) |
{ |
perror ("setitimer(tmlnk)"); |
exit (EXIT_FAILURE); |
} |
} |
void tmulk () { |
struct itimerval tdelay; |
tdelay.it_value.tv_sec = 0; |
tdelay.it_value.tv_usec = 0; |
tdelay.it_interval.tv_sec = 0; |
tdelay.it_interval.tv_usec = 0; |
if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0) |
{ |
perror ("setitimer(tmulk)"); |
exit (EXIT_FAILURE); |
} |
if (sigaction (SIGALRM, &oact, NULL) < 0) |
{ |
perror ("sigaction(tmulk)"); |
exit (EXIT_FAILURE); |
} |
} |
#ifndef MRP |
rp_calib_params_t rp_calib_params; /** Pointer to externally defined calibration parameters. */ rp_calib_params_t *gen_calib_params = NULL; |
#endif |
int daq_init (char * buff) { |
#ifdef DEBUG |
fprintf (stderr, "Server: init\n"); |
#endif |
int * hdr = (int *) buff; |
int delay = hdr[0]; |
int decimation = hdr[1]; |
float threshold_voltage = hdr[2]/1000.; |
fprintf(stderr, "delay = %d\tdecimation = %d\tthreshold = %f\n", delay, decimation, threshold_voltage); |
/* |
rp_default_calib_params(&rp_calib_params); |
gen_calib_params = &rp_calib_params; |
if(rp_read_calib_params(gen_calib_params) < 0) { |
fprintf(stderr, "rp_read_calib_params() failed, using default" |
" parameters\n"); |
} |
*/ |
// use this to acquire calibrated offset: int offset = gen_calib_params->fe_ch1_dc_offs; |
#ifdef MRP |
if(rp_Init() != RP_OK){ |
fprintf(stderr, "Rp api init failed!\n"); |
} |
rp_AcqReset(); |
const int rpdecimation[6]={RP_DEC_1 ,RP_DEC_8 ,RP_DEC_64, |
RP_DEC_1024 ,RP_DEC_8192 ,RP_DEC_65536 }; |
rp_AcqSetDecimation(rpdecimation[decimation%6]); |
const int c[2] = {RP_CH_1, RP_CH_2}; |
rp_AcqSetTriggerLevel(c[0],threshold_voltage); //Trig level is set in Volts while in SCPI |
rp_AcqSetTriggerLevel(c[1],threshold_voltage); |
rp_AcqSetTriggerDelay(delay); |
return 0; |
#else |
// initialization |
int start = osc_fpga_init(); |
if(start) |
{ |
printf("osc_fpga_init didn't work, retval = %d",start); |
return -1; |
} |
// set acquisition parameters |
osc_fpga_set_trigger_delay(delay); |
g_osc_fpga_reg_mem->data_dec = decimation; |
osc_fpga_reset(); |
g_osc_fpga_reg_mem->chb_thr = osc_fpga_cnv_v_to_cnt(threshold_voltage); //sets trigger voltage |
#endif |
fprintf(stderr, "%s : %d\n", __FILE__, __LINE__); |
return 0; |
} |
int daq_end () { |
#ifdef DEBUG |
fprintf (stderr, "Server: end\n"); |
#endif |
#ifdef MRP |
rp_Release(); |
#else |
osc_fpga_exit(); |
#endif |
return 0; |
} |
int daq_clear () { |
#ifdef DEBUG |
fprintf (stderr, "Server: clear\n"); |
#endif |
return 0; |
} |
int16_t chdata[16*1024]; |
float * chfdata = (float *) chdata; |
int daq_run (const char *par, char ** data, int *maxlen) |
{ |
int *data_buf; |
int neve; |
unsigned short *sbuff = (unsigned short *) (par); |
unsigned short maxeve = sbuff[0]; |
unsigned short nsamples = sbuff[1]; |
unsigned short tout = sbuff[2]; |
unsigned char trigger = par[6]; |
unsigned char chmask = par[7]; |
clock_t t,t0; |
neve = 0; |
t0=clock(); |
int eventsize = 0; |
if (chmask & 0x1) eventsize += (nsamples+2); |
if (chmask & 0x2) eventsize += (nsamples+2); |
eventsize+=4; |
int required_size = eventsize * maxeve+3; |
#ifdef DEBUG |
time_t mtime; |
time(&mtime); |
fprintf (stderr, "daq_run:\tmaxeve %d\tnsamples=%d\ttimeout=%d\ttrigger=%d\tchmask=%d\t%s", maxeve ,nsamples,tout,trigger,chmask, ctime(&mtime)); // |
#endif |
if (required_size > *maxlen ) { |
free (*data); |
*data = (char *) malloc(required_size *sizeof(int)); |
fprintf(stderr, "New Buffer with size %d allocated. Old size %d\n", required_size, *maxlen); |
*maxlen = required_size; |
} |
int *ibuf = (int *) (*data); |
data_buf = ibuf + 3; |
const int sleeptime = 135*nsamples/16386; //135 us for 16386 samples and to fill the 16k ADC buffer/ |
for (int ieve=0; ieve < maxeve; ieve++) |
{ |
#ifdef MRP |
rp_AcqStart(); |
usleep(sleeptime); |
rp_AcqSetTriggerSrc(trigger); |
timer_out = FALSE; |
tmlnk (tout); |
rp_acq_trig_src_t source; |
do { |
rp_AcqGetTriggerSrc(&source); |
//printf("TRG %d src %d\n", trigger, source); |
if (timer_out || ctrl_c) break; |
} while (source == trigger); |
tmulk (); |
usleep(sleeptime); |
#else |
osc_fpga_arm_trigger(); |
usleep(sleeptime); |
osc_fpga_set_trigger(trigger); |
while (g_osc_fpga_reg_mem->trig_source != 0){ |
if (timer_out || ctrl_c) break; |
} |
// with this loop the program waits until the acquistion is completed before continue. |
int trig_ptr = g_osc_fpga_reg_mem->wr_ptr_trigger; // get pointer to mem. adress where trigger was met |
int * ch_signal[2]; |
osc_fpga_get_sig_ptr(&ch_signal[0], &ch_signal[1]); |
#endif |
*(data_buf++) = 0x2; |
*(data_buf++) = chmask; |
for (int id = 0;id<2;id++){ |
if ( !(chmask & (1 << id)) ) continue; |
*(data_buf++) = id; |
*(data_buf++) = nsamples; |
#ifdef MRP |
const int c[2] = {RP_CH_1, RP_CH_2}; |
unsigned int isamples = nsamples; |
rp_AcqGetLatestDataV(c[id], &isamples, (float *) data_buf ); |
data_buf+=nsamples; |
#else |
const int BUF = 16*1024; |
const int offset = 0; |
if (trig_ptr > (BUF-nsamples)) // Enter logic to transition from end to beginning of cha_signal buffer. |
{ |
for (int i=trig_ptr;i<BUF;i++) *(data_buf++) = ch_signal[id][i]-offset; |
for (int i=0;i<nsamples-(BUF-trig_ptr);i++) *(data_buf++) = ch_signal[id][i]-offset; |
} |
else // Enter simple logic to send sampleSize from trigger point |
{ |
for (int i=0;i<nsamples;i++) *(data_buf++) = ch_signal[id][trig_ptr + i]-offset; |
} |
#endif |
} |
*(data_buf++) = 0x3; |
*(data_buf++) = neve; |
neve++; |
if (ieve+1 % 500 == 0) fprintf(stderr, "Event %d\n", ieve); |
if (timer_out) break; |
} |
int *len = ibuf; |
int *nev = ibuf + 1; |
float *dt = (float *)(ibuf + 2); |
*len = (data_buf-len)*sizeof(int); |
*nev = neve; |
t = clock(); |
*dt = t-t0; |
*dt /= CLOCKS_PER_SEC; |
return *len; |
} |
#define MAXLEN 0XFFFF |
struct RUNHDR { |
unsigned short neve; |
unsigned short nsamples; |
unsigned short tout; |
unsigned char trigger; |
unsigned char mask; |
int nloops ; |
int data [MAXLEN]; |
} ; |
struct INIHDR { |
int delay ; |
int decimation; |
int threshold; |
}; |
int daq_help(char *fname, struct INIHDR * i, struct RUNHDR *r, int verbosity){ |
printf("-o filename ... output filename %s\n", fname); |
printf("-v verbose ... verbosity %d\n", verbosity); |
printf("-b decimation ... decimation %d\n", i->decimation); |
printf("-i timeout ... interrupt timeout %d\n", r->tout); |
printf("-s nsamples ... number of samples %d\n", r->nsamples); |
printf("-d delay ... delay %d\n", i->delay); |
printf("-t trigger ... trigger type %d\n", r->trigger); |
printf("-l level ... trigger level %f\n", i->threshold*0.001); |
printf("-m mask ... channel mask %d\n", r->mask ); |
printf("-n neve ... number of events per call %d\n", r->neve); |
printf("-r nloops ... number of calls %d\n", r->nloops); |
return 0; |
} |
int daq_main( int argc , char ** argv) { |
// intercept routine |
if (signal (SIGINT, SigInt) == SIG_ERR) { |
perror ("sigignore"); |
} |
char filename[0xFF]=""; |
struct INIHDR inihdr = { |
.decimation = 1, |
.threshold = 100, |
.delay = 1024 |
}; |
struct RUNHDR runhdr; |
runhdr.neve =10000; |
runhdr.nsamples = 1024; |
runhdr.tout = 1000; |
runhdr.trigger = 1; |
runhdr.mask = 0x1; |
runhdr.nloops = 1; |
int verbose = 0; |
int argdata = 0; |
if (argc <2) { |
daq_help(filename, &inihdr, &runhdr, verbose); |
exit(-1); |
} |
opterr = 0; |
int c; |
while ((c = getopt (argc, argv, "o:v:b:i:s:d:t:l:m:n:r:h")) != -1) |
switch (c) { |
case 'o': |
sprintf(filename,"%s", optarg ); |
break; // output |
case 'v': |
verbose = strtoul (optarg,NULL,0); |
break; // verbosity |
case 'b': |
inihdr.decimation = strtoul (optarg,NULL,0); |
break; |
case 'i': |
runhdr.tout = strtoul (optarg,NULL,0); |
break; |
case 's': |
runhdr.nsamples = strtoul (optarg,NULL,0); |
break; |
case 'd': |
inihdr.delay = strtoul (optarg,NULL,0); |
break; |
case 't': |
runhdr.trigger = strtoul (optarg,NULL,0); |
break; |
case 'm': |
runhdr.mask = strtoul (optarg,NULL,0); |
break; |
case 'n': |
runhdr.neve = atoi (optarg); |
break; |
case 'r': |
runhdr.nloops = atoi (optarg); |
break; |
case 'l': |
inihdr.threshold = (int) (1000*atof (optarg)); |
break; |
case 'h': |
daq_help(filename, &inihdr, &runhdr, verbose); |
break; |
case '?': |
if (optopt == 'c') |
fprintf (stderr, "Option -%c requires an argument.\n", optopt); |
else if (isprint (optopt)) |
fprintf (stderr, "Unknown option `-%c'.\n", optopt); |
else |
fprintf (stderr, |
"Unknown option character `\\x%x'.\n", |
optopt); |
return 1; |
default: |
abort (); |
} |
for (int i=optind; i<argc; i++) argdata = strtoul (argv[i],NULL,0); |
if (verbose) daq_help(filename, &inihdr, &runhdr, verbose); |
printf("argdata %d nloops %d\n",argdata,runhdr.nloops); |
daq_init((char *)&inihdr); |
FILE *fp=NULL; |
if (strlen(filename)>0) fp = fopen(filename, "wb"); |
int maxlen = MAXLEN; |
char *data = (char *) malloc(maxlen * sizeof(int)); |
time_t t,tstart; |
time(&tstart); |
for (int i=0;i< runhdr.nloops;i++){ |
int nb =daq_run((const char*) &runhdr, &data, &maxlen); |
if (ctrl_c) break; |
time(&t); |
fprintf(stderr, "Loop %d dt=%d s\n", i, (int)(t-tstart)); |
if (fp) { |
fprintf(stderr, "Writing %d to %s", nb, filename); |
fwrite(data, 1, nb, fp); |
} |
} |
time(&t); |
fprintf(stderr, "Total events %d in %d s\n", runhdr.nloops*runhdr.neve, (int)(t-tstart)); |
if (fp) fclose(fp); |
if (data!=NULL) free(data); |
return 0; |
} |
/cvi/apps/RedPitaya/sockserv/etc/systemd/system/redpitaya_tcpsocket.service |
---|
0,0 → 1,21 |
[Unit] |
Description=TCP socket server for binary transfers of waveforms on Red Pitaya |
After=network.target |
[Service] |
Type=simple |
Restart=always |
#PIDFile=/var/run/redpitaya_scpi.pid |
# TODO: it should be possible to use EnvironmentFile, but it is not working properly |
# complains about failing library path, or something else |
#EnvironmentFile=/etc/sysconfig/redpitaya |
Environment=PATH_REDPITAYA=/opt/redpitaya |
Environment=LD_LIBRARY_PATH=/opt/redpitaya/lib PATH=/sbin:/usr/sbin:/bin:/usr/bin:/opt/redpitaya/sbin:/opt/redpitaya/bin |
ExecStartPre=/bin/sh -c "cat /opt/redpitaya/fpga/fpga_0.94.bit > /dev/xdevcfg" |
#ExecStart =/opt/redpitaya/bin/socket-server |
ExecStart =/root/sockserv/sockserv |
#ExecReload= |
ExecStop =/bin/kill -15 $MAINPID |
[Install] |
WantedBy=multi-user.target |
/cvi/apps/RedPitaya/sockserv/www/apps/assets/desktop.js |
---|
0,0 → 1,260 |
//------------------------------------------------- |
// Redpitaya desktop |
// Created by Alexey Kaygorodov |
//------------------------------------------------- |
; |
(function(Desktop, $) { |
var applications = []; |
var groups = [{ |
name: "System", |
description: "System tools for configuring your Red Pitaya", |
image: "../assets/images/system.png", |
applications: ["updater", "wifi", "licmngr"] |
}, { |
name: "Development", |
description: "Documentation, tutorials and a lot of interesting stuff", |
image: "../assets/images/development.png", |
applications: ["visualprogramming", "scpi", "tcpsocket", "tutorials", "fpga", "apis", "capps", "cmd", "hardwaredoc", "instructions", "github","activelearning"] |
}]; |
var currentGroup = undefined; |
Desktop.init = function() { |
// Here's should be loading from custom user groups from Cookies |
} |
Desktop.save = function() { |
// Here's should be saveing from custom user groups from Cookies |
} |
Desktop.getCurrentGroup = function() { |
return currentGroup; |
} |
Desktop.setApplications = function(listOfapplications) { |
applications = []; |
$.extend(true, applications, listOfapplications); |
var url_arr = window.location.href.split("/"); |
var url = url_arr[0] + '//' + url_arr[2] + '/'; |
for (var i = 0; i < default_applications.length; i++) { |
if (default_applications[i].id == "marketplace") |
default_applications[i].url = url + 'bazaar' |
if (default_applications[i].url[0] == "/") |
default_applications[i].url = window.location.origin + default_applications[i].url; |
applications.push(default_applications[i]); |
} |
for (var i = 0; i < applications.length; i++) { |
applications[i].group = checkApplicationInGroup(applications[i].id); |
applications[i].is_group = false; |
} |
for (var i = 0; i < groups.length; i++) { |
var gr = { |
id: "", |
name: groups[i].name, |
description: groups[i].description, |
url: "#", |
image: groups[i].image, |
check_online: false, |
licensable: false, |
callback: openGroup, |
type: 'run', |
group: "", |
is_group: true |
}; |
applications.push(gr); |
} |
applications.unshift(backButton); |
Desktop.selectGroup(); |
} |
var checkApplicationInGroup = function(app_id) { |
for (var i = 0; i < groups.length; i++) |
if (groups[i].applications.indexOf(app_id) != -1) |
return groups[i].name; |
return ""; |
} |
var openGroup = function(key) { |
Desktop.selectGroup(applications[+key].name); |
} |
var onBackButton = function() { |
Desktop.selectGroup(); |
} |
var placeElements = function() { |
var elemWidth = $('.app-item').outerWidth(true); |
var containerWidth = $('#list-container').width(); |
var elemsInRow = Math.floor(containerWidth / elemWidth); |
elemsInRow = (elemsInRow == 0) ? 1 : elemsInRow; |
var elemHeight = $('.app-item').outerHeight(true); |
var containerHeight = $('#main-container').height(); |
var elemsInCol = Math.floor(containerHeight / elemHeight); |
elemsInCol = (elemsInCol == 0) ? 1 : elemsInCol; |
$("ul.paging").quickPager({ |
pageSize: elemsInRow * elemsInCol |
}); |
} |
var refillList = function() { |
$('.app-item').unbind('click'); |
$('.app-item').unbind('mouseenter'); |
$('.app-item').unbind('mouseleave'); |
$('#main-container').empty(); |
$('#main-container').append('<ul class="paging" id="list-container"></ul>'); |
$('#list-container').empty(); |
for (var i = 0; i < applications.length; i++) { |
if ((currentGroup === undefined && (applications[i].group == "" || applications[i].group === undefined)) || applications[i].group == currentGroup || i==0) { |
var txt = '<li class="app-item" key="' + i + '" group="' + applications[i].group + '" style="display: none;">'; |
txt += '<a href="#" class="app-link"><div class="img-container"><img class="app-icon" src="' + applications[i]['image'] + '"></div><span class="app-name">' + applications[i]['name'] + '</span></a>'; |
txt += '</li>'; |
$('#list-container').append(txt); |
} |
} |
$('.app-item').click(clickApp); |
$('.app-item').mouseenter(overApp); |
$('.app-item').mouseleave(leaveApp); |
} |
Desktop.selectGroup = function(group) { |
currentGroup = group; |
refillList(); |
placeElements(); |
if (currentGroup === undefined) |
$('.app-item[key=0]').hide(); |
else |
$('.app-item[key=0]').show(); |
} |
var clickApp = function(e) { |
var key = parseInt($(this).attr('key')) * 1; |
e.preventDefault(); |
if (applications[key].check_online) { |
OnlineChecker.checkAsync(function() { |
if (!OnlineChecker.isOnline()) { |
if (applications[key].licensable) { |
$('#ignore_link').text('Ignore'); |
$('#ignore_link').attr('href', applications[key].url); |
$('#lic_failed').show(); |
} else { |
$('#ignore_link').text('Close'); |
$('#ignore_link').attr('href', "#"); |
$('#lic_failed').hide(); |
} |
$('#ic_missing').modal('show'); |
return; |
} |
if (applications[key].url != "") |
window.location = applications[key].url; |
if (applications[key].callback !== undefined) |
applications[key].callback(key); |
}); |
} else { |
if (applications[key].url != "") |
window.location = applications[key].url; |
if (applications[key].callback !== undefined) |
applications[key].callback(key); |
} |
} |
var showFeedBack = function() { |
mail = "support@redpitaya.com"; |
subject = "Feedback Red Pitaya OS " + RedPitayaOS.getVersion(); |
var body = "%0D%0A%0D%0A------------------------------------%0D%0A" + "DEBUG INFO, DO NOT EDIT!%0D%0A" + "------------------------------------%0D%0A%0D%0A"; |
body += "Browser:" + "%0D%0A" + JSON.stringify({ parameters: $.browser }) + "%0D%0A"; |
document.location.href = "mailto:" + mail + "?subject=" + subject + "&body=" + body; |
} |
var overApp = function(e) { |
var key = parseInt($(this).attr('key')) * 1; |
$('#description').html(applications[key].description); |
} |
var leaveApp = function(e) { |
$('#description').html(""); |
} |
var onSwipe = function(ev) { |
if ($('.simplePagerNav').length == 0) |
return; |
var rel = 1; |
if (ev.direction == Hammer.DIRECTION_LEFT) |
rel = parseInt($('.active-dot').parent().attr('rel')) * 1 + 1; |
else if (ev.direction == Hammer.DIRECTION_RIGHT) { |
var crel = parseInt($('.active-dot').parent().attr('rel')) * 1; |
if (crel == 1) return; |
rel = crel - 1; |
} |
var obj = $('.simplePageNav' + rel).find('a'); |
if (obj.length == 0) |
return; |
else obj.click(); |
} |
var default_applications = [ |
{ id: "github", name: "Sources", description: "Access to open source code and programming instructions", url: "https://github.com/redpitaya", image: "../assets/images/github.png", check_online: false, licensable: false, callback: undefined, type: 'run' }, |
{ id: "applicationstore", name: "Red Pitaya Store", description: "Access to Red Pitaya official store", url: "http://store.redpitaya.com/", image: "../assets/images/shop.png", check_online: false, licensable: false, callback: undefined, type: 'run' }, |
{ id: "marketplace", name: "Application marketplace", description: "Access to open source and contributed applications", url: "http://bazaar.redpitaya.com/", image: "images/download_icon.png", check_online: true, licensable: false, callback: undefined, type: 'run' }, |
{ id: "feedback", name: "Feedback", description: "Tell us what you like or dislike and what you would like to see improved", url: "", image: "../assets/images/feedback.png", check_online: true, licensable: false, callback: showFeedBack, type: 'run' }, |
{ id: "instructions", name: "Instructions", description: "Quick start instructions, user manuals, specifications, examples & more.", url: "http://redpitaya.readthedocs.io/en/latest/index.html", image: "../assets/images/instr.png", check_online: false, licensable: false, callback: undefined, type: 'run' }, |
{ id: "tutorials", name: "Create own WEB application", description: "RedPitaya tutorials.", url: "http://redpitaya.readthedocs.io/en/latest/doc/developerGuide/software/webApps.html?highlight=own%20web%20application", image: "../assets/images/tutors.png", check_online: false, licensable: false, callback: undefined, type: 'run' }, |
{ id: "wifi", name: "Network manager", description: "Simple way to establish wireless connection with the Red Pitaya", url: "/network_manager/", image: "../network_manager/info/icon.png", check_online: false, licensable: false, callback: undefined, type: 'run' }, |
{ id: "scpi", name: "SCPI server", description: "Remote access to all Red Pitaya inputs/outputs from MATLAB/LabVIEW/Scilab/Python", url: "/scpi_manager/", image: "../scpi_manager/info/icon.png", check_online: false, licensable: false, callback: undefined, type: 'run' }, |
{ id: "tcpsocket", name: "TCP socket server", description: "Remote access to all Red Pitaya inputs/outputs through binary multievent socket", url: "/tcpsocket_manager/", image: "../tcpsocket_manager/info/icon.png", check_online: false, licensable: false, callback: undefined, type: 'run' }, |
{ id: "updater", name: "Red Pitaya OS Update", description: "Red Pitaya ecosystem updater", url: "/updater/", image: "../assets/images/updater.png", check_online: false, licensable: false, callback: undefined, type: 'run' }, |
{ id: "activelearning", name: "Active Learning", description: "Active Learning with Red Pitaya", url: "http://red-pitaya-active-learning.readthedocs.io/en/latest/", image: "../assets/images/active-learning.png", check_online: false, licensable: false, callback: undefined, type: 'run' }, |
{ id: "jupyter", name: "Jupyter server", description: "Jupyter notebook server for running Python applications in a browser tab", url: "/jupyter/", image: "../jupyter_manager/info/icon.png", check_online: false, licensable: false, callback: undefined, type: 'run' }, |
]; |
var backButton = { |
id: "back", |
name: "Back", |
description: "Return to the desktop", |
url: "#", |
image: "../assets/images/back_button.png", |
check_online: false, |
licensable: false, |
callback: onBackButton, |
type: 'run', |
group: "", |
is_group: false |
}; |
$(window).resize(function($) { |
refillList(); |
placeElements(); |
Desktop.selectGroup(); |
}); |
$(document).load(function($) { |
Desktop.init(); |
}); |
$(document).ready(function($) { |
var myElement = document.getElementById('main-container'); |
var mc = new Hammer(myElement); |
mc.on('swipe', onSwipe); |
$("#reboot").click(function(event) { |
$('#reboot_dialog').modal("show"); |
}); |
$("#reboot_confirm").click(function(event) { |
$.get('/reboot'); |
setTimeout(function(){ window.close(); }, 1000); |
}); |
}); |
})(window.Desktop = window.Desktop || {}, jQuery); |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/cvi/apps/RedPitaya/sockserv/www/apps/tcpsocket_manager/css/style.css |
---|
0,0 → 1,278 |
html, body { |
width: 100%; |
height: 100%; |
} |
body { |
color: #cdcccc; |
overflow: auto; |
padding-right: 0 !important; |
} |
* { |
-webkit-touch-callout: none; |
-webkit-user-select: none; |
-khtml-user-select: none; |
-moz-user-select: none; |
-ms-user-select: none; |
user-select: none; |
} |
.clear:before, .clear:after { |
content: ""; |
display: table; |
} |
.clear:after { |
clear: both; |
} |
.modal { |
} |
.left-content-tcpsocket > p { |
color: #48b3d2; |
} |
.left-content-tcpsocket > ul > li { |
list-style-type: none; |
color: #cccccc; |
} |
.left-content-tcpsocket > ul > li:before |
{ |
content: "- "; |
} |
input, #info div, #info span, .selectable { |
-webkit-touch-callout: text; |
-webkit-user-select: text; |
-khtml-user-select: text; |
-moz-user-select: text; |
-ms-user-select: text; |
user-select: text; |
} |
input { |
-webkit-user-modify: read-write-plaintext-only; |
-webkit-tap-highlight-color: transparent; |
} |
button:focus, button:active, select:focus, input:focus, option:focus { |
outline: 0 !important; |
-webkit-appearance: none !important; |
} |
area:hover { |
cursor: pointer; |
} |
.full-content { |
/*min-width: 1024px;*/ |
margin: 0 auto; |
position: relative; |
} |
.container-fluid { |
margin-top: 20px; |
} |
.container { |
width: 100%; |
padding-left: 0px; |
padding-right: 0px; |
} |
.navbar-collapse { |
padding-left: 0px; |
padding-right: 0px; |
} |
.navbar-collapse { |
float: right; |
} |
.navbar-nav li { |
width: 131px; |
text-align: center; |
} |
.nav > li > a { |
position: relative; |
display: block; |
padding: 10px 30px; |
border-left: 1px solid #999; |
} |
.navbar-inverse .navbar-nav > li > a { |
color: #cdcccc; |
outline: none; |
} |
.nav > li > a:hover { |
background-color: #444 !important; |
color: #E5D5D5; |
} |
.navbar { |
border-radius: 0px; |
background-color: #343433; |
background-image: linear-gradient(to bottom, #343433 0, #343433 100%); |
border: 1px solid #999; |
min-height: 42px; |
border-left: 1px solid #999; |
} |
.back-btn { |
height: 22px; |
float: left; |
margin: -6px 0px 0px 11px; |
} |
.logo { |
margin: 5px 0px 0px 15px; |
float: left; |
} |
.navbar-collapse collapse in { |
width: 100%; |
overflow: hidden; |
} |
.navbar-brand { |
height: 40px; |
} |
.close { |
color: #CAB7B7; |
opacity: 1; |
text-shadow: 0 0 0 !important; |
} |
.modal-content { |
background-color: #343433; |
border: 1px solid #999; |
border-radius: 0px; |
outline: 0; |
} |
#main { |
margin-right: 188px; |
} |
.dialog { |
margin-right: 0px; |
display: none; |
} |
.close:hover, .close:focus { |
color: #fff !important; |
text-decoration: none; |
cursor: pointer; |
opacity: 1; |
} |
.btn { |
background-image: none; |
border: 0 solid transparent; |
white-space: nowrap; |
padding: 6px 12px; |
line-height: 1.42857143; |
border-radius: 0; |
width: 100%; |
background-color: transparent; |
text-shadow: 0px 0px; |
/* box-shadow: 0 0 0 1px #777; */ |
color:#cdcccc !important; |
} |
.btn:hover, btn:active { |
color: #fff !important; |
background-image: none; |
} |
.btn.focus { |
color: #777; |
border: 0px solid transparent; |
} |
.btn:active, .btn.active { |
background-image: none; |
background-color: #999; |
color: #111 !important; |
} |
.left-tcpsocket { |
float:left; |
width:100%; |
} |
.left-content-tcpsocket { |
margin-right:120px; |
} |
.right-tcpsocket { |
float:right; |
width: 120px; |
margin-left: -120px; |
} |
#header { |
background-color: black; |
color: #CCC; |
text-align: center; |
padding: 6px; |
overflow: hidden; |
height: 30px; |
width: 100%; |
white-space: nowrap; |
} |
.example_button |
{ |
margin-top: 20px; |
width: 131px; |
text-align: center; |
list-style: none; |
height: 40px; |
padding-top:10px; |
border: 1px solid; |
} |
.example_button:hover |
{ |
background: gray; |
cursor: pointer; |
} |
.example_button span { |
color: #337ab7; |
} |
.run_buttons { |
display: inline-block; |
text-align: center; |
border: 1px solid; |
border-color: #cccccc;; |
background-color: #47b2d1; |
color: #000000; |
margin: 0 auto; |
margin-top: 15px; |
margin-bottom: 15px; |
font-size: 16pt; |
padding: 6px 20px 6px 20px; |
width: 120px; |
} |
.run_buttons:hover { |
background-color: #69d4d1; |
cursor: pointer; |
} |
.run_buttons a { |
color: #000000; |
text-decoration: none; |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/cvi/apps/RedPitaya/sockserv/www/apps/tcpsocket_manager/fpga.conf |
---|
0,0 → 1,0 |
/opt/redpitaya/fpga/fpga_0.94.bit |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/cvi/apps/RedPitaya/sockserv/www/apps/tcpsocket_manager/img/apps.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/cvi/apps/RedPitaya/sockserv/www/apps/tcpsocket_manager/img/dummy.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/cvi/apps/RedPitaya/sockserv/www/apps/tcpsocket_manager/index.html |
---|
0,0 → 1,168 |
<!-- $Id$ |
* |
* Red Pitaya TCPSOCKET service manager |
* |
* Author: Dakus <info@eskala.eu> |
* |
* (c) Red Pitaya http://www.redpitaya.com |
* |
--> |
<!DOCTYPE html> |
<html lang="en"> |
<head> |
<meta http-equiv="content-type" content="text/html; charset=utf-8"></meta> |
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> |
<title>Red Pitaya</title> |
<link rel="stylesheet" href="../assets/bootstrap/css/bootstrap.min.css"> |
<link rel="stylesheet" href="../assets/popupstack.css" type="text/css" /> |
<link rel="stylesheet" href="../assets/help-system/help-system.css" type="text/css" /> |
<link rel="stylesheet" href="css/style.css?2"> |
<script src="../assets/jquery/jquery-2.1.3.min.js"></script> |
<script src="../assets/jquery/jquery-ui.min.js"></script> |
<script src="../assets/jquery/jquery.ui.touch-punch.min.js"></script> |
<script src="../assets/jquery/jquery.cookie.js?3"></script> |
<script src="../assets/jquery/jquery.browser.js"></script> |
<script src="../assets/bootstrap/js/bootstrap.min.js"></script> |
<script src="../assets/browsercheck.js?1"></script> |
<script src="../assets/analytics-core.js"></script> |
<script src="../assets/popupstack.js?1"></script> |
<script src="../assets/help-system/help-system.js"></script> |
<script src="js/help-tcpsocket.js"></script> |
<script src="js/manager.js?3"></script> |
<script src="js/analytics-main.js?1"></script> |
</head> |
<body> |
<div id="loader-wrapper"> |
<div id="loader"></div> |
</div> |
<div id="header"> |
<div id="description"> </div> |
</div> |
<div class="full-content"> |
<div class="container-fluid"> |
<div class="navbar navbar-inverse" role="navigation"> |
<div class="container"> |
<div class="navbar-header"> |
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> |
<span class="sr-only">T</span> |
<span class="icon-bar"></span> |
<span class="icon-bar"></span> |
<span class="icon-bar"></span> |
</button> |
<a class="navbar-brand" href="/"> |
<img class="back-btn" src="../assets/images/navigation_arrow_left.png"> |
</a> |
<img class="logo" width=110 src="../assets/images/navigation_logo.png"> |
</div> |
<div class="collapse navbar-collapse"> |
<ul class="nav navbar-nav"> |
</ul> |
</div> |
</div> |
</div> |
<div id="global_container" style="position: relative;"> |
<div id="main"> |
<div class="left-tcpsocket"> |
<div class="left-content-tcpsocket" style="font-size: 18pt; color: gray;"> |
<p>TCPSOCKET server application</p> |
<ul> |
<li>Enables remote control of Red Pitaya using multievent binary buffer</li> |
<li>Provides access to Red Pitaya waveform sampler (fast ADC).</li> |
<li>Supports WIFI or LAN remote interface</li> |
</ul> |
</div> |
</div> |
<div class="right-tcpsocket"> |
<br> |
<br> |
<br> |
<img src="img/apps.png" width="200%"> |
</div> |
<div> |
<div id="label-is-runnung" align=center style="font-size: 16pt; color: red;"> |
TCPSOCKET server is not running, press RUN button to start it |
</div> |
<div id="label-is-not-runnung" align=center style="font-size: 16pt; color: green; display: none;"> |
TCPSOCKET server is running... (IP="<span id="ip-addr">127.0.0.1</span>", port="9930") |
</div> |
<div align="center"> |
<ul class=""> |
<li class="run_buttons" id="TCPSOCKET_RUN"> |
<a href="#" id="a_run" style="">RUN</a> |
</li> |
<li class="run_buttons" id="TCPSOCKET_STOP" style="display:none;"> |
<a href="#" id="a_stop">STOP</a> |
</li> |
</ul> |
</div> |
<div align=center> |
Example about how to Control your Red Pitaya using MATLAB/Python/LabVIEW/Scilab. |
Are available on link below |
<div align="center"> |
<ul class=""> |
<li class="example_button" id="TCPSOCKET_EXAMPLES"> |
<span>Examples</span> |
</li> |
</ul> |
</div> |
</div> |
</div> |
</div> |
</div> |
</div> |
</div> |
<div> |
<div id="sys_info_view" style="display:none; position:fixed; bottom:0; left: 0; background-color: rgba(0, 0, 0, 0.2); text-align:left; padding: 5px; font-size:12px; color:white; "> |
FPS:<span id="fps_view">0</span> Throughput:<span id="throughput_view">0</span> CPU Load:<span id="cpu_load">0</span> |
<br/> Memory total:<span id="totalmem_view">0</span> Free:<span id="freemem_view">0</span> Usage:<span id="usagemem_view">0</span> |
</div> |
</div> |
<div class="modal fade" id="feedback_error" tabindex="-1" role="dialog" aria-labelledby="bazaar_naLabel" aria-hidden="true"> |
<div class="modal-dialog"> |
<div class="modal-content"> |
<div class="modal-header"> |
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> |
<h4 class="modal-title" id="oops_label">Oops, something went wrong</h4> |
</div> |
<div class="modal-body" style="text-align: center; font-size: 18px;"> |
<p>Please send us the report and help us to fix this issue</p> |
<p>Thank you!</p> |
</div> |
<div class="modal-footer"> |
<div class="bazaar-link" style="float: left; width: 50%;"> |
<a href="#" style="border: 1px solid; width: 100%" id="send_report_btn" data-dismiss="modal" class="list-group-item btn">Send report</a> |
</div> |
<div class="bazaar-link" style="float: left; width: 50%;"> |
<a href="#" style="border: 1px solid; width: 100%" id="restart_app_btn" data-dismiss="modal" class="list-group-item btn">Restart Application</a> |
</div> |
</div> |
</div> |
</div> |
</div> |
<div class="modal fade" id="analytics_dialog" tabindex="-1" role="dialog" aria-labelledby="bazaar_naLabel" aria-hidden="true"> |
<div class="modal-dialog"> |
<div class="modal-content"> |
<div class="modal-header"> |
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> |
<h4 class="modal-title" id="bazaar_naLabel">Diagnostic & Usage</h4> |
</div> |
<div class="modal-body"> |
<p>Would you like to help Red Pitaya team to improve its product and services by occasionally providing anonymous diagnostic and usage information?</p> |
</div> |
<div class="modal-footer"> |
<div class="bazaar-link" style="float: left; width: 50%;"> |
<a href="#" data-dismiss="modal" id="enable_analytics" class="list-group-item btn">Yes</a> |
</div> |
<div class="bazaar-link" style="float: left; width: 50%;"> |
<a href="#" data-dismiss="modal" id="disable_analytics" class="list-group-item btn">No</a> |
</div> |
</div> |
</div> |
</div> |
</div> |
</body> |
</html> |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/cvi/apps/RedPitaya/sockserv/www/apps/tcpsocket_manager/info/icon.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/cvi/apps/RedPitaya/sockserv/www/apps/tcpsocket_manager/info/info.json |
---|
0,0 → 1,6 |
{ |
"name": "TcpSocket", |
"version": "0.96-336", |
"revision": "4506f6e", |
"description": "Remote access and binary multievent transfer of waveforms" |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/cvi/apps/RedPitaya/sockserv/www/apps/tcpsocket_manager/js/analytics-main.js |
---|
0,0 → 1,21 |
//------------------------------------------------- |
// Redpitaya analytics system |
// Created by Alexey Kaygorodov |
//------------------------------------------------- |
(function($) { |
var startUsing = 0; |
$(document).ready(function($) { |
AnalyticsCore.init(function(){ |
AnalyticsCore.sendExecTime('/tcpsocket_manager', 'tcpsocket_manager'); |
AnalyticsCore.sendScreenView('/tcpsocket_manager', 'Redpitaya', 'Remote control'); |
AnalyticsCore.sendSysInfo('/tcpsocket_manager'); |
startUsing = performance.now(); |
}); |
}); |
$(window).on('beforeunload', function(){ |
$.cookie('tcpsocket_manager-run', performance.now() - startUsing); |
}); |
})(jQuery); |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/cvi/apps/RedPitaya/sockserv/www/apps/tcpsocket_manager/js/help-tcpsocket.js |
---|
0,0 → 1,27 |
var helpListTCPSOCKET = |
{ |
idle: [ |
{ |
Text: "How to control your Red Pitaya remotely?", |
URL: "http://redpitaya.com/control/", |
Img: "pool" |
}, |
{ |
Text: "Red Pitaya's Forum", |
URL: "http://forum.redpitaya.com/", |
Img: "star" |
} |
], |
loaded: [ |
{ |
Text: "Description3", |
URL: "http://redpitaya.com", |
Img: "star" |
}, |
{ |
Text: "Description4", |
URL: "http://redpitaya.com", |
Img: "pool" |
} |
] |
}; |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/cvi/apps/RedPitaya/sockserv/www/apps/tcpsocket_manager/js/manager.js |
---|
0,0 → 1,120 |
/* |
* Red Pitaya TCPSOCKET service manager |
* |
* Author: Artem Kokos <a.kokos@integrasources.eu> |
* |
* (c) Red Pitaya http://www.redpitaya.com |
* |
*/ |
(function(TCPSOCKET, $, undefined) { |
TCPSOCKET.CheckServerStatus = function() { |
$.ajax({ |
url: '/get_tcpsocket_status', |
type: 'GET', |
timeout: 1500 |
}) |
.fail(function(msg) { |
if (msg.responseText.split('\n')[0] == "active") { |
$('#TCPSOCKET_RUN').hide(); |
$('#TCPSOCKET_STOP').css('display', 'block'); |
$('#label-is-runnung').hide(); |
$('#label-is-not-runnung').show(); |
} else { |
$('#TCPSOCKET_STOP').hide(); |
$('#TCPSOCKET_RUN').css('display', 'block'); |
$('#label-is-not-runnung').hide(); |
$('#label-is-runnung').show(); |
} |
}) |
} |
TCPSOCKET.StartServer = function() { |
$.ajax({ |
url: '/start_tcpsocket_manager', |
type: 'GET', |
timeout: 1500 |
}) |
.fail(function(msg) { |
if (msg.responseText) {} else {} |
}) |
} |
TCPSOCKET.StopServer = function() { |
$.ajax({ |
url: '/stop_tcpsocket_manager', |
type: 'GET', |
timeout: 1500 |
}) |
.fail(function(msg) { |
if (msg.responseText) {} else {} |
}) |
} |
TCPSOCKET.GetIP = function() { |
$.ajax({ |
url: '/get_rpip', |
type: 'GET', |
}).fail(function(msg) { |
var res = msg.responseText.split(";"); |
var ethIP = res[0].match(/inet\s+\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/2[0-90]\b/); |
var wlanIP = res[1].match(/inet\s+\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/2[0-90]\b/); |
if (ethIP != null){ |
ethIP = ethIP[0].split(" ")[1].split("/")[0]; |
$('#ip-addr').text(ethIP); |
} |
else if (wlanIP != null){ |
wlanIP = wlanIP[0].split(" ")[1].split("/")[0]; |
$('#ip-addr').text(wlanIP); |
} |
else $('#ip-addr').text("None"); |
}).done(function(msg) { |
var res = msg.responseText.split(";"); |
var ethIP = res[0].match(/inet\s+\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/2[0-90]\b/); |
var wlanIP = res[1].match(/inet\s+\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/2[0-90]\b/); |
if (ethIP != null){ |
ethIP = ethIP[0].split(" ")[1].split("/")[0]; |
$('#ip-addr').text(ethIP); |
} |
else if (wlanIP != null){ |
wlanIP = wlanIP[0].split(" ")[1].split("/")[0]; |
$('#ip-addr').text(wlanIP); |
} |
else $('#ip-addr').text("None"); |
}); |
} |
}(window.TCPSOCKET = window.TCPSOCKET || {}, jQuery)); |
// Page onload event handler |
$(function() { |
// Init help |
Help.init(helpListTCPSOCKET); |
Help.setState("idle"); |
TCPSOCKET.CheckServerStatus(); |
setInterval(TCPSOCKET.GetIP, 1000); |
setInterval(TCPSOCKET.CheckServerStatus, 3000); |
$('#TCPSOCKET_RUN').click(TCPSOCKET.StartServer); |
$('#TCPSOCKET_STOP').click(TCPSOCKET.StopServer); |
$('#TCPSOCKET_EXAMPLES').click(function(){ |
window.open('http://redpitaya.com/examples-new/','_blank'); |
}); |
}); |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/cvi/apps/RedPitaya/sockserv/www/apps/tcpsocket_manager/nginx.conf |
---|
0,0 → 1,68 |
location /get_tcpsocket_status { |
add_header 'Access-Control-Allow-Origin' '*'; |
add_header 'Access-Control-Allow-Credentials' 'true'; |
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; |
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; |
default_type application/json; |
content_by_lua ' |
local f = io.popen("systemctl is-active redpitaya_tcpsocket.service") |
local content = f:read("*all") |
f:close() |
ngx.say(content) |
'; |
} |
location /start_tcpsocket_manager { |
add_header 'Access-Control-Allow-Origin' '*'; |
add_header 'Access-Control-Allow-Credentials' 'true'; |
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; |
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; |
default_type application/json; |
content_by_lua ' |
local f = io.popen("systemctl start redpitaya_tcpsocket.service") |
f:close() |
ngx.say("OK") |
'; |
} |
location /stop_tcpsocket_manager { |
add_header 'Access-Control-Allow-Origin' '*'; |
add_header 'Access-Control-Allow-Credentials' 'true'; |
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; |
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; |
default_type application/json; |
content_by_lua ' |
local f = io.popen("systemctl stop redpitaya_tcpsocket.service") |
f:close() |
ngx.say("OK") |
'; |
} |
location /get_rpip { |
add_header 'Access-Control-Allow-Origin' '*'; |
add_header 'Access-Control-Allow-Credentials' 'true'; |
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; |
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; |
default_type application/json; |
content_by_lua ' |
local eth = io.popen("ip -4 addr list eth0") |
local wlan = io.popen("ip addr list wlan0wext") |
local eth_content = eth:read("*all") |
local wlan_content = wlan:read("*all") |
eth:close() |
wlan:close() |
ngx.say(eth_content..";"..wlan_content) |
'; |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/cvi/apps/RedPitaya/sockserv/sockserv.sh |
---|
0,0 → 1,4 |
#!/bin/bash |
export LD_LIBRARY_PATH=/opt/redpitaya/lib/ |
cat /opt/redpitaya/fpga/fpga_0.94.bit > /dev/xdevcfg |
./sockserv |
/cvi/apps/RedPitaya/sockserv/Makefile |
---|
0,0 → 1,96 |
CFLAGS = -DMRP |
# |
# $Id: Makefile 1249 2014-02-22 20:21:40Z ales.bardorfer $ |
# |
# (c) Red Pitaya http://www.redpitaya.com |
# |
# Trigger |
# Trigger project source file. |
# |
# make CROSS_COMPILE=arm-linux-gnueabi- clean all |
# on PC and move to Red Pitaya: |
# scp trig root@172.16.255.27:/tmp |
# |
# This project file is written for GNU/Make software. For more details please |
# visit: http://www.gnu.org/software/make/manual/make.html |
# GNU Compiler Collection (GCC) tools are used for the compilation and linkage. |
# For the details about the usage and building please visit: |
# http://gcc.gnu.org/onlinedocs/gcc/ |
# |
# Versioning system |
VERSION ?= 0.00-0000 |
REVISION ?= devbuild |
# List of compiled object files (not yet linked to executable) |
OBJS = sockserv.o fpga_osc.o calib.o daq.o |
# List of raw source files (all object files, renamed from .o to .c) |
SRCS = $(subst .o,.c, $(OBJS))) |
# Executable name |
TARGET=sockserv |
# GCC compiling & linking flags |
CFLAGS += -g -std=gnu99 -Wall -Werror |
CFLAGS += -DVERSION=$(VERSION) -DREVISION=$(REVISION) |
CFLAGS += -DDEBUG |
CFLAGS += -I/opt/redpitaya/include |
CFLAGS += -L/opt/redpitaya/lib |
#LDLIBS = -lm -lpthread -lrp |
# Red Pitaya common SW directory |
SHARED=/opt/redpitaya |
# Additional libraries which needs to be dynamically linked to the executable |
# -lm - System math library (used by cos(), sin(), sqrt(), ... functions) |
LIBS=-lm -lpthread -lrp |
# Main GCC executable (used for compiling and linking) |
CC=$(CROSS_COMPILE)gcc |
# Installation directory |
INSTALL_DIR ?= . |
# Makefile is composed of so called 'targets'. They give basic structure what |
# needs to be execued during various stages of the building/removing/installing |
# of software package. |
# Simple Makefile targets have the following structure: |
# <name>: <dependencies> |
# <command1> |
# <command2> |
# ... |
# The target <name> is completed in the following order: |
# - list od <dependencies> finished |
# - all <commands> in the body of targets are executed succsesfully |
# Main Makefile target 'all' - it iterates over all targets listed in $(TARGET) |
# variable. |
all: $(TARGET) |
# Target with compilation rules to compile object from source files. |
# It applies to all files ending with .o. During partial building only new object |
# files are created for the source files (.c) which have newer timestamp then |
# objects (.o) files. |
%.o: %.c version.h |
$(CC) -c $(CFLAGS) $< -o $@ |
# Makefile target with rules how to link executable for each target from $(TARGET) |
# list. |
$(TARGET): $(OBJS) |
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) |
# Version header for traceability |
version.h: |
cp $(SHARED)/include/redpitaya/version.h . |
# Clean target - when called it cleans all object files and executables. |
clean: |
rm -f $(TARGET) *.o |
# Install target - creates 'bin/' sub-directory in $(INSTALL_DIR) and copies all |
# executables to that location. |
install: |
mkdir -p $(INSTALL_DIR)/bin |
cp $(TARGET) $(INSTALL_DIR)/bin |
mkdir -p $(INSTALL_DIR)/src/utils/$(TARGET) |
-rm -f $(TARGET) *.o |
cp -r * $(INSTALL_DIR)/src/utils/$(TARGET)/ |
-rm `find $(INSTALL_DIR)/src/tools/$(TARGET)/ -iname .svn` -rf |
/cvi/apps/RedPitaya/sockserv/daq.h |
---|
0,0 → 1,10 |
#ifndef DAQ_H |
#define DAQ_H |
int daq_init (char * buff); |
int daq_clear (); |
int daq_end (); |
int daq_run (const char *par, char ** buff, int *maxlen); |
int daq_main (int argc, char **argv); |
#endif |
/cvi/apps/RedPitaya/sockserv/sockserv.c |
---|
0,0 → 1,209 |
/* |
C socket server example, handles multiple clients using threads */ |
#include<stdio.h> |
#include<string.h> //strlen |
#include<stdlib.h> //strlen |
#include<sys/socket.h> |
#include<arpa/inet.h> //inet_addr |
#include<unistd.h> |
#//write |
#include<pthread.h> |
#include "daq.h" |
#define PORT 9930 |
//the thread function |
void *connection_handler(void *); |
int is_connected = 0; |
int ncalls=0; |
extern int ctrl_c; |
int writesock(int sock, int id , char *msg, int len ){ |
int hdr[2]; |
hdr[0]= id; |
hdr[1]= len + 8; |
write(sock , hdr , 8); |
return write(sock , msg , len); |
} |
int main(int argc , char *argv[]) { |
int socket_desc , client_sock , c , *new_sock=NULL; |
struct sockaddr_in server , client; |
if (argc >1) return daq_main(argc, argv); |
//Create socket |
socket_desc = socket(AF_INET , SOCK_STREAM , 0); |
if (socket_desc == -1) |
{ |
printf("Could not create socket"); |
} |
puts("Socket created"); |
//Prepare the sockaddr_in structure |
server.sin_family = AF_INET; |
server.sin_addr.s_addr = INADDR_ANY; |
server.sin_port = htons( PORT ); |
//Bind |
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) |
{ |
//print the error message |
perror("bind failed. Error"); |
return 1; |
} |
puts("bind done"); |
//Listen |
listen(socket_desc , 3); |
//Accept and incoming connection |
puts("Waiting for incoming connections..."); |
c = sizeof(struct sockaddr_in); |
//Accept and incoming connection |
puts("Waiting for incoming connections..."); |
c = sizeof(struct sockaddr_in); |
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) ) |
{ |
puts("Connection accepted"); |
pthread_t sniffer_thread; |
if (is_connected){ |
char message[0xFF]="Only one client can connect. Disconnect it first!"; |
perror(message); |
writesock(client_sock , 0, message , strlen(message)); |
close (client_sock); |
continue; |
} |
new_sock = (int *) malloc(1); |
*new_sock = client_sock; |
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0) |
{ |
perror("could not create thread"); |
return 1; |
} |
//Now join the thread , so that we dont terminate before the thread |
//pthread_join( sniffer_thread , NULL); |
puts("Handler assigned"); |
} |
if (client_sock < 0) |
{ |
perror("accept failed"); |
return 1; |
} |
return 0; |
} |
void *daq_handler(void *rdata){ |
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); |
//Get the socket descriptor |
int sock = *(int*)rdata; |
int *idata = (int *)rdata; |
char * settings = (char *) (idata+2); |
daq_init(settings); |
settings +=12; |
int bufsize = 0; |
char * data = NULL; |
//for(int i =0;i<5;i++) printf("%d %d\n",i, idata[i]); |
while (1){ |
int nb = daq_run ( settings, &data, &bufsize ); |
int error = 0; |
socklen_t len = sizeof (error); |
int retval = getsockopt (sock, SOL_SOCKET, SO_ERROR, &error, &len); |
if (retval!=0 || error!=0) break; |
writesock(sock , 1, data , nb ); |
if (ctrl_c) break; |
//break; |
} |
if (data!=NULL) free(data); |
fprintf(stderr, "Exiting thread %d\n", sock ) ; |
return NULL; |
} |
/* |
* This will handle connection for each client |
* */ |
void *connection_handler(void *socket_desc) { |
//Get the socket descriptor |
int sock = *(int*)socket_desc; |
int read_size; |
char *message , client_message[2000]; |
is_connected = 1; |
//Send some messages to the client |
message = "Info from connection handler\n"; |
writesock(sock , 0, message , strlen(message)); |
//Receive a message from client |
pthread_t daq_thread = 0; |
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 ) |
{ |
//Send the message back to client |
int * hdr = (int *) client_message; |
printf("Received %d bytes RECID = %d LEN %d\n",read_size, hdr[0], hdr[1]); |
switch (hdr[0]){ |
case 0: |
ctrl_c = 0; |
hdr[0]= sock; |
if( pthread_create( &daq_thread , NULL , daq_handler , (void*) &client_message) < 0) |
{ |
perror("could not create daq thread"); |
} |
break; |
case 1: |
ctrl_c = 1; |
sleep(1); |
if (daq_thread) { |
pthread_cancel(daq_thread); |
daq_thread = 0; |
} |
break; |
default: break; |
} |
} |
if(read_size == 0) |
{ |
puts("Client disconnected"); |
fflush(stdout); |
} |
else if(read_size == -1) |
{ |
perror("recv failed"); |
} |
if (daq_thread) { |
pthread_cancel(daq_thread); |
daq_thread = 0; |
} |
//Free the socket pointer |
free(socket_desc); |
socket_desc = 0; |
is_connected = 0; |
return 0; |
} |
/cvi/apps/RedPitaya/sockserv/calib.c |
---|
0,0 → 1,105 |
/** |
* $Id: calib.c 881 2013-12-16 05:37:34Z rp_jmenart $ |
* |
* @brief Red Pitaya Oscilloscope Calibration Module. |
* |
* @Author Jure Menart <juremenart@gmail.com> |
* |
* (c) Red Pitaya http://www.redpitaya.com |
* |
* This part of code is written in C programming language. |
* Please visit http://en.wikipedia.org/wiki/C_(programming_language) |
* for more details on the language used herein. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <errno.h> |
#include <string.h> |
#include "calib.h" |
const char eeprom_device[]="/sys/bus/i2c/devices/0-0050/eeprom"; |
const int eeprom_calib_off=0x0008; |
/*----------------------------------------------------------------------------*/ |
/** |
* @brief Read calibration parameters from EEPROM device. |
* |
* Function reads calibration parameters from EEPROM device and stores them to the |
* specified buffer. Communication to the EEPROM device is taken place through |
* appropriate system driver accessed through the file system device |
* /sys/bus/i2c/devices/0-0050/eeprom. |
* |
* @param[out] calib_params Pointer to destination buffer. |
* @retval 0 Success |
* @retval -1 Failure, error message is put on stderr device |
* |
*/ |
int rp_read_calib_params(rp_calib_params_t *calib_params) |
{ |
FILE *fp; |
size_t size; |
/* sanity check */ |
if(calib_params == NULL) { |
fprintf(stderr, "rp_read_calib_params(): input structure " |
"not initialized\n"); |
return -1; |
} |
/* open eeprom device */ |
fp=fopen(eeprom_device, "r"); |
if(fp == NULL) { |
fprintf(stderr, "rp_read_calib_params(): Can not open EEPROM device: " |
" %s\n", strerror(errno)); |
return -1; |
} |
/* ...and seek to the appropriate storage offset */ |
if(fseek(fp, eeprom_calib_off, SEEK_SET) < 0) { |
fclose(fp); |
fprintf(stderr, "rp_read_calib_params(): fseek() failed: %s\n", |
strerror(errno)); |
return -1; |
} |
/* read data from eeprom component and store it to the specified buffer */ |
size=fread(calib_params, sizeof(char), sizeof(rp_calib_params_t), fp); |
if(size != sizeof(rp_calib_params_t)) { |
fclose(fp); |
fprintf(stderr, "rp_read_calib_params(): fread() failed, " |
"returned bytes: %d (should be :%d)\n", size, |
sizeof(rp_calib_params_t)); |
return -1; |
} |
fclose(fp); |
return 0; |
} |
/*----------------------------------------------------------------------------*/ |
/** |
* Initialize calibration parameters to default values. |
* |
* @param[out] calib_params Pointer to target buffer to be initialized. |
* @retval 0 Success, could never fail. |
*/ |
int rp_default_calib_params(rp_calib_params_t *calib_params) |
{ |
calib_params->fe_ch1_fs_g_hi = 28101971; /* 0.6543 [V] */ |
calib_params->fe_ch2_fs_g_hi = 28101971; /* 0.6543 [V] */ |
calib_params->fe_ch1_fs_g_lo = 625682246; /* 14.56 [V] */ |
calib_params->fe_ch2_fs_g_lo = 625682246; /* 14.56 [V] */ |
calib_params->fe_ch1_dc_offs = 585; |
calib_params->fe_ch2_dc_offs = 585; |
calib_params->be_ch1_fs = 42949673; /* 1 [V] */ |
calib_params->be_ch2_fs = 42949673; /* 1 [V] */ |
calib_params->be_ch1_dc_offs = 0x3eac; |
calib_params->be_ch2_dc_offs = 0x3eac; |
return 0; |
} |
/cvi/apps/RedPitaya/sockserv/calib.h |
---|
0,0 → 1,45 |
/** |
* $Id: calib.h 881 2013-12-16 05:37:34Z rp_jmenart $ |
* |
* @brief Red Pitaya Oscilloscope Calibration Module. |
* |
* @Author Jure Menart <juremenart@gmail.com> |
* |
* (c) Red Pitaya http://www.redpitaya.com |
* |
* This part of code is written in C programming language. |
* Please visit http://en.wikipedia.org/wiki/C_(programming_language) |
* for more details on the language used herein. |
*/ |
#ifndef __CALIB_H |
#define __CALIB_H |
#include <stdint.h> |
/** @defgroup calib_h Calibration |
* @{ |
*/ |
/** Calibration parameters, stored in eeprom device |
*/ |
typedef struct rp_osc_calib_params_s { |
uint32_t fe_ch1_fs_g_hi; /**< High gain front end full scale voltage, channel 1 */ |
uint32_t fe_ch2_fs_g_hi; /**< High gain front end full scale voltage, channel 2 */ |
uint32_t fe_ch1_fs_g_lo; /**< Low gain front end full scale voltage, channel 1 */ |
uint32_t fe_ch2_fs_g_lo; /**< Low gain front end full scale voltage, channel 2 */ |
int32_t fe_ch1_dc_offs; /**< Front end DC offset, channel 1 */ |
int32_t fe_ch2_dc_offs; /**< Front end DC offset, channel 2 */ |
uint32_t be_ch1_fs; /**< Back end full scale voltage, channel 1 */ |
uint32_t be_ch2_fs; /**< Back end full scale voltage, channel 2 */ |
int32_t be_ch1_dc_offs; /**< Back end DC offset, channel 1 */ |
int32_t be_ch2_dc_offs; /**< Back end DC offset, on channel 2 */ |
} rp_calib_params_t; |
/** @} */ |
int rp_read_calib_params(rp_calib_params_t *calib_params); |
int rp_default_calib_params(rp_calib_params_t *calib_params); |
#endif //__CALIB_H |
/cvi/apps/RedPitaya/sockserv/fpga_osc.c |
---|
0,0 → 1,564 |
/** |
* $Id: fpga_osc.c 881 2013-12-16 05:37:34Z rp_jmenart $ |
* |
* @brief Red Pitaya Oscilloscope FPGA controller. |
* |
* @Author Jure Menart <juremenart@gmail.com> |
* |
* (c) Red Pitaya http://www.redpitaya.com |
* |
* This part of code is written in C programming language. |
* Please visit http://en.wikipedia.org/wiki/C_(programming_language) |
* for more details on the language used herein. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <math.h> |
#include <errno.h> |
#include <sys/mman.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <unistd.h> |
#include <fcntl.h> |
#include "fpga_osc.h" |
/** |
* GENERAL DESCRIPTION: |
* |
* This module initializes and provides for other SW modules the access to the |
* FPGA OSC module. The oscilloscope memory space is divided to three parts: |
* - registers (control and status) |
* - input signal buffer (Channel A) |
* - input signal buffer (Channel B) |
* |
* This module maps physical address of the oscilloscope core to the logical |
* address, which can be used in the GNU/Linux user-space. To achieve this, |
* OSC_FPGA_BASE_ADDR from CPU memory space is translated automatically to |
* logical address with the function mmap(). After all the initialization is done, |
* other modules can use this module to controll oscilloscope FPGA core. Before |
* any functions or functionality from this module can be used it needs to be |
* initialized with osc_fpga_init() function. When this module is no longer |
* needed osc_fpga_exit() must be called. |
* |
* FPGA oscilloscope state machine in various modes. Basic principle is that |
* SW sets the machine, 'arm' the writting machine (FPGA writes from ADC to |
* input buffer memory) and then set the triggers. FPGA machine is continue |
* writting to the buffers until the trigger is detected plus the amount set |
* in trigger delay register. For more detauled description see the FPGA OSC |
* registers description. |
* |
* Nice example how to use this module can be seen in worker.c module. |
*/ |
/* internal structures */ |
/** The FPGA register structure (defined in fpga_osc.h) */ |
osc_fpga_reg_mem_t *g_osc_fpga_reg_mem = NULL; |
/** The FPGA input signal buffer pointer for channel A */ |
uint32_t *g_osc_fpga_cha_mem = NULL; |
/** The FPGA input signal buffer pointer for channel B */ |
uint32_t *g_osc_fpga_chb_mem = NULL; |
/** The memory file descriptor used to mmap() the FPGA space */ |
int g_osc_fpga_mem_fd = -1; |
/* Constants */ |
/** ADC number of bits */ |
const int c_osc_fpga_adc_bits = 14; |
/** @brief Max and min voltage on ADCs. |
* Symetrical - Max Voltage = +14, Min voltage = -1 * c_osc_fpga_max_v |
*/ |
const float c_osc_fpga_adc_max_v = +14; |
/** Sampling frequency = 125Mspmpls (non-decimated) */ |
const float c_osc_fpga_smpl_freq = 125e6; |
/** Sampling period (non-decimated) - 8 [ns] */ |
const float c_osc_fpga_smpl_period = (1. / 125e6); |
/** |
* @brief Internal function used to clean up memory. |
* |
* This function un-maps FPGA register and signal buffers, closes memory file |
* descriptor and cleans all memory allocated by this module. |
* |
* @retval 0 Success |
* @retval -1 Error happened during cleanup. |
*/ |
int __osc_fpga_cleanup_mem(void) |
{ |
/* If register structure is NULL we do not need to un-map and clean up */ |
if(g_osc_fpga_reg_mem) { |
if(munmap(g_osc_fpga_reg_mem, OSC_FPGA_BASE_SIZE) < 0) { |
fprintf(stderr, "munmap() failed: %s\n", strerror(errno)); |
return -1; |
} |
g_osc_fpga_reg_mem = NULL; |
if(g_osc_fpga_cha_mem) |
g_osc_fpga_cha_mem = NULL; |
if(g_osc_fpga_chb_mem) |
g_osc_fpga_chb_mem = NULL; |
} |
if(g_osc_fpga_mem_fd >= 0) { |
close(g_osc_fpga_mem_fd); |
g_osc_fpga_mem_fd = -1; |
} |
return 0; |
} |
/** |
* @brief Maps FPGA memory space and prepares register and buffer variables. |
* |
* This function opens memory device (/dev/mem) and maps physical memory address |
* OSC_FPGA_BASE_ADDR (of length OSC_FPGA_BASE_SIZE) to logical addresses. It |
* initializes the pointers g_osc_fpga_reg_mem, g_osc_fpga_cha_mem and |
* g_osc_fpga_chb_mem to point to FPGA OSC. |
* If function failes FPGA variables must not be used. |
* |
* @retval 0 Success |
* @retval -1 Failure, error is printed to standard error output. |
*/ |
int osc_fpga_init(void) |
{ |
/* Page variables used to calculate correct mapping addresses */ |
void *page_ptr; |
long page_addr, page_off, page_size = sysconf(_SC_PAGESIZE); |
/* If module was already initialized once, clean all internals. */ |
if(__osc_fpga_cleanup_mem() < 0) |
return -1; |
/* Open /dev/mem to access directly system memory */ |
g_osc_fpga_mem_fd = open("/dev/mem", O_RDWR | O_SYNC); |
if(g_osc_fpga_mem_fd < 0) { |
fprintf(stderr, "open(/dev/mem) failed: %s\n", strerror(errno)); |
return -1; |
} |
/* Calculate correct page address and offset from OSC_FPGA_BASE_ADDR and |
* OSC_FPGA_BASE_SIZE |
*/ |
page_addr = OSC_FPGA_BASE_ADDR & (~(page_size-1)); |
page_off = OSC_FPGA_BASE_ADDR - page_addr; |
/* Map FPGA memory space to page_ptr. */ |
page_ptr = mmap(NULL, OSC_FPGA_BASE_SIZE, PROT_READ | PROT_WRITE, |
MAP_SHARED, g_osc_fpga_mem_fd, page_addr); |
if((void *)page_ptr == MAP_FAILED) { |
fprintf(stderr, "mmap() failed: %s\n", strerror(errno)); |
__osc_fpga_cleanup_mem(); |
return -1; |
} |
/* Set FPGA OSC module pointers to correct values. */ |
g_osc_fpga_reg_mem = page_ptr + page_off; |
g_osc_fpga_cha_mem = (uint32_t *)g_osc_fpga_reg_mem + |
(OSC_FPGA_CHA_OFFSET / sizeof(uint32_t)); |
g_osc_fpga_chb_mem = (uint32_t *)g_osc_fpga_reg_mem + |
(OSC_FPGA_CHB_OFFSET / sizeof(uint32_t)); |
return 0; |
} |
/** |
* @brief Cleans up FPGA OSC module internals. |
* |
* This function closes the memory file descriptor, unmap the FPGA memory space |
* and cleans also all other internal things from FPGA OSC module. |
* @retval 0 Sucess |
* @retval -1 Failure |
*/ |
int osc_fpga_exit(void) |
{ |
return __osc_fpga_cleanup_mem(); |
} |
// TODO: Move to a shared folder and share with scope & spectrum. |
/** |
* @brief Provides equalization & shaping filter coefficients. |
* |
* |
* This function provides equalization & shaping filter coefficients, based on |
* the type of use and gain settings. |
* |
* @param [in] equal Enable(1)/disable(0) equalization filter. |
* @param [in] shaping Enable(1)/disable(0) shaping filter. |
* @param [in] gain Gain setting (0 = LV, 1 = HV). |
* @param [out] filt Filter coefficients. |
*/ |
void get_equ_shape_filter(ecu_shape_filter_t *filt, uint32_t equal, |
uint32_t shaping, uint32_t gain) |
{ |
/* Equalization filter */ |
if (equal) { |
if (gain == 0) { |
/* High gain = LV */ |
filt->aa = 0x7D93; |
filt->bb = 0x437C7; |
} else { |
/* Low gain = HV */ |
filt->aa = 0x4C5F; |
filt->bb = 0x2F38B; |
} |
} else { |
filt->aa = 0; |
filt->bb = 0; |
} |
/* Shaping filter */ |
if (shaping) { |
filt->pp = 0x2666; |
filt->kk = 0xd9999a; |
} else { |
filt->pp = 0; |
filt->kk = 0xffffff; |
} |
} |
/** |
* @brief Updates triggering parameters in FPGA registers. |
* |
* This function updates trigger related parameters in FPGA registers. |
* |
* @param [in] trig_imm Trigger immediately - if set to 1, FPGA state machine |
* will trigger immediately and other trigger parameters |
* will be ignored. |
* @param [in] trig_source Trigger source, as defined in rp_main_params. |
* @param [in] trig_edge Trigger edge, as defined in rp_main_params. |
* @param [in] trig_delay Trigger delay in [s]. |
* @param [in] trig_level Trigger level in [V]. |
* @param [in] time_range Time range, as defined in rp_main_params. |
* @param [in] equal Enable(1)/disable(0) equalization filter. |
* @param [in] shaping Enable(1)/disable(0) shaping filter. |
* @param [in] gain1 Gain setting for Channel1 (0 = LV, 1 = HV). |
* @param [in] gain2 Gain setting for Channel2 (0 = LV, 1 = HV). |
* |
* |
* @retval 0 Success |
* @retval -1 Failure |
* |
* @see rp_main_params |
*/ |
int osc_fpga_update_params(int trig_imm, int trig_source, int trig_edge, |
float trig_delay, float trig_level, int time_range, |
int equal, int shaping, int gain1, int gain2) |
{ |
int fpga_trig_source = osc_fpga_cnv_trig_source(trig_imm, trig_source, |
trig_edge); |
int fpga_dec_factor = osc_fpga_cnv_time_range_to_dec(time_range); |
int fpga_delay; |
float after_trigger; /* how much after trigger FPGA should write */ |
int fpga_trig_thr = osc_fpga_cnv_v_to_cnt(trig_level); |
/* Equalization filter coefficients */ |
ecu_shape_filter_t cha_filt; |
ecu_shape_filter_t chb_filt; |
get_equ_shape_filter(&cha_filt, equal, shaping, gain1); |
get_equ_shape_filter(&chb_filt, equal, shaping, gain2); |
if((fpga_trig_source < 0) || (fpga_dec_factor < 0)) { |
fprintf(stderr, "osc_fpga_update_params() failed\n"); |
return -1; |
} |
/* Pre-trigger - we need to limit after trigger acquisition so we can |
* readout historic (pre-trigger) values */ |
if (trig_imm) |
after_trigger=OSC_FPGA_SIG_LEN* c_osc_fpga_smpl_period * fpga_dec_factor; |
else |
after_trigger = |
((OSC_FPGA_SIG_LEN-7) * c_osc_fpga_smpl_period * fpga_dec_factor) + |
trig_delay; |
if(after_trigger < 0) |
after_trigger = 0; |
fpga_delay = osc_fpga_cnv_time_to_smpls(after_trigger, fpga_dec_factor); |
/* Trig source is written after ARM */ |
/* g_osc_fpga_reg_mem->trig_source = fpga_trig_source;*/ |
if(trig_source == 0) |
g_osc_fpga_reg_mem->cha_thr = fpga_trig_thr; |
else |
g_osc_fpga_reg_mem->chb_thr = fpga_trig_thr; |
g_osc_fpga_reg_mem->data_dec = fpga_dec_factor; |
g_osc_fpga_reg_mem->trigger_delay = (uint32_t)fpga_delay; |
/* Update equalization filter with desired coefficients. */ |
g_osc_fpga_reg_mem->cha_filt_aa = cha_filt.aa; |
g_osc_fpga_reg_mem->cha_filt_bb = cha_filt.bb; |
g_osc_fpga_reg_mem->cha_filt_pp = cha_filt.pp; |
g_osc_fpga_reg_mem->cha_filt_kk = cha_filt.kk; |
g_osc_fpga_reg_mem->chb_filt_aa = chb_filt.aa; |
g_osc_fpga_reg_mem->chb_filt_bb = chb_filt.bb; |
g_osc_fpga_reg_mem->chb_filt_pp = chb_filt.pp; |
g_osc_fpga_reg_mem->chb_filt_kk = chb_filt.kk; |
return 0; |
} |
/** @brief OSC FPGA reset |
* |
* Triggers internal oscilloscope FPGA state machine reset. |
* |
* @retval 0 Always returns 0. |
*/ |
int osc_fpga_reset(void) |
{ |
g_osc_fpga_reg_mem->conf |= OSC_FPGA_CONF_RST_BIT; |
return 0; |
} |
/** @brief OSC FPGA ARM |
* |
* ARM internal oscilloscope FPGA state machine to start writting input buffers. |
* @retval 0 Always returns 0. |
*/ |
int osc_fpga_arm_trigger(void) |
{ |
g_osc_fpga_reg_mem->conf |= OSC_FPGA_CONF_ARM_BIT; |
return 0; |
} |
/** @brief Sets the trigger source in OSC FPGA register. |
* |
* Sets the trigger source in oscilloscope FPGA register. |
* |
* @param [in] trig_source Trigger source, as defined in FPGA register |
* description. |
*/ |
int osc_fpga_set_trigger(uint32_t trig_source) |
{ |
g_osc_fpga_reg_mem->trig_source = trig_source; |
return 0; |
} |
/** @brief Sets the trigger delay in OSC FPGA register. |
* |
* Sets the trigger delay in oscilloscope FPGA register. |
* |
* @param [in] trig_delay Trigger delay, as defined in FPGA register |
* description. |
* |
* @retval 0 Always returns 0. |
*/ |
int osc_fpga_set_trigger_delay(uint32_t trig_delay) |
{ |
g_osc_fpga_reg_mem->trigger_delay = trig_delay; |
return 0; |
} |
/** @brief Checks if FPGA detected trigger. |
* |
* This function checks if trigger was detected by the FPGA. |
* |
* @retval 0 Trigger not detected. |
* @retval 1 Trigger detected. |
*/ |
int osc_fpga_triggered(void) |
{ |
return ((g_osc_fpga_reg_mem->trig_source & OSC_FPGA_TRIG_SRC_MASK)==0); |
} |
/** @brief Returns memory pointers for both input signal buffers. |
* |
* This function returns pointers for input signal buffers for both channels. |
* |
* @param [out] cha_signal Output pointer for Channel A buffer |
* @param [out] cha_signal Output pointer for Channel B buffer |
* |
* @retval 0 Always returns 0. |
*/ |
int osc_fpga_get_sig_ptr(int **cha_signal, int **chb_signal) |
{ |
*cha_signal = (int *)g_osc_fpga_cha_mem; |
*chb_signal = (int *)g_osc_fpga_chb_mem; |
return 0; |
} |
/** @brief Returns values for current and trigger write FPGA pointers. |
* |
* This functions returns values for current and trigger write pointers. They |
* are an address of the input signal buffer and are the same for both channels. |
* |
* @param [out] wr_ptr_curr Current FPGA input buffer address. |
* @param [out] wr_ptr_trig Trigger FPGA input buffer address. |
* |
* @retval 0 Always returns 0. |
*/ |
int osc_fpga_get_wr_ptr(int *wr_ptr_curr, int *wr_ptr_trig) |
{ |
if(wr_ptr_curr) |
*wr_ptr_curr = g_osc_fpga_reg_mem->wr_ptr_cur; |
if(wr_ptr_trig) |
*wr_ptr_trig = g_osc_fpga_reg_mem->wr_ptr_trigger; |
return 0; |
} |
/** @brief Convert trigger parameters to FPGA trigger source value. |
* |
* This function takes as an argument trigger parameters and converts it to |
* trigger source value used by the FPGA trigger source reigster. |
* |
* @param [in] trig_imm Trigger immediately, if set to 1 other trigger parameters |
* are ignored. |
* @param [in] trig_source Trigger source as defined in rp_main_params |
* @param [in] trig_edge Trigger edge as defined in rp_main_params |
* |
* @retval -1 Error |
* @retval otherwise Trigger source FPGA value |
*/ |
int osc_fpga_cnv_trig_source(int trig_imm, int trig_source, int trig_edge) |
{ |
int fpga_trig_source = 0; |
/* Trigger immediately */ |
if(trig_imm) |
return 1; |
switch(trig_source) { |
case 0: /* ChA*/ |
if(trig_edge == 0) |
fpga_trig_source = 2; |
else |
fpga_trig_source = 3; |
break; |
case 1: /* ChB*/ |
if(trig_edge == 0) |
fpga_trig_source = 4; |
else |
fpga_trig_source = 5; |
break; |
case 2: /* External */ |
if(trig_edge == 0) |
fpga_trig_source = 6; |
else |
fpga_trig_source = 7; |
break; |
default: |
/* Error */ |
return -1; |
} |
return fpga_trig_source; |
} |
/** @brief Converts time range to decimation value. |
* |
* This function converts time range value defined by rp_main_params to |
* decimation factor value. |
* |
* @param [in] time_range Time range, integer between 0 and 5, as defined by |
* rp_main_params. |
* |
* @retval -1 Error |
* |
* @retval otherwise Decimation factor. |
*/ |
int osc_fpga_cnv_time_range_to_dec(int time_range) |
{ |
/* Input: 0, 1, 2, 3, 4, 5 translates to: |
* Output: 1x, 8x, 64x, 1kx, 8kx, 65kx */ |
switch(time_range) { |
case 0: |
return 1; |
break; |
case 1: |
return 8; |
break; |
case 2: |
return 64; |
break; |
case 3: |
return 1024; |
break; |
case 4: |
return 8*1024; |
break; |
case 5: |
return 64*1024; |
break; |
default: |
return -1; |
} |
return -1; |
} |
/** @brief Converts time to number of samples. |
* |
* This function converts time in [s], based on current decimation factor to |
* number of samples at ADC sampling frequency. |
* |
* @param [in] time Time in [s] |
* @param [in] dec_factor Decimation factor |
* |
* @retval Number of ADC samples define dby input parameters. |
*/ |
int osc_fpga_cnv_time_to_smpls(float time, int dec_factor) |
{ |
/* Calculate sampling period (including decimation) */ |
float smpl_p = (c_osc_fpga_smpl_period * dec_factor); |
int fpga_smpls = (int)round(time / smpl_p); |
return fpga_smpls; |
} |
/** @brief Converts voltage to ADC counts. |
* |
* This function converts voltage in [V] to ADC counts. |
* |
* @param [in] voltage Voltage in [V] |
* |
* @retval adc_cnts ADC counts |
*/ |
int osc_fpga_cnv_v_to_cnt(float voltage) |
{ |
int adc_cnts = 0; |
if((voltage > c_osc_fpga_adc_max_v) || (voltage < -c_osc_fpga_adc_max_v)) |
return -1; |
adc_cnts = (int)round(voltage * (float)((int)(1<<c_osc_fpga_adc_bits)) / |
(2*c_osc_fpga_adc_max_v)); |
/* Clip highest value (+14 is calculated in int32_t to 0x2000, but we have |
* only 14 bits |
*/ |
if((voltage > 0) && (adc_cnts & (1<<(c_osc_fpga_adc_bits-1)))) |
adc_cnts = (1<<(c_osc_fpga_adc_bits-1))-1; |
else |
adc_cnts = adc_cnts & ((1<<(c_osc_fpga_adc_bits))-1); |
return adc_cnts; |
} |
/** @brief Converts ADC counts to voltage |
* |
* This function converts ADC counts to voltage (in [V]) |
* |
* @param [in] cnts ADC counts |
* |
* @retval voltage Voltage in [V] |
*/ |
float osc_fpga_cnv_cnt_to_v(int cnts) |
{ |
int m; |
if(cnts & (1<<(c_osc_fpga_adc_bits-1))) { |
/* negative number */ |
m = -1 *((cnts ^ ((1<<c_osc_fpga_adc_bits)-1)) + 1); |
} else { |
m = cnts; |
/* positive number */ |
} |
return m; |
} |
/cvi/apps/RedPitaya/sockserv/fpga_osc.h |
---|
0,0 → 1,261 |
/** |
* $Id: fpga_osc.h 881 2013-12-16 05:37:34Z rp_jmenart $ |
* |
* @brief Red Pitaya Oscilloscope FPGA controller. |
* |
* @Author Jure Menart <juremenart@gmail.com> |
* |
* (c) Red Pitaya http://www.redpitaya.com |
* |
* This part of code is written in C programming language. |
* Please visit http://en.wikipedia.org/wiki/C_(programming_language) |
* for more details on the language used herein. |
*/ |
#ifndef __FPGA_OSC_H |
#define __FPGA_OSC_H |
#include <stdint.h> |
/** @defgroup fpga_osc_h fpga_osc_h |
* @{ |
*/ |
/** Base OSC FPGA address */ |
#define OSC_FPGA_BASE_ADDR 0x40100000 |
/** Base OSC FPGA core size */ |
#define OSC_FPGA_BASE_SIZE 0x30000 |
/** OSC FPGA input signal buffer length */ |
#define OSC_FPGA_SIG_LEN (16*1024) |
/** OSC FPGA ARM bit in configuration register */ |
#define OSC_FPGA_CONF_ARM_BIT 1 |
/** OSC FPGA reset bit in configuration register */ |
#define OSC_FPGA_CONF_RST_BIT 2 |
/** OSC FPGA trigger source register mask */ |
#define OSC_FPGA_TRIG_SRC_MASK 0x00000007 |
/** OSC FPGA Channel A threshold register mask */ |
#define OSC_FPGA_CHA_THR_MASK 0x00003fff |
/** OSC FPGA Channel B threshold register mask */ |
#define OSC_FPGA_CHB_THR_MASK 0x00003fff |
/** OSC FPGA trigger delay register register mask */ |
#define OSC_FPGA_TRIG_DLY_MASK 0xffffffff |
/** OSC FPGA data decimation mask */ |
#define OSC_FPGA_DATA_DEC_MASK 0x0001ffff |
/** OSC FPGA Channel A input signal buffer offset */ |
#define OSC_FPGA_CHA_OFFSET 0x10000 |
/** OSC FPGA Channel B input signal buffer offset */ |
#define OSC_FPGA_CHB_OFFSET 0x20000 |
/** @brief OSC FPGA registry structure. |
* |
* This structure is direct image of physical FPGA memory. When accessing it all |
* reads/writes are performed directly from/to FPGA OSC core. |
*/ |
typedef struct osc_fpga_reg_mem_s { |
/** @brief Offset 0x00 - configuration register |
* |
* Configuration register (offset 0x00): |
* bit [0] - arm_trigger |
* bit [1] - rst_wr_state_machine |
* bits [31:2] - reserved |
*/ |
uint32_t conf; |
/** @brief Offset 0x04 - trigger source register |
* |
* Trigger source register (offset 0x04): |
* bits [ 2 : 0] - trigger source: |
* 1 - trig immediately |
* 2 - ChA positive edge |
* 3 - ChA negative edge |
* 4 - ChB positive edge |
* 5 - ChB negative edge |
* 6 - External trigger 0 |
* 7 - External trigger 1 |
* bits [31 : 3] -reserved |
*/ |
uint32_t trig_source; |
/** @brief Offset 0x08 - Channel A threshold register |
* |
* Channel A threshold register (offset 0x08): |
* bits [13: 0] - ChA threshold |
* bits [31:14] - reserved |
*/ |
uint32_t cha_thr; |
/** @brief Offset 0x0C - Channel B threshold register |
* |
* Channel B threshold register (offset 0x0C): |
* bits [13: 0] - ChB threshold |
* bits [31:14] - reserved |
*/ |
uint32_t chb_thr; |
/** @brief Offset 0x10 - After trigger delay register |
* |
* After trigger delay register (offset 0x10) |
* bits [31: 0] - trigger delay |
* 32 bit number - how many decimated samples should be stored into a buffer. |
* (max 16k samples) |
*/ |
uint32_t trigger_delay; |
/** @brief Offset 0x14 - Data decimation register |
* |
* Data decimation register (offset 0x14): |
* bits [16: 0] - decimation factor, legal values: |
* 1, 8, 64, 1024, 8192 65536 |
* If other values are written data is undefined |
* bits [31:17] - reserved |
*/ |
uint32_t data_dec; |
/** @brief Offset 0x18 - Current write pointer register |
* |
* Current write pointer register (offset 0x18), read only: |
* bits [13: 0] - current write pointer |
* bits [31:14] - reserved |
*/ |
uint32_t wr_ptr_cur; |
/** @brief Offset 0x1C - Trigger write pointer register |
* |
* Trigger write pointer register (offset 0x1C), read only: |
* bits [13: 0] - trigger pointer (pointer where trigger was detected) |
* bits [31:14] - reserved |
*/ |
uint32_t wr_ptr_trigger; |
/** @brief ChA & ChB hysteresis - both of the format: |
* bits [13: 0] - hysteresis threshold |
* bits [31:14] - reserved |
*/ |
uint32_t cha_hystersis; |
uint32_t chb_hystersis; |
/** @brief |
* bits [0] - enable signal average at decimation |
* bits [31:1] - reserved |
*/ |
uint32_t other; |
uint32_t reseved; |
/** @brief ChA Equalization filter |
* bits [17:0] - AA coefficient (pole) |
* bits [31:18] - reserved |
*/ |
uint32_t cha_filt_aa; |
/** @brief ChA Equalization filter |
* bits [24:0] - BB coefficient (zero) |
* bits [31:25] - reserved |
*/ |
uint32_t cha_filt_bb; |
/** @brief ChA Equalization filter |
* bits [24:0] - KK coefficient (gain) |
* bits [31:25] - reserved |
*/ |
uint32_t cha_filt_kk; |
/** @brief ChA Equalization filter |
* bits [24:0] - PP coefficient (pole) |
* bits [31:25] - reserved |
*/ |
uint32_t cha_filt_pp; |
/** @brief ChB Equalization filter |
* bits [17:0] - AA coefficient (pole) |
* bits [31:18] - reserved |
*/ |
uint32_t chb_filt_aa; |
/** @brief ChB Equalization filter |
* bits [24:0] - BB coefficient (zero) |
* bits [31:25] - reserved |
*/ |
uint32_t chb_filt_bb; |
/** @brief ChB Equalization filter |
* bits [24:0] - KK coefficient (gain) |
* bits [31:25] - reserved |
*/ |
uint32_t chb_filt_kk; |
/** @brief ChB Equalization filter |
* bits [24:0] - PP coefficient (pole) |
* bits [31:25] - reserved |
*/ |
uint32_t chb_filt_pp; |
/* ChA & ChB data - 14 LSB bits valid starts from 0x10000 and |
* 0x20000 and are each 16k samples long */ |
} osc_fpga_reg_mem_t; |
/** @} */ |
// TODO: Move to a shared folder and share with scope & spectrum. |
/** Equalization & shaping filter coefficients */ |
typedef struct { |
uint32_t aa; |
uint32_t bb; |
uint32_t pp; |
uint32_t kk; |
} ecu_shape_filter_t; |
int osc_fpga_init(void); |
int osc_fpga_exit(void); |
void get_equ_shape_filter(ecu_shape_filter_t *filt, uint32_t equal, |
uint32_t shaping, uint32_t gain); |
int osc_fpga_update_params(int trig_imm, int trig_source, int trig_edge, |
float trig_delay, float trig_level, int time_range, |
int equal, int shaping, int gain1, int gain2); |
int osc_fpga_reset(void); |
int osc_fpga_arm_trigger(void); |
int osc_fpga_set_trigger(uint32_t trig_source); |
int osc_fpga_set_trigger_delay(uint32_t trig_delay); |
/* Returns 0 if no trigger, 1 if trigger */ |
int osc_fpga_triggered(void); |
/* Returns pointer to the ChA and ChB signals (of length OSC_FPGA_SIG_LEN) */ |
int osc_fpga_get_sig_ptr(int **cha_signal, int **chb_signal); |
/* Returns signal pointers from the FPGA */ |
int osc_fpga_get_wr_ptr(int *wr_ptr_curr, int *wr_ptr_trig); |
/* Returnes signal content */ |
/* various constants */ |
extern const float c_osc_fpga_smpl_freq; |
extern const float c_osc_fpga_smpl_period; |
/* helper conversion functions */ |
/* Convert correct value for FPGA trigger source from trig_immediately, |
* trig_source and trig_edge from application params. |
*/ |
int osc_fpga_cnv_trig_source(int trig_imm, int trig_source, int trig_edge); |
/* Converts time_range parameter (0-5) to decimation factor */ |
int osc_fpga_cnv_time_range_to_dec(int time_range); |
/* Converts time in [s] to ADC samples (depends on decimation) */ |
int osc_fpga_cnv_time_to_smpls(float time, int dec_factor); |
/* Converts voltage in [V] to ADC counts */ |
int osc_fpga_cnv_v_to_cnt(float voltage); |
/* Converts ADC ounts to [V] */ |
float osc_fpga_cnv_cnt_to_v(int cnts); |
/* Debug - dump to stderr current parameter settings (leave out data) */ |
void osc_fpga_dump_regs(void); |
/* debugging - will be removed */ |
extern osc_fpga_reg_mem_t *g_osc_fpga_reg_mem; |
extern int g_osc_fpga_mem_fd; |
int __osc_fpga_cleanup_mem(void); |
#endif /* __FPGA_OSC_H*/ |
/cvi/apps/RedPitaya/sockserv/version.h |
---|
0,0 → 1,34 |
/** |
* $Id: $ |
* |
* @brief Red Pitaya simple version strings. To be embedded in binaries |
* at build time for SW traceability. |
* |
* @Author Ales Bardorfer <ales.bardorfer@redpitaya.com> |
* |
* (c) Red Pitaya http://www.redpitaya.com |
* |
* This part of code is written in C programming language. |
* Please visit http://en.wikipedia.org/wiki/C_(programming_language) |
* for more details on the language used herein. |
*/ |
#ifndef VERSION_H |
#define VERSION_H |
#define XSTR(s) STR(s) |
#define STR(s) #s |
#ifndef VERSION |
#define VERSION_STR "0.00-0000" |
#else |
#define VERSION_STR XSTR(VERSION) |
#endif |
#ifndef REVISION |
#define REVISION_STR "unknown" |
#else |
#define REVISION_STR XSTR(REVISION) |
#endif |
#endif /* VERSION_H */ |
Property changes: |
Added: svn:executable |