From 2c9892cc3e68f00e71cf3d3b066a0c7080e1e220 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Thu, 22 Oct 2020 09:18:18 -0400 Subject: [PATCH] set sampling rate --- Makefile | 12 ++++---- cfg/mcuconf.h | 5 ++-- gui/stmdsp.cpp | 10 +++++++ gui/stmdsp.hpp | 1 + gui/wxmain.cpp | 30 ++++++++++++++++++++ gui/wxmain.hpp | 1 + source/adc.cpp | 75 ++++++++++++++++++++++++++----------------------- source/adc.hpp | 35 ++++++++++++++++------- source/main.cpp | 13 +++++---- 9 files changed, 123 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index 3b05917..f35692a 100644 --- a/Makefile +++ b/Makefile @@ -100,10 +100,10 @@ include $(CHIBIOS)/os/license/license.mk include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l4xx.mk # HAL-OSAL files (optional). include $(CHIBIOS)/os/hal/hal.mk -include $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/platform.mk -include $(CHIBIOS)/os/hal/boards/ST_STM32L476_DISCOVERY/board.mk -#include $(CHIBIOS)/os/hal/boards/ST_NUCLEO32_L432KC/board.mk -#include $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/platform_l432.mk +#include $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/platform.mk +#include $(CHIBIOS)/os/hal/boards/ST_STM32L476_DISCOVERY/board.mk +include $(CHIBIOS)/os/hal/boards/ST_NUCLEO32_L432KC/board.mk +include $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/platform_l432.mk include $(CHIBIOS)/os/hal/osal/rt-nil/osal.mk # RTOS files (optional). include $(CHIBIOS)/os/rt/rt.mk @@ -116,8 +116,8 @@ include $(CHIBIOS)/tools/mk/autobuild.mk #include $(CHIBIOS)/test/oslib/oslib_test.mk # Define linker script file here. -LDSCRIPT= $(STARTUPLD)/STM32L476xG.ld -#LDSCRIPT= $(STARTUPLD)/STM32L432xC.ld +#LDSCRIPT= $(STARTUPLD)/STM32L476xG.ld +LDSCRIPT= $(STARTUPLD)/STM32L432xC.ld # C sources that can be compiled in ARM or THUMB mode depending on the global # setting. diff --git a/cfg/mcuconf.h b/cfg/mcuconf.h index 929e049..3a246fa 100644 --- a/cfg/mcuconf.h +++ b/cfg/mcuconf.h @@ -32,8 +32,9 @@ #define MCUCONF_H #define STM32L4xx_MCUCONF -#define STM32L476_MCUCONF -//#define STM32L432_MCUCONF +//#define STM32L476_MCUCONF +#define STM32L432_MCUCONF +//#define STM32L433_MCUCONF /* * HAL driver system settings. diff --git a/gui/stmdsp.cpp b/gui/stmdsp.cpp index 633c61a..3de3324 100644 --- a/gui/stmdsp.cpp +++ b/gui/stmdsp.cpp @@ -52,6 +52,16 @@ namespace stmdsp } } + void device::set_sample_rate(unsigned int id) { + if (connected()) { + uint8_t request[2] = { + 'r', + static_cast(id) + }; + m_serial.write(request, 2); + } + } + void device::continuous_start() { if (connected()) m_serial.write("R"); diff --git a/gui/stmdsp.hpp b/gui/stmdsp.hpp index 46113bf..25c6a8c 100644 --- a/gui/stmdsp.hpp +++ b/gui/stmdsp.hpp @@ -44,6 +44,7 @@ namespace stmdsp //std::vector sample(unsigned long int count = 1); void continuous_set_buffer_size(unsigned int size); + void set_sample_rate(unsigned int id); void continuous_start(); void continuous_start_measure(); uint32_t continuous_start_get_measurement(); diff --git a/gui/wxmain.cpp b/gui/wxmain.cpp index c9e8b3d..412f775 100644 --- a/gui/wxmain.cpp +++ b/gui/wxmain.cpp @@ -29,6 +29,7 @@ enum Id { MRunUpload, MRunUnload, MRunEditBSize, + MRunEditSRate, MRunGenUpload, MRunGenStart, MCodeCompile, @@ -106,6 +107,8 @@ 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, @@ -439,6 +442,33 @@ void MainFrame::onRunEditBSize([[maybe_unused]] wxCommandEvent&) } } +void MainFrame::onRunEditSRate([[maybe_unused]] wxCommandEvent&) +{ + 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."); + } + } else { + wxMessageBox("No device connected!", "Run", wxICON_WARNING); + m_status_bar->SetStatusText("Please connect."); + } +} + void MainFrame::onRunGenUpload([[maybe_unused]] wxCommandEvent&) { if (m_device != nullptr && m_device->connected()) { diff --git a/gui/wxmain.hpp b/gui/wxmain.hpp index 60c3ee1..c46ed95 100644 --- a/gui/wxmain.hpp +++ b/gui/wxmain.hpp @@ -37,6 +37,7 @@ public: void onRunUpload(wxCommandEvent&); void onRunUnload(wxCommandEvent&); void onRunEditBSize(wxCommandEvent&); + void onRunEditSRate(wxCommandEvent&); void onRunGenUpload(wxCommandEvent&); void onRunGenStart(wxCommandEvent&); diff --git a/source/adc.cpp b/source/adc.cpp index 9fd3285..0318a6b 100644 --- a/source/adc.cpp +++ b/source/adc.cpp @@ -44,6 +44,32 @@ constexpr static const GPTConfig gpt_config = { .dier = 0 }; +static uint32_t adc_sample_rate_settings[] = { + 10, ADC_SMPR_SMP_47P5, // 3125 + 11, ADC_SMPR_SMP_12P5, // 3750 + 9, ADC_SMPR_SMP_47P5, // 6250 + 10, ADC_SMPR_SMP_12P5, // 7500 + 8, ADC_SMPR_SMP_47P5, // 12K5 + 9, ADC_SMPR_SMP_12P5, // 15K + 7, ADC_SMPR_SMP_47P5, // 25K + 8, ADC_SMPR_SMP_12P5, // 30K + 5, ADC_SMPR_SMP_47P5, // 40K + 4, ADC_SMPR_SMP_47P5, // 50K + 7, ADC_SMPR_SMP_12P5, // 60K + 6, ADC_SMPR_SMP_12P5, // 80K + 5, ADC_SMPR_SMP_12P5, // 96K + 2, ADC_SMPR_SMP_47P5, // 100K + 4, ADC_SMPR_SMP_12P5, // 120K + 3, ADC_SMPR_SMP_12P5, // 160K + 1, ADC_SMPR_SMP_47P5, // 200K + 2, ADC_SMPR_SMP_12P5, // 240K + 0, ADC_SMPR_SMP_47P5, // 400K + 1, ADC_SMPR_SMP_12P5, // 480K + 1, ADC_SMPR_SMP_2P5, // 800K + 0, ADC_SMPR_SMP_12P5, // 960K + 0, ADC_SMPR_SMP_2P5 // 1M6 +}; + static bool adc_is_read_finished = false; static adcsample_t *adc_current_buffer = nullptr; static size_t adc_current_buffer_size = 0; @@ -59,6 +85,19 @@ namespace adc adcStart(adcd, &adc_config); adcSTM32EnableVREF(adcd); } + + void set_rate(rate new_rate) + { + auto presc = adc_sample_rate_settings[static_cast(new_rate) * 2] << 18; + auto smp = adc_sample_rate_settings[static_cast(new_rate) * 2 + 1]; + + adcStop(adcd); + // Set ADC prescaler + adcd->adcc->CCR = (adcd->adcc->CCR & ~(0xF << 18)) | presc; + // Set sampling time + adc_group_config.smpr[0] = ADC_SMPR1_SMP_AN5(smp); + adcStart(adcd, &adc_config); + } adcsample_t *read(adcsample_t *buffer, size_t count) { @@ -94,42 +133,8 @@ namespace adc adc_current_buffer_size = 0; adc_operation_func = nullptr; } - - void set_rate(rate r) - { - uint32_t val = 0; - - switch (r) { - case rate::R2P5: - val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_2P5); - break; - case rate::R6P5: - val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_6P5); - break; - case rate::R12P5: - val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_12P5); - break; - case rate::R24P5: - val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_24P5); - break; - case rate::R47P5: - val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_47P5); - break; - case rate::R92P5: - val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_92P5); - break; - case rate::R247P5: - val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_247P5); - break; - case rate::R640P5: - val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_640P5); - break; - } - - adc_group_config.smpr[0] = val; - } } - + void adc_read_callback(ADCDriver *driver) { if (adc_group_config.circular) { diff --git a/source/adc.hpp b/source/adc.hpp index d1cd292..d31d60a 100644 --- a/source/adc.hpp +++ b/source/adc.hpp @@ -18,23 +18,38 @@ namespace adc { using operation_t = void (*)(adcsample_t *buffer, size_t count); - enum class rate { - R2P5, - R6P5, - R12P5, - R24P5, - R47P5, - R92P5, - R247P5, - R640P5 + enum class rate : unsigned int { + R3125 = 0, + R3750, + R6250, + R7500, + R12K5, + R15K, + R25K, + R30K, + R40K, + R50K, + R60K, + R80K, + R96K, + R100K, + R120K, + R160K, + R200K, + R240K, + R400K, + R480K, + R800K, + R960K, + R1M6 }; void init(); + void set_rate(rate new_rate); adcsample_t *read(adcsample_t *buffer, size_t count); void read_start(operation_t operation_func, adcsample_t *buffer, size_t count); void read_set_operation_func(operation_t operation_func); void read_stop(); - void set_rate(rate r); } #endif // STMDSP_ADC_HPP_ diff --git a/source/main.cpp b/source/main.cpp index 7a55b6c..67a39a3 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -253,14 +253,15 @@ void main_loop() } break; - //case 'r': - // if (usbserial::read(&cmd[1], 1) == 1) { + case 'r': + if (usbserial::read(&cmd[1], 1) == 1) { + adc::set_rate(static_cast(cmd[1])); // adc_preloaded = cmd[1] & (1 << 0); // dac_preloaded = cmd[1] & (1 << 1); - // } else { - // error_queue_add(Error::BadParamSize); - // } - // break; + } else { + error_queue_add(Error::BadParamSize); + } + break; // 'S' - Stops the continuous sampling/conversion. case 'S':