8x oversample; other fixes

master
Clyne 3 years ago
parent 123cc4c756
commit 555749ef5d

@ -18,7 +18,7 @@ endif
# C++ specific options here (added to USE_OPT). # C++ specific options here (added to USE_OPT).
ifeq ($(USE_CPPOPT),) ifeq ($(USE_CPPOPT),)
USE_CPPOPT = -std=c++2a -fno-rtti USE_CPPOPT = -std=c++2a -fno-rtti -fno-exceptions
endif endif
# Enable this if you want the linker to remove unused code and data. # Enable this if you want the linker to remove unused code and data.

@ -47,11 +47,11 @@
#define STM32_HSE_ENABLED FALSE #define STM32_HSE_ENABLED FALSE
#define STM32_LSE_ENABLED FALSE #define STM32_LSE_ENABLED FALSE
#define STM32_MSIPLL_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_MSISRANGE STM32_MSISRANGE_4M
#define STM32_SW STM32_SW_PLL #define STM32_SW STM32_SW_PLL
#define STM32_PLLSRC STM32_PLLSRC_MSI #define STM32_PLLSRC STM32_PLLSRC_MSI
#define STM32_PLLM_VALUE 2 #define STM32_PLLM_VALUE 1
#define STM32_PLLN_VALUE 72 #define STM32_PLLN_VALUE 72
#define STM32_PLLP_VALUE 7 #define STM32_PLLP_VALUE 7
#define STM32_PLLQ_VALUE 6 #define STM32_PLLQ_VALUE 6

@ -124,6 +124,7 @@ void updateGenerator(unsigned char *cmd)
more = DAC::sigGenWantsMore(); more = DAC::sigGenWantsMore();
} while (more == -1); } while (more == -1);
// Receive streamed samples in half-buffer chunks.
USBSerial::read(reinterpret_cast<uint8_t *>( USBSerial::read(reinterpret_cast<uint8_t *>(
more == 0 ? Samples::Generator.data() : Samples::Generator.middata()), more == 0 ? Samples::Generator.data() : Samples::Generator.middata()),
Samples::Generator.bytesize() / 2); Samples::Generator.bytesize() / 2);

@ -7,13 +7,16 @@
#include "runstatus.hpp" #include "runstatus.hpp"
#include "samples.hpp" #include "samples.hpp"
constexpr msg_t MSG_CONVFIRST = 1; // MSG_* things below are macros rather than constexpr
constexpr msg_t MSG_CONVSECOND = 2; // to ensure inlining.
constexpr msg_t MSG_CONVFIRST_MEASURE = 3;
constexpr msg_t MSG_CONVSECOND_MEASURE = 4;
constexpr auto MSG_FOR_FIRST = [](msg_t m) { return m & 1; }; #define MSG_CONVFIRST (1)
constexpr auto MSG_FOR_MEASURE = [](msg_t m) { return m > 2; }; #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; time_measurement_t conversion_time_measurement;
@ -24,7 +27,7 @@ thread_t *ConversionManager::m_thread_runner = nullptr;
__attribute__((section(".stacks"))) __attribute__((section(".stacks")))
std::array<char, 1024> ConversionManager::m_thread_monitor_stack = {}; std::array<char, 1024> ConversionManager::m_thread_monitor_stack = {};
__attribute__((section(".stacks"))) __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"))) __attribute__((section(".convdata")))
std::array<char, CONVERSION_THREAD_STACK_SIZE> ConversionManager::m_thread_runner_stack = {}; std::array<char, CONVERSION_THREAD_STACK_SIZE> ConversionManager::m_thread_runner_stack = {};

@ -53,7 +53,7 @@ private:
static thread_t *m_thread_runner; static thread_t *m_thread_runner;
static std::array<char, 1024> m_thread_monitor_stack; 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<char, CONVERSION_THREAD_STACK_SIZE> m_thread_runner_stack;
static std::array<msg_t, 2> m_mailbox_buffer; static std::array<msg_t, 2> m_mailbox_buffer;

@ -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' }; 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> template<typename T>
constexpr static auto ptr_from_offset(void *base, uint32_t offset) constexpr static auto ptr_from_offset(void *base, uint32_t offset)
{ {

@ -25,18 +25,9 @@ public:
using EntryFunc = Sample *(*)(Sample *, size_t); using EntryFunc = Sample *(*)(Sample *, size_t);
static EntryFunc loadFromInternalBuffer(); static EntryFunc loadFromInternalBuffer();
static EntryFunc loadedElf();
static EntryFunc loadedElf() { static unsigned char *fileBuffer();
return m_entry; static void unload();
}
static unsigned char *fileBuffer() {
return m_file_buffer.data();
}
static void unload() {
m_entry = nullptr;
}
private: private:
static EntryFunc m_entry; static EntryFunc m_entry;

@ -14,9 +14,11 @@
#include "error.hpp" #include "error.hpp"
#include "runstatus.hpp" #include "runstatus.hpp"
#include "ch.h"
#include "hal.h" #include "hal.h"
__attribute__((section(".stacks")))
std::array<char, THD_WORKING_AREA_SIZE(256)> Monitor::m_thread_stack = {};
void Monitor::begin() void Monitor::begin()
{ {
chThdCreateStatic(m_thread_stack.data(), chThdCreateStatic(m_thread_stack.data(),
@ -75,6 +77,3 @@ void Monitor::threadMonitor(void *)
} }
} }
__attribute__((section(".stacks")))
std::array<char, 256> Monitor::m_thread_stack = {};

@ -12,6 +12,8 @@
#ifndef STMDSP_MONITOR_HPP #ifndef STMDSP_MONITOR_HPP
#define STMDSP_MONITOR_HPP #define STMDSP_MONITOR_HPP
#include "ch.h"
#include <array> #include <array>
class Monitor class Monitor
@ -22,7 +24,7 @@ public:
private: private:
static void threadMonitor(void *); 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 #endif // STMDSP_MONITOR_HPP

@ -39,7 +39,7 @@ ADCConversionGroup ADC::m_group_config = {
.end_cb = ADC::conversionCallback, .end_cb = ADC::conversionCallback,
.error_cb = nullptr, .error_cb = nullptr,
.cfgr = ADC_CFGR_EXTEN_RISING | ADC_CFGR_EXTSEL_SRC(13), /* TIM6_TRGO */ .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) #if defined(TARGET_PLATFORM_H7)
.ccr = 0, .ccr = 0,
.pcsel = 0, .pcsel = 0,
@ -73,7 +73,7 @@ ADCConversionGroup ADC::m_group_config2 = {
.end_cb = readAltCallback, .end_cb = readAltCallback,
.error_cb = nullptr, .error_cb = nullptr,
.cfgr = ADC_CFGR_EXTEN_RISING | ADC_CFGR_EXTSEL_SRC(13), /* TIM6_TRGO */ .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) #if defined(TARGET_PLATFORM_H7)
.ccr = 0, .ccr = 0,
.pcsel = 0, .pcsel = 0,
@ -182,13 +182,29 @@ void ADC::setRate(SClock::Rate rate)
adcStart(m_driver, &m_config); adcStart(m_driver, &m_config);
#elif defined(TARGET_PLATFORM_L4) #elif defined(TARGET_PLATFORM_L4)
std::array<std::array<uint32_t, 3>, 6> m_rate_presets = {{ 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 // Rate PLLSAI2N R SMPR
{/* 8k */ 8, 1, ADC_SMPR_SMP_12P5}, {/* 8k */ 16, 1, ADC_SMPR_SMP_12P5}, // R3=32k (min), R1=64k
{/* 16k */ 16, 1, ADC_SMPR_SMP_12P5}, {/* 16k */ 16, 0, ADC_SMPR_SMP_12P5},
{/* 20k */ 20, 1, ADC_SMPR_SMP_12P5}, {/* 20k */ 20, 0, ADC_SMPR_SMP_12P5},
{/* 32k */ 32, 1, ADC_SMPR_SMP_12P5}, {/* 32k */ 32, 0, ADC_SMPR_SMP_12P5},
{/* 48k */ 24, 0, ADC_SMPR_SMP_12P5}, {/* 48k */ 48, 0, ADC_SMPR_SMP_12P5},
{/* 96k */ 73, 1, ADC_SMPR_SMP_6P5} // Technically 96.05263kS/s {/* 96k */ 73, 0, ADC_SMPR_SMP_6P5} // Technically 96.05263kS/s
}}; }};
auto& preset = m_rate_presets[static_cast<int>(rate)]; 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); m_group_config.smpr[0] = ADC_SMPR1_SMP_AN5(smpr);
// Set 2x oversampling // 8x oversample
m_group_config.cfgr2 = ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_0 | ADC_CFGR2_OVSS_1; m_group_config.cfgr2 = ADC_CFGR2_ROVSE | (2 << ADC_CFGR2_OVSR_Pos) | (3 << ADC_CFGR2_OVSS_Pos);
m_group_config2.cfgr2 = ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_0 | ADC_CFGR2_OVSS_1; m_group_config2.cfgr2 = ADC_CFGR2_ROVSE | (2 << ADC_CFGR2_OVSR_Pos) | (3 << ADC_CFGR2_OVSS_Pos);
#endif #endif
} }

@ -35,7 +35,12 @@ const std::array<unsigned int, 6> SClock::m_rate_divs = {{
/* 48k */ 100, /* 48k */ 100,
/* 96k */ 50 /* 96k */ 50
#else #else
4500, 2250, 1800, 1125, 750, 375 /* 8k */ 4500,
/* 16k */ 2250,
/* 20k */ 1800,
/* 32k */ 1125,
/* 48k */ 750,
/* 96k */ 375
#endif #endif
}}; }};

Loading…
Cancel
Save