]> code.bitgloo.com Git - clyne/stmdsp.git/commitdiff
filter loading and real-time execution
authorClyne Sullivan <clyne@bitgloo.com>
Sun, 23 Aug 2020 00:34:03 +0000 (20:34 -0400)
committerClyne Sullivan <clyne@bitgloo.com>
Sun, 23 Aug 2020 00:34:03 +0000 (20:34 -0400)
filter/test.cpp
gui/stmdsp.cpp
gui/stmdsp.hpp
gui/wxmain.hpp
source/elf_load.cpp
source/elf_load.hpp
source/main.cpp

index 0953539e2e594c2e269bd42a25a9c749507047ec..24fdb7207409b83e8172e9d7c1555c9bfd530235 100644 (file)
@@ -8,8 +8,7 @@ void process_data(adcsample_t *samples, unsigned int size);
 
 void process_data(adcsample_t *samples, unsigned int size)
 {
-    size--;
     for (unsigned int i = 0; i < size; i++)
-        samples[i] = samples[i] * 80 / 100  + samples[i + 1] * 20 / 100;
+        samples[i] /= 2;
 }
 
index ed152f7bdc4fabbb01f19b5004ed9400e1f9235a..73ae8808e4613a207894893a97af8e12e8e1e22a 100644 (file)
@@ -53,10 +53,25 @@ namespace stmdsp
             m_serial.read(reinterpret_cast<uint8_t *>(data.data()), 2048 * sizeof(adcsample_t));
             return data;
         }
+
+        return {};
     }
 
     void device::continuous_stop() {
         if (connected())
             m_serial.write("S");
     }
+
+    void device::upload_filter(unsigned char *buffer, size_t size) {
+        if (connected()) {
+            uint8_t request[3] = {
+                'e',
+                static_cast<uint8_t>(size),
+                static_cast<uint8_t>(size >> 8)
+            };
+            m_serial.write(request, 3);
+
+            m_serial.write(buffer, size);
+        }
+    }
 }
index c1799553b3bd0428609fa58a6d1cc23f3afa74bf..ec58e5a2d306c1973bf70b13eae215c396aab980 100644 (file)
@@ -44,6 +44,8 @@ namespace stmdsp
         std::vector<adcsample_t> continuous_read();
         void continuous_stop();
 
+        void upload_filter(unsigned char *buffer, size_t size);
+
     private:
         serial::Serial m_serial;
     };
index 1fc74bd879e97cc28fa9b15b389286be65cdc1e2..289e89159c1dd0937b29942f24970e18cc3d61d7 100644 (file)
@@ -8,9 +8,11 @@
 #include <wx/button.h>
 #include <wx/combobox.h>
 #include <wx/dcclient.h>
+#include <wx/filedlg.h>
 #include <wx/frame.h>
 #include <wx/stattext.h>
 #include <wx/timer.h>
+#include <wx/wfstream.h>
 
 class MainFrame : public wxFrame
 {
@@ -18,6 +20,7 @@ class MainFrame : public wxFrame
         Welcome = 1,
         Single,
         SelectDevice,
+        UploadFilter,
         RenderTimer
     };
 
@@ -36,6 +39,7 @@ public:
     {
         new wxStaticText(this, Id::Welcome, "Welcome to the GUI.", wxPoint(20, 20));
         new wxButton(this, Id::Single, "Single", wxPoint(20, 60));
+        new wxButton(this, Id::UploadFilter, "Upload Filter", wxPoint(120, 60));
         m_device_combo = new wxComboBox(this, Id::SelectDevice, "", wxPoint(470, 20), wxSize(150, 30));
         m_device_combo->SetEditable(false);
         stmdsp::scanner scanner;
@@ -47,6 +51,7 @@ public:
         m_render_timer = new wxTimer(this, Id::RenderTimer);
 
         Bind(wxEVT_BUTTON, &MainFrame::onSinglePressed, this, Id::Single);
+        Bind(wxEVT_BUTTON, &MainFrame::onUploadPressed, this, Id::UploadFilter);
         Bind(wxEVT_PAINT, &MainFrame::onPaint, this, wxID_ANY);
         Bind(wxEVT_TIMER, &MainFrame::onRenderTimer, this, Id::RenderTimer);
     }
@@ -106,6 +111,22 @@ public:
         }
     }
 
+    void onUploadPressed(wxCommandEvent& ce) {
+        wxFileDialog dialog (this, "Select filter to upload", "", "", "*.so",
+                             wxFD_OPEN | wxFD_FILE_MUST_EXIST);
+        if (dialog.ShowModal() != wxID_CANCEL) {
+            if (wxFileInputStream file_stream (dialog.GetPath()); file_stream.IsOk()) {
+                auto size = file_stream.GetSize();
+                auto buffer = new unsigned char[size];
+                auto device = new stmdsp::device(m_device_combo->GetStringSelection().ToStdString());
+                if (device->connected()) {
+                    file_stream.ReadAll(buffer, size);
+                    device->upload_filter(buffer, size);
+                }
+            }
+        }
+    }
+
     void onRenderTimer([[maybe_unused]] wxTimerEvent& te) {
         updateDrawing();
     }
index 661dbc32ad55cb903d87267f42033c7bbe5202c9..8149e8a5d5349a231674264db46fd46ef147b2fc 100644 (file)
@@ -4,7 +4,6 @@
 #include <algorithm>
 #include <cstring>
 
-extern void *elf_load_offset;
 static const unsigned char elf_header[] = { '\177', 'E', 'L', 'F' };
 
 template<typename T>
@@ -17,10 +16,10 @@ static Elf32_Shdr *find_section(Elf32_Ehdr *ehdr, const char *name);
 
 namespace elf {
 
-entry_t elf_load(void *elf_data)
+entry_t load(void *elf_data, void *elf_load_offset)
 {
     auto ehdr = reinterpret_cast<Elf32_Ehdr *>(elf_data);
-    if (std::equal(ehdr->e_ident, ehdr->e_ident + 4, elf_header))
+    if (!std::equal(ehdr->e_ident, ehdr->e_ident + 4, elf_header))
         return nullptr;
 
     auto phdr = ptr_from_offset<Elf32_Phdr *>(elf_data, ehdr->e_phoff);
@@ -31,6 +30,8 @@ entry_t elf_load(void *elf_data)
                         phdr->p_filesz);
             //break;
         }
+
+        phdr = ptr_from_offset<Elf32_Phdr *>(phdr, ehdr->e_phentsize);
     }
 
     // Zero .bss section
@@ -53,7 +54,11 @@ entry_t elf_load(void *elf_data)
     //                  [elf_load_offset](auto func) { (func + elf_load_offset)(); });
     //}
 
-    return ptr_from_offset<entry_t>(elf_load_offset, ehdr->e_entry);
+    // Find filter code start
+    if (auto filter = find_section(ehdr, ".process_data"); filter)
+        return ptr_from_offset<entry_t>(elf_load_offset, filter->sh_addr | 1); // OR 1 to enable thumb
+    else
+        return nullptr;
 }
 
 } // namespace elf
index 722b19b3b5e2c6d76fde7dfa25f3c65cbdc33d67..3e03f1da29846de18c5d2a85ddef1908522b5cac 100644 (file)
@@ -1,11 +1,14 @@
 #ifndef ELF_LOAD_HPP_
 #define ELF_LOAD_HPP_
 
+#include <cstddef>
+#include <cstdint>
+
 namespace elf
 {
-    using entry_t = void (*)();
+    using entry_t = void (*)(uint16_t *, size_t);
 
-    entry_t load(void *file_data);
+    entry_t load(void *elf_data, void *elf_load_offset);
 }
 
 #endif // ELF_LOAD_HPP_
index 162771ad3f7bf3cdc50901a991ad350d5244329a..6c418ceb7f19dca575bb3b7bd3cda77ae986062b 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "adc.hpp"
 #include "dac.hpp"
+#include "elf_load.hpp"
 #include "usbserial.hpp"
 
 #include <array>
@@ -30,6 +31,10 @@ CC_ALIGN(CACHE_LINE_SIZE)
 #endif
 static std::array<dacsample_t, CACHE_SIZE_ALIGN(dacsample_t, 2048)> dac_samples;
 
+static uint8_t elf_file_store[2048];
+static uint8_t elf_exec_store[2048];
+static elf::entry_t elf_entry = nullptr;
+
 static volatile bool signal_operate_done = false;
 
 static void signal_operate(adcsample_t *buffer, size_t count);
@@ -73,7 +78,12 @@ int main()
                     adc::read_stop();
                     break;
                 case 'e':
-                    
+                    if (usbserial::read(&cmd[1], 2) < 2)
+                        break;
+                    if (unsigned int count = cmd[1] | (cmd[2] << 8); count < sizeof(elf_file_store)) {
+                        usbserial::read(elf_file_store, count);
+                        elf_entry = elf::load(elf_file_store, elf_exec_store);
+                    }
                     break;
                 case 'W':
                     if (usbserial::read(&cmd[1], 2) < 2)
@@ -103,6 +113,8 @@ int main()
 
 void signal_operate(adcsample_t *buffer, size_t count)
 {
+    if (elf_entry)
+        elf_entry(buffer, count);
     auto dac_buffer = &dac_samples[buffer == &adc_samples[0] ? 0 : 1024];
     std::copy(buffer, buffer + count, dac_buffer);
     signal_operate_done = buffer == &adc_samples[1024];