]> code.bitgloo.com Git - clyne/stmdsp.git/commitdiff
8x oversample; other fixes
authorClyne Sullivan <clyne@bitgloo.com>
Sun, 1 Aug 2021 22:53:09 +0000 (18:53 -0400)
committerClyne Sullivan <clyne@bitgloo.com>
Sun, 1 Aug 2021 22:53:09 +0000 (18:53 -0400)
Makefile
source/cfg/mcuconf_l4.h
source/communication.cpp
source/conversion.cpp
source/conversion.hpp
source/elfload.cpp
source/elfload.hpp
source/monitor.cpp
source/monitor.hpp
source/periph/adc.cpp
source/sclock.cpp

index e308e1eb08058ec9a5f55168c42665e4f9212e8c..44f4c8aea6c6c542128f98d285696fefcea13d40 100644 (file)
--- 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.
index 438e0be029550c92dff33c4e3975a5e9ce7cbd58..bf19f7ae1ed8dc108b7a28b2e4818dc90837f2bb 100644 (file)
 #define STM32_HSE_ENABLED                   FALSE\r
 #define STM32_LSE_ENABLED                   FALSE\r
 #define STM32_MSIPLL_ENABLED                FALSE\r
-#define STM32_MSIRANGE                      STM32_MSIRANGE_8M\r
+#define STM32_MSIRANGE                      STM32_MSIRANGE_4M\r
 #define STM32_MSISRANGE                     STM32_MSISRANGE_4M\r
 #define STM32_SW                            STM32_SW_PLL\r
 #define STM32_PLLSRC                        STM32_PLLSRC_MSI\r
-#define STM32_PLLM_VALUE                    2\r
+#define STM32_PLLM_VALUE                    1\r
 #define STM32_PLLN_VALUE                    72\r
 #define STM32_PLLP_VALUE                    7\r
 #define STM32_PLLQ_VALUE                    6\r
index 5835aa51a0be8fb9d45330c16c704a3f78593d1a..3a264fb90084f0e29865d58ff53078b6ef0fcfde 100644 (file)
@@ -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<uint8_t *>(
                     more == 0 ? Samples::Generator.data() : Samples::Generator.middata()),
                     Samples::Generator.bytesize() / 2);
index 27954be26b1cdc1939677ae86d219380e1006b21..95118f0b3b0164ce03aa804516798c93a0c186bf 100644 (file)
@@ -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<char, 1024> ConversionManager::m_thread_monitor_stack = {};
 __attribute__((section(".stacks")))
-std::array<char, 128> ConversionManager::m_thread_runner_entry_stack = {};
+std::array<char, THD_WORKING_AREA_SIZE(128)> ConversionManager::m_thread_runner_entry_stack = {};
 __attribute__((section(".convdata")))
 std::array<char, CONVERSION_THREAD_STACK_SIZE> ConversionManager::m_thread_runner_stack = {};
 
index ad949dc3523bcf0f24c8f9bf63b9cd93973f7b2d..0a18f3b69d2d027ac9aea11572854533fb91bd6c 100644 (file)
@@ -53,7 +53,7 @@ private:
     static thread_t *m_thread_runner;
 
     static std::array<char, 1024> m_thread_monitor_stack;
-    static std::array<char, 128> m_thread_runner_entry_stack;
+    static std::array<char, THD_WORKING_AREA_SIZE(128)> m_thread_runner_entry_stack;
     static std::array<char, CONVERSION_THREAD_STACK_SIZE> m_thread_runner_stack;
 
     static std::array<msg_t, 2> m_mailbox_buffer;
index a430ad26f74de37a5b8047d08db2c52d579f0205..2d75cb0e7e0ed0350661c485360ffa4d2815f381 100644 (file)
@@ -21,6 +21,22 @@ std::array<unsigned char, MAX_ELF_FILE_SIZE> 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<typename T>
 constexpr static auto ptr_from_offset(void *base, uint32_t offset)
 {
index ada35e5ef1acce9b4c8b0f41ab99e7559c9db261..84d49d3e3c2ef194dc196ec6b79666ba3fce3ee1 100644 (file)
@@ -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;
index 335a1eb2c76f2318c872960a8536215f6ce19af3..08a62d5f0a276781aebfb1c02bea3c9138b1ac93 100644 (file)
 #include "error.hpp"
 #include "runstatus.hpp"
 
-#include "ch.h"
 #include "hal.h"
 
+__attribute__((section(".stacks")))
+std::array<char, THD_WORKING_AREA_SIZE(256)> 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<char, 256> Monitor::m_thread_stack = {};
-
index 44545c3a4306546d426f692624e49ea38b2aed19..93f75e37a4d7ae8f1baf12fd16cc408e39d833eb 100644 (file)
@@ -12,6 +12,8 @@
 #ifndef STMDSP_MONITOR_HPP
 #define STMDSP_MONITOR_HPP
 
+#include "ch.h"
+
 #include <array>
 
 class Monitor
@@ -22,7 +24,7 @@ public:
 private:
     static void threadMonitor(void *);
 
-    static std::array<char, 256> m_thread_stack;
+    static std::array<char, THD_WORKING_AREA_SIZE(256)> m_thread_stack;
 };
 
 #endif // STMDSP_MONITOR_HPP
index 00438f20b8fe74eca82559ad5d6c2c2dceaa680e..46673071f9b63e7c2d8f4c6c739eca3c1dcbabf4 100644 (file)
@@ -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<std::array<uint32_t, 3>, 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<int>(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
 }
 
index 317b9952937fcbac959b975690c07dd388fedb06..6660f951bc02d5b0e199ee4e3f57d1f32f4373d4 100644 (file)
@@ -35,7 +35,12 @@ const std::array<unsigned int, 6> 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
 }};