From abd051f7c8a408e61a21e8021cd89fca89839e23 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Romain=20Bron=C3=A8s?= <romain.brones@synchrotron-soleil.fr>
Date: Tue, 14 Nov 2023 17:21:40 +0100
Subject: [PATCH] feat(archiver): Evolve application

* Configure and Start DAQ with ChimeraTK accessors.
* MMAP and copy to file

TODO
* Switch buffer
* rolling file destination
* Both BPM and PSC
---
 recipes-app/simple-test/files/archiver.c   |  77 -----------
 recipes-app/simple-test/files/archiver.cpp | 149 +++++++++++++++++++++
 recipes-app/simple-test/simple-test_0.1.bb |   6 +-
 3 files changed, 152 insertions(+), 80 deletions(-)
 delete mode 100644 recipes-app/simple-test/files/archiver.c
 create mode 100644 recipes-app/simple-test/files/archiver.cpp

diff --git a/recipes-app/simple-test/files/archiver.c b/recipes-app/simple-test/files/archiver.c
deleted file mode 100644
index 64116e3..0000000
--- a/recipes-app/simple-test/files/archiver.c
+++ /dev/null
@@ -1,77 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <poll.h>
-#include <sys/mman.h>
-#include <stdint.h>
-#include <fcntl.h>
-
-int main(){
-
-    int fd_ddr, fd_ddr_ro;      // File descriptors for DDR4
-    int fd_dst;                 // File descriptor for destination
-    unsigned int fcnt=0;        // Binary file counter
-    int rp;
-    ssize_t s_wr;
-    const uint32_t unmask = 1;
-    uint32_t info;
-    char fname[128];
-    char *src;
-    struct pollfd pfd;
-
-
-    // Open file descriptor for DDR4
-    fd_ddr = open("/dev/ddr4", O_RDWR);
-    fd_ddr_ro = open("/dev/ddr4", O_RDONLY);
-    if (fd_ddr <= 0 || fd_ddr_ro <= 0) {
-        fprintf(stderr, "Failed to open UIO device.\n");
-        return -1;
-    };
-    pfd.fd = fd_ddr;
-    pfd.events = POLLIN;
-
-    // Open MMAP for DDR4
-    src = mmap(NULL, 0x20000000, PROT_READ, MAP_SHARED, fd_ddr_ro, 0);
-
-    // Open destination file
-    snprintf(fname, 128, "/mnt/data/archiver/file_%08d.bin", fcnt);
-    fd_dst = creat(fname, 0);
-    if (fd_dst <= 0) {
-        fprintf(stderr, "Failed to open destination file '%s'.\n", fname);
-        return -2;
-    };
-
-    // Unmask interrupt
-    s_wr = write(fd_ddr, &unmask, sizeof(unmask));
-    if (s_wr != (ssize_t)sizeof(unmask)) {
-        fprintf(stderr, "Error when unmasking interrupt !\n");
-        return -3;
-    };
-
-    // Wait for interrupt
-    fprintf(stdout, "Waiting for interrupt...");
-    rp = poll(&pfd, 1, -1);     // Timeout = -1, infinite wait
-
-    if (rp >= 1) {
-        read(fd_ddr, &info, sizeof(info));
-        fprintf(stdout, "Read %d interrupts\n", info);
-    } else if (rp == 0) {
-        fprintf(stderr, "Wait for IRQ interrupted, timeout or signal.\n");
-        return -4;
-    } else {
-        fprintf(stderr, "Failed poll.\n");
-        return -5;
-        //fprintf(stderr, "Failed poll. Relaunch for next iteration.\n");
-        //continue;
-    };
-
-    // Copy data
-    s_wr = write(fd_dst, &src, 0x1000);
-    if (s_wr < 0x1000) {
-        fprintf(stderr, "Error while writing to file '%s'.\n", fname);
-    }
-
-    close(fd_dst);
-
-    return 0;
-
-}
diff --git a/recipes-app/simple-test/files/archiver.cpp b/recipes-app/simple-test/files/archiver.cpp
new file mode 100644
index 0000000..9dacddf
--- /dev/null
+++ b/recipes-app/simple-test/files/archiver.cpp
@@ -0,0 +1,149 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <poll.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <ChimeraTK/Device.h>
+#include <errno.h>
+
+int main(){
+
+    int fd_ddr, fd_ddr_sro;     // File descriptors for DDR4
+    int fd_dst;                 // File descriptor for destination
+    unsigned int fcnt=0;        // Binary file counter
+    int rp;
+    int i;
+    ssize_t s_wr;
+    const uint32_t unmask = 1, mask = 0;
+    uint32_t info;
+    char fname[128];
+    char *src;
+    struct pollfd pfd;
+
+    // Initialize ChimeraTK ===================================================
+    ChimeraTK::setDMapFilePath("/opt/fofb/map/appuio.dmap");
+    ChimeraTK::Device dev("APPUIO");
+    dev.open();
+
+    // Declare register accessors
+    ChimeraTK::ScalarRegisterAccessor<uint32_t> daq_enable =
+        dev.getScalarRegisterAccessor<uint32_t>("APP/daq_0/ENABLE");
+    ChimeraTK::ScalarRegisterAccessor<uint32_t> daq_dbuf_ena =
+        dev.getScalarRegisterAccessor<uint32_t>("APP/daq_0/DOUBLE_BUF_ENA");
+    ChimeraTK::ScalarRegisterAccessor<uint32_t> daq_trigger =
+        dev.getScalarRegisterAccessor<uint32_t>("APP/DAQ_CONTROL");
+    ChimeraTK::OneDRegisterAccessor<uint32_t> daq_tabsel =
+        dev.getOneDRegisterAccessor<uint32_t>("APP/daq_0/TAB_SEL");
+    ChimeraTK::OneDRegisterAccessor<uint32_t> daq_curbuff =
+        dev.getOneDRegisterAccessor<uint32_t>("APP/daq_0/ACTIVE_BUF");
+
+    // Open DDR access ========================================================
+    // Open file descriptor for DDR4
+    fd_ddr = open("/dev/ddr4", O_RDWR);
+    fd_ddr_sro = open("/dev/ddr4", O_RDONLY | O_SYNC);
+    if (fd_ddr <= 0 || fd_ddr_sro <= 0) {
+        fprintf(stderr, "Failed to open UIO device.\n");
+        return -1;
+    };
+    pfd.fd = fd_ddr;
+    pfd.events = POLLIN;
+
+    // Open MMAP for DDR4
+    src = static_cast<char*>(mmap(NULL, 0x20000000, PROT_READ, MAP_SHARED, fd_ddr_sro, 0));
+    if (src == MAP_FAILED) {
+        fprintf(stderr, "Failed to MMAP the DDR: %s.\n", strerror(errno));
+        return -9;
+    };
+
+    // Initialize DAQ =========================================================
+    // Disable DAQ, mask IRQ
+    daq_enable = 0;
+    daq_enable.write();
+    s_wr = write(fd_ddr, &mask, sizeof(mask));
+
+    // Configure DAQ
+    daq_dbuf_ena = 3;
+    daq_dbuf_ena.write();
+    daq_tabsel[0] = 1;
+    daq_tabsel[1] = 1;
+    daq_tabsel.write();
+
+    // Enable DAQ
+    daq_enable = 1;
+    daq_enable.write();
+    daq_curbuff.read();
+
+    // trigger
+    daq_trigger = 1;
+    daq_trigger.write();
+    daq_trigger = 0;
+    daq_trigger.write();
+
+    // ========================================================================
+    // Open destination file
+    snprintf(fname, 128, "/mnt/data/archive_files/file_%08d.bin", fcnt);
+    fd_dst = open(fname, O_CREAT | O_WRONLY | O_APPEND , 0666);
+    if (fd_dst <= 0) {
+        fprintf(stderr, "Failed to open destination file '%s'.\n", fname);
+        return -2;
+    };
+
+    // Unmask interrupt
+    s_wr = write(fd_ddr, &unmask, sizeof(unmask));
+    if (s_wr != (ssize_t)sizeof(unmask)) {
+        fprintf(stderr, "Error when unmasking interrupt !\n");
+        return -3;
+    };
+
+    // Wait for interrupt
+    fprintf(stdout, "Waiting for interrupt...\n");
+    rp = poll(&pfd, 1, -1);     // Timeout = -1, infinite wait
+
+    if (rp >= 1) {
+        read(fd_ddr, &info, sizeof(info));
+        fprintf(stdout, "Read %d interrupts\n", info);
+    } else if (rp == 0) {
+        fprintf(stderr, "Wait for IRQ interrupted, timeout or signal.\n");
+        return -4;
+    } else {
+        fprintf(stderr, "Failed poll.\n");
+        return -5;
+        //fprintf(stderr, "Failed poll. Relaunch for next iteration.\n");
+        //continue;
+    };
+
+    fprintf(stdout, "Write to file '%s'.\n", fname);
+    // Copy data, whole block
+    /*
+    s_wr = write(fd_dst, &src, 0x08000000);
+    if (s_wr < 0x08000000) {
+        fprintf(stderr, "Error while writing to file '%s' (%d).\n", fname, s_wr);
+        return -6;
+    };
+    // */
+
+    // Copy data, page by page
+    //*
+    for (i = 0 ; i < 0x08000 ; i++) {
+        s_wr = write(fd_dst, &src[i*0x1000], 0x1000);
+        if (s_wr < 0x1000) {
+            fprintf(stderr, "Error while writing to file '%s' (%d:%d).\n", fname, i, s_wr);
+            return -6;
+        };
+    };
+    // */
+
+    close(fd_dst);
+
+    // Disable DAQ, mask IRQ
+    daq_enable = 0;
+    daq_enable.write();
+    s_wr = write(fd_ddr, &mask, sizeof(mask));
+
+    fprintf(stdout, "Done !\n");
+
+    return 0;
+
+}
diff --git a/recipes-app/simple-test/simple-test_0.1.bb b/recipes-app/simple-test/simple-test_0.1.bb
index b9f7866..e952e35 100644
--- a/recipes-app/simple-test/simple-test_0.1.bb
+++ b/recipes-app/simple-test/simple-test_0.1.bb
@@ -5,14 +5,14 @@ LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda
 
 inherit pkgconfig
 
-SRC_URI = "file://archiver.c"
+SRC_URI = "file://archiver.cpp"
 
 S = "${WORKDIR}"
 
-DEPENDS = ""
+DEPENDS = "deviceaccess"
 
 do_compile() {
-         ${CC} -O archiver.c -o archiver
+         ${CXX} `pkg-config ChimeraTK-DeviceAccess --cflags --libs` archiver.cpp -o archiver
 }
 
 do_install() {
-- 
GitLab