From 876bbbec3a6bf3d02d4ab7020cc73eaa6e247e9e Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Fri, 12 Jun 2020 18:49:09 -0400 Subject: [PATCH 1/9] have basic wxwidgets gui working --- .gitignore | 1 + gui/Makefile | 10 +++++++--- gui/main.cpp | 22 +++++++++++++--------- gui/stmdsp.hpp | 7 ++++--- gui/wxapp.hpp | 20 ++++++++++++++++++++ gui/wxmain.hpp | 17 +++++++++++++++++ 6 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 gui/wxapp.hpp create mode 100644 gui/wxmain.hpp diff --git a/.gitignore b/.gitignore index ccfe582..804a382 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ build ChibiOS_* **/.* +gui/stmdspgui diff --git a/gui/Makefile b/gui/Makefile index 419ed33..7cb0315 100644 --- a/gui/Makefile +++ b/gui/Makefile @@ -1,13 +1,17 @@ -CXX = clang++-10 -CXXFLAGS = --std=c++20 -Wall -Wextra -pedantic +CXX = g++-10 +CXXFLAGS = --std=c++20 \ + -Wall -Wextra -pedantic \ + -Wno-deprecated-copy \ + $(shell wx-config --cxxflags) CXXFILES = $(wildcard *.cpp) +LIBS = $(shell wx-config --libs) OUTELF = stmdspgui all: $(CXXFILES) @echo " CXX " $(CXXFILES) - @$(CXX) $(CXXFLAGS) $(CXXFILES) -o $(OUTELF) + @$(CXX) $(CXXFLAGS) $(CXXFILES) $(LIBS) -o $(OUTELF) clean: @echo " CLEAN" diff --git a/gui/main.cpp b/gui/main.cpp index 48f2990..ae6ecb4 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -1,15 +1,19 @@ #include "stmdsp.hpp" +#include "wxapp.hpp" #include +#include -int main() -{ - stmdsp::scanner scanner; +wxIMPLEMENT_APP(MainApp); - scanner.scan(); - for (const auto& device : scanner.devices()) - std::cout << "Found stmdsp at: " << device.path() << std::endl; - - return 0; -} +//int main() +//{ +// stmdsp::scanner scanner; +// +// scanner.scan(); +// for (const auto& device : scanner.devices()) +// std::cout << "Found stmdsp at: " << device.path() << std::endl; +// +// return 0; +//} diff --git a/gui/stmdsp.hpp b/gui/stmdsp.hpp index 12e4578..99a3bd3 100644 --- a/gui/stmdsp.hpp +++ b/gui/stmdsp.hpp @@ -1,5 +1,5 @@ -#ifndef STMDSPSCANNER_H -#define STMDSPSCANNER_H +#ifndef STMDSP_HPP_ +#define STMDSP_HPP_ #include #include @@ -57,4 +57,5 @@ namespace stmdsp }; } -#endif // STMDSPSCANNER_H +#endif // STMDSP_HPP_ + diff --git a/gui/wxapp.hpp b/gui/wxapp.hpp new file mode 100644 index 0000000..6536554 --- /dev/null +++ b/gui/wxapp.hpp @@ -0,0 +1,20 @@ +#ifndef WXAPP_HPP_ +#define WXAPP_HPP_ + +#include "wxmain.hpp" + +#include + +class MainApp : public wxApp +{ +public: + virtual bool OnInit() final { + auto mainFrame = new MainFrame; + mainFrame->Show(true); + SetTopWindow(mainFrame); + return true; + } +}; + +#endif // WXAPP_HPP_ + diff --git a/gui/wxmain.hpp b/gui/wxmain.hpp new file mode 100644 index 0000000..b5122f6 --- /dev/null +++ b/gui/wxmain.hpp @@ -0,0 +1,17 @@ +#ifndef WXMAIN_HPP_ +#define WXMAIN_HPP_ + +#include +#include + +class MainFrame : public wxFrame +{ +public: + MainFrame() : wxFrame(nullptr, -1, "Hello world", wxPoint(50, 50), wxSize(640, 480)) + { + auto lTitle = new wxStaticText(this, wxID_ANY, "Welcome to the GUI."); + } +}; + +#endif // WXMAIN_HPP_ + From ba34f22f9ca604cadf8a7fd88af0f22e52ef58e9 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Fri, 12 Jun 2020 19:07:29 -0400 Subject: [PATCH 2/9] button input --- gui/wxmain.hpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/gui/wxmain.hpp b/gui/wxmain.hpp index b5122f6..793fbc1 100644 --- a/gui/wxmain.hpp +++ b/gui/wxmain.hpp @@ -1,15 +1,29 @@ #ifndef WXMAIN_HPP_ #define WXMAIN_HPP_ +#include #include #include class MainFrame : public wxFrame { + enum Id { + Welcome = 1, + Single + }; + public: MainFrame() : wxFrame(nullptr, -1, "Hello world", wxPoint(50, 50), wxSize(640, 480)) { - auto lTitle = new wxStaticText(this, wxID_ANY, "Welcome to the GUI."); + new wxStaticText(this, Id::Welcome, "Welcome to the GUI.", wxPoint(20, 20)); + new wxButton(this, Id::Single, "Single", wxPoint(20, 60)); + + Bind(wxEVT_BUTTON, &MainFrame::onSinglePressed, this, Id::Single); + } + + void onSinglePressed(wxCommandEvent& ce) { + auto button = dynamic_cast(ce.GetEventObject()); + button->SetLabel("Nice"); } }; From 3b1f2bc9d2ea61e816308630a628b123c7223ad8 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sat, 13 Jun 2020 11:59:07 -0400 Subject: [PATCH 3/9] added window region painting --- gui/wxmain.hpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/gui/wxmain.hpp b/gui/wxmain.hpp index 793fbc1..974affb 100644 --- a/gui/wxmain.hpp +++ b/gui/wxmain.hpp @@ -2,6 +2,7 @@ #define WXMAIN_HPP_ #include +#include #include #include @@ -12,6 +13,10 @@ class MainFrame : public wxFrame Single }; + int m_radius = 10; + + const wxRect m_clipping_region = {20, 100, 600, 360}; + public: MainFrame() : wxFrame(nullptr, -1, "Hello world", wxPoint(50, 50), wxSize(640, 480)) { @@ -19,11 +24,30 @@ public: new wxButton(this, Id::Single, "Single", wxPoint(20, 60)); Bind(wxEVT_BUTTON, &MainFrame::onSinglePressed, this, Id::Single); + Bind(wxEVT_PAINT, &MainFrame::onPaint, this, wxID_ANY); + } + + void onPaint([[maybe_unused]] wxPaintEvent& pe) { + auto *dc = new wxClientDC(this); + dc->SetClippingRegion(m_clipping_region); + + dc->SetBrush(*wxBLACK_BRUSH); + dc->SetPen(*wxBLACK_PEN); + dc->DrawRectangle(m_clipping_region); + + dc->SetPen(*wxRED_PEN); + dc->DrawCircle(320, 240, m_radius); } void onSinglePressed(wxCommandEvent& ce) { auto button = dynamic_cast(ce.GetEventObject()); button->SetLabel("Nice"); + updateDrawing(); + } + + void updateDrawing() { + m_radius += 10; + this->RefreshRect(m_clipping_region); } }; From 65b755658c62c8cf608c0ba46af4607fd7c74cc5 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sat, 13 Jun 2020 12:25:58 -0400 Subject: [PATCH 4/9] debug flags; rendering with timer --- gui/Makefile | 2 +- gui/wxmain.hpp | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/gui/Makefile b/gui/Makefile index 7cb0315..a53d412 100644 --- a/gui/Makefile +++ b/gui/Makefile @@ -1,5 +1,5 @@ CXX = g++-10 -CXXFLAGS = --std=c++20 \ +CXXFLAGS = --std=c++20 -ggdb -Og \ -Wall -Wextra -pedantic \ -Wno-deprecated-copy \ $(shell wx-config --cxxflags) diff --git a/gui/wxmain.hpp b/gui/wxmain.hpp index 974affb..7832bdb 100644 --- a/gui/wxmain.hpp +++ b/gui/wxmain.hpp @@ -5,14 +5,18 @@ #include #include #include +#include class MainFrame : public wxFrame { enum Id { Welcome = 1, - Single + Single, + RenderTimer }; + bool m_is_rendering = false; + wxTimer *m_render_timer = nullptr; int m_radius = 10; const wxRect m_clipping_region = {20, 100, 600, 360}; @@ -22,9 +26,11 @@ public: { new wxStaticText(this, Id::Welcome, "Welcome to the GUI.", wxPoint(20, 20)); new wxButton(this, Id::Single, "Single", wxPoint(20, 60)); + m_render_timer = new wxTimer(this, Id::RenderTimer); Bind(wxEVT_BUTTON, &MainFrame::onSinglePressed, this, Id::Single); Bind(wxEVT_PAINT, &MainFrame::onPaint, this, wxID_ANY); + Bind(wxEVT_TIMER, &MainFrame::onRenderTimer, this, Id::RenderTimer); } void onPaint([[maybe_unused]] wxPaintEvent& pe) { @@ -41,12 +47,22 @@ public: void onSinglePressed(wxCommandEvent& ce) { auto button = dynamic_cast(ce.GetEventObject()); - button->SetLabel("Nice"); + + if (!m_render_timer->IsRunning()) { + m_render_timer->Start(100); + button->SetLabel("Stop"); + } else { + m_render_timer->Stop(); + button->SetLabel("Single"); + } + } + + void onRenderTimer([[maybe_unused]] wxTimerEvent& te) { updateDrawing(); } void updateDrawing() { - m_radius += 10; + m_radius++; this->RefreshRect(m_clipping_region); } }; From 6473b57cefe4c13cb262ed78bf0e49fe18a20267 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Thu, 18 Jun 2020 19:35:11 -0400 Subject: [PATCH 5/9] using serial lib, can connect to device --- .gitignore | 1 + .gitmodules | 6 ++++++ gui/Makefile | 22 +++++++++++++++++----- gui/serial | 1 + gui/stmdsp.cpp | 30 ++++++++---------------------- gui/stmdsp.hpp | 44 +++++--------------------------------------- gui/wxmain.hpp | 12 ++++++++++++ source/main.cpp | 4 +++- 8 files changed, 53 insertions(+), 67 deletions(-) create mode 100644 .gitmodules create mode 160000 gui/serial diff --git a/.gitignore b/.gitignore index 804a382..235fb51 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ build ChibiOS_* **/.* gui/stmdspgui +*.o diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0c9d779 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "gui/gui/serial"] + path = gui/gui/serial + url = https://github.com/wjwwood/serial +[submodule "gui/serial"] + path = gui/serial + url = https://github.com/wjwwood/serial diff --git a/gui/Makefile b/gui/Makefile index a53d412..99a0243 100644 --- a/gui/Makefile +++ b/gui/Makefile @@ -2,18 +2,30 @@ CXX = g++-10 CXXFLAGS = --std=c++20 -ggdb -Og \ -Wall -Wextra -pedantic \ -Wno-deprecated-copy \ + -Iserial/include \ $(shell wx-config --cxxflags) -CXXFILES = $(wildcard *.cpp) +CXXFILES = $(shell find serial/src -name "*.cc") $(wildcard *.cpp) +OFILES = $(patsubst %.cc, %.o, $(patsubst %.cpp, %.o, $(CXXFILES))) LIBS = $(shell wx-config --libs) OUTELF = stmdspgui -all: $(CXXFILES) - @echo " CXX " $(CXXFILES) - @$(CXX) $(CXXFLAGS) $(CXXFILES) $(LIBS) -o $(OUTELF) +all: $(OUTELF) + +$(OUTELF): $(OFILES) + @echo " CXX " $(OUTELF) + @$(CXX) $(CXXFLAGS) $(OFILES) $(LIBS) -o $(OUTELF) + +.cc.o: + @echo " CXX " $< + @$(CXX) $(CXXFLAGS) -c $< -o $@ + +.cpp.o: + @echo " CXX " $< + @$(CXX) $(CXXFLAGS) -c $< -o $@ clean: @echo " CLEAN" - @rm -f $(OUTELF) + @rm -f $(OUTELF) $(OFILES) diff --git a/gui/serial b/gui/serial new file mode 160000 index 0000000..cbcca7c --- /dev/null +++ b/gui/serial @@ -0,0 +1 @@ +Subproject commit cbcca7c83745fedd75afb7a0a27ee5c4112435c2 diff --git a/gui/stmdsp.cpp b/gui/stmdsp.cpp index 267bebc..5445264 100644 --- a/gui/stmdsp.cpp +++ b/gui/stmdsp.cpp @@ -1,31 +1,17 @@ #include "stmdsp.hpp" -#include -#include -#include - -using namespace std::chrono_literals; +#include namespace stmdsp { - void scanner::scan() + std::list& scanner::scan() { - std::string path ("/dev/ttyACM0"); - - for (unsigned int i = 0; i < 10; i++) { - path.back() = '0' + i; - if (std::filesystem::exists(path)) { - if (device dev (path); dev.open()) { - dev.write("i", 1); - std::this_thread::sleep_for(1s); - char buf[7]; - if (dev.read(buf, 6) == 6) { - buf[6] = '\0'; - if (std::string(buf) == "stmdsp") - m_devices.emplace(std::move(dev)); - } - } - } + auto serialDevices = serial::list_ports(); + for (auto& device : serialDevices) { + if (device.hardware_id.find(STMDSP_USB_ID) != std::string::npos) + m_devices.emplace_front(device.port); } + + return m_devices; } } diff --git a/gui/stmdsp.hpp b/gui/stmdsp.hpp index 99a3bd3..7695abe 100644 --- a/gui/stmdsp.hpp +++ b/gui/stmdsp.hpp @@ -2,58 +2,24 @@ #define STMDSP_HPP_ #include -#include +#include #include namespace stmdsp { - class device - { - public: - device(const std::string& path) : - m_path(path) {} - - bool open() { - m_stream.open(m_path, std::ios_base::in | std::ios_base::out | std::ios_base::binary); - return m_stream.is_open(); - } - - std::size_t read(char *buffer, std::size_t count) { - return m_stream.readsome(buffer, count); - } - - std::size_t write(const char *buffer, std::size_t count) { - m_stream.write(buffer, count); - return m_stream.good() ? count : 0; - } - - const std::string& path() const { - return m_path; - } - - auto operator<=>(const device& other) const { - return m_path <=> other.m_path; - } - - private: - std::string m_path; - std::fstream m_stream; - }; - class scanner { private: - constexpr static unsigned int STMDSP_VENDOR_ID = 0x0483; - constexpr static unsigned int STMDSP_DEVICE_ID = 0x5740; + constexpr static const char *STMDSP_USB_ID = "USB VID:PID=0483:5740"; public: - void scan(); - const auto& devices() const { + std::list& scan(); + auto& devices() { return m_devices; } private: - std::set m_devices; + std::list m_devices; }; } diff --git a/gui/wxmain.hpp b/gui/wxmain.hpp index 7832bdb..f23ae38 100644 --- a/gui/wxmain.hpp +++ b/gui/wxmain.hpp @@ -1,7 +1,10 @@ #ifndef WXMAIN_HPP_ #define WXMAIN_HPP_ +#include "stmdsp.hpp" + #include +#include #include #include #include @@ -12,6 +15,7 @@ class MainFrame : public wxFrame enum Id { Welcome = 1, Single, + SelectDevice, RenderTimer }; @@ -26,6 +30,14 @@ public: { new wxStaticText(this, Id::Welcome, "Welcome to the GUI.", wxPoint(20, 20)); new wxButton(this, Id::Single, "Single", wxPoint(20, 60)); + auto combo = new wxComboBox(this, Id::SelectDevice, "", wxPoint(470, 20), wxSize(150, 30)); + combo->SetEditable(false); + stmdsp::scanner scanner; + for (auto& dev : scanner.scan()) + combo->Append(dev); + if (combo->GetCount() > 0) + combo->SetSelection(0); + m_render_timer = new wxTimer(this, Id::RenderTimer); Bind(wxEVT_BUTTON, &MainFrame::onSinglePressed, this, Id::Single); diff --git a/source/main.cpp b/source/main.cpp index b8d2fa1..dc38ddd 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -18,6 +18,8 @@ #include +static_assert(sizeof(adcsample_t) == sizeof(uint16_t)); + #if CACHE_LINE_SIZE > 0 CC_ALIGN(CACHE_LINE_SIZE) #endif @@ -50,7 +52,7 @@ int main() if (char cmd; usbd.read(&cmd) > 0) { switch (cmd) { case 'r': // Read in analog signal - adc.getSamples(&adc_samples[0], adc_samples.size()); + adc.getSamples(&adc_samples[0], 100);//adc_samples.size()); usbd.write(adc_samples.data(), adc_samples.size()); break; case 'i': // Identify ourself as an stmdsp device From da8d7ffe8a12c10f819f103de1194511bdb3776e Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Thu, 18 Jun 2020 20:40:37 -0400 Subject: [PATCH 6/9] drafted device interface --- gui/main.cpp | 13 ------------- gui/stmdsp.cpp | 8 ++++---- gui/stmdsp.hpp | 41 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/gui/main.cpp b/gui/main.cpp index ae6ecb4..29f74d3 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -1,19 +1,6 @@ -#include "stmdsp.hpp" #include "wxapp.hpp" -#include #include wxIMPLEMENT_APP(MainApp); -//int main() -//{ -// stmdsp::scanner scanner; -// -// scanner.scan(); -// for (const auto& device : scanner.devices()) -// std::cout << "Found stmdsp at: " << device.path() << std::endl; -// -// return 0; -//} - diff --git a/gui/stmdsp.cpp b/gui/stmdsp.cpp index 5445264..4812884 100644 --- a/gui/stmdsp.cpp +++ b/gui/stmdsp.cpp @@ -6,12 +6,12 @@ namespace stmdsp { std::list& scanner::scan() { - auto serialDevices = serial::list_ports(); - for (auto& device : serialDevices) { + auto devices = serial::list_ports(); + for (auto& device : devices) { if (device.hardware_id.find(STMDSP_USB_ID) != std::string::npos) - m_devices.emplace_front(device.port); + m_available_devices.emplace_front(device.port); } - return m_devices; + return m_available_devices; } } diff --git a/gui/stmdsp.hpp b/gui/stmdsp.hpp index 7695abe..030038d 100644 --- a/gui/stmdsp.hpp +++ b/gui/stmdsp.hpp @@ -1,8 +1,9 @@ #ifndef STMDSP_HPP_ #define STMDSP_HPP_ -#include +#include #include +#include #include namespace stmdsp @@ -15,11 +16,45 @@ namespace stmdsp public: std::list& scan(); auto& devices() { - return m_devices; + return m_available_devices; } private: - std::list m_devices; + std::list m_available_devices; + }; + + using adcsample_t = uint16_t; + + class device + { + public: + device(const std::string& file) : + m_serial(file, 115200, serial::Timeout::simpleTimeout(1000)) {} + + ~device() { + m_serial.close(); + } + + bool connected() { + return m_serial.isOpen() && (m_serial.write("i"), m_serial.read(6) == "stmdsp"); + } + + std::vector sample(unsigned long int count = 1) { + if (connected()) { + m_serial.write(std::vector {'r', + static_cast(count), + static_cast(count >> 8)}); + std::vector data (count); + m_serial.read(reinterpret_cast(data.data()), + data.size() * sizeof(adcsample_t)); + return data; + } else { + return {}; + } + } + + private: + serial::Serial m_serial; }; } From 875b6a062029f0738ac309ef4a915120aee24ef7 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Wed, 24 Jun 2020 19:57:29 -0400 Subject: [PATCH 7/9] GUI reads ADC channel --- .gitignore | 1 + gui/stmdsp.cpp | 20 +++++++++++++++++ gui/stmdsp.hpp | 17 ++------------ gui/wxmain.hpp | 60 +++++++++++++++++++++++++++++++++++++++---------- source/main.cpp | 14 +++++++----- 5 files changed, 79 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index 235fb51..a9adb0f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ ChibiOS_* **/.* gui/stmdspgui *.o +perf* diff --git a/gui/stmdsp.cpp b/gui/stmdsp.cpp index 4812884..837d09c 100644 --- a/gui/stmdsp.cpp +++ b/gui/stmdsp.cpp @@ -14,4 +14,24 @@ namespace stmdsp return m_available_devices; } + + device::device(const std::string& file) : + m_serial(file, 230400, serial::Timeout::simpleTimeout(50)) {} + + std::vector device::sample(unsigned long int count) { + if (connected()) { + uint8_t request[3] = { + 'r', + static_cast(count), + static_cast(count >> 8) + }; + m_serial.write(request, 3); + std::vector data (count); + m_serial.read(reinterpret_cast(data.data()), + data.size() * sizeof(adcsample_t)); + return data; + } else { + return {}; + } + } } diff --git a/gui/stmdsp.hpp b/gui/stmdsp.hpp index 030038d..2148fa1 100644 --- a/gui/stmdsp.hpp +++ b/gui/stmdsp.hpp @@ -28,8 +28,7 @@ namespace stmdsp class device { public: - device(const std::string& file) : - m_serial(file, 115200, serial::Timeout::simpleTimeout(1000)) {} + device(const std::string& file); ~device() { m_serial.close(); @@ -39,19 +38,7 @@ namespace stmdsp return m_serial.isOpen() && (m_serial.write("i"), m_serial.read(6) == "stmdsp"); } - std::vector sample(unsigned long int count = 1) { - if (connected()) { - m_serial.write(std::vector {'r', - static_cast(count), - static_cast(count >> 8)}); - std::vector data (count); - m_serial.read(reinterpret_cast(data.data()), - data.size() * sizeof(adcsample_t)); - return data; - } else { - return {}; - } - } + std::vector sample(unsigned long int count = 1); private: serial::Serial m_serial; diff --git a/gui/wxmain.hpp b/gui/wxmain.hpp index f23ae38..97baae3 100644 --- a/gui/wxmain.hpp +++ b/gui/wxmain.hpp @@ -3,6 +3,8 @@ #include "stmdsp.hpp" +#include +#include #include #include #include @@ -21,22 +23,26 @@ class MainFrame : public wxFrame bool m_is_rendering = false; wxTimer *m_render_timer = nullptr; - int m_radius = 10; + wxComboBox *m_device_combo = nullptr; const wxRect m_clipping_region = {20, 100, 600, 360}; + stmdsp::device *m_device = nullptr; + std::future> m_device_samples_future; + std::vector m_device_samples; + public: MainFrame() : wxFrame(nullptr, -1, "Hello world", wxPoint(50, 50), wxSize(640, 480)) { new wxStaticText(this, Id::Welcome, "Welcome to the GUI.", wxPoint(20, 20)); new wxButton(this, Id::Single, "Single", wxPoint(20, 60)); - auto combo = new wxComboBox(this, Id::SelectDevice, "", wxPoint(470, 20), wxSize(150, 30)); - combo->SetEditable(false); + m_device_combo = new wxComboBox(this, Id::SelectDevice, "", wxPoint(470, 20), wxSize(150, 30)); + m_device_combo->SetEditable(false); stmdsp::scanner scanner; for (auto& dev : scanner.scan()) - combo->Append(dev); - if (combo->GetCount() > 0) - combo->SetSelection(0); + m_device_combo->Append(dev); + if (m_device_combo->GetCount() > 0) + m_device_combo->SetSelection(0); m_render_timer = new wxTimer(this, Id::RenderTimer); @@ -53,19 +59,47 @@ public: dc->SetPen(*wxBLACK_PEN); dc->DrawRectangle(m_clipping_region); - dc->SetPen(*wxRED_PEN); - dc->DrawCircle(320, 240, m_radius); + if (m_device_samples.size() > 0) { + dc->SetPen(*wxRED_PEN); + auto points = new wxPoint[m_device_samples.size()]; + const float spacing = static_cast(m_clipping_region.GetWidth()) / m_device_samples.size(); + float x = 0; + for (auto ptr = points; auto sample : m_device_samples) { + *ptr++ = wxPoint { + static_cast(x), + m_clipping_region.GetHeight() - sample * m_clipping_region.GetHeight() / 4096 + }; + x += spacing; + } + dc->DrawLines(m_device_samples.size(), points, m_clipping_region.GetX(), m_clipping_region.GetY()); + delete[] points; + } + } + + void doSingle() { + m_device_samples_future = std::async(std::launch::async, + [this]() { return m_device->sample(250); }); } void onSinglePressed(wxCommandEvent& ce) { auto button = dynamic_cast(ce.GetEventObject()); if (!m_render_timer->IsRunning()) { - m_render_timer->Start(100); - button->SetLabel("Stop"); + m_device = new stmdsp::device(m_device_combo->GetStringSelection().ToStdString()); + if (m_device->connected()) { + doSingle(); + m_render_timer->Start(100); + button->SetLabel("Stop"); + } else { + delete m_device; + m_device = nullptr; + } } else { m_render_timer->Stop(); button->SetLabel("Single"); + + delete m_device; + m_device = nullptr; } } @@ -74,8 +108,10 @@ public: } void updateDrawing() { - m_radius++; - this->RefreshRect(m_clipping_region); + if (m_device_samples = m_device_samples_future.get(); m_device_samples.size() > 0) + this->RefreshRect(m_clipping_region); + + doSingle(); } }; diff --git a/source/main.cpp b/source/main.cpp index dc38ddd..b73776a 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -23,7 +23,7 @@ static_assert(sizeof(adcsample_t) == sizeof(uint16_t)); #if CACHE_LINE_SIZE > 0 CC_ALIGN(CACHE_LINE_SIZE) #endif -static std::array adc_samples; +static std::array adc_samples; int main() { @@ -49,11 +49,13 @@ int main() while (true) { if (usbd.active()) { // Expect to receive a byte command 'packet'. - if (char cmd; usbd.read(&cmd) > 0) { - switch (cmd) { + if (char cmd[3]; usbd.read(&cmd, 3) > 0) { + switch (cmd[0]) { case 'r': // Read in analog signal - adc.getSamples(&adc_samples[0], 100);//adc_samples.size()); - usbd.write(adc_samples.data(), adc_samples.size()); + if (auto count = std::min(static_cast(cmd[1] | (cmd[2] << 8)), adc_samples.size()); count > 0) { + adc.getSamples(&adc_samples[0], count); + usbd.write(adc_samples.data(), count * sizeof(adcsample_t)); + } break; case 'i': // Identify ourself as an stmdsp device usbd.write("stmdsp", 6); @@ -64,7 +66,7 @@ int main() } } - chThdSleepMilliseconds(250); + chThdSleepMilliseconds(1); } } From 546fb2d9dce879b79855af50379fb0cdbba46551 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Thu, 9 Jul 2020 11:00:08 -0400 Subject: [PATCH 8/9] fixed command receiving code --- source/main.cpp | 146 ++++++++++++++++++++++++------------------------ 1 file changed, 74 insertions(+), 72 deletions(-) diff --git a/source/main.cpp b/source/main.cpp index b73776a..95211b4 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,72 +1,74 @@ -/** - * @file main.cpp - * @brief Program entry point. - * - * Copyright (C) 2020 Clyne Sullivan - * - * Distributed under the GNU GPL v3 or later. You should have received a copy of - * the GNU General Public License along with this program. - * If not, see . - */ - -#include "ch.h" -#include "hal.h" - -#include "adc.hpp" -#include "dac.hpp" -#include "usbserial.hpp" - -#include - -static_assert(sizeof(adcsample_t) == sizeof(uint16_t)); - -#if CACHE_LINE_SIZE > 0 -CC_ALIGN(CACHE_LINE_SIZE) -#endif -static std::array adc_samples; - -int main() -{ - halInit(); - chSysInit(); - - palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL); // LED - - ADCd adc (ADCD1, GPTD4); - adc.start(); - - //DACd dac (DACD1, { - // .init = 0, - // .datamode = DAC_DHRM_12BIT_RIGHT, - // .cr = 0 - //}); - //dac.start(); - //dac.write(0, 1024); - - USBSeriald usbd (SDU1); - usbd.start(); - - while (true) { - if (usbd.active()) { - // Expect to receive a byte command 'packet'. - if (char cmd[3]; usbd.read(&cmd, 3) > 0) { - switch (cmd[0]) { - case 'r': // Read in analog signal - if (auto count = std::min(static_cast(cmd[1] | (cmd[2] << 8)), adc_samples.size()); count > 0) { - adc.getSamples(&adc_samples[0], count); - usbd.write(adc_samples.data(), count * sizeof(adcsample_t)); - } - break; - case 'i': // Identify ourself as an stmdsp device - usbd.write("stmdsp", 6); - break; - default: - break; - } - } - } - - chThdSleepMilliseconds(1); - } -} - +/** + * @file main.cpp + * @brief Program entry point. + * + * Copyright (C) 2020 Clyne Sullivan + * + * Distributed under the GNU GPL v3 or later. You should have received a copy of + * the GNU General Public License along with this program. + * If not, see . + */ + +#include "ch.h" +#include "hal.h" + +#include "adc.hpp" +#include "dac.hpp" +#include "usbserial.hpp" + +#include + +static_assert(sizeof(adcsample_t) == sizeof(uint16_t)); + +#if CACHE_LINE_SIZE > 0 +CC_ALIGN(CACHE_LINE_SIZE) +#endif +static std::array adc_samples; + +int main() +{ + halInit(); + chSysInit(); + + palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL); // LED + + ADCd adc (ADCD1, GPTD4); + adc.start(); + + //DACd dac (DACD1, { + // .init = 0, + // .datamode = DAC_DHRM_12BIT_RIGHT, + // .cr = 0 + //}); + //dac.start(); + //dac.write(0, 1024); + + USBSeriald usbd (SDU1); + usbd.start(); + + while (true) { + if (usbd.active()) { + // Expect to receive a byte command 'packet'. + if (char cmd[3]; usbd.read(&cmd, 1) > 0) { + switch (cmd[0]) { + case 'r': // Read in analog signal + if (usbd.read(&cmd[1], 2) < 2) + break; + if (auto count = std::min(static_cast(cmd[1] | (cmd[2] << 8)), adc_samples.size()); count > 0) { + adc.getSamples(&adc_samples[0], count); + usbd.write(adc_samples.data(), count * sizeof(adcsample_t)); + } + break; + case 'i': // Identify ourself as an stmdsp device + usbd.write("stmdsp", 6); + break; + default: + break; + } + } + } + + chThdSleepMilliseconds(1); + } +} + From f07e878cd23e6e35743358ea306951f2218653a4 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Thu, 16 Jul 2020 20:11:26 -0400 Subject: [PATCH 9/9] added sample rate setting --- source/adc.cpp | 34 ++++++++++++++++++++++++++++++++++ source/adc.hpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/source/adc.cpp b/source/adc.cpp index 0c58e21..4e68a6e 100644 --- a/source/adc.cpp +++ b/source/adc.cpp @@ -39,6 +39,40 @@ adcsample_t *ADCd::getSamples(adcsample_t *buffer, size_t count) return buffer; } +void ADCd::setSampleRate(ADCdRate rate) +{ + uint32_t val = 0; + + switch (rate) { + case ADCdRate::R2P5: + val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_2P5); + break; + case ADCdRate::R6P5: + val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_6P5); + break; + case ADCdRate::R12P5: + val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_12P5); + break; + case ADCdRate::R24P5: + val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_24P5); + break; + case ADCdRate::R47P5: + val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_47P5); + break; + case ADCdRate::R92P5: + val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_92P5); + break; + case ADCdRate::R247P5: + val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_247P5); + break; + case ADCdRate::R640P5: + val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_640P5); + break; + } + + m_adc_group_config.smpr[0] = val; +} + void ADCd::initPins() { palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG); diff --git a/source/adc.hpp b/source/adc.hpp index 456e697..9989883 100644 --- a/source/adc.hpp +++ b/source/adc.hpp @@ -21,9 +21,53 @@ struct ADCdConfig : public ADCConfig ADCd *adcdinst; }; +enum class ADCdRate : unsigned int { + R2P5, + R6P5, + R12P5, + R24P5, + R47P5, + R92P5, + R247P5, + R640P5 +}; + class ADCd { public: + constexpr static const unsigned int CLOCK_RATE = 40000000; + constexpr static unsigned int SAMPLES_PER_SECOND(ADCdRate rate) { + unsigned int sps = 0; + switch (rate) { + case ADCdRate::R2P5: + sps = 15; + break; + case ADCdRate::R6P5: + sps = 19; + break; + case ADCdRate::R12P5: + sps = 25; + break; + case ADCdRate::R24P5: + sps = 37; + break; + case ADCdRate::R47P5: + sps = 60; + break; + case ADCdRate::R92P5: + sps = 105; + break; + case ADCdRate::R247P5: + sps = 260; + break; + case ADCdRate::R640P5: + sps = 653; + break; + } + + return static_cast(1.f / (sps / static_cast(CLOCK_RATE))); + } + constexpr explicit ADCd(ADCDriver& adcd, GPTDriver& gptd) : m_adcd(&adcd), m_gptd(&gptd), m_adc_config{}, m_adc_group_config(ADC_GROUP_CONFIG), @@ -31,6 +75,7 @@ public: void start(); adcsample_t *getSamples(adcsample_t *buffer, size_t count); + void setSampleRate(ADCdRate rate); private: static const GPTConfig m_gpt_config; @@ -43,6 +88,8 @@ private: bool m_is_adc_finished; void initPins(); + //void selectPins(bool a0, bool a1); + static void adcEndCallback(ADCDriver *adcd); constexpr static const ADCConversionGroup ADC_GROUP_CONFIG = {