From 9253fef396b15f114641b513b4eed63097e3c43c Mon Sep 17 00:00:00 2001
From: Lucas Russo <lerwys@gmail.com>
Date: Fri, 20 May 2016 09:15:11 -0300
Subject: [PATCH] examples/trigger.c: add simple example for trigger functions

---
 examples/trigger.c | 295 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 295 insertions(+)
 create mode 100644 examples/trigger.c

diff --git a/examples/trigger.c b/examples/trigger.c
new file mode 100644
index 00000000..33c51657
--- /dev/null
+++ b/examples/trigger.c
@@ -0,0 +1,295 @@
+/*
+ *   Simple example demonstrating the communication between
+ *   a client and the FPGA device
+ *  
+ *  */
+
+#include <getopt.h>
+#include <czmq.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <bpm_client.h>
+
+#define DFLT_BIND_FOLDER            "/tmp/bpm"
+
+#define DFLT_BPM_NUMBER             0
+#define MAX_BPM_NUMBER              1
+
+#define DFLT_BOARD_NUMBER           0
+
+#define DFLT_CHAN_NUM               0
+
+static struct option long_options[] =
+{
+    {"help",                no_argument,         NULL, 'h'},
+    {"brokerendp",          required_argument,   NULL, 'b'},
+    {"verbose",             no_argument,         NULL, 'v'},
+    {"bpmnumber",           required_argument,   NULL, 's'},
+    {"boardslot",           required_argument,   NULL, 'o'},
+    {"channumber",          required_argument,   NULL, 'c'},
+    {"rcvsrc",              required_argument,   NULL, 'r'},
+    {"rcvsel",              required_argument,   NULL, 'p'},
+    {"transmsrc",           required_argument,   NULL, 't'},
+    {"transsel",            required_argument,   NULL, 'u'},
+    {"dir",                 required_argument,   NULL, 'd'},
+    {NULL, 0, NULL, 0}
+};
+
+static const char* shortopt = "hb:vo:s:c:r:p:t:u:d:";
+
+void print_help (char *program_name)
+{
+    fprintf (stdout, "EBPM Trigger Utility\n"
+            "Usage: %s [options]\n"
+            "\n"
+            "  -h  --help                           Display this usage information\n"
+            "  -b  --brokerendp <Broker endpoint>   Broker endpoint\n"
+            "  -v  --verbose                        Verbose output\n"
+            "  -o  --boardslot <Board slot number = [1-12]> \n"
+	    "  -s  --bpmnumber <BPM number = [0|1]> BPM number\n"
+            "                                       Board slot number\n"
+            "  -c  --channumber <Channel>           Trigger Channel number\n"
+            "                                     <Channel> must be one of the following:\n"
+            "                                     0 -> ADC; 1 -> ADC_SWAP; 2 -> Mixer IQ120; 3 -> Mixer IQ340;\n"
+            "                                     4 -> TBT Decim IQ120; 5 -> TBT Decim IQ340; 6 -> TBT Amp;\n"
+            "                                     7 -> TBT Phase; 8 -> TBT Pos; 9 -> FOFB Decim IQ120;\n"
+            "                                     10 -> FOFB Decim IQ340; 11 -> FOFB Amp; 12 -> FOFB Pha;\n"
+            "                                     13 -> FOFB Pos; 14 -> Monit Amp; 15 -> Monit Pha; 16 -> Monit Pos]\n"
+            "                                     17 -> Swithcing Clock]\n"
+            "  -r  --rcvsrc <Receive source for the selected channel = [0 = trigger backplane, 1 = FPGA internal]> \n"
+            "  -p  --rcvsel <Receive selection source for the selected channel = [TBD]> \n"
+            "  -t  --transmsrc <Transmit source for the selected channel = [0 = trigger backplane, 1 = FPGA internal]> \n"
+            "  -u  --transmsel <Transmit selection source for the selected channel = [TBD]> \n"
+            "  -d  --dir <Trigger direction = [0 = FPGA Output, 1 = FPGA Input]> \n",
+            program_name);
+}
+
+int main (int argc, char *argv [])
+{
+    int verbose = 0;
+    char *broker_endp = NULL;
+    char *num_samples_str = NULL;
+    char *board_number_str = NULL;
+    char *bpm_number_str = NULL;
+    char *chan_str = NULL;
+    int chan_sel = 0;
+    char *rcvsrc_str = NULL;
+    int rcvsrc_sel = 0;
+    char *rcvsel_str = NULL;
+    int rcvsel_sel = 0;
+    char *transmsrc_str = NULL;
+    int transmsrc_sel = 0;
+    char *transmsel_str = NULL;
+    int transmsel_sel = 0;
+    char *dir_str = NULL;
+    int dir_sel = 0;
+    int opt;
+
+    while ((opt = getopt_long (argc, argv, shortopt, long_options, NULL)) != -1) {
+        /* Get the user selected options */
+        switch (opt) {
+            /* Display Help */
+            case 'h':
+                print_help (argv [0]);
+                exit (1);
+                break;
+
+            case 'b':
+                broker_endp = strdup (optarg);
+                break;
+
+            case 'v':
+                verbose = 1;
+                break;
+
+            case 'o':
+                board_number_str = strdup (optarg);
+                break;
+
+            case 's':
+                bpm_number_str = strdup (optarg);
+                break;
+
+            case 'c':
+                chan_str = strdup (optarg);
+                chan_sel = 1;
+                break;
+
+            case 'r':
+                rcvsrc_str = strdup (optarg);
+                rcvsrc_sel = 1;
+                break;
+
+            case 'p':
+                rcvsel_str = strdup (optarg);
+                rcvsel_sel = 1;
+                break;
+
+            case 't':
+                transmsrc_str = strdup (optarg);
+                transmsrc_sel = 1;
+                break;
+
+            case 'u':
+                transmsel_str = strdup (optarg);
+                transmsel_sel = 1; 
+                break;
+
+            case 'd':
+                dir_str = strdup (optarg);
+                dir_sel = 1;
+                break;
+
+            case '?':
+                fprintf (stderr, "[client:trigger] Option not recognized or missing argument\n");
+                print_help (argv [0]);
+                exit (1);
+                break;
+
+            default:
+                fprintf (stderr, "[client:trigger] Could not parse options\n");
+                print_help (argv [0]);
+                exit (1);
+         }
+    }
+
+    /* If we want to change a channel property, we must select a channel first */
+    if ((rcvsrc_sel == 1 || rcvsel_sel == 1 || transmsrc_sel == 1 || transmsel_sel == 1 ||
+        dir_sel == 1) && chan_sel == 0) {
+        fprintf (stderr, "[client:trigger]: Channel number not selected (use -c or --channumber option)\n");
+        exit (1);
+    }
+    
+    /* Set default broker address */
+    if (broker_endp == NULL) {
+        fprintf (stderr, "[client:trigger]: Setting default broker endpoint: %s\n",
+                "ipc://"DFLT_BIND_FOLDER);
+        broker_endp = strdup ("ipc://"DFLT_BIND_FOLDER);
+    }
+
+    /* Set default channel */
+    uint32_t chan;
+    if (chan_str == NULL) {
+        fprintf (stderr, "[client:trigger]: Setting default value to 'chan'\n");
+        chan = DFLT_CHAN_NUM;
+    }
+    else {
+        chan = strtoul (chan_str, NULL, 10);
+    }
+
+    /* Set default board number */
+    uint32_t board_number;
+    if (board_number_str == NULL) {
+        fprintf (stderr, "[client:trigger]: Setting default value to BOARD number: %u\n",
+                DFLT_BOARD_NUMBER);
+        board_number = DFLT_BOARD_NUMBER;
+    }
+    else {
+        board_number = strtoul (board_number_str, NULL, 10);
+    }
+
+    /* Set default bpm number */
+    uint32_t bpm_number;
+    if (bpm_number_str == NULL) {
+        fprintf (stderr, "[client:trigger]: Setting default value to BPM number: %u\n",
+                DFLT_BPM_NUMBER);
+        bpm_number = DFLT_BPM_NUMBER;
+    }
+    else {
+        bpm_number = strtoul (bpm_number_str, NULL, 10);
+
+        if (bpm_number > MAX_BPM_NUMBER) {
+            fprintf (stderr, "[client:trigger]: BPM number too big! Defaulting to: %u\n",
+                    MAX_BPM_NUMBER);
+            bpm_number = MAX_BPM_NUMBER;
+        }
+    }
+
+    char service_iface[50];
+    snprintf (service_iface, sizeof (service_iface), "BPM%u:DEVIO:TRIGGER_IFACE", board_number);
+    char service_mux[50];
+    snprintf (service_mux, sizeof (service_mux), "BPM%u:DEVIO:TRIGGER_MUX%u", board_number, bpm_number);
+
+    bpm_client_t *bpm_client = bpm_client_new (broker_endp, verbose, NULL);
+    if (bpm_client == NULL) {
+        fprintf (stderr, "[client:trigger]: bpm_client could be created\n");
+        goto err_bpm_client_new;
+    }
+
+    uint32_t rcvsrc = 0;
+    if (rcvsrc_sel == 1) {
+        rcvsrc = strtoul (rcvsrc_str, NULL, 10);
+        bpm_client_err_e err = bpm_set_trigger_rcv_src (bpm_client, service_mux, chan, rcvsrc);
+        if (err != BPM_CLIENT_SUCCESS){
+            fprintf (stderr, "[client:trigger]: bpm_set_trigger_rcv_src failed\n");
+            goto err_bpm_set;
+        }
+    }
+
+    uint32_t rcvsel = 0;
+    if (rcvsel_sel == 1) {
+        rcvsel = strtoul (rcvsel_str, NULL, 10);
+        bpm_client_err_e err = bpm_set_trigger_rcv_in_sel (bpm_client, service_mux, chan, rcvsel);
+        if (err != BPM_CLIENT_SUCCESS){
+            fprintf (stderr, "[client:trigger]: bpm_set_trigger_rcv_sel failed\n");
+            goto err_bpm_set;
+        }
+    }
+
+    uint32_t transmsrc = 0;
+    if (transmsrc_sel == 1) {
+        transmsrc = strtoul (transmsrc_str, NULL, 10);
+        bpm_client_err_e err = bpm_set_trigger_transm_src (bpm_client, service_mux, chan, transmsrc);
+        if (err != BPM_CLIENT_SUCCESS){
+            fprintf (stderr, "[client:trigger]: bpm_set_trigger_transm_sel failed\n");
+            goto err_bpm_set;
+        }
+    }
+
+    uint32_t transmsel = 0;
+    if (transmsel_sel == 1) {
+        transmsel = strtoul (transmsel_str, NULL, 10);
+        bpm_client_err_e err = bpm_set_trigger_transm_out_sel (bpm_client, service_mux, chan, transmsel);
+        if (err != BPM_CLIENT_SUCCESS){
+            fprintf (stderr, "[client:trigger]: bpm_set_trigger_transm_sel failed\n");
+            goto err_bpm_set;
+        }
+    }
+
+    uint32_t dir = 0;
+    if (dir_sel == 1) {
+        dir = strtoul (dir_str, NULL, 10);
+        bpm_client_err_e err = bpm_set_trigger_dir (bpm_client, service_iface, chan, dir);
+        if (err != BPM_CLIENT_SUCCESS){
+            fprintf (stderr, "[client:trigger]: bpm_set_trigger_rcv_sel failed\n");
+            goto err_bpm_set;
+        }
+    }
+
+err_bpm_set:
+err_bpm_client_new:
+    free (dir_str);
+    dir_str = NULL;
+    free (transmsel_str);
+    transmsel_str = NULL;
+    free (transmsrc_str);
+    transmsrc_str = NULL;
+    free (rcvsel_str);
+    rcvsel_str = NULL;
+    free (rcvsrc_str);
+    rcvsrc_str = NULL;
+    free (chan_str);
+    chan_str = NULL;
+    free (board_number_str);
+    board_number_str = NULL;
+    free (bpm_number_str);
+    bpm_number_str = NULL;
+    free (num_samples_str);
+    num_samples_str = NULL;
+    free (broker_endp);
+    broker_endp = NULL;
+    bpm_client_destroy (&bpm_client);
+
+    return 0;
+}
-- 
GitLab