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).
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.

@ -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

@ -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);

@ -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 = {};

@ -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;

@ -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)
{

@ -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;

@ -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 = {};

@ -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

@ -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
}

@ -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
}};

Loading…
Cancel
Save