diff options
Diffstat (limited to 'source/main.cpp')
-rw-r--r-- | source/main.cpp | 156 |
1 files changed, 92 insertions, 64 deletions
diff --git a/source/main.cpp b/source/main.cpp index aaf268a..e9c33ef 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -2,7 +2,7 @@ * @file main.cpp * @brief Program entry point. * - * Copyright (C) 2020 Clyne Sullivan + * 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. @@ -26,8 +26,16 @@ static_assert(sizeof(dacsample_t) == sizeof(uint16_t)); #include <array> -constexpr unsigned int MAX_ELF_FILE_SIZE = 16 * 1024; +// Pin definitions +// +#if defined(TARGET_PLATFORM_L4) +constexpr auto LINE_LED_GREEN = PAL_LINE(GPIOC_BASE, 10U); +constexpr auto LINE_LED_YELLOW = PAL_LINE(GPIOC_BASE, 11U); +constexpr auto LINE_LED_RED = PAL_LINE(GPIOC_BASE, 12U); +#endif +// Run status +// enum class RunStatus : char { Idle = '1', @@ -36,6 +44,8 @@ enum class RunStatus : char }; static RunStatus run_status = RunStatus::Idle; +// Conversion threads messaging +// #define MSG_CONVFIRST (1) #define MSG_CONVSECOND (2) #define MSG_CONVFIRST_MEASURE (3) @@ -44,43 +54,11 @@ static RunStatus run_status = RunStatus::Idle; #define MSG_FOR_FIRST(m) (m & 1) #define MSG_FOR_MEASURE(m) (m > 2) -static ErrorManager EM; - static msg_t conversionMBBuffer[2]; static MAILBOX_DECL(conversionMB, conversionMBBuffer, 2); -// Thread for LED status and wakeup hold -__attribute__((section(".stacks"))) -static THD_WORKING_AREA(monitorThreadWA, 256); -static THD_FUNCTION(monitorThread, arg); - -// Thread for managing the conversion task -__attribute__((section(".stacks"))) -static THD_WORKING_AREA(conversionThreadMonitorWA, 1024); -static THD_FUNCTION(conversionThreadMonitor, arg); -static thread_t *conversionThreadHandle = nullptr; - -// Thread for unprivileged algorithm execution -__attribute__((section(".stacks"))) -static THD_WORKING_AREA(conversionThreadWA, 128); // All we do is enter unprivileged mode. -static THD_FUNCTION(conversionThread, arg); -constexpr unsigned int conversionThreadUPWASize = -#if defined(TARGET_PLATFORM_H7) - 62 * 1024; -#else - 15 * 1024; -#endif -__attribute__((section(".convdata"))) -static THD_WORKING_AREA(conversionThreadUPWA, conversionThreadUPWASize); -__attribute__((section(".convdata"))) -static thread_t *conversionThreadMonitorHandle = nullptr; - -// Thread for USB monitoring -__attribute__((section(".stacks"))) -static THD_WORKING_AREA(communicationThreadWA, 4096); -static THD_FUNCTION(communicationThread, arg); - -static time_measurement_t conversion_time_measurement; +// Sample input and output buffers +// #if defined(TARGET_PLATFORM_H7) __attribute__((section(".convdata"))) static SampleBuffer samplesIn (reinterpret_cast<Sample *>(0x38000000)); // 16k @@ -95,35 +73,38 @@ static SampleBuffer samplesOut (reinterpret_cast<Sample *>(0x2000C000)); // 16k static SampleBuffer samplesSigGen (reinterpret_cast<Sample *>(0x20010000)); // 16k #endif +// Algorithm binary storage +// +constexpr unsigned int MAX_ELF_FILE_SIZE = 16 * 1024; static unsigned char elf_file_store[MAX_ELF_FILE_SIZE]; __attribute__((section(".convdata"))) static ELF::Entry elf_entry = nullptr; +// Other variables +// +static ErrorManager EM; +static time_measurement_t conversion_time_measurement; static char userMessageBuffer[128]; static unsigned char userMessageSize = 0; +// Functions +// __attribute__((section(".convcode"))) static void conversion_unprivileged_main(); - -static void mpu_setup(); +static void startThreads(); +static void mpuSetup(); static void abortAlgorithmFromISR(); -static void signal_operate(adcsample_t *buffer, size_t count); -static void signal_operate_measure(adcsample_t *buffer, size_t count); - -#if defined(TARGET_PLATFORM_L4) -constexpr auto LINE_LED_GREEN = PAL_LINE(GPIOC_BASE, 10U); -constexpr auto LINE_LED_YELLOW = PAL_LINE(GPIOC_BASE, 11U); -constexpr auto LINE_LED_RED = PAL_LINE(GPIOC_BASE, 12U); -#endif +static void signalOperate(adcsample_t *buffer, size_t count); +static void signalOperateMeasure(adcsample_t *buffer, size_t count); int main() { - // Initialize the RTOS + // Initialize ChibiOS halInit(); chSysInit(); SCB->CPACR |= 0xF << 20; // Enable FPU - mpu_setup(); + mpuSetup(); #if defined(TARGET_PLATFORM_L4) palSetLineMode(LINE_LED_GREEN, PAL_MODE_OUTPUT_PUSHPULL); @@ -140,7 +121,42 @@ int main() SClock::setRate(SClock::Rate::R32K); ADC::setRate(SClock::Rate::R32K); - chTMObjectInit(&conversion_time_measurement); + startThreads(); + chThdExit(0); + return 0; +} + +static THD_FUNCTION(monitorThread, arg); // Runs status LEDs and allows debug halt. +static THD_FUNCTION(conversionThreadMonitor, arg); // Monitors and manages algo. thread. +static THD_FUNCTION(conversionThread, arg); // Algorithm thread (unprivileged). +static THD_FUNCTION(communicationThread, arg); // Manages USB communications. + +// Need to hold some thread handles for mailbox usage. +static thread_t *conversionThreadHandle = nullptr; +__attribute__((section(".convdata"))) +static thread_t *conversionThreadMonitorHandle = nullptr; + +// The more stack for the algorithm, the merrier. +constexpr unsigned int conversionThreadUPWASize = +#if defined(TARGET_PLATFORM_H7) + 62 * 1024; +#else + 15 * 1024; +#endif + +__attribute__((section(".stacks"))) +static THD_WORKING_AREA(monitorThreadWA, 256); +__attribute__((section(".stacks"))) +static THD_WORKING_AREA(conversionThreadMonitorWA, 1024); +__attribute__((section(".stacks"))) +static THD_WORKING_AREA(conversionThreadWA, 128); // For entering unprivileged mode. +__attribute__((section(".convdata"))) +static THD_WORKING_AREA(conversionThreadUPWA, conversionThreadUPWASize); +__attribute__((section(".stacks"))) +static THD_WORKING_AREA(communicationThreadWA, 4096); + +void startThreads() +{ chThdCreateStatic( monitorThreadWA, sizeof(monitorThreadWA), LOWPRIO, @@ -149,19 +165,17 @@ int main() conversionThreadMonitorWA, sizeof(conversionThreadMonitorWA), NORMALPRIO + 1, conversionThreadMonitor, nullptr); + auto conversionThreadUPWAEnd = + reinterpret_cast<uint32_t>(conversionThreadUPWA) + conversionThreadUPWASize; conversionThreadHandle = chThdCreateStatic( conversionThreadWA, sizeof(conversionThreadWA), HIGHPRIO, conversionThread, - reinterpret_cast<void *>(reinterpret_cast<uint32_t>(conversionThreadUPWA) + - conversionThreadUPWASize)); + reinterpret_cast<void *>(conversionThreadUPWAEnd)); chThdCreateStatic( communicationThreadWA, sizeof(communicationThreadWA), NORMALPRIO, communicationThread, nullptr); - - chThdExit(0); - return 0; } THD_FUNCTION(communicationThread, arg) @@ -190,7 +204,7 @@ THD_FUNCTION(communicationThread, arg) // 'S' - Stop conversion. // 's' - Get latest block of conversion results. // 't' - Get latest block of conversion input. - // 'u' - Get user message. + // 'u' - Get user message. // 'W' - Start signal generator (siggen). // 'w' - Stop siggen. @@ -222,8 +236,22 @@ THD_FUNCTION(communicationThread, arg) 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)) { - samplesSigGen.setSize(count); - USBSerial::read(samplesSigGen.bytedata(), samplesSigGen.bytesize()); + if (run_status == RunStatus::Idle) { + samplesSigGen.setSize(count * 2); + USBSerial::read( + reinterpret_cast<uint8_t *>(samplesSigGen.middata()), + samplesSigGen.bytesize() / 2); + } else if (run_status == RunStatus::Running) { + int more; + do { + chThdSleepMicroseconds(10); + more = DAC::sigGenWantsMore(); + } while (more == -1); + + USBSerial::read(reinterpret_cast<uint8_t *>( + more == 0 ? samplesSigGen.data() : samplesSigGen.middata()), + samplesSigGen.bytesize() / 2); + } } } break; @@ -275,7 +303,7 @@ THD_FUNCTION(communicationThread, arg) if (EM.assert(run_status == RunStatus::Idle, Error::NotIdle)) { run_status = RunStatus::Running; samplesOut.clear(); - ADC::start(samplesIn.data(), samplesIn.size(), signal_operate_measure); + ADC::start(samplesIn.data(), samplesIn.size(), signalOperateMeasure); DAC::start(0, samplesOut.data(), samplesOut.size()); } break; @@ -293,7 +321,7 @@ THD_FUNCTION(communicationThread, arg) if (EM.assert(run_status == RunStatus::Idle, Error::NotIdle)) { run_status = RunStatus::Running; samplesOut.clear(); - ADC::start(samplesIn.data(), samplesIn.size(), signal_operate); + ADC::start(samplesIn.data(), samplesIn.size(), signalOperate); DAC::start(0, samplesOut.data(), samplesOut.size()); } break; @@ -488,7 +516,7 @@ void conversion_unprivileged_main() } } -void mpu_setup() +void mpuSetup() { // Set up MPU for user algorithm #if defined(TARGET_PLATFORM_H7) @@ -561,7 +589,7 @@ void abortAlgorithmFromISR() } } -void signal_operate(adcsample_t *buffer, size_t) +void signalOperate(adcsample_t *buffer, size_t) { chSysLockFromISR(); @@ -582,7 +610,7 @@ void signal_operate(adcsample_t *buffer, size_t) } } -void signal_operate_measure(adcsample_t *buffer, [[maybe_unused]] size_t count) +void signalOperateMeasure(adcsample_t *buffer, [[maybe_unused]] size_t count) { chSysLockFromISR(); if (buffer == samplesIn.data()) { @@ -594,7 +622,7 @@ void signal_operate_measure(adcsample_t *buffer, [[maybe_unused]] size_t count) } chSysUnlockFromISR(); - ADC::setOperation(signal_operate); + ADC::setOperation(signalOperate); } extern "C" { @@ -654,7 +682,7 @@ void port_syscall(struct port_extctx *ctxp, uint32_t n) } break; case 3: - ctxp->r0 = ADC::readAlt(0); + ctxp->r0 = ADC::readAlt(ctxp->r0); break; case 4: { |