filter loading and real-time execution

pull/3/head
Clyne 4 years ago
parent 96e4883081
commit 32fc992f6a

@ -8,8 +8,7 @@ void process_data(adcsample_t *samples, unsigned int size);
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++) for (unsigned int i = 0; i < size; i++)
samples[i] = samples[i] * 80 / 100 + samples[i + 1] * 20 / 100; samples[i] /= 2;
} }

@ -53,10 +53,25 @@ namespace stmdsp
m_serial.read(reinterpret_cast<uint8_t *>(data.data()), 2048 * sizeof(adcsample_t)); m_serial.read(reinterpret_cast<uint8_t *>(data.data()), 2048 * sizeof(adcsample_t));
return data; return data;
} }
return {};
} }
void device::continuous_stop() { void device::continuous_stop() {
if (connected()) if (connected())
m_serial.write("S"); 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);
}
}
} }

@ -44,6 +44,8 @@ namespace stmdsp
std::vector<adcsample_t> continuous_read(); std::vector<adcsample_t> continuous_read();
void continuous_stop(); void continuous_stop();
void upload_filter(unsigned char *buffer, size_t size);
private: private:
serial::Serial m_serial; serial::Serial m_serial;
}; };

@ -8,9 +8,11 @@
#include <wx/button.h> #include <wx/button.h>
#include <wx/combobox.h> #include <wx/combobox.h>
#include <wx/dcclient.h> #include <wx/dcclient.h>
#include <wx/filedlg.h>
#include <wx/frame.h> #include <wx/frame.h>
#include <wx/stattext.h> #include <wx/stattext.h>
#include <wx/timer.h> #include <wx/timer.h>
#include <wx/wfstream.h>
class MainFrame : public wxFrame class MainFrame : public wxFrame
{ {
@ -18,6 +20,7 @@ class MainFrame : public wxFrame
Welcome = 1, Welcome = 1,
Single, Single,
SelectDevice, SelectDevice,
UploadFilter,
RenderTimer RenderTimer
}; };
@ -36,6 +39,7 @@ public:
{ {
new wxStaticText(this, Id::Welcome, "Welcome to the GUI.", wxPoint(20, 20)); 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::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 = new wxComboBox(this, Id::SelectDevice, "", wxPoint(470, 20), wxSize(150, 30));
m_device_combo->SetEditable(false); m_device_combo->SetEditable(false);
stmdsp::scanner scanner; stmdsp::scanner scanner;
@ -47,6 +51,7 @@ public:
m_render_timer = new wxTimer(this, Id::RenderTimer); m_render_timer = new wxTimer(this, Id::RenderTimer);
Bind(wxEVT_BUTTON, &MainFrame::onSinglePressed, this, Id::Single); 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_PAINT, &MainFrame::onPaint, this, wxID_ANY);
Bind(wxEVT_TIMER, &MainFrame::onRenderTimer, this, Id::RenderTimer); 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) { void onRenderTimer([[maybe_unused]] wxTimerEvent& te) {
updateDrawing(); updateDrawing();
} }

@ -4,7 +4,6 @@
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
extern void *elf_load_offset;
static const unsigned char elf_header[] = { '\177', 'E', 'L', 'F' }; static const unsigned char elf_header[] = { '\177', 'E', 'L', 'F' };
template<typename T> template<typename T>
@ -17,10 +16,10 @@ static Elf32_Shdr *find_section(Elf32_Ehdr *ehdr, const char *name);
namespace elf { 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); 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; return nullptr;
auto phdr = ptr_from_offset<Elf32_Phdr *>(elf_data, ehdr->e_phoff); 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); phdr->p_filesz);
//break; //break;
} }
phdr = ptr_from_offset<Elf32_Phdr *>(phdr, ehdr->e_phentsize);
} }
// Zero .bss section // Zero .bss section
@ -53,7 +54,11 @@ entry_t elf_load(void *elf_data)
// [elf_load_offset](auto func) { (func + elf_load_offset)(); }); // [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 } // namespace elf

@ -1,11 +1,14 @@
#ifndef ELF_LOAD_HPP_ #ifndef ELF_LOAD_HPP_
#define ELF_LOAD_HPP_ #define ELF_LOAD_HPP_
#include <cstddef>
#include <cstdint>
namespace elf 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_ #endif // ELF_LOAD_HPP_

@ -14,6 +14,7 @@
#include "adc.hpp" #include "adc.hpp"
#include "dac.hpp" #include "dac.hpp"
#include "elf_load.hpp"
#include "usbserial.hpp" #include "usbserial.hpp"
#include <array> #include <array>
@ -30,6 +31,10 @@ CC_ALIGN(CACHE_LINE_SIZE)
#endif #endif
static std::array<dacsample_t, CACHE_SIZE_ALIGN(dacsample_t, 2048)> dac_samples; 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 volatile bool signal_operate_done = false;
static void signal_operate(adcsample_t *buffer, size_t count); static void signal_operate(adcsample_t *buffer, size_t count);
@ -73,7 +78,12 @@ int main()
adc::read_stop(); adc::read_stop();
break; break;
case 'e': 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; break;
case 'W': case 'W':
if (usbserial::read(&cmd[1], 2) < 2) if (usbserial::read(&cmd[1], 2) < 2)
@ -103,6 +113,8 @@ int main()
void signal_operate(adcsample_t *buffer, size_t count) 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]; auto dac_buffer = &dac_samples[buffer == &adc_samples[0] ? 0 : 1024];
std::copy(buffer, buffer + count, dac_buffer); std::copy(buffer, buffer + count, dac_buffer);
signal_operate_done = buffer == &adc_samples[1024]; signal_operate_done = buffer == &adc_samples[1024];

Loading…
Cancel
Save