]> code.bitgloo.com Git - clyne/stmdsp.git/commitdiff
signal gen with dac channel 2
authorClyne Sullivan <clyne@bitgloo.com>
Tue, 20 Oct 2020 16:27:21 +0000 (12:27 -0400)
committerClyne Sullivan <clyne@bitgloo.com>
Tue, 20 Oct 2020 16:27:21 +0000 (12:27 -0400)
cfg/mcuconf.h
gui/stmdsp.cpp
gui/stmdsp.hpp
gui/wxmain.cpp
gui/wxmain.hpp
source/dac.cpp
source/dac.hpp
source/main.cpp

index 520d6093abae38c4b245bae842589baa1b865f80..8b49f7a4b22bb5233b08490863339c3e40ee1edc 100644 (file)
  */\r
 #define STM32_DAC_DUAL_MODE                 FALSE\r
 #define STM32_DAC_USE_DAC1_CH1              TRUE\r
-#define STM32_DAC_USE_DAC1_CH2              FALSE\r
+#define STM32_DAC_USE_DAC1_CH2              TRUE\r
 #define STM32_DAC_DAC1_CH1_IRQ_PRIORITY     10\r
 #define STM32_DAC_DAC1_CH2_IRQ_PRIORITY     10\r
 #define STM32_DAC_DAC1_CH1_DMA_PRIORITY     2\r
index 8f190651c0c11f7671b4b2ace1dbf195d10991de..87b608d9570bbb74e27330a5a7f6d1716a901ce7 100644 (file)
@@ -77,6 +77,29 @@ namespace stmdsp
             m_serial.write("S");
     }
 
+    void device::siggen_upload(dacsample_t *buffer, unsigned int size) {
+        if (connected()) {
+            uint8_t request[3] = {
+                'D',
+                static_cast<uint8_t>(size),
+                static_cast<uint8_t>(size >> 8)
+            };
+            m_serial.write(request, 3);
+
+            m_serial.write((uint8_t *)buffer, size * sizeof(dacsample_t));
+        }
+    }
+
+    void device::siggen_start() {
+        if (connected())
+            m_serial.write("W");
+    }
+
+    void device::siggen_stop() {
+        if (connected())
+            m_serial.write("w");
+    }
+
     void device::upload_filter(unsigned char *buffer, size_t size) {
         if (connected()) {
             uint8_t request[3] = {
index 2d336c534614ddeb91a0533b63d6ca1c21706448..a9b8b7e3b3ef69ab025b906c5d489f60bb51b5a8 100644 (file)
@@ -24,6 +24,7 @@ namespace stmdsp
     };
 
     using adcsample_t = uint16_t;
+    using dacsample_t = uint16_t;
 
     class device
     {
@@ -40,12 +41,18 @@ namespace stmdsp
 
         //std::vector<adcsample_t> sample(unsigned long int count = 1);
 
+        void continuous_set_buffer_size(unsigned int size);
         void continuous_start();
         void continuous_start_measure();
         uint32_t continuous_start_get_measurement();
         std::vector<adcsample_t> continuous_read();
         void continuous_stop();
 
+        void siggen_upload(dacsample_t *buffer, unsigned int size);
+        void siggen_start();
+        void siggen_stop();
+
+        // buffer is ELF binary
         void upload_filter(unsigned char *buffer, size_t size);
         void unload_filter();
 
index 58f0d37f04f5009885e62718f3814c6b6998b44a..aa57066156a6e5b702911968b4ecf0ff0094accd 100644 (file)
@@ -10,6 +10,9 @@
 #include <wx/sizer.h>
 #include <wx/splitter.h>
 #include <wx/statusbr.h>
+#include <wx/textdlg.h>
+
+#include <vector>
 
 enum Id {
     MeasureTimer = 1,
@@ -25,6 +28,8 @@ enum Id {
     MRunMeasure,
     MRunUpload,
     MRunUnload,
+    MRunGenUpload,
+    MRunGenStart,
     MCodeCompile,
     MCodeDisassemble
 };
@@ -99,6 +104,12 @@ MainFrame::MainFrame() : wxFrame(nullptr, wxID_ANY, "stmdspgui", wxPoint(50, 50)
     Bind(wxEVT_MENU, &MainFrame::onRunUnload, this, Id::MRunUnload, wxID_ANY,
          menuRun->Append(MRunUnload, "U&nload code"));
 
+    menuRun->AppendSeparator();
+    Bind(wxEVT_MENU, &MainFrame::onRunGenUpload, this, Id::MRunGenUpload, wxID_ANY,
+         menuRun->Append(MRunGenUpload, "&Load signal generator..."));
+    Bind(wxEVT_MENU, &MainFrame::onRunGenStart, this, Id::MRunGenStart, wxID_ANY,
+         menuRun->AppendCheckItem(MRunGenStart, "Start &generator"));
+
     Bind(wxEVT_MENU, &MainFrame::onRunCompile, this, Id::MCodeCompile, wxID_ANY,
          menuCode->Append(MCodeCompile, "&Compile code"));
     Bind(wxEVT_MENU, &MainFrame::onCodeDisassemble, this, Id::MCodeDisassemble, wxID_ANY,
@@ -398,6 +409,59 @@ void MainFrame::onRunStart(wxCommandEvent& ce)
     }
 }
 
+void MainFrame::onRunGenUpload([[maybe_unused]] wxCommandEvent&)
+{
+    if (m_device != nullptr && m_device->connected()) {
+        wxTextEntryDialog dialog (this, "Enter generator values", "Hey");
+        if (dialog.ShowModal() == wxID_OK) {
+            if (wxString values = dialog.GetValue(); !values.IsEmpty()) {
+                std::vector<stmdsp::dacsample_t> samples;
+                while (!values.IsEmpty()) {
+                    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;
+                    }
+                }
+
+                m_device->siggen_upload(&samples[0], samples.size());
+            }
+        }
+    } else {
+        wxMessageBox("No device connected!", "Run", wxICON_WARNING);
+        m_status_bar->SetStatusText("Please connect.");
+    }
+}
+
+void MainFrame::onRunGenStart(wxCommandEvent& ce)
+{
+    auto menuItem = dynamic_cast<wxMenuItem *>(ce.GetEventUserData());
+    if (m_device != nullptr && m_device->connected()) {
+        if (menuItem->IsChecked()) {
+            m_device->siggen_start();
+            menuItem->SetItemLabel("Stop &generator");
+        } else {
+            m_device->siggen_stop();
+            menuItem->SetItemLabel("Start &generator");
+        }
+    } else {
+        wxMessageBox("No device connected!", "Run", wxICON_WARNING);
+        m_status_bar->SetStatusText("Please connect.");
+    }
+}
+
 void MainFrame::onRunUpload([[maybe_unused]] wxCommandEvent&)
 {
     if (auto file = compileEditorCode(); !file.IsEmpty()) {
index ce3e5a539633c597301638163c72344ff2946d1a..0da0b79ea2feaf3dcd4969276915cf81951d6be6 100644 (file)
@@ -36,6 +36,8 @@ public:
     void onRunStart(wxCommandEvent&);
     void onRunUpload(wxCommandEvent&);
     void onRunUnload(wxCommandEvent&);
+    void onRunGenUpload(wxCommandEvent&);
+    void onRunGenStart(wxCommandEvent&);
 
     void onRunCompile(wxCommandEvent&);
     void onCodeDisassemble(wxCommandEvent&);
index 74b69e3e7aedf98f241df29230b5dc03d5af90f0..c39da3829d88689ce1c15bc7a21539542a059f1f 100644 (file)
@@ -12,6 +12,7 @@
 #include "dac.hpp"
 
 constexpr static const auto dacd = &DACD1;
+constexpr static const auto dacd2 = &DACD2;
 constexpr static const auto gptd = &GPTD6;
 
 constexpr static const DACConfig dac_config = {
@@ -34,27 +35,40 @@ constexpr static const GPTConfig gpt_config = {
   .dier = 0
 };
 
+static unsigned int dacs_running = 0;
+
 namespace dac
 {
     void init()
     {
         palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG);
-        //palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG);
+        palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG);
     
         dacStart(dacd, &dac_config);
+        dacStart(dacd2, &dac_config);
         gptStart(gptd, &gpt_config);
     }
-    
-    void write_start(dacsample_t *buffer, size_t count)
+
+    void write_start(unsigned int channel, dacsample_t *buffer, size_t count)
     {
-        dacStartConversion(dacd, &dac_group_config, buffer, count);
-        gptStartContinuous(gptd, 25);
+        if (channel < 2) {
+            dacStartConversion(channel == 0 ? dacd : dacd2, &dac_group_config, buffer, count);
+
+            if (dacs_running == 0)
+                gptStartContinuous(gptd, 25);
+            dacs_running |= 1 << channel;
+        }
     }
     
-    void write_stop()
+    void write_stop(unsigned int channel)
     {
-        gptStopTimer(gptd);
-        dacStopConversion(dacd);
+        if (channel < 2) {
+            dacStopConversion(channel == 0 ? dacd : dacd2);
+
+            dacs_running &= ~(1 << channel);
+            if (dacs_running == 0)
+                gptStopTimer(gptd);
+        }
     }
 }
 
index 9d529bf57c4a1183f2ad31598075f971435f1c64..dec1b36aac0499a76be3a9e4328cf6f693a8d744 100644 (file)
@@ -17,8 +17,8 @@
 namespace dac
 {
     void init();
-    void write_start(dacsample_t *buffer, size_t count);
-    void write_stop();
+    void write_start(unsigned int channel, dacsample_t *buffer, size_t count);
+    void write_stop(unsigned int channel);
 }
 
 #endif // STMDSP_DAC_HPP_
index c46685f136805f291f41a81a48a6383e35164754..63bd66b2de9127e8ad1dc33b19256d4736034868 100644 (file)
@@ -77,6 +77,10 @@ static std::array<adcsample_t, CACHE_SIZE_ALIGN(adcsample_t, MAX_SAMPLE_BUFFER_S
 CC_ALIGN(CACHE_LINE_SIZE)
 #endif
 static std::array<dacsample_t, CACHE_SIZE_ALIGN(dacsample_t, MAX_SAMPLE_BUFFER_SIZE)> dac_samples;
+#if CACHE_LINE_SIZE > 0
+CC_ALIGN(CACHE_LINE_SIZE)
+#endif
+static std::array<dacsample_t, CACHE_SIZE_ALIGN(dacsample_t, MAX_SAMPLE_BUFFER_SIZE)> dac2_samples;
 
 static uint8_t elf_file_store[MAX_ELF_FILE_SIZE];
 static elf::entry_t elf_entry = nullptr;
@@ -112,6 +116,7 @@ int main()
 }
 
 static unsigned int dac_sample_count = MAX_SAMPLE_BUFFER_SIZE;
+static unsigned int dac2_sample_count = MAX_SAMPLE_BUFFER_SIZE;
 static unsigned int adc_sample_count = MAX_SAMPLE_BUFFER_SIZE;
 static bool adc_preloaded = false;
 static bool dac_preloaded = false;
@@ -133,6 +138,8 @@ void main_loop()
                     usbserial::read(&adc_samples[0], adc_sample_count * sizeof(adcsample_t));
                     break;
 
+                case 'b':
+                    break;
                 case 'B':
                     if (run_status == RunStatus::Idle) {
                         if (usbserial::read(&cmd[1], 2) == 2) {
@@ -155,7 +162,17 @@ void main_loop()
                     usbserial::write(dac_samples.data(), dac_sample_count * sizeof(dacsample_t));
                     break;
                 case 'D':
-                    usbserial::read(&dac_samples[0], dac_sample_count * sizeof(dacsample_t));
+                    if (usbserial::read(&cmd[1], 2) == 2) {
+                        unsigned int count = cmd[1] | (cmd[2] << 8);
+                        if (count <= MAX_SAMPLE_BUFFER_SIZE / 2) {
+                            dac2_sample_count = count;
+                            usbserial::read(&dac2_samples[0], dac2_sample_count * sizeof(dacsample_t));
+                        } else {
+                            error_queue_add(Error::BadParam);
+                        }
+                    } else {
+                        error_queue_add(Error::BadParamSize);
+                    }
                     break;
 
                 // 'E' - Reads in and loads the compiled conversion code binary from USB.
@@ -211,7 +228,7 @@ void main_loop()
                         if (!adc_preloaded)
                             adc::read_start(signal_operate_measure, &adc_samples[0], adc_sample_count);
                         if (!dac_preloaded)
-                            dac::write_start(&dac_samples[0], dac_sample_count);
+                            dac::write_start(0, &dac_samples[0], dac_sample_count);
                     } else {
                         error_queue_add(Error::NotIdle);
                     }
@@ -232,7 +249,7 @@ void main_loop()
                         if (!adc_preloaded)
                             adc::read_start(signal_operate, &adc_samples[0], adc_sample_count);
                         if (!dac_preloaded)
-                            dac::write_start(&dac_samples[0], dac_sample_count);
+                            dac::write_start(0, &dac_samples[0], dac_sample_count);
                     } else {
                         error_queue_add(Error::NotIdle);
                     }
@@ -251,13 +268,20 @@ void main_loop()
                 case 'S':
                     if (run_status == RunStatus::Running) {
                         if (!dac_preloaded)
-                            dac::write_stop();
+                            dac::write_stop(0);
                         if (!adc_preloaded)
                             adc::read_stop();
                         run_status = RunStatus::Idle;
                     }
                     break;
 
+                case 'W':
+                    dac::write_start(1, &dac2_samples[0], dac2_sample_count);
+                    break;
+                case 'w':
+                    dac::write_stop(1);
+                    break;
+
                 default:
                     break;
                 }
@@ -272,7 +296,7 @@ void conversion_abort()
 {
     elf_entry = nullptr;
     if (!dac_preloaded)
-        dac::write_stop();
+        dac::write_stop(0);
     if (!adc_preloaded)
         adc::read_stop();
     error_queue_add(Error::ConversionAborted);