From 555749ef5dde558f745f0dc6d00a168d3b3e9d58 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sun, 1 Aug 2021 18:53:09 -0400 Subject: [PATCH] 8x oversample; other fixes --- Makefile | 2 +- source/cfg/mcuconf_l4.h | 4 ++-- source/communication.cpp | 1 + source/conversion.cpp | 17 ++++++++++------- source/conversion.hpp | 2 +- source/elfload.cpp | 16 ++++++++++++++++ source/elfload.hpp | 15 +++------------ source/monitor.cpp | 7 +++---- source/monitor.hpp | 4 +++- source/periph/adc.cpp | 38 +++++++++++++++++++++++++++----------- source/sclock.cpp | 7 ++++++- 11 files changed, 73 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index e308e1e..44f4c8a 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ endif # C++ specific options here (added to USE_OPT). ifeq ($(USE_CPPOPT),) - USE_CPPOPT = -std=c++2a -fno-rtti + USE_CPPOPT = -std=c++2a -fno-rtti -fno-exceptions endif # Enable this if you want the linker to remove unused code and data. diff --git a/source/cfg/mcuconf_l4.h b/source/cfg/mcuconf_l4.h index 438e0be..bf19f7a 100644 --- a/source/cfg/mcuconf_l4.h +++ b/source/cfg/mcuconf_l4.h @@ -47,11 +47,11 @@ #define STM32_HSE_ENABLED FALSE #define STM32_LSE_ENABLED FALSE #define STM32_MSIPLL_ENABLED FALSE -#define STM32_MSIRANGE STM32_MSIRANGE_8M +#define STM32_MSIRANGE STM32_MSIRANGE_4M #define STM32_MSISRANGE STM32_MSISRANGE_4M #define STM32_SW STM32_SW_PLL #define STM32_PLLSRC STM32_PLLSRC_MSI -#define STM32_PLLM_VALUE 2 +#define STM32_PLLM_VALUE 1 #define STM32_PLLN_VALUE 72 #define STM32_PLLP_VALUE 7 #define STM32_PLLQ_VALUE 6 diff --git a/source/communication.cpp b/source/communication.cpp index 5835aa5..3a264fb 100644 --- a/source/communication.cpp +++ b/source/communication.cpp @@ -124,6 +124,7 @@ void updateGenerator(unsigned char *cmd) more = DAC::sigGenWantsMore(); } while (more == -1); + // Receive streamed samples in half-buffer chunks. USBSerial::read(reinterpret_cast( more == 0 ? Samples::Generator.data() : Samples::Generator.middata()), Samples::Generator.bytesize() / 2); diff --git a/source/conversion.cpp b/source/conversion.cpp index 27954be..95118f0 100644 --- a/source/conversion.cpp +++ b/source/conversion.cpp @@ -7,13 +7,16 @@ #include "runstatus.hpp" #include "samples.hpp" -constexpr msg_t MSG_CONVFIRST = 1; -constexpr msg_t MSG_CONVSECOND = 2; -constexpr msg_t MSG_CONVFIRST_MEASURE = 3; -constexpr msg_t MSG_CONVSECOND_MEASURE = 4; +// MSG_* things below are macros rather than constexpr +// to ensure inlining. -constexpr auto MSG_FOR_FIRST = [](msg_t m) { return m & 1; }; -constexpr auto MSG_FOR_MEASURE = [](msg_t m) { return m > 2; }; +#define MSG_CONVFIRST (1) +#define MSG_CONVSECOND (2) +#define MSG_CONVFIRST_MEASURE (3) +#define MSG_CONVSECOND_MEASURE (4) + +#define MSG_FOR_FIRST(msg) (msg & 1) +#define MSG_FOR_MEASURE(msg) (msg > 2) time_measurement_t conversion_time_measurement; @@ -24,7 +27,7 @@ thread_t *ConversionManager::m_thread_runner = nullptr; __attribute__((section(".stacks"))) std::array ConversionManager::m_thread_monitor_stack = {}; __attribute__((section(".stacks"))) -std::array ConversionManager::m_thread_runner_entry_stack = {}; +std::array ConversionManager::m_thread_runner_entry_stack = {}; __attribute__((section(".convdata"))) std::array ConversionManager::m_thread_runner_stack = {}; diff --git a/source/conversion.hpp b/source/conversion.hpp index ad949dc..0a18f3b 100644 --- a/source/conversion.hpp +++ b/source/conversion.hpp @@ -53,7 +53,7 @@ private: static thread_t *m_thread_runner; static std::array m_thread_monitor_stack; - static std::array m_thread_runner_entry_stack; + static std::array m_thread_runner_entry_stack; static std::array m_thread_runner_stack; static std::array m_mailbox_buffer; diff --git a/source/elfload.cpp b/source/elfload.cpp index a430ad2..2d75cb0 100644 --- a/source/elfload.cpp +++ b/source/elfload.cpp @@ -21,6 +21,22 @@ std::array ELFManager::m_file_buffer = {}; static const unsigned char elf_header[] = { '\177', 'E', 'L', 'F' }; +__attribute__((section(".convcode"))) +ELFManager::EntryFunc ELFManager::loadedElf() +{ + return m_entry; +} + +unsigned char *ELFManager::fileBuffer() +{ + return m_file_buffer.data(); +} + +void ELFManager::unload() +{ + m_entry = nullptr; +} + template constexpr static auto ptr_from_offset(void *base, uint32_t offset) { diff --git a/source/elfload.hpp b/source/elfload.hpp index ada35e5..84d49d3 100644 --- a/source/elfload.hpp +++ b/source/elfload.hpp @@ -25,18 +25,9 @@ public: using EntryFunc = Sample *(*)(Sample *, size_t); static EntryFunc loadFromInternalBuffer(); - - static EntryFunc loadedElf() { - return m_entry; - } - - static unsigned char *fileBuffer() { - return m_file_buffer.data(); - } - - static void unload() { - m_entry = nullptr; - } + static EntryFunc loadedElf(); + static unsigned char *fileBuffer(); + static void unload(); private: static EntryFunc m_entry; diff --git a/source/monitor.cpp b/source/monitor.cpp index 335a1eb..08a62d5 100644 --- a/source/monitor.cpp +++ b/source/monitor.cpp @@ -14,9 +14,11 @@ #include "error.hpp" #include "runstatus.hpp" -#include "ch.h" #include "hal.h" +__attribute__((section(".stacks"))) +std::array Monitor::m_thread_stack = {}; + void Monitor::begin() { chThdCreateStatic(m_thread_stack.data(), @@ -75,6 +77,3 @@ void Monitor::threadMonitor(void *) } } -__attribute__((section(".stacks"))) -std::array Monitor::m_thread_stack = {}; - diff --git a/source/monitor.hpp b/source/monitor.hpp index 44545c3..93f75e3 100644 --- a/source/monitor.hpp +++ b/source/monitor.hpp @@ -12,6 +12,8 @@ #ifndef STMDSP_MONITOR_HPP #define STMDSP_MONITOR_HPP +#include "ch.h" + #include class Monitor @@ -22,7 +24,7 @@ public: private: static void threadMonitor(void *); - static std::array m_thread_stack; + static std::array m_thread_stack; }; #endif // STMDSP_MONITOR_HPP diff --git a/source/periph/adc.cpp b/source/periph/adc.cpp index 00438f2..4667307 100644 --- a/source/periph/adc.cpp +++ b/source/periph/adc.cpp @@ -39,7 +39,7 @@ ADCConversionGroup ADC::m_group_config = { .end_cb = ADC::conversionCallback, .error_cb = nullptr, .cfgr = ADC_CFGR_EXTEN_RISING | ADC_CFGR_EXTSEL_SRC(13), /* TIM6_TRGO */ - .cfgr2 = ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_1 | ADC_CFGR2_OVSS_0, // Oversampling 2x + .cfgr2 = 0,//ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_1 | ADC_CFGR2_OVSS_0, // Oversampling 2x #if defined(TARGET_PLATFORM_H7) .ccr = 0, .pcsel = 0, @@ -73,7 +73,7 @@ ADCConversionGroup ADC::m_group_config2 = { .end_cb = readAltCallback, .error_cb = nullptr, .cfgr = ADC_CFGR_EXTEN_RISING | ADC_CFGR_EXTSEL_SRC(13), /* TIM6_TRGO */ - .cfgr2 = ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_1 | ADC_CFGR2_OVSS_0, // Oversampling 2x + .cfgr2 = 0,//ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_1 | ADC_CFGR2_OVSS_0, // Oversampling 2x #if defined(TARGET_PLATFORM_H7) .ccr = 0, .pcsel = 0, @@ -182,13 +182,29 @@ void ADC::setRate(SClock::Rate rate) adcStart(m_driver, &m_config); #elif defined(TARGET_PLATFORM_L4) std::array, 6> m_rate_presets = {{ + // PLLSAI2 sources MSI of 4MHz, divided by PLLM of /1 = 4MHz. + // 4MHz is then multiplied by PLLSAI2N (x8 to x86), with result + // between 64 and 344 MHz. + // + // SAI2N MUST BE AT LEAST 16 TO MAKE 64MHz MINIMUM. + // + // That is then divided by PLLSAI2R: + // R of 0 = /2; 1 = /4, 2 = /6, 3 = /8. + // PLLSAI2 then feeds into the ADC, which has a prescaler of /10. + // Finally, the ADC's SMP value produces the desired sample rate. + // + // 4MHz * N / R / 10 / SMP = sample rate. + // + // With oversampling, must create faster clock + // (x2 oversampling requires x2 sample rate clock). + // // Rate PLLSAI2N R SMPR - {/* 8k */ 8, 1, ADC_SMPR_SMP_12P5}, - {/* 16k */ 16, 1, ADC_SMPR_SMP_12P5}, - {/* 20k */ 20, 1, ADC_SMPR_SMP_12P5}, - {/* 32k */ 32, 1, ADC_SMPR_SMP_12P5}, - {/* 48k */ 24, 0, ADC_SMPR_SMP_12P5}, - {/* 96k */ 73, 1, ADC_SMPR_SMP_6P5} // Technically 96.05263kS/s + {/* 8k */ 16, 1, ADC_SMPR_SMP_12P5}, // R3=32k (min), R1=64k + {/* 16k */ 16, 0, ADC_SMPR_SMP_12P5}, + {/* 20k */ 20, 0, ADC_SMPR_SMP_12P5}, + {/* 32k */ 32, 0, ADC_SMPR_SMP_12P5}, + {/* 48k */ 48, 0, ADC_SMPR_SMP_12P5}, + {/* 96k */ 73, 0, ADC_SMPR_SMP_6P5} // Technically 96.05263kS/s }}; auto& preset = m_rate_presets[static_cast(rate)]; @@ -205,9 +221,9 @@ void ADC::setRate(SClock::Rate rate) m_group_config.smpr[0] = ADC_SMPR1_SMP_AN5(smpr); - // Set 2x oversampling - m_group_config.cfgr2 = ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_0 | ADC_CFGR2_OVSS_1; - m_group_config2.cfgr2 = ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_0 | ADC_CFGR2_OVSS_1; + // 8x oversample + m_group_config.cfgr2 = ADC_CFGR2_ROVSE | (2 << ADC_CFGR2_OVSR_Pos) | (3 << ADC_CFGR2_OVSS_Pos); + m_group_config2.cfgr2 = ADC_CFGR2_ROVSE | (2 << ADC_CFGR2_OVSR_Pos) | (3 << ADC_CFGR2_OVSS_Pos); #endif } diff --git a/source/sclock.cpp b/source/sclock.cpp index 317b995..6660f95 100644 --- a/source/sclock.cpp +++ b/source/sclock.cpp @@ -35,7 +35,12 @@ const std::array SClock::m_rate_divs = {{ /* 48k */ 100, /* 96k */ 50 #else - 4500, 2250, 1800, 1125, 750, 375 + /* 8k */ 4500, + /* 16k */ 2250, + /* 20k */ 1800, + /* 32k */ 1125, + /* 48k */ 750, + /* 96k */ 375 #endif }};