aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2021-08-01 18:53:09 -0400
committerClyne Sullivan <clyne@bitgloo.com>2021-08-01 18:53:09 -0400
commit555749ef5dde558f745f0dc6d00a168d3b3e9d58 (patch)
treeeba6929696b04e4d4fb67271f9dee78bfa6ff2e1
parent123cc4c756cc8a22f66351ab65595c5a20e53e27 (diff)
8x oversample; other fixes
-rw-r--r--Makefile2
-rw-r--r--source/cfg/mcuconf_l4.h4
-rw-r--r--source/communication.cpp1
-rw-r--r--source/conversion.cpp17
-rw-r--r--source/conversion.hpp2
-rw-r--r--source/elfload.cpp16
-rw-r--r--source/elfload.hpp15
-rw-r--r--source/monitor.cpp7
-rw-r--r--source/monitor.hpp4
-rw-r--r--source/periph/adc.cpp38
-rw-r--r--source/sclock.cpp7
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<uint8_t *>(
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<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 = {};
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<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;
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<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)
{
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<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 = {};
-
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 <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
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<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
}
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<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
}};