HW/DAS/USBscopes/usbtm/bash/multipulse.c

#include "usbpulse.h"
#include <string.h>

#define MAXDEV 4

struct devinfo {
  int addr;
  int fd;
  int delay;
  int durat;
  double amp;
  int invert;
};


int detect_init(struct devinfo *di, int devs, int master) {
  int i, ret;
  for(i = 0; i < devs; i++) {
    usbtm_set_trig_master(di[i].fd, 0);
    usbtm_set_detect_line(di[i].fd, 0, 1);
  }

  usbtm_set_detect_line(master, 0, 1);
  usbtm_get_detect_line(master, &ret);
  if(!ret) {
    fprintf(stderr, "Nektere z propojenych zarizeni neni pripojeno na USB!\n");
    return 0;
  }
  usbtm_set_detect_line(master, 1, 0);

  for(i = 1; i < devs; i++) {
    usbtm_set_detect_line(di[i].fd, 0, 1);
    usbtm_get_detect_line(di[i].fd, &ret);
    if(ret) {
      fprintf(stderr, "Nektere uvedene zarizeni neni propojeno s ostatnimi!\n");
      return 0;
    }
  }

  for(i = 0; i < devs; i++)
    if(!pulse100_init_pulse(di[i].fd, i==0)) return 0;

  usbtm_set_clock_master(master, 1);
  usbtm_set_trig_master(master, 1);

  return 1;
}


int main(int argc, char *argv[]) {
  int opt, exp = 3, help = 0;
  struct devinfo di[MAXDEV];
  float defamp = 2;
  int m, base, max, i, devs = 0;
  int master;

  while((opt = getopt(argc, argv, "d:a:ie:u:h?")) != -1)
    switch(opt) {
      case 'd':
        if(devs == MAXDEV) {
          help = 1;
          break;
        }
        if(sscanf(optarg, "%i:%i,%i", &di[devs].addr, &di[devs].delay, &di[devs].durat) != 3)
          help = 1;
        if(di[devs].delay < 0 || di[devs].durat < 0) help = 1;
        di[devs].amp = defamp;
        di[devs].invert = 0;
        devs++;
        break;
      case 'a':
        if(!devs) defamp = atof(optarg);
        else di[devs-1].amp = atof(optarg);
        break;
      case 'i':
        if(!devs) help = 1;
        else di[devs-1].invert = 1;
        break;
      case 'e':
        exp = atoi(optarg);
        break;
      case 'u':
        if(!strcmp(optarg, "s")) exp = 0;
        else if(!strcmp(optarg, "ms")) exp = 3;
        else if(!strcmp(optarg, "us")) exp = 6;
        else help = 1;
        break;
      default:
        help = 1;
        break;
    }
  if(help || optind != argc || defamp < 1 || devs < 2 || exp < 0 || exp > 8) {
    printf("Pouziti: %s [-e exp|-u unit] [-d dev:delay,dur] [-a amp] [-i] [-d...\n"
        "  dev je cislo zarizeni %sn, na ktere se pripojit.\n"
        "  Prvni uvedene zarizeni bude plnit funkci Trigger Master.\n"
        "  delay je relativni doba zacatku pulsu, dur jeho trvani.\n"
        "  Casova jednotka je urcena unit (s, ms, us) nebo exp (0 az 8;\n"
        "    0 = s, 3 = ms, 6 = us), vychozi je ms.\n"
        "  amp je amplituda daneho pulsu, -i zapina inverzi jeho logicke hodnoty,\n"
        "    pricemz obe tyto volby se vztahuji pouze na predchozi -d.\n"
        "    Jestlize je uvedeno pred prvnim -d, urcuje vychozi hodnotu (jinak 2V).\n",
        argv[0], DEVNAME);
    return 0;
  }

  for(i = 0; i < devs; i++)
    if(!opendev(di[i].addr, &di[i].fd)) {
      fprintf(stderr, deverror(di[i].addr));
      return 1;
    }

  master = di[0].fd;

  if(!detect_init(di, devs, master)) {
    for(i = 0; i < devs; i++)
      closedev(di[i].addr, di[i].fd);
    return 1;
  }

  for(base = 1, i = 8; i > exp; i--)
    base *= 10;
  if(exp > 5) {
    m = 1<<(exp - 5);
    base >>= 8-exp;
  } else {
    m = 1;
    base >>= 3;
  }

  max = 0;
  for(i = 0; i < devs; i++)
    if(di[i].delay + di[i].durat > max)
      max = di[i].delay + di[i].durat;

  for(i = 0; i < devs; i++) {
    pulse100_set_pll(di[i].fd, m, 1, 1, 0);
    pulse100_set_amplitude(di[i].fd, di[i].amp);
    pulse100_set_xyz(di[i].fd, max*base+2, (max-di[i].delay-di[i].durat)*base, (max-di[i].delay)*base);
    pulse100_set_bypass(di[i].fd, 0);
    pulse100_set_prng(di[i].fd, 0);
    pulse100_set_invert(di[i].fd, di[i].invert);
    pulse100_set_enable(di[i].fd, 1);
  }

  for(i = 0; i < devs; i++) {
    pulse100_set_trigger(di[i].fd, 0);
    pulse100_set_arm(di[i].fd, 0);
    pulse100_set_run(di[i].fd, 0);
  }
  for(i = 0; i < devs; i++) {
    pulse100_set_run(di[i].fd, 1);
    pulse100_set_oneshot(di[i].fd, 1);
    pulse100_set_arm(di[i].fd, 1);
  }

  pulse100_set_trigger(master, 1);

  sleep((int)(1/12.5E6*base/m*max)+1);
  for(i = 0; i < devs; i++)
    closedev(di[i].addr, di[i].fd);

  return 0;
}