From 123cc4c756cc8a22f66351ab65595c5a20e53e27 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sat, 31 Jul 2021 10:47:00 -0400 Subject: reorganized source, wip --- source/communication.cpp | 291 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 source/communication.cpp (limited to 'source/communication.cpp') diff --git a/source/communication.cpp b/source/communication.cpp new file mode 100644 index 0000000..5835aa5 --- /dev/null +++ b/source/communication.cpp @@ -0,0 +1,291 @@ +#include "communication.hpp" + +#include "ch.h" +#include "hal.h" + +#include "periph/adc.hpp" +#include "periph/dac.hpp" +#include "periph/usbserial.hpp" +#include "elfload.hpp" +#include "error.hpp" +#include "conversion.hpp" +#include "runstatus.hpp" +#include "samples.hpp" + +#include +#include + +__attribute__((section(".stacks"))) +std::array CommunicationManager::m_thread_stack = {}; + +void CommunicationManager::begin() +{ + chThdCreateStatic(m_thread_stack.data(), + m_thread_stack.size(), + NORMALPRIO, + threadComm, + nullptr); +} + +static void writeADCBuffer(unsigned char *); +static void setBufferSize(unsigned char *); +static void updateGenerator(unsigned char *); +static void loadAlgorithm(unsigned char *); +static void readStatus(unsigned char *); +static void startConversionMeasure(unsigned char *); +static void startConversion(unsigned char *); +static void stopConversion(unsigned char *); +static void startGenerator(unsigned char *); +static void readADCBuffer(unsigned char *); +static void readDACBuffer(unsigned char *); +static void unloadAlgorithm(unsigned char *); +static void readIdentifier(unsigned char *); +static void readExecTime(unsigned char *); +static void sampleRate(unsigned char *); +static void readConversionResults(unsigned char *); +static void readConversionInput(unsigned char *); +static void readMessage(unsigned char *); +static void stopGenerator(unsigned char *); + +static const std::array, 19> commandTable {{ + {'A', writeADCBuffer}, + {'B', setBufferSize}, + {'D', updateGenerator}, + {'E', loadAlgorithm}, + {'I', readStatus}, + {'M', startConversionMeasure}, + {'R', startConversion}, + {'S', stopConversion}, + {'W', startGenerator}, + {'a', readADCBuffer}, + {'d', readDACBuffer}, + {'e', unloadAlgorithm}, + {'i', readIdentifier}, + {'m', readExecTime}, + {'r', sampleRate}, + {'s', readConversionResults}, + {'t', readConversionInput}, + {'u', readMessage}, + {'w', stopGenerator} +}}; + +void CommunicationManager::threadComm(void *) +{ + while (1) { + if (USBSerial::isActive()) { + // Attempt to receive a command packet + if (unsigned char cmd[3]; USBSerial::read(&cmd[0], 1) > 0) { + // Packet received, first byte represents the desired command/action + auto func = std::find_if(commandTable.cbegin(), commandTable.cend(), + [&cmd](const auto& f) { return f.first == cmd[0]; }); + if (func != commandTable.cend()) + func->second(cmd); + } + } + + chThdSleepMicroseconds(100); + } +} + +void writeADCBuffer(unsigned char *) +{ + USBSerial::read(Samples::In.bytedata(), Samples::In.bytesize()); +} + +void setBufferSize(unsigned char *cmd) +{ + if (EM.assert(run_status == RunStatus::Idle, Error::NotIdle) && + EM.assert(USBSerial::read(&cmd[1], 2) == 2, Error::BadParamSize)) + { + // count is multiplied by two since this command receives size of buffer + // for each algorithm application. + unsigned int count = (cmd[1] | (cmd[2] << 8)) * 2; + if (EM.assert(count <= MAX_SAMPLE_BUFFER_SIZE, Error::BadParam)) { + Samples::In.setSize(count); + Samples::Out.setSize(count); + } + } +} + +void updateGenerator(unsigned char *cmd) +{ + if (EM.assert(USBSerial::read(&cmd[1], 2) == 2, Error::BadParamSize)) { + unsigned int count = cmd[1] | (cmd[2] << 8); + if (EM.assert(count <= MAX_SAMPLE_BUFFER_SIZE, Error::BadParam)) { + if (run_status == RunStatus::Idle) { + Samples::Generator.setSize(count); + USBSerial::read( + reinterpret_cast(Samples::Generator.data()), + Samples::Generator.bytesize()); + } else if (run_status == RunStatus::Running) { + int more; + do { + chThdSleepMicroseconds(10); + more = DAC::sigGenWantsMore(); + } while (more == -1); + + USBSerial::read(reinterpret_cast( + more == 0 ? Samples::Generator.data() : Samples::Generator.middata()), + Samples::Generator.bytesize() / 2); + } + } + } +} + +void loadAlgorithm(unsigned char *cmd) +{ + if (EM.assert(run_status == RunStatus::Idle, Error::NotIdle) && + EM.assert(USBSerial::read(&cmd[1], 2) == 2, Error::BadParamSize)) + { + // Only load the binary if it can fit in the memory reserved for it. + unsigned int size = cmd[1] | (cmd[2] << 8); + if (EM.assert(size < MAX_ELF_FILE_SIZE, Error::BadUserCodeSize)) { + USBSerial::read(ELFManager::fileBuffer(), size); + auto entry = ELFManager::loadFromInternalBuffer(); + EM.assert(entry != nullptr, Error::BadUserCodeLoad); + } + } +} + +void readStatus(unsigned char *) +{ + unsigned char buf[2] = { + static_cast(run_status), + static_cast(EM.pop()) + }; + + USBSerial::write(buf, sizeof(buf)); +} + +void startConversionMeasure(unsigned char *) +{ + if (EM.assert(run_status == RunStatus::Idle, Error::NotIdle)) { + run_status = RunStatus::Running; + ConversionManager::startMeasured(); + } +} + +void startConversion(unsigned char *) +{ + if (EM.assert(run_status == RunStatus::Idle, Error::NotIdle)) { + run_status = RunStatus::Running; + ConversionManager::start(); + } +} + +void stopConversion(unsigned char *) +{ + if (run_status == RunStatus::Running) { + ConversionManager::stop(); + run_status = RunStatus::Idle; + } +} + +void startGenerator(unsigned char *) +{ + DAC::start(1, Samples::Generator.data(), Samples::Generator.size()); +} + +void readADCBuffer(unsigned char *) +{ + USBSerial::write(Samples::In.bytedata(), Samples::In.bytesize()); +} + +void readDACBuffer(unsigned char *) +{ + + USBSerial::write(Samples::Out.bytedata(), Samples::Out.bytesize()); +} + +void unloadAlgorithm(unsigned char *) +{ + ELFManager::unload(); +} + +void readIdentifier(unsigned char *) +{ +#if defined(TARGET_PLATFORM_H7) + USBSerial::write(reinterpret_cast("stmdsph"), 7); +#else + USBSerial::write(reinterpret_cast("stmdspl"), 7); +#endif +} + +void readExecTime(unsigned char *) +{ + USBSerial::write(reinterpret_cast(&conversion_time_measurement.last), + sizeof(rtcnt_t)); +} + +void sampleRate(unsigned char *cmd) +{ + if (EM.assert(USBSerial::read(&cmd[1], 1) == 1, Error::BadParamSize)) { + if (cmd[1] == 0xFF) { + unsigned char r = SClock::getRate(); + USBSerial::write(&r, 1); + } else { + auto r = static_cast(cmd[1]); + SClock::setRate(r); + ADC::setRate(r); + } + } +} + +void readConversionResults(unsigned char *) +{ + if (auto samps = Samples::Out.modified(); samps != nullptr) { + unsigned char buf[2] = { + static_cast(Samples::Out.size() / 2 & 0xFF), + static_cast(((Samples::Out.size() / 2) >> 8) & 0xFF) + }; + USBSerial::write(buf, 2); + unsigned int total = Samples::Out.bytesize() / 2; + unsigned int offset = 0; + unsigned char unused; + while (total > 512) { + USBSerial::write(reinterpret_cast(samps) + offset, 512); + while (USBSerial::read(&unused, 1) == 0); + offset += 512; + total -= 512; + } + USBSerial::write(reinterpret_cast(samps) + offset, total); + while (USBSerial::read(&unused, 1) == 0); + } else { + USBSerial::write(reinterpret_cast("\0\0"), 2); + } +} + +void readConversionInput(unsigned char *) +{ + if (auto samps = Samples::In.modified(); samps != nullptr) { + unsigned char buf[2] = { + static_cast(Samples::In.size() / 2 & 0xFF), + static_cast(((Samples::In.size() / 2) >> 8) & 0xFF) + }; + USBSerial::write(buf, 2); + unsigned int total = Samples::In.bytesize() / 2; + unsigned int offset = 0; + unsigned char unused; + while (total > 512) { + USBSerial::write(reinterpret_cast(samps) + offset, 512); + while (USBSerial::read(&unused, 1) == 0); + offset += 512; + total -= 512; + } + USBSerial::write(reinterpret_cast(samps) + offset, total); + while (USBSerial::read(&unused, 1) == 0); + } else { + USBSerial::write(reinterpret_cast("\0\0"), 2); + } +} + +void readMessage(unsigned char *) +{ + //USBSerial::write(reinterpret_cast(userMessageBuffer), userMessageSize); +} + +void stopGenerator(unsigned char *) +{ + DAC::stop(1); +} + -- cgit v1.2.3 From 555749ef5dde558f745f0dc6d00a168d3b3e9d58 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sun, 1 Aug 2021 18:53:09 -0400 Subject: 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(-) (limited to 'source/communication.cpp') 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 }}; -- cgit v1.2.3 From b430a38ce5674b319ef9bf1c6e773c9eb33f1542 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Tue, 5 Oct 2021 13:58:27 -0400 Subject: algorithm load fix --- source/communication.cpp | 6 ++++-- source/conversion.cpp | 13 +++++++++++-- source/conversion.hpp | 3 --- source/elfload.cpp | 11 ++++++++--- source/elfload.hpp | 2 +- source/handlers.cpp | 2 ++ 6 files changed, 26 insertions(+), 11 deletions(-) (limited to 'source/communication.cpp') diff --git a/source/communication.cpp b/source/communication.cpp index 3a264fb..ec02a42 100644 --- a/source/communication.cpp +++ b/source/communication.cpp @@ -142,8 +142,8 @@ void loadAlgorithm(unsigned char *cmd) unsigned int size = cmd[1] | (cmd[2] << 8); if (EM.assert(size < MAX_ELF_FILE_SIZE, Error::BadUserCodeSize)) { USBSerial::read(ELFManager::fileBuffer(), size); - auto entry = ELFManager::loadFromInternalBuffer(); - EM.assert(entry != nullptr, Error::BadUserCodeLoad); + auto success = ELFManager::loadFromInternalBuffer(); + EM.assert(success, Error::BadUserCodeLoad); } } } @@ -214,6 +214,8 @@ void readIdentifier(unsigned char *) void readExecTime(unsigned char *) { + // Stores the measured execution time. + extern time_measurement_t conversion_time_measurement; USBSerial::write(reinterpret_cast(&conversion_time_measurement.last), sizeof(rtcnt_t)); } diff --git a/source/conversion.cpp b/source/conversion.cpp index 95118f0..c9dc0c9 100644 --- a/source/conversion.cpp +++ b/source/conversion.cpp @@ -1,3 +1,14 @@ +/** + * @file conversion.cpp + * @brief Manages algorithm application (converts input samples to output). + * + * Copyright (C) 2021 Clyne Sullivan + * + * Distributed under the GNU GPL v3 or later. You should have received a copy of + * the GNU General Public License along with this program. + * If not, see . + */ + #include "conversion.hpp" #include "periph/adc.hpp" @@ -18,8 +29,6 @@ #define MSG_FOR_FIRST(msg) (msg & 1) #define MSG_FOR_MEASURE(msg) (msg > 2) -time_measurement_t conversion_time_measurement; - __attribute__((section(".convdata"))) thread_t *ConversionManager::m_thread_monitor = nullptr; thread_t *ConversionManager::m_thread_runner = nullptr; diff --git a/source/conversion.hpp b/source/conversion.hpp index 0a18f3b..6af4972 100644 --- a/source/conversion.hpp +++ b/source/conversion.hpp @@ -60,8 +60,5 @@ private: static mailbox_t m_mailbox; }; -// Stores the measured execution time. -extern time_measurement_t conversion_time_measurement; - #endif // STMDSP_CONVERSION_HPP diff --git a/source/elfload.cpp b/source/elfload.cpp index 2d75cb0..87461e4 100644 --- a/source/elfload.cpp +++ b/source/elfload.cpp @@ -43,14 +43,16 @@ constexpr static auto ptr_from_offset(void *base, uint32_t offset) return reinterpret_cast(reinterpret_cast(base) + offset); } -ELFManager::EntryFunc ELFManager::loadFromInternalBuffer() +bool ELFManager::loadFromInternalBuffer() { + m_entry = nullptr; + auto elf_data = m_file_buffer.data(); // Check the ELF's header signature auto ehdr = reinterpret_cast(elf_data); if (!std::equal(ehdr->e_ident, ehdr->e_ident + 4, elf_header)) - return nullptr; + return false; // Iterate through program header LOAD sections bool loaded = false; @@ -74,6 +76,9 @@ ELFManager::EntryFunc ELFManager::loadFromInternalBuffer() } - return loaded ? reinterpret_cast(ehdr->e_entry) : nullptr; + if (loaded) + m_entry = reinterpret_cast(ehdr->e_entry); + + return loaded; } diff --git a/source/elfload.hpp b/source/elfload.hpp index 84d49d3..10d95d7 100644 --- a/source/elfload.hpp +++ b/source/elfload.hpp @@ -24,7 +24,7 @@ class ELFManager public: using EntryFunc = Sample *(*)(Sample *, size_t); - static EntryFunc loadFromInternalBuffer(); + static bool loadFromInternalBuffer(); static EntryFunc loadedElf(); static unsigned char *fileBuffer(); static void unload(); diff --git a/source/handlers.cpp b/source/handlers.cpp index 4b0e3eb..07f6ed3 100644 --- a/source/handlers.cpp +++ b/source/handlers.cpp @@ -7,6 +7,8 @@ extern "C" { +time_measurement_t conversion_time_measurement; + __attribute__((naked)) void port_syscall(struct port_extctx *ctxp, uint32_t n) { -- cgit v1.2.3 From 3dd57491b1e81a9d93054eff19ca0e6c65c85b9b Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sat, 20 Nov 2021 14:29:08 -0500 Subject: fixed signal generator input data streaming --- source/communication.cpp | 25 +++++++++++++------------ source/periph/dac.cpp | 13 ++++++++++++- source/periph/dac.hpp | 1 + 3 files changed, 26 insertions(+), 13 deletions(-) (limited to 'source/communication.cpp') diff --git a/source/communication.cpp b/source/communication.cpp index ec02a42..b5ee28e 100644 --- a/source/communication.cpp +++ b/source/communication.cpp @@ -112,22 +112,23 @@ void updateGenerator(unsigned char *cmd) if (EM.assert(USBSerial::read(&cmd[1], 2) == 2, Error::BadParamSize)) { unsigned int count = cmd[1] | (cmd[2] << 8); if (EM.assert(count <= MAX_SAMPLE_BUFFER_SIZE, Error::BadParam)) { - if (run_status == RunStatus::Idle) { + if (!DAC::isSigGenRunning()) { Samples::Generator.setSize(count); USBSerial::read( reinterpret_cast(Samples::Generator.data()), Samples::Generator.bytesize()); - } else if (run_status == RunStatus::Running) { - int more; - do { - chThdSleepMicroseconds(10); - 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); + } else { + const int more = DAC::sigGenWantsMore(); + if (more == -1) { + USBSerial::write(reinterpret_cast("\0"), 1); + } else { + USBSerial::write(reinterpret_cast("\1"), 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/periph/dac.cpp b/source/periph/dac.cpp index 1ff8867..35c2908 100644 --- a/source/periph/dac.cpp +++ b/source/periph/dac.cpp @@ -61,7 +61,18 @@ void DAC::start(int channel, dacsample_t *buffer, size_t count) int DAC::sigGenWantsMore() { - return dacIsDone; + if (dacIsDone != -1) { + int tmp = dacIsDone; + dacIsDone = -1; + return tmp; + } else { + return -1; + } +} + +int DAC::isSigGenRunning() +{ + return m_driver[1]->state == DAC_ACTIVE; } void DAC::stop(int channel) diff --git a/source/periph/dac.hpp b/source/periph/dac.hpp index 4360c26..7250a52 100644 --- a/source/periph/dac.hpp +++ b/source/periph/dac.hpp @@ -24,6 +24,7 @@ public: static void stop(int channel); static int sigGenWantsMore(); + static int isSigGenRunning(); private: static DACDriver *m_driver[2]; -- cgit v1.2.3