#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <ctype.h>
#include <string.h>
#include "rtapi.h"
#include "hal.h"
#include <gtk/gtk.h>
#include "miscgtk.h"
#include "scope_usr.h"
typedef enum {
INT,
FLOAT,
STRING
} arg_type_t;
typedef struct {
const char* name;
arg_type_t arg_type;
char * (*handler)(void *arg);
} cmd_lut_entry_t;
static int parse_command(char *in);
static char *dummy_cmd(void * arg);
static char *thread_cmd(void * arg);
static char *maxchan_cmd(void * arg);
static char *hzoom_cmd(void * arg);
static char *hpos_cmd(void * arg);
static char *hmult_cmd(void * arg);
static char *chan_cmd(void * arg);
static char *choff_cmd(void * arg);
static char *pin_cmd(void * arg);
static char *sig_cmd(void * arg);
static char *param_cmd(void * arg);
static char *vscale_cmd(void * arg);
static char *vpos_cmd(void * arg);
static char *voff_cmd(void * arg);
static char *voff_ac_cmd(void * arg);
static char *tsource_cmd(void * arg);
static char *tlevel_cmd(void * arg);
static char *tpos_cmd(void * arg);
static char *tpolar_cmd(void * arg);
static char *tmode_cmd(void * arg);
static char *rmode_cmd(void * arg);
static const cmd_lut_entry_t cmd_lut[25] =
{
{ "thread", STRING, thread_cmd },
{ "maxchan", INT, maxchan_cmd },
{ "hmult", INT, hmult_cmd },
{ "hzoom", INT, hzoom_cmd },
{ "hpos", FLOAT, hpos_cmd },
{ "chan", INT, chan_cmd },
{ "choff", INT, choff_cmd },
{ "pin", STRING, pin_cmd },
{ "sig", STRING, sig_cmd },
{ "param", STRING, param_cmd },
{ "vscale", INT, vscale_cmd },
{ "vpos", FLOAT, vpos_cmd },
{ "vac", FLOAT, voff_ac_cmd },
{ "voff", FLOAT, voff_cmd },
{ "tsource", INT, tsource_cmd },
{ "tlevel", FLOAT, tlevel_cmd },
{ "tpos", FLOAT, tpos_cmd },
{ "tpolar", INT, tpolar_cmd },
{ "tmode", INT, tmode_cmd },
{ "rmode", INT, rmode_cmd },
{ "", 0, dummy_cmd }
};
static int deferred_channel;
int read_config_file (char *filename)
{
FILE *fp;
char cmd_buf[100];
char *cp;
int retval;
deferred_channel = 0;
fp = fopen(filename, "r");
if ( fp == NULL ) {
fprintf(stderr, "halscope: config file '%s' could not be opened\n", filename );
return -1;
}
retval = 0;
while ( fgets(cmd_buf, 99, fp) != NULL ) {
cp = cmd_buf;
while (( *cp != '\n' ) && ( *cp != '\0' )) {
cp++;
}
*cp = '\0';
retval += parse_command(cmd_buf);
}
fclose(fp);
if ( retval < 0 ) {
fprintf(stderr, "halscope: config file '%s' caused %d warnings\n", filename, -retval );
return -1;
}
return 0;
}
void write_config_file (char *filename)
{
FILE *fp;
fp = fopen(filename, "w");
if ( fp == NULL ) {
fprintf(stderr, "halscope: config file '%s' could not be created\n", filename );
return;
}
write_horiz_config(fp);
write_vert_config(fp);
write_trig_config(fp);
if (ctrl_usr->run_mode == NORMAL ) {
fprintf(fp, "RMODE 1\n" );
} else if ( ctrl_usr->run_mode == SINGLE ) {
fprintf(fp, "RMODE 2\n" );
#if 0#endif
} else {
fprintf(fp, "RMODE 0\n" );
}
fclose(fp);
}
void write_log_file (char *filename)
{
scope_data_t *dptr, *start;
scope_horiz_t *horiz;
int sample_len, chan_num, sample_period_ns, samples, n;
char *label[16];
scope_log_t *log;
scope_chan_t *chan;
hal_type_t type[16];
FILE *fp;
fp = fopen(filename, "w");
if ( fp == NULL ) {
fprintf(stderr, "ERROR: log file '%s' could not be created\n", filename );
return;
}
for (chan_num=0; chan_num<16; chan_num++) {
chan = &(ctrl_usr->chan[chan_num]);
label[chan_num] = chan->name;
type[chan_num] = chan->data_type;
}
sample_len = ctrl_shm->sample_len;
n=0;
samples = ctrl_usr->samples*sample_len ;
log = &(ctrl_usr->log);
horiz = &(ctrl_usr->horiz);
sample_period_ns = horiz->thread_period_ns * ctrl_shm->mult;
log->order=INTERLACED;
fprintf(fp, "Sampling period is %i nSec \n", sample_period_ns );
start = ctrl_usr->disp_buf ;
switch (log->order) {
case INTERLACED:
while (n <= samples) {
for (chan_num=0; chan_num<sample_len; chan_num++) {
dptr=start+n;
if ((n%sample_len)==0){
fprintf( fp, "\n");
}
write_sample( fp, label[chan_num], dptr, type[chan_num]);
n++;
}
}
break;
case NOT_INTERLACED:
for (chan_num=0; chan_num<sample_len; chan_num++) {
n=chan_num;
while (n <= samples) {
dptr=start+n;
write_sample( fp, label[chan_num], dptr, type[chan_num]);
fprintf( fp, "\n");
n += sample_len;
}
}
break;
}
fclose(fp);
fprintf(stderr, "Log file '%s' written.\n", filename );
}
void write_sample(FILE *fp, char *label, scope_data_t *dptr, hal_type_t type)
{
double data_value;
switch (type) {
case HAL_BIT:
if (dptr->d_u8) {
data_value = 1.0;
} else {
data_value = 0.0;
};
break;
case HAL_FLOAT:
data_value = dptr->d_real;
break;
case HAL_S32:
data_value = dptr->d_s32;
break;
case HAL_U32:
data_value = dptr->d_u32;
break;
default:
data_value = 0.0;
break;
}
fprintf(fp, "%s %+.14f ", label, data_value );
}
static int parse_command(char *in)
{
int n;
char *cp1, *rv;
const char *cp2;
int arg_int;
double arg_float;
char *arg_string;
n = -1;
do {
cp1 = in;
cp2 = cmd_lut[++n].name;
while (( *cp2 != '\0') && (tolower(*cp1) == *cp2 )) {
cp1++;
cp2++;
}
} while ( *cp2 != '\0' );
if ( cp1 == in ) {
if ( *in != '#' ) {
fprintf (stderr, "halscope: unknown config command: '%s'\n", in );
return -1;
}
}
switch ( cmd_lut[n].arg_type ) {
case STRING:
while ( isspace(*cp1) ) {
cp1++;
}
arg_string = cp1;
while (( *cp1 != '\n' ) && ( *cp1 != '\0' )) {
cp1++;
}
*cp1 = '\0';
rv = cmd_lut[n].handler(arg_string);
break;
case FLOAT:
arg_float = strtod(cp1, &cp1);
rv = cmd_lut[n].handler(&arg_float);
break;
case INT:
arg_int = strtol(cp1, &cp1, 10);
rv = cmd_lut[n].handler(&arg_int);
break;
default:
return -1;
break;
}
if ( rv != NULL ) {
fprintf(stderr, "halscope: %s: '%s'\n", rv, in );
return -1;
}
return 0;
}
static char *dummy_cmd(void * arg)
{
return "command not implemented";
}
static char *thread_cmd(void * arg)
{
char *name;
int rv;
name = (char *)(arg);
rv = set_sample_thread(name);
if ( rv < 0 ) {
return "could not find thread";
}
return NULL;
}
static char *maxchan_cmd(void * arg)
{
int *argp, rv;
argp = (int *)(arg);
rv = set_rec_len(*argp);
if ( rv < 0 ) {
return "could not set record length";
}
return NULL;
}
static char *hzoom_cmd(void * arg)
{
int *argp, rv;
argp = (int *)(arg);
rv = set_horiz_zoom(*argp);
if ( rv < 0 ) {
return "could not set horizontal zoom";
}
return NULL;
}
static char *hpos_cmd(void * arg)
{
double *argp;
int rv;
argp = (double *)(arg);
rv = set_horiz_pos(*argp);
if ( rv < 0 ) {
return "could not set horizontal position";
}
return NULL;
}
static char *hmult_cmd(void * arg)
{
int *argp, rv;
argp = (int *)(arg);
rv = set_horiz_mult(*argp);
if ( rv < 0 ) {
return "could not set horizontal multiplier";
}
return NULL;
}
static char *chan_cmd(void * arg)
{
int *argp, chan_num, rv;
argp = (int *)(arg);
chan_num = *argp;
deferred_channel = 0;
rv = set_active_channel(chan_num);
switch (rv) {
case 0:
return NULL;
case -1:
return "illegal channel number";
case -2:
return "too many active channels";
case -3:
deferred_channel = chan_num;
return NULL;
default:
return "unknown result";
}
}
static char *choff_cmd(void * arg)
{
int chan_num;
if ( deferred_channel != 0 ) {
deferred_channel = 0;
return NULL;
}
chan_num = ctrl_usr->vert.selected;
set_channel_off(chan_num);
return NULL;
}
static char *chan_src_cmd(int src_type, char *src_name)
{
int chan_num, rv;
if ( deferred_channel == 0 ) {
chan_num = ctrl_usr->vert.selected;
rv = set_channel_source(chan_num, src_type, src_name);
} else {
chan_num = deferred_channel;
rv = set_channel_source(chan_num, src_type, src_name);
if ( rv == 0 ) {
return chan_cmd(&chan_num);
}
}
if ( rv < 0 ) {
return "object not found";
}
return NULL;
}
static char *pin_cmd(void * arg)
{
return chan_src_cmd(0, (char *)(arg));
}
static char *sig_cmd(void * arg)
{
return chan_src_cmd(1, (char *)(arg));
}
static char *param_cmd(void * arg)
{
return chan_src_cmd(2, (char *)(arg));
}
static char *vscale_cmd(void * arg)
{
int *argp, rv;
argp = (int *)(arg);
rv = set_vert_scale(*argp);
if ( rv < 0 ) {
return "could not set vertical scale";
}
return NULL;
}
static char *vpos_cmd(void * arg)
{
double *argp;
int rv;
argp = (double *)(arg);
rv = set_vert_pos(*argp);
if ( rv < 0 ) {
return "could not set vertical position";
}
return NULL;
}
static char *voff_cmd(void * arg)
{
double *argp;
int rv;
argp = (double *)(arg);
rv = set_vert_offset(*argp, 0);
if ( rv < 0 ) {
return "could not set vertical offset";
}
return NULL;
}
static char *voff_ac_cmd(void * arg)
{
double *argp;
int rv;
argp = (double *)(arg);
rv = set_vert_offset(*argp, 1);
if ( rv < 0 ) {
return "could not set vertical offset";
}
return NULL;
}
static char *tsource_cmd(void * arg)
{
int *argp, rv;
argp = (int *)(arg);
rv = set_trigger_source(*argp);
if ( rv < 0 ) {
return "could not set trigger source";
}
return NULL;
}
static char *tlevel_cmd(void * arg)
{
double *argp;
int rv;
argp = (double *)(arg);
rv = set_trigger_level(*argp);
if ( rv < 0 ) {
return "could not set trigger level";
}
return NULL;
}
static char *tpos_cmd(void * arg)
{
double *argp;
int rv;
argp = (double *)(arg);
rv = set_trigger_pos(*argp);
if ( rv < 0 ) {
return "could not set trigger position";
}
return NULL;
}
static char *tpolar_cmd(void * arg)
{
int *argp;
int rv;
argp = (int *)(arg);
rv = set_trigger_polarity(*argp);
if ( rv < 0 ) {
return "could not set trigger polarity";
}
return NULL;
}
static char *tmode_cmd(void * arg)
{
int *argp;
int rv;
argp = (int *)(arg);
rv = set_trigger_mode(*argp);
if ( rv < 0 ) {
return "could not set trigger mode";
}
return NULL;
}
static char *rmode_cmd(void * arg)
{
int *argp;
int rv;
argp = (int *)(arg);
rv = set_run_mode(*argp);
if ( rv < 0 ) {
return "could not set run mode";
}
return NULL;
}