From e12639c46f0be29461803ffa1790d6f69c16d280 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sun, 8 Nov 2020 18:31:02 -0500 Subject: [PATCH] fixed sample rate setting --- cfg/chconf.h | 4 +-- cfg/mcuconf.h | 4 +-- gui/stmdsp.cpp | 14 +++++++++++ gui/stmdsp.hpp | 1 + gui/wxmain.cpp | 66 ++++++++++++++++++++++++++++++------------------- gui/wxmain.hpp | 4 ++- source/adc.cpp | 61 ++++++++++++++++++++++++--------------------- source/adc.hpp | 25 ++++--------------- source/dac.cpp | 2 +- source/main.cpp | 19 +++++++++----- 10 files changed, 114 insertions(+), 86 deletions(-) diff --git a/cfg/chconf.h b/cfg/chconf.h index 04570c1..faa8600 100644 --- a/cfg/chconf.h +++ b/cfg/chconf.h @@ -544,7 +544,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS TRUE #endif /** @@ -556,7 +556,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS TRUE #endif /** diff --git a/cfg/mcuconf.h b/cfg/mcuconf.h index 929e049..caad802 100644 --- a/cfg/mcuconf.h +++ b/cfg/mcuconf.h @@ -69,7 +69,7 @@ #define STM32_PLLSAI1R_VALUE 4 #define STM32_PLLSAI2N_VALUE 24 #define STM32_PLLSAI2P_VALUE 7 -#define STM32_PLLSAI2R_VALUE 2 +#define STM32_PLLSAI2R_VALUE 8 /* * Peripherals clock sources. @@ -88,7 +88,7 @@ #define STM32_SAI1SEL STM32_SAI1SEL_OFF #define STM32_SAI2SEL STM32_SAI2SEL_OFF #define STM32_CLK48SEL STM32_CLK48SEL_PLLSAI1 -#define STM32_ADCSEL STM32_ADCSEL_PLLSAI1 +#define STM32_ADCSEL STM32_ADCSEL_PLLSAI2 #define STM32_SWPMI1SEL STM32_SWPMI1SEL_PCLK1 #define STM32_DFSDMSEL STM32_DFSDMSEL_PCLK2 #define STM32_RTCSEL STM32_RTCSEL_LSI diff --git a/gui/stmdsp.cpp b/gui/stmdsp.cpp index 2091d48..0621ba1 100644 --- a/gui/stmdsp.cpp +++ b/gui/stmdsp.cpp @@ -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"); diff --git a/gui/stmdsp.hpp b/gui/stmdsp.hpp index 25c6a8c..9c60b85 100644 --- a/gui/stmdsp.hpp +++ b/gui/stmdsp.hpp @@ -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(); diff --git a/gui/wxmain.cpp b/gui/wxmain.cpp index 8089911..cdbc06d 100644 --- a/gui/wxmain.cpp +++ b/gui/wxmain.cpp @@ -1,5 +1,6 @@ #include "wxmain.hpp" +#include #include #include #include @@ -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(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."); diff --git a/gui/wxmain.hpp b/gui/wxmain.hpp index d4d24de..4a73b2f 100644 --- a/gui/wxmain.hpp +++ b/gui/wxmain.hpp @@ -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; diff --git a/source/adc.cpp b/source/adc.cpp index a8c0e62..c8da25f 100644 --- a/source/adc.cpp +++ b/source/adc.cpp @@ -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(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() { diff --git a/source/adc.hpp b/source/adc.hpp index 5f41117..1431aa1 100644 --- a/source/adc.hpp +++ b/source/adc.hpp @@ -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); diff --git a/source/dac.cpp b/source/dac.cpp index 1a7254a..ed4dce1 100644 --- a/source/dac.cpp +++ b/source/dac.cpp @@ -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 diff --git a/source/main.cpp b/source/main.cpp index 17b0adb..8948b8e 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -250,10 +250,16 @@ void main_loop() break; case 'r': - if (usbserial::read(&cmd[1], 1) == 1) - adc::set_rate(static_cast(cmd[1])); - else + if (usbserial::read(&cmd[1], 1) == 1) { + if (cmd[1] == 0xFF) { + unsigned char r = static_cast(adc::get_rate()); + usbserial::write(&r, 1); + } else { + adc::set_rate(static_cast(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_cast(dac_samples_new)); + dac_samples_new = nullptr; + unsigned char buf[2] = { static_cast(dac_sample_count / 2 & 0xFF), static_cast(((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_cast(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); }