diff options
Diffstat (limited to 'gui/wxmain.cpp')
-rw-r--r-- | gui/wxmain.cpp | 494 |
1 files changed, 7 insertions, 487 deletions
diff --git a/gui/wxmain.cpp b/gui/wxmain.cpp index 1a10b84..64f36e4 100644 --- a/gui/wxmain.cpp +++ b/gui/wxmain.cpp @@ -10,6 +10,7 @@ */ #include "wxmain.hpp" +#include "wxsiggen.hpp" #include <wx/combobox.h> #include <wx/dcclient.h> @@ -29,171 +30,7 @@ #include <sys/mman.h> #include <vector> -static const std::array<wxString, 6> srateValues { - "8 kS/s", - "16 kS/s", - "20 kS/s", - "32 kS/s", - "48 kS/s", - "96 kS/s" -}; -static const std::array<unsigned int, 6> srateNums { - 8000, - 16000, - 20000, - 32000, - 48000, - 96000 -}; - -static const char *makefile_text_h7 = R"make( -all: - @arm-none-eabi-g++ -x c++ -Os -fno-exceptions -fno-rtti \ - -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16 -mtune=cortex-m7 \ - -nostartfiles \ - -Wl,-Ttext-segment=0x00000000 -Wl,-zmax-page-size=512 -Wl,-eprocess_data_entry \ - $0 -o $0.o - @cp $0.o $0.orig.o - @arm-none-eabi-strip -s -S --strip-unneeded $0.o - @arm-none-eabi-objcopy --remove-section .ARM.attributes \ - --remove-section .comment \ - --remove-section .noinit \ - $0.o - arm-none-eabi-size $0.o -)make"; -static const char *makefile_text_l4 = R"make( -all: - @arm-none-eabi-g++ -x c++ -Os -fno-exceptions -fno-rtti \ - -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 \ - -nostartfiles \ - -Wl,-Ttext-segment=0x10000000 -Wl,-zmax-page-size=512 -Wl,-eprocess_data_entry \ - $0 -o $0.o - @cp $0.o $0.orig.o - @arm-none-eabi-strip -s -S --strip-unneeded $0.o - @arm-none-eabi-objcopy --remove-section .ARM.attributes \ - --remove-section .comment \ - --remove-section .noinit \ - $0.o - arm-none-eabi-size $0.o -)make"; - -static const char *file_header_h7 = R"cpp( -#include <cstdint> - -using adcsample_t = uint16_t; -constexpr unsigned int SIZE = $0; -adcsample_t *process_data(adcsample_t *samples, unsigned int size); -extern "C" void process_data_entry() -{ - ((void (*)())process_data)(); -} - -constexpr double PI = 3.14159265358979323846L; -__attribute__((naked)) -auto sin(double x) { -asm("vmov.f64 r1, r2, d0;" - "eor r0, r0;" - "svc 1;" - "vmov.f64 d0, r1, r2;" - "bx lr"); -return 0; -} -__attribute__((naked)) -auto cos(double x) { -asm("vmov.f64 r1, r2, d0;" - "mov r0, #1;" - "svc 1;" - "vmov.f64 d0, r1, r2;" - "bx lr"); -return 0; -} -__attribute__((naked)) -auto tan(double x) { -asm("vmov.f64 r1, r2, d0;" - "mov r0, #2;" - "svc 1;" - "vmov.f64 d0, r1, r2;" - "bx lr"); -return 0; -} -__attribute__((naked)) -auto sqrt(double x) { -asm("vsqrt.f64 d0, d0; bx lr"); -return 0; -} - -auto readalt() { -adcsample_t s; -asm("svc 3; mov %0, r0" : "=&r"(s)); -return s; -} - -// End stmdspgui header code - -)cpp"; -static const char *file_header_l4 = R"cpp( -#include <cstdint> - -using adcsample_t = uint16_t; -constexpr unsigned int SIZE = $0; -adcsample_t *process_data(adcsample_t *samples, unsigned int size); -extern "C" void process_data_entry() -{ - ((void (*)())process_data)(); -} - -constexpr float PI = 3.14159265358979L; -__attribute__((naked)) -auto sin(float x) { -asm("vmov.f32 r1, s0;" - "eor r0, r0;" - "svc 1;" - "vmov.f32 s0, r1;" - "bx lr"); -return 0; -} -__attribute__((naked)) -auto cos(float x) { -asm("vmov.f32 r1, s0;" - "mov r0, #1;" - "svc 1;" - "vmov.f32 s0, r1;" - "bx lr"); -return 0; -} -__attribute__((naked)) -auto tan(float x) { -asm("vmov.f32 r1, s0;" - "mov r0, #2;" - "svc 1;" - "vmov.f32 s0, r1;" - "bx lr"); -return 0; -} -__attribute__((naked)) -auto sqrt(float) { -asm("vsqrt.f32 s0, s0; bx lr"); -return 0; -} - -auto readalt() { -adcsample_t s; -asm("push {r4-r6}; svc 3; mov %0, r0; pop {r4-r6}" : "=&r"(s)); -return s; -} - -// End stmdspgui header code - -)cpp"; - - -static const char *file_content = -R"cpp(adcsample_t *process_data(adcsample_t *samples, unsigned int size) -{ - return samples; -} -)cpp"; - +#include "wxmain_devdata.h" enum Id { MeasureTimer = 1, @@ -218,7 +55,11 @@ enum Id { MCodeDisassemble }; -MainFrame::MainFrame() : wxFrame(nullptr, wxID_ANY, "stmdspgui", wxPoint(50, 50), wxSize(640, 800)) +#include "wxmain_mfile.h" +#include "wxmain_mrun.h" + +MainFrame::MainFrame() : + wxFrame(nullptr, wxID_ANY, "stmdspgui", wxDefaultPosition, wxSize(640, 800)) { // Main frame structure: // Begin with a main splitter for the code and terminal panes @@ -527,234 +368,6 @@ wxString MainFrame::compileEditorCode() } } -void MainFrame::onFileNew(wxCommandEvent&) -{ - m_open_file_path = ""; - m_text_editor->SetText(file_content); - m_text_editor->DiscardEdits(); - m_status_bar->SetStatusText("Ready."); -} - -void MainFrame::onFileOpen(wxCommandEvent&) -{ - wxFileDialog openDialog(this, "Open filter file", "", "", - "C++ source file (*.cpp)|*.cpp", - wxFD_OPEN | wxFD_FILE_MUST_EXIST); - - if (openDialog.ShowModal() != wxID_CANCEL) { - if (wxFileInputStream file_stream (openDialog.GetPath()); file_stream.IsOk()) { - auto size = file_stream.GetSize(); - auto buffer = new char[size + 1]; - buffer[size] = '\0'; - if (file_stream.ReadAll(buffer, size)) { - m_open_file_path = openDialog.GetPath(); - m_text_editor->SetText(buffer); - m_text_editor->DiscardEdits(); - m_compile_output->ChangeValue(""); - m_status_bar->SetStatusText("Ready."); - } else { - m_status_bar->SetStatusText("Failed to read file contents."); - } - delete[] buffer; - } else { - m_status_bar->SetStatusText("Failed to open file."); - } - } else { - m_status_bar->SetStatusText("Ready."); - } -} - -void MainFrame::onFileOpenTemplate(wxCommandEvent& event) -{ - auto file_path = wxGetCwd() + "/templates/" + m_menu_bar->GetLabel(event.GetId()); - - if (wxFileInputStream file_stream (file_path); file_stream.IsOk()) { - auto size = file_stream.GetSize(); - auto buffer = new char[size + 1]; - buffer[size] = '\0'; - if (file_stream.ReadAll(buffer, size)) { - m_open_file_path = ""; - m_text_editor->SetText(buffer); - //m_text_editor->DiscardEdits(); - m_status_bar->SetStatusText("Ready."); - } else { - m_status_bar->SetStatusText("Failed to read file contents."); - } - delete[] buffer; - } else { - m_status_bar->SetStatusText("Ready."); - } -} - - -void MainFrame::onFileSave(wxCommandEvent& ce) -{ - if (m_text_editor->IsModified()) { - if (m_open_file_path.IsEmpty()) { - onFileSaveAs(ce); - } else { - if (wxFile file (m_open_file_path, wxFile::write); file.IsOpened()) { - file.Write(m_text_editor->GetText()); - file.Close(); - m_text_editor->DiscardEdits(); - m_status_bar->SetStatusText("Saved."); - } else { - m_status_bar->SetStatusText("Save failed: couldn't open file."); - } - } - } else { - m_status_bar->SetStatusText("No modifications to save."); - } -} - -void MainFrame::onFileSaveAs(wxCommandEvent&) -{ - if (m_text_editor->IsModified()) { - wxFileDialog saveDialog(this, "Save filter file", "", "", - "C++ source file (*.cpp)|*.cpp", - wxFD_SAVE | wxFD_OVERWRITE_PROMPT); - - if (saveDialog.ShowModal() != wxID_CANCEL) { - if (wxFile file (saveDialog.GetPath(), wxFile::write); file.IsOpened()) { - file.Write(m_text_editor->GetText()); - file.Close(); - m_text_editor->DiscardEdits(); - m_open_file_path = saveDialog.GetPath(); - m_status_bar->SetStatusText("Saved."); - } else { - m_status_bar->SetStatusText("Save failed: couldn't open file."); - } - } - } else { - m_status_bar->SetStatusText("No modifications to save."); - } -} - -void MainFrame::onFileQuit(wxCommandEvent&) -{ - Close(true); -} - -void MainFrame::onRunConnect(wxCommandEvent& ce) -{ - auto menuItem = dynamic_cast<wxMenuItem *>(ce.GetEventUserData()); - - if (!m_device) { - stmdsp::scanner scanner; - if (auto devices = scanner.scan(); devices.size() > 0) { - m_device = new stmdsp::device(devices.front()); - if (m_device->connected()) { - auto rate = m_device->get_sample_rate(); - m_rate_select->SetSelection(rate); - - updateMenuOptions(); - menuItem->SetItemLabel("&Disconnect"); - m_status_bar->SetStatusText("Connected."); - } else { - delete m_device; - m_device = nullptr; - - menuItem->SetItemLabel("&Connect"); - m_status_bar->SetStatusText("Failed to connect."); - } - } else { - m_status_bar->SetStatusText("No devices found."); - } - } else { - delete m_device; - m_device = nullptr; - updateMenuOptions(); - menuItem->SetItemLabel("&Connect"); - m_status_bar->SetStatusText("Disconnected."); - } -} - -void MainFrame::onRunStart(wxCommandEvent& ce) -{ - auto menuItem = dynamic_cast<wxMenuItem *>(ce.GetEventUserData()); - - if (!m_is_running) { - if (m_run_measure->IsChecked()) { - m_device->continuous_start_measure(); - m_measure_timer->StartOnce(1000); - } else { - if (m_device->is_siggening() && m_wav_clip) { - m_measure_timer->Start(m_device->get_buffer_size() * 500 / - srateNums[m_rate_select->GetSelection()]); - } else if (m_conv_result_log) { - m_measure_timer->Start(15); - } else if (m_run_draw_samples->IsChecked()) { - m_measure_timer->Start(300); - } - - m_device->continuous_start(); - } - - m_rate_select->Enable(false); - menuItem->SetItemLabel("&Stop"); - m_status_bar->SetStatusText("Running."); - m_is_running = true; - } else { - m_device->continuous_stop(); - m_measure_timer->Stop(); - - m_rate_select->Enable(true); - menuItem->SetItemLabel("&Start"); - m_status_bar->SetStatusText("Ready."); - m_is_running = false; - - if (m_run_draw_samples->IsChecked()) - m_compile_output->Refresh(); - } -} - -void MainFrame::onRunLogResults(wxCommandEvent& ce) -{ - auto menuItem = dynamic_cast<wxMenuItem *>(ce.GetEventUserData()); - if (menuItem->IsChecked()) { - wxFileDialog dialog (this, "Choose log file", "", "", "*.csv", - wxFD_SAVE | wxFD_OVERWRITE_PROMPT); - - if (dialog.ShowModal() != wxID_CANCEL) { - if (m_conv_result_log) { - m_conv_result_log->Close(); - delete m_conv_result_log; - m_conv_result_log = nullptr; - } - - m_conv_result_log = new wxFileOutputStream(dialog.GetPath()); - } - - m_status_bar->SetStatusText("Ready."); - } else if (m_conv_result_log) { - m_conv_result_log->Close(); - delete m_conv_result_log; - m_conv_result_log = nullptr; - } -} - -void MainFrame::onRunEditBSize(wxCommandEvent&) -{ - wxTextEntryDialog dialog (this, "Enter new buffer size (100-4096)", "Set Buffer Size"); - if (dialog.ShowModal() == wxID_OK) { - if (wxString value = dialog.GetValue(); !value.IsEmpty()) { - if (unsigned long n; value.ToULong(&n)) { - if (n >= 100 && n <= stmdsp::SAMPLES_MAX) { - m_device->continuous_set_buffer_size(n); - } else { - m_status_bar->SetStatusText("Error: Invalid buffer size."); - } - } else { - m_status_bar->SetStatusText("Error: Invalid buffer size."); - } - } else { - m_status_bar->SetStatusText("Ready."); - } - } else { - m_status_bar->SetStatusText("Ready."); - } -} - void MainFrame::onToolbarSampleRate(wxCommandEvent& ce) { auto combo = dynamic_cast<wxComboBox *>(ce.GetEventUserData()); @@ -762,99 +375,6 @@ void MainFrame::onToolbarSampleRate(wxCommandEvent& ce) m_status_bar->SetStatusText("Ready."); } -void MainFrame::onRunGenUpload(wxCommandEvent&) -{ - wxTextEntryDialog dialog (this, "Enter up to 8000 generator values below. " - "Values must be whole numbers between zero and 4095.", - "Enter Generator Values"); - if (dialog.ShowModal() == wxID_OK) { - if (wxString values = dialog.GetValue(); !values.IsEmpty()) { - if (values[0] == '/') { - m_wav_clip = new wav::clip(values.Mid(1)); - if (m_wav_clip->valid()) { - m_status_bar->SetStatusText("Generator ready."); - } else { - delete m_wav_clip; - m_wav_clip = nullptr; - m_status_bar->SetStatusText("Error: Bad WAV file."); - } - } else { - std::vector<stmdsp::dacsample_t> samples; - while (!values.IsEmpty() && samples.size() <= stmdsp::SAMPLES_MAX * 2) { - if (auto number_end = values.find_first_not_of("0123456789"); - number_end != wxString::npos && number_end > 0) - { - auto number = values.Left(number_end); - if (unsigned long n; number.ToULong(&n)) - samples.push_back(n & 4095); - - if (auto next = values.find_first_of("0123456789", number_end + 1); - next != wxString::npos) - { - values = values.Mid(next); - } else { - break; - } - } else { - break; - } - } - - if (samples.size() <= stmdsp::SAMPLES_MAX) { - m_device->siggen_upload(&samples[0], samples.size()); - m_status_bar->SetStatusText("Generator ready."); - } else { - m_status_bar->SetStatusText("Error: Too many samples (max is 8000)."); - } - } - } else { - m_status_bar->SetStatusText("Error: No samples given."); - } - } else { - m_status_bar->SetStatusText("Ready."); - } -} - -void MainFrame::onRunGenStart(wxCommandEvent& ce) -{ - auto menuItem = dynamic_cast<wxMenuItem *>(ce.GetEventUserData()); - if (menuItem->IsChecked()) { - m_device->siggen_start(); - menuItem->SetItemLabel("Stop &generator"); - m_status_bar->SetStatusText("Generator running."); - } else { - m_device->siggen_stop(); - menuItem->SetItemLabel("Start &generator"); - m_status_bar->SetStatusText("Ready."); - } -} - -void MainFrame::onRunUpload(wxCommandEvent&) -{ - if (auto file = compileEditorCode(); !file.IsEmpty()) { - if (wxFileInputStream file_stream (file); file_stream.IsOk()) { - auto size = file_stream.GetSize(); - auto buffer = new unsigned char[size]; - file_stream.ReadAll(buffer, size); - m_device->upload_filter(buffer, size); - m_status_bar->SetStatusText("Code uploaded."); - } else { - m_status_bar->SetStatusText("Couldn't load compiled code."); - } - } -} - -void MainFrame::onRunUnload(wxCommandEvent&) -{ - m_device->unload_filter(); - m_status_bar->SetStatusText("Unloaded code."); -} - -void MainFrame::onRunCompile(wxCommandEvent&) -{ - compileEditorCode(); -} - void MainFrame::onCodeDisassemble(wxCommandEvent&) { if (!m_temp_file_name.IsEmpty()) { |