]> code.bitgloo.com Git - clyne/stmdsp.git/commitdiff
fixed sample rate setting
authorClyne Sullivan <clyne@bitgloo.com>
Sun, 8 Nov 2020 23:31:02 +0000 (18:31 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Sun, 8 Nov 2020 23:31:02 +0000 (18:31 -0500)
cfg/chconf.h
cfg/mcuconf.h
gui/stmdsp.cpp
gui/stmdsp.hpp
gui/wxmain.cpp
gui/wxmain.hpp
source/adc.cpp
source/adc.hpp
source/dac.cpp
source/main.cpp

index 04570c1a13261fa948c8a0e1fe81e12a17042ef4..faa8600019000ba4dd935948f8666f89d29e9e1f 100644 (file)
  * @note    The default is @p FALSE.\r
  */\r
 #if !defined(CH_DBG_ENABLE_CHECKS)\r
-#define CH_DBG_ENABLE_CHECKS                FALSE\r
+#define CH_DBG_ENABLE_CHECKS                TRUE\r
 #endif\r
 \r
 /**\r
  * @note    The default is @p FALSE.\r
  */\r
 #if !defined(CH_DBG_ENABLE_ASSERTS)\r
-#define CH_DBG_ENABLE_ASSERTS               FALSE\r
+#define CH_DBG_ENABLE_ASSERTS               TRUE\r
 #endif\r
 \r
 /**\r
index 929e04990be018aae86a5ab0931d4dc9060eebd1..caad802ce2873b059d55b2167f674d87a0628b4a 100644 (file)
@@ -69,7 +69,7 @@
 #define STM32_PLLSAI1R_VALUE                4\r
 #define STM32_PLLSAI2N_VALUE                24\r
 #define STM32_PLLSAI2P_VALUE                7\r
-#define STM32_PLLSAI2R_VALUE                2\r
+#define STM32_PLLSAI2R_VALUE                8\r
 \r
 /*\r
  * Peripherals clock sources.\r
@@ -88,7 +88,7 @@
 #define STM32_SAI1SEL                       STM32_SAI1SEL_OFF\r
 #define STM32_SAI2SEL                       STM32_SAI2SEL_OFF\r
 #define STM32_CLK48SEL                      STM32_CLK48SEL_PLLSAI1\r
-#define STM32_ADCSEL                        STM32_ADCSEL_PLLSAI1\r
+#define STM32_ADCSEL                        STM32_ADCSEL_PLLSAI2\r
 #define STM32_SWPMI1SEL                     STM32_SWPMI1SEL_PCLK1\r
 #define STM32_DFSDMSEL                      STM32_DFSDMSEL_PCLK2\r
 #define STM32_RTCSEL                        STM32_RTCSEL_LSI\r
index 2091d480439f411e25fcad5b458816d51c1028fa..0621ba1aeb306aef35cbf2ff60947ae27d143815 100644 (file)
@@ -62,6 +62,20 @@ namespace stmdsp
         }
     }
 
+    unsigned int device::get_sample_rate() {
+        unsigned char result = 0xFF;
+
+        if (connected()) {
+            uint8_t request[2] = {
+                'r', 0xFF
+            };
+            m_serial.write(request, 2);
+            m_serial.read(&result, 1);
+        }
+
+        return result;
+    }
+
     void device::continuous_start() {
         if (connected())
             m_serial.write("R");
index 25c6a8c6562a0c801f2ee5133dbd2b5c8b357926..9c60b85a92136917f1477a0cd0f804a30134914a 100644 (file)
@@ -45,6 +45,7 @@ namespace stmdsp
 
         void continuous_set_buffer_size(unsigned int size);
         void set_sample_rate(unsigned int id);
+        unsigned int get_sample_rate();
         void continuous_start();
         void continuous_start_measure();
         uint32_t continuous_start_get_measurement();
index 8089911e7b9c87cbc6d192e6ed9f00ae99f71f20..cdbc06d05e6b98829f2258ccfb42b82badd4bcd3 100644 (file)
@@ -1,5 +1,6 @@
 #include "wxmain.hpp"
 
+#include <wx/combobox.h>
 #include <wx/dir.h>
 #include <wx/filename.h>
 #include <wx/filedlg.h>
@@ -40,8 +41,10 @@ enum Id {
 MainFrame::MainFrame() : wxFrame(nullptr, wxID_ANY, "stmdspgui", wxPoint(50, 50), wxSize(640, 800))
 {
     auto splitter = new wxSplitterWindow(this, wxID_ANY);
+    auto panelToolbar = new wxPanel(this, wxID_ANY);
     auto panelCode = new wxPanel(splitter, wxID_ANY);
     auto panelOutput = new wxPanel(splitter, wxID_ANY);
+    auto sizerToolbar = new wxBoxSizer(wxHORIZONTAL);
     auto sizerCode = new wxBoxSizer(wxVERTICAL);
     auto sizerOutput = new wxBoxSizer(wxVERTICAL);
     auto sizerSplitter = new wxBoxSizer(wxVERTICAL);
@@ -51,7 +54,7 @@ MainFrame::MainFrame() : wxFrame(nullptr, wxID_ANY, "stmdspgui", wxPoint(50, 50)
 
     // Member initialization
     m_status_bar = new wxStatusBar(this);
-    m_text_editor = new wxStyledTextCtrl(panelCode, wxID_ANY, wxDefaultPosition, wxSize(620, 500));
+    m_text_editor = new wxStyledTextCtrl(panelCode, wxID_ANY, wxDefaultPosition, wxSize(620, 440));
     m_compile_output = new wxTextCtrl(panelOutput, wxID_ANY, wxEmptyString, wxDefaultPosition,
                                       wxSize(620, 250), wxTE_READONLY | wxTE_MULTILINE | wxHSCROLL);
     m_measure_timer = new wxTimer(this, Id::MeasureTimer);
@@ -63,8 +66,30 @@ MainFrame::MainFrame() : wxFrame(nullptr, wxID_ANY, "stmdspgui", wxPoint(50, 50)
     splitter->SetSashGravity(0.5);
     splitter->SetMinimumPaneSize(20);
 
+    auto comp = new wxButton(panelToolbar, Id::MCodeCompile, "Compile");
+    static const wxString srateValues[] = {
+        "16 kS/s",
+        "48 kS/s",
+        "96 kS/s",
+        "100 kS/s",
+        "200 kS/s",
+        "1 MS/s",
+        "2 MS/s"
+    };
+    m_rate_select = new wxComboBox(panelToolbar, wxID_ANY,
+                                   wxEmptyString, wxDefaultPosition, wxDefaultSize,
+                                   7, srateValues, wxCB_READONLY);
+    m_rate_select->Disable();
+
+    sizerToolbar->Add(comp, 0, wxLEFT, 4);
+    sizerToolbar->Add(m_rate_select, 0, wxLEFT, 12);
+    panelToolbar->SetSizer(sizerToolbar);
+    Bind(wxEVT_BUTTON, &MainFrame::onRunCompile, this, Id::MCodeCompile, wxID_ANY, comp);
+    Bind(wxEVT_COMBOBOX, &MainFrame::onToolbarSampleRate, this, wxID_ANY, wxID_ANY, m_rate_select);
+
     prepareEditor();
-    sizerCode->Add(m_text_editor, 1, wxEXPAND | wxALL, 0);
+    sizerCode->Add(panelToolbar, 0, wxTOP | wxBOTTOM, 4);
+    sizerCode->Add(m_text_editor, 1, wxEXPAND, 0);
     panelCode->SetSizer(sizerCode);
 
     m_compile_output->SetBackgroundColour(wxColour(0, 0, 0));
@@ -72,7 +97,7 @@ MainFrame::MainFrame() : wxFrame(nullptr, wxID_ANY, "stmdspgui", wxPoint(50, 50)
     sizerOutput->Add(m_compile_output, 1, wxEXPAND | wxALL, 0);
     panelOutput->SetSizer(sizerOutput);
 
-    splitter->SplitHorizontally(panelCode, panelOutput, 500);
+    splitter->SplitHorizontally(panelCode, panelOutput, 440);
 
     sizerSplitter->Add(splitter, 1, wxEXPAND, 5);
     SetSizer(sizerSplitter);
@@ -110,8 +135,6 @@ MainFrame::MainFrame() : wxFrame(nullptr, wxID_ANY, "stmdspgui", wxPoint(50, 50)
          menuRun->Append(MRunUnload, "U&nload code"));
     Bind(wxEVT_MENU, &MainFrame::onRunEditBSize, this, Id::MRunEditBSize, wxID_ANY,
          menuRun->Append(MRunEditBSize, "Set &buffer size..."));
-    Bind(wxEVT_MENU, &MainFrame::onRunEditSRate, this, Id::MRunEditSRate, wxID_ANY,
-         menuRun->Append(MRunEditSRate, "Set sample &rate..."));
 
     menuRun->AppendSeparator();
     Bind(wxEVT_MENU, &MainFrame::onRunGenUpload, this, Id::MRunGenUpload, wxID_ANY,
@@ -210,6 +233,7 @@ all:
                            --remove-section .comment \
                            --remove-section .noinit \
                            $0.o
+       arm-none-eabi-size $0.o
 )make";
 
 static wxString file_header (R"cpp(
@@ -257,11 +281,9 @@ wxString MainFrame::compileEditorCode()
 
     if (result == 0) {
         m_status_bar->SetStatusText("Compilation succeeded.");
-        m_compile_output->ChangeValue("");
         return m_temp_file_name + ".o";
     } else {
         m_status_bar->SetStatusText("Compilation failed.");
-        m_compile_output->LoadFile(make_output);
         return "";
     }
 }
@@ -294,6 +316,7 @@ void MainFrame::onFileOpen([[maybe_unused]] wxCommandEvent&)
                 m_open_file_path = openDialog.GetPath();
                 m_text_editor->SetText(buffer);
                 m_text_editor->DiscardEdits();
+                m_compile_output->ChangeValue("");
                 m_status_bar->SetStatusText("Ready.");
             }
             delete[] buffer;
@@ -377,11 +400,17 @@ void MainFrame::onRunConnect(wxCommandEvent& ce)
         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);
+                m_rate_select->Enable();
+
                 menuItem->SetItemLabel("&Disconnect");
                 m_status_bar->SetStatusText("Connected.");
             } else {
                 delete m_device;
                 m_device = nullptr;
+
+                m_rate_select->Disable();
                 menuItem->SetItemLabel("&Connect");
                 m_status_bar->SetStatusText("Failed to connect.");
             }
@@ -478,27 +507,12 @@ void MainFrame::onRunEditBSize([[maybe_unused]] wxCommandEvent&)
     }
 }
 
-void MainFrame::onRunEditSRate([[maybe_unused]] wxCommandEvent&)
+void MainFrame::onToolbarSampleRate(wxCommandEvent& ce)
 {
     if (m_device != nullptr && m_device->connected()) {
-        wxTextEntryDialog dialog (this, "Enter new sample rate id:", "Set Sample Rate");
-        if (dialog.ShowModal() == wxID_OK) {
-            if (wxString value = dialog.GetValue(); !value.IsEmpty()) {
-                if (unsigned long n; value.ToULong(&n)) {
-                    if (n < 20) {
-                        m_device->set_sample_rate(n);
-                    } else {
-                        m_status_bar->SetStatusText("Error: Invalid sample rate.");
-                    }
-                } else {
-                    m_status_bar->SetStatusText("Error: Invalid sample rate.");
-                }
-            } else {
-                m_status_bar->SetStatusText("Ready.");
-            }
-        } else {
-            m_status_bar->SetStatusText("Ready.");
-        }
+        auto combo = dynamic_cast<wxComboBox *>(ce.GetEventUserData());
+        m_device->set_sample_rate(combo->GetCurrentSelection());
+        m_status_bar->SetStatusText("Ready.");
     } else {
         wxMessageBox("No device connected!", "Run", wxICON_WARNING);
         m_status_bar->SetStatusText("Please connect.");
index d4d24deaaad6fd6c490c20b6c6c5204b2c5c3079..4a73b2fa845dd1b66372df2e83a7d5b3c6cd6256 100644 (file)
@@ -38,10 +38,11 @@ public:
     void onRunUpload(wxCommandEvent&);
     void onRunUnload(wxCommandEvent&);
     void onRunEditBSize(wxCommandEvent&);
-    void onRunEditSRate(wxCommandEvent&);
     void onRunGenUpload(wxCommandEvent&);
     void onRunGenStart(wxCommandEvent&);
 
+    void onToolbarSampleRate(wxCommandEvent&);
+
     void onRunCompile(wxCommandEvent&);
     void onCodeDisassemble(wxCommandEvent&);
 
@@ -57,6 +58,7 @@ private:
     wxTimer *m_measure_timer = nullptr;
     wxStatusBar *m_status_bar = nullptr;
     wxMenuBar *m_menu_bar = nullptr;
+    wxComboBox *m_rate_select = nullptr;
     wxFileOutputStream *m_conv_result_log = nullptr;
     wxString m_open_file_path;
     wxString m_temp_file_name;
index a8c0e626c10d9c2f7fe07b94070a6038b224b836..c8da25ff8277cc7a69a423991c2d0f84f525f7ba 100644 (file)
@@ -38,36 +38,23 @@ static ADCConversionGroup adc_group_config = {
 };
 
 constexpr static const GPTConfig gpt_config = {
-    .frequency = 14400000,
+    .frequency = 36000000,
     .callback = nullptr,
     .cr2 = TIM_CR2_MMS_1, /* TRGO */
     .dier = 0
 };
 
+#define ADC_CCR_PRESC_DIV1 (0)
+#define ADC_SAMPLE_RATE_SETTINGS_COUNT (7)
 static uint32_t adc_sample_rate_settings[] = {
-    10, ADC_SMPR_SMP_47P5, 4608, // 3125
-    11, ADC_SMPR_SMP_12P5, 3840, // 3750
-    9,  ADC_SMPR_SMP_47P5, 2304, // 6250
-    10, ADC_SMPR_SMP_12P5, 1920, // 7500
-    8,  ADC_SMPR_SMP_47P5, 1152, // 12K5
-    9,  ADC_SMPR_SMP_12P5, 960,  // 15K
-    7,  ADC_SMPR_SMP_47P5, 576,  // 25K
-    8,  ADC_SMPR_SMP_12P5, 480,  // 30K
-    5,  ADC_SMPR_SMP_47P5, 360,  // 40K
-    4,  ADC_SMPR_SMP_47P5, 288,  // 50K
-    7,  ADC_SMPR_SMP_12P5, 240,  // 60K
-    6,  ADC_SMPR_SMP_12P5, 180,  // 80K
-    5,  ADC_SMPR_SMP_12P5, 150,  // 96K
-    2,  ADC_SMPR_SMP_47P5, 144,  // 100K
-    4,  ADC_SMPR_SMP_12P5, 120,  // 120K
-    3,  ADC_SMPR_SMP_12P5, 90,   // 160K
-    1,  ADC_SMPR_SMP_47P5, 72,   // 200K
-    2,  ADC_SMPR_SMP_12P5, 60,   // 240K
-    0,  ADC_SMPR_SMP_47P5, 36,   // 400K
-    1,  ADC_SMPR_SMP_12P5, 30,   // 480K
-    1,  ADC_SMPR_SMP_2P5,  18,   // 800K
-    0,  ADC_SMPR_SMP_12P5, 15,   // 960K
-    0,  ADC_SMPR_SMP_2P5,  9     // 1M6
+    // Rate    PLLSAI2N  ADC_PRESC            ADC_SMPR           GPT_DIV
+    /* 16k  */ 8,        ADC_CCR_PRESC_DIV10, ADC_SMPR_SMP_12P5, 2250,
+    /* 48k  */ 24,       ADC_CCR_PRESC_DIV10, ADC_SMPR_SMP_12P5, 750,
+    /* 96k  */ 48,       ADC_CCR_PRESC_DIV10, ADC_SMPR_SMP_12P5, 375,
+    /* 100k */ 40,       ADC_CCR_PRESC_DIV8,  ADC_SMPR_SMP_12P5, 360,
+    /* 400k */ 40,       ADC_CCR_PRESC_DIV2,  ADC_SMPR_SMP_12P5, 90,
+    /* 1M   */ 38,       ADC_CCR_PRESC_DIV1,  ADC_SMPR_SMP_6P5,  36,
+    /* 2M   */ 76,       ADC_CCR_PRESC_DIV1,  ADC_SMPR_SMP_6P5,  18
 };
 
 static bool adc_is_read_finished = false;
@@ -92,17 +79,35 @@ namespace adc
     void set_rate(rate new_rate)
     {
         auto index = static_cast<unsigned int>(new_rate);
-        auto presc = adc_sample_rate_settings[index * 3] << 18;
-        auto smp = adc_sample_rate_settings[index * 3 + 1];
-        adc_gpt_divisor = adc_sample_rate_settings[index * 3 + 2];
+        auto plln = adc_sample_rate_settings[index * 4] << RCC_PLLSAI2CFGR_PLLSAI2N_Pos;
+        auto presc = adc_sample_rate_settings[index * 4 + 1] << ADC_CCR_PRESC_Pos;
+        auto smp = adc_sample_rate_settings[index * 4 + 2];
+        adc_gpt_divisor = adc_sample_rate_settings[index * 4 + 3];
     
         adcStop(adcd);
+
+        // Adjust PLLSAI2
+        RCC->CR &= ~(RCC_CR_PLLSAI2ON);
+        while ((RCC->CR & RCC_CR_PLLSAI2RDY) == RCC_CR_PLLSAI2RDY);
+        RCC->PLLSAI2CFGR = (RCC->PLLSAI2CFGR & ~(RCC_PLLSAI2CFGR_PLLSAI2N_Msk)) | plln;
+        RCC->CR |= RCC_CR_PLLSAI2ON;
+
         // Set ADC prescaler
-        adcd->adcc->CCR = (adcd->adcc->CCR & ~(0xF << 18)) | presc;
+        adcd->adcc->CCR = (adcd->adcc->CCR & ~(ADC_CCR_PRESC_Msk)) | presc;
         // Set sampling time
         adc_group_config.smpr[0] = ADC_SMPR1_SMP_AN5(smp);
         adcStart(adcd, &adc_config);
     }
+    
+    unsigned int get_rate()
+    {
+        for (unsigned int i = 0; i < ADC_SAMPLE_RATE_SETTINGS_COUNT; i++) {
+            if (adc_gpt_divisor == adc_sample_rate_settings[i * 3 + 3])
+                return i;
+        }
+
+        return 0xFF;
+    }
 
     unsigned int get_gpt_divisor()
     {
index 5f411174d14d9f4d5fd6f6b366c926730230e64c..1431aa11bd6d9da8f27d214129b3f112972f2cab 100644 (file)
@@ -19,33 +19,18 @@ namespace adc
     using operation_t = void (*)(adcsample_t *buffer, size_t count);
 
     enum class rate : unsigned int {
-        R3125 = 0,
-        R3750,
-        R6250,
-        R7500,
-        R12K5,
-        R15K,
-        R25K,
-        R30K,
-        R40K,
-        R50K,
-        R60K,
-        R80K,
+        R16K = 0,
+        R48K,
         R96K,
         R100K,
-        R120K,
-        R160K,
-        R200K,
-        R240K,
         R400K,
-        R480K,
-        R800K,
-        R960K,
-        R1M6
+        R1M,
+        R2M
     };
     
     void init();
     void set_rate(rate new_rate);
+    unsigned int get_rate();
     unsigned int get_gpt_divisor();
     adcsample_t *read(adcsample_t *buffer, size_t count);
     void read_start(operation_t operation_func, adcsample_t *buffer, size_t count);
index 1a7254a94748fe9e1f6614dab4395ead40a5b6d5..ed4dce167f6c8f3fc883f670a945b5492bcc19f6 100644 (file)
@@ -30,7 +30,7 @@ constexpr static const DACConversionGroup dac_group_config = {
 };
 
 constexpr static const GPTConfig gpt_config = {
-  .frequency = 14400000,
+  .frequency = 36000000,
   .callback = nullptr,
   .cr2 = TIM_CR2_MMS_1, /* TRGO */
   .dier = 0
index 17b0adbd9c1215bd8f55b4f38befcb3bffea7330..8948b8e94206e957f9c204302adb2396940b99f2 100644 (file)
@@ -250,10 +250,16 @@ void main_loop()
                     break;
 
                 case 'r':
-                    if (usbserial::read(&cmd[1], 1) == 1)
-                        adc::set_rate(static_cast<adc::rate>(cmd[1]));
-                    else
+                    if (usbserial::read(&cmd[1], 1) == 1) {
+                        if (cmd[1] == 0xFF) {
+                            unsigned char r = static_cast<unsigned char>(adc::get_rate());
+                            usbserial::write(&r, 1);
+                        } else {
+                            adc::set_rate(static_cast<adc::rate>(cmd[1]));
+                        }
+                    } else {
                         error_queue_add(Error::BadParamSize);
+                    }
                     break;
 
                 // 'S' - Stops the continuous sampling/conversion.
@@ -267,6 +273,10 @@ void main_loop()
 
                 case 's':
                     if (dac_samples_new != nullptr) {
+                        auto samps = reinterpret_cast<const uint8_t *>(
+                            const_cast<const dacsample_t *>(dac_samples_new));
+                        dac_samples_new = nullptr;
+
                         unsigned char buf[2] = {
                             static_cast<unsigned char>(dac_sample_count / 2 & 0xFF),
                             static_cast<unsigned char>(((dac_sample_count / 2) >> 8) & 0xFF)
@@ -275,8 +285,6 @@ void main_loop()
                         unsigned int total = dac_sample_count / 2 * sizeof(dacsample_t);
                         unsigned int offset = 0;
                         unsigned char unused;
-                        auto samps = reinterpret_cast<const uint8_t *>(
-                            const_cast<const dacsample_t *>(dac_samples_new));
                         while (total > 512) {
                             usbserial::write(samps + offset, 512);
                             while (usbserial::read(&unused, 1) == 0);
@@ -285,7 +293,6 @@ void main_loop()
                         }
                         usbserial::write(samps + offset, total);
                         while (usbserial::read(&unused, 1) == 0);
-                        dac_samples_new = nullptr;
                     } else {
                         usbserial::write("\0\0", 2);
                     }