From 5f6181bb3c6ab4274a8068aaf14b278fa65e443e Mon Sep 17 00:00:00 2001
From: Clyne Sullivan <clyne@bitgloo.com>
Date: Sun, 21 Feb 2021 08:59:15 -0500
Subject: signal monitoring support

---
 source/adc.hpp          |  1 +
 source/main.cpp         | 42 ++++++++++++++++++++++++++++++++++++++----
 source/samplebuffer.cpp | 14 +++++++++++---
 source/samplebuffer.hpp |  4 +++-
 4 files changed, 53 insertions(+), 8 deletions(-)

(limited to 'source')

diff --git a/source/adc.hpp b/source/adc.hpp
index 488501c..d9a435a 100644
--- a/source/adc.hpp
+++ b/source/adc.hpp
@@ -42,6 +42,7 @@ private:
     static size_t m_current_buffer_size;
     static Operation m_operation;
 
+public:
     static void conversionCallback(ADCDriver *);
 };
 
diff --git a/source/main.cpp b/source/main.cpp
index 0dfc0e7..6e58510 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -52,7 +52,7 @@ static MAILBOX_DECL(conversionMB, conversionMBBuffer, 2);
 // Thread for LED status and wakeup hold
 __attribute__((section(".stacks")))
 static THD_WORKING_AREA(monitorThreadWA, 4096);
-static THD_FUNCTION(monitorThread, arg);
+/*extern "C"*/static THD_FUNCTION(monitorThread, arg);
 
 // Thread for managing the conversion task
 __attribute__((section(".stacks")))
@@ -161,6 +161,7 @@ THD_FUNCTION(communicationThread, arg)
                 // 'r' - Read or write sample rate.
                 // 'S' - Stop conversion.
                 // 's' - Get latest block of conversion results.
+                // 't' - Get latest block of conversion input.
                 // 'W' - Start signal generator (siggen).
                 // 'w' - Stop siggen.
 
@@ -308,6 +309,28 @@ THD_FUNCTION(communicationThread, arg)
                         USBSerial::write(reinterpret_cast<const uint8_t *>("\0\0"), 2);
                     }
                     break;
+                case 't':
+                    if (auto samps = samplesIn.modified(); samps != nullptr) {
+                        unsigned char buf[2] = {
+                            static_cast<unsigned char>(samplesIn.size() / 2 & 0xFF),
+                            static_cast<unsigned char>(((samplesIn.size() / 2) >> 8) & 0xFF)
+                        };
+                        USBSerial::write(buf, 2);
+                        unsigned int total = samplesIn.bytesize() / 2;
+                        unsigned int offset = 0;
+                        unsigned char unused;
+                        while (total > 512) {
+                            USBSerial::write(reinterpret_cast<uint8_t *>(samps) + offset, 512);
+                            while (USBSerial::read(&unused, 1) == 0);
+                            offset += 512;
+                            total -= 512;
+                        }
+                        USBSerial::write(reinterpret_cast<uint8_t *>(samps) + offset, total);
+                        while (USBSerial::read(&unused, 1) == 0);
+                    } else {
+                        USBSerial::write(reinterpret_cast<const uint8_t *>("\0\0"), 2);
+                    }
+                    break;
 
                 case 'W':
                     DAC::start(1, samplesSigGen.data(), samplesSigGen.size());
@@ -455,7 +478,13 @@ void signal_operate(adcsample_t *buffer, size_t)
         chSysUnlockFromISR();
         conversion_abort();
     } else {
-        chMBPostI(&conversionMB, buffer == samplesIn.data() ? MSG_CONVFIRST : MSG_CONVSECOND);
+        if (buffer == samplesIn.data()) {
+            samplesIn.setModified();
+            chMBPostI(&conversionMB, MSG_CONVFIRST);
+        } else {
+            samplesIn.setMidmodified();
+            chMBPostI(&conversionMB, MSG_CONVSECOND);
+        }
         chSysUnlockFromISR();
     }
 }
@@ -463,8 +492,13 @@ void signal_operate(adcsample_t *buffer, size_t)
 void signal_operate_measure(adcsample_t *buffer, [[maybe_unused]] size_t count)
 {
     chSysLockFromISR();
-    chMBPostI(&conversionMB, buffer == samplesIn.data() ? MSG_CONVFIRST_MEASURE
-                                                        : MSG_CONVSECOND_MEASURE);
+    if (buffer == samplesIn.data()) {
+        samplesIn.setModified();
+        chMBPostI(&conversionMB, MSG_CONVFIRST_MEASURE);
+    } else {
+        samplesIn.setMidmodified();
+        chMBPostI(&conversionMB, MSG_CONVSECOND_MEASURE);
+    }
     chSysUnlockFromISR();
 
     ADC::setOperation(signal_operate);
diff --git a/source/samplebuffer.cpp b/source/samplebuffer.cpp
index 55ebc81..24cc424 100644
--- a/source/samplebuffer.cpp
+++ b/source/samplebuffer.cpp
@@ -9,15 +9,23 @@ void SampleBuffer::clear() {
 __attribute__((section(".convcode")))
 void SampleBuffer::modify(Sample *data, unsigned int srcsize) {
     auto size = srcsize < m_size ? srcsize : m_size;
-    for (Sample *d = data, *s = m_buffer; d != data + size;)
-        *d++ = *s++;
     m_modified = m_buffer;
+    for (Sample *d = m_buffer, *s = data; s != data + size;)
+        *d++ = *s++;
 }
 __attribute__((section(".convcode")))
 void SampleBuffer::midmodify(Sample *data, unsigned int srcsize) {
     auto size = srcsize < m_size / 2 ? srcsize : m_size / 2;
-    for (Sample *d = data, *s = middata(); d != data + size;)
+    m_modified = middata();
+    for (Sample *d = middata(), *s = data; s != data + size;)
         *d++ = *s++;
+}
+
+void SampleBuffer::setModified() {
+    m_modified = m_buffer;
+}
+
+void SampleBuffer::setMidmodified() {
     m_modified = middata();
 }
 
diff --git a/source/samplebuffer.hpp b/source/samplebuffer.hpp
index 334c048..bed52bf 100644
--- a/source/samplebuffer.hpp
+++ b/source/samplebuffer.hpp
@@ -6,7 +6,7 @@
 
 using Sample = uint16_t;
 
-// gives 8000 (8192)
+// Gives 8000 (8192) samples total (algorithm works with max 4096).
 constexpr unsigned int MAX_SAMPLE_BUFFER_BYTESIZE = 16384;
 constexpr unsigned int MAX_SAMPLE_BUFFER_SIZE = MAX_SAMPLE_BUFFER_BYTESIZE / sizeof(Sample);
 
@@ -19,6 +19,8 @@ public:
 
     void modify(Sample *data, unsigned int srcsize);
     void midmodify(Sample *data, unsigned int srcsize);
+    void setModified();
+    void setMidmodified();
     Sample *modified();
 
     Sample *data();
-- 
cgit v1.2.3