diff --git a/firmware/source/communication.hpp b/firmware/source/communication.hpp index 03220b8..a4f818a 100644 --- a/firmware/source/communication.hpp +++ b/firmware/source/communication.hpp @@ -2,7 +2,7 @@ * @file communication.hpp * @brief Manages communication with the host computer. * - * Copyright (C) 2021 Clyne Sullivan + * Copyright (C) 2023 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. @@ -17,9 +17,17 @@ class CommunicationManager { public: + /** + * Starts the communication manager thread (threadComm). + */ static void begin(); private: + /** + * Continuously polls the USB serial connection, handling received commands + * as necessary. + * Does not return. + */ static void threadComm(void *); static std::array m_thread_stack; diff --git a/firmware/source/conversion.hpp b/firmware/source/conversion.hpp index ca0054a..75d644e 100644 --- a/firmware/source/conversion.hpp +++ b/firmware/source/conversion.hpp @@ -2,7 +2,7 @@ * @file conversion.hpp * @brief Manages algorithm application (converts input samples to output). * - * Copyright (C) 2021 Clyne Sullivan + * Copyright (C) 2023 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. @@ -27,6 +27,10 @@ constexpr unsigned int CONVERSION_THREAD_STACK_SIZE = class ConversionManager { public: + /** + * Starts two threads: the privileged monitor thread and the unprivileged + * algorithm execution thread. + */ static void begin(); // Begins sample conversion. diff --git a/firmware/source/elf.h b/firmware/source/elf.h index 998356d..fe817e1 100644 --- a/firmware/source/elf.h +++ b/firmware/source/elf.h @@ -2,7 +2,7 @@ * @file elf.h * @brief Defines ELF binary format info. * - * Free to use, written by Clyne Sullivan. + * Public domain, written by Clyne Sullivan. */ #ifndef STMDSP_ELF_HPP diff --git a/firmware/source/elfload.hpp b/firmware/source/elfload.hpp index 10d95d7..9cfcbf9 100644 --- a/firmware/source/elfload.hpp +++ b/firmware/source/elfload.hpp @@ -2,7 +2,7 @@ * @file elfload.hpp * @brief Loads ELF binary data into memory for execution. * - * Copyright (C) 2021 Clyne Sullivan + * Copyright (C) 2023 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. @@ -24,9 +24,26 @@ class ELFManager public: using EntryFunc = Sample *(*)(Sample *, size_t); + /** + * Attempts to parse the ELF binary loaded in the file buffer. + * Returns true if successful. + */ static bool loadFromInternalBuffer(); + + /** + * Returns a function pointer to the loaded ELF's entry point. + * Returns nullptr if a valid ELF is not loaded. + */ static EntryFunc loadedElf(); + + /** + * Returns the address of the ELF file buffer (copy ELF binary to here). + */ static unsigned char *fileBuffer(); + + /** + * "Unloads" the loaded binary by invalidating the entry pointer. + */ static void unload(); private: diff --git a/firmware/source/error.hpp b/firmware/source/error.hpp index c6a7f5c..0765167 100644 --- a/firmware/source/error.hpp +++ b/firmware/source/error.hpp @@ -2,7 +2,7 @@ * @file error.hpp * @brief Tracks and reports non-critical errors. * - * Copyright (C) 2021 Clyne Sullivan + * Copyright (C) 2023 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. @@ -31,9 +31,25 @@ class ErrorManager constexpr static unsigned int MAX_ERROR_QUEUE_SIZE = 8; public: + /** + * Adds the given error to the error queue. + */ void add(Error error); + + /** + * If condition is false, add the given error to the error queue. + * Returns condition. + */ bool assert(bool condition, Error error); + + /** + * Returns true if the error queue is not empty. + */ bool hasError(); + + /** + * Returns the oldest error queue entry after removing it from the queue. + */ Error pop(); private: diff --git a/firmware/source/handlers.hpp b/firmware/source/handlers.hpp index fd7e10c..9aa87b5 100644 --- a/firmware/source/handlers.hpp +++ b/firmware/source/handlers.hpp @@ -2,7 +2,7 @@ * @file handlers.hpp * @brief Interrupt service routine handlers. * - * Copyright (C) 2021 Clyne Sullivan + * Copyright (C) 2023 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. @@ -16,12 +16,15 @@ extern "C" { +// Service call handler ("svc" calls) __attribute__((naked)) void port_syscall(struct port_extctx *ctxp, uint32_t n); +// Handle memory faults possibly caused by the algorithm. __attribute__((naked)) void MemManage_Handler(); +// Handle execution faults possibly caused by the algorithm. __attribute__((naked)) void HardFault_Handler(); diff --git a/firmware/source/monitor.hpp b/firmware/source/monitor.hpp index 93f75e3..500fbbb 100644 --- a/firmware/source/monitor.hpp +++ b/firmware/source/monitor.hpp @@ -2,7 +2,7 @@ * @file monitor.hpp * @brief Manages the device monitoring thread (status LEDs, etc.). * - * Copyright (C) 2021 Clyne Sullivan + * Copyright (C) 2023 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. @@ -19,9 +19,15 @@ class Monitor { public: + /** + * Starts the monitor thread. + */ static void begin(); private: + /** + * Updates status LEDs. Does not return. + */ static void threadMonitor(void *); static std::array m_thread_stack; diff --git a/firmware/source/periph/adc.hpp b/firmware/source/periph/adc.hpp index 5f7fa08..ae2e881 100644 --- a/firmware/source/periph/adc.hpp +++ b/firmware/source/periph/adc.hpp @@ -2,7 +2,7 @@ * @file adc.hpp * @brief Manages signal reading through the ADC. * - * Copyright (C) 2021 Clyne Sullivan + * Copyright (C) 2023 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. @@ -22,18 +22,47 @@ class ADC public: using Operation = void (*)(adcsample_t *buffer, size_t count); + /** + * Initializes analog input pins and the microcontoller's ADC peripheral. + */ static void begin(); + /** + * Begins continuous ADC sampling triggered by SClock at the set sampling + * rate. + * @param buffer Pointer to buffer for sample data. + * @param count Number of samples that the buffer can hold. + * @param operation Handler function to operate on filled half-buffers. + */ static void start(adcsample_t *buffer, size_t count, Operation operation); + + /** + * Stops the continuous ADC sampling. + */ static void stop(); + /** + * Runs a single conversion on the "alt" inputs (parameter knobs). + * @param id The ID of the desired "alt" input (zero or one). + * @return The sampled value for the given input. + */ static adcsample_t readAlt(unsigned int id); + /** + * Sets the desired sampling rate for the ADC to operate at. + */ static void setRate(SClock::Rate rate); + + /** + * Used to override the handler function for the currently running + * conversion. + */ static void setOperation(Operation operation); private: + // ADC driver for signal input. static ADCDriver *m_driver; + // ADC driver for "alt" inputs. static ADCDriver *m_driver2; static const ADCConfig m_config; diff --git a/firmware/source/periph/cordic.cpp b/firmware/source/periph/cordic.cpp index 29ee068..b6a9d7e 100644 --- a/firmware/source/periph/cordic.cpp +++ b/firmware/source/periph/cordic.cpp @@ -1,3 +1,14 @@ +/** + * @file cordic.cpp + * @brief Provides mathematical functions for algorithms. + * + * Copyright (C) 2023 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 "cordic.hpp" #include "hal.h" diff --git a/firmware/source/periph/cordic.hpp b/firmware/source/periph/cordic.hpp index 5d640cc..a9a0466 100644 --- a/firmware/source/periph/cordic.hpp +++ b/firmware/source/periph/cordic.hpp @@ -1,11 +1,33 @@ +/** + * @file cordic.hpp + * @brief Provides mathematical functions for algorithms. + * + * Copyright (C) 2023 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 . + */ + #ifndef CORDIC_HPP_ #define CORDIC_HPP_ +/** + * Named after the hardware CORDIC peripheral even though software + * implementations may be used. + */ namespace cordic { + // Provides pi in case cordic functions require it. constexpr double PI = 3.1415926535L; + /** + * Prepares cordic functions for use. + */ void init(); + // mod - Calculates remainder for given fraction. + // cos, sin, tan - The trig functions. + #if !defined(TARGET_PLATFORM_L4) double mod(double n, double d); diff --git a/firmware/source/periph/dac.hpp b/firmware/source/periph/dac.hpp index 7250a52..f4266c7 100644 --- a/firmware/source/periph/dac.hpp +++ b/firmware/source/periph/dac.hpp @@ -2,7 +2,7 @@ * @file dac.hpp * @brief Manages signal creation using the DAC. * - * Copyright (C) 2021 Clyne Sullivan + * Copyright (C) 2023 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. @@ -18,12 +18,35 @@ class DAC { public: + /** + * Initializes DAC output pins and peripheral. + */ static void begin(); + /** + * Begins continuous DAC conversion on the given channel, running at the + * current SClock sampling rate. + * @param channel Selected output channel (0 = sig. out, 1 = sig. gen.). + * @param buffer Buffer of sample data to output. + * @param count Number of samples in sample buffer. + */ static void start(int channel, dacsample_t *buffer, size_t count); + + /** + * Stops DAC conversion on the given channel. + */ static void stop(int channel); + /** + * Determines if signal generator needs more sample data for streamed + * output (i.e. audio file streaming). + * @return >0 if samples needed, <0 on initial run. + */ static int sigGenWantsMore(); + + /** + * Returns true if signal generator is currently running. + */ static int isSigGenRunning(); private: diff --git a/firmware/source/periph/usbserial.hpp b/firmware/source/periph/usbserial.hpp index 58113c9..85da470 100644 --- a/firmware/source/periph/usbserial.hpp +++ b/firmware/source/periph/usbserial.hpp @@ -2,7 +2,7 @@ * @file usbserial.hpp * @brief Wrapper for ChibiOS's SerialUSBDriver. * - * Copyright (C) 2021 Clyne Sullivan + * Copyright (C) 2023 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. @@ -17,11 +17,30 @@ class USBSerial { public: + /** + * Prepares for USB serial communication. + */ static void begin(); + /** + * Returns true if input data has been received. + */ static bool isActive(); + /** + * Reads received input data into the given buffer. + * @param buffer Buffer to store input data. + * @param count Number of bytes to read. + * @return Number of bytes actually read. + */ static size_t read(unsigned char *buffer, size_t count); + + /** + * Writes data to serial output. + * @param buffer Buffer of output data. + * @param count Number of bytes to write. + * @return Number of bytes actually written. + */ static size_t write(const unsigned char *buffer, size_t count); private: diff --git a/firmware/source/runstatus.hpp b/firmware/source/runstatus.hpp index ab269b4..18fe2e6 100644 --- a/firmware/source/runstatus.hpp +++ b/firmware/source/runstatus.hpp @@ -1,5 +1,4 @@ // Run status -// enum class RunStatus : char { Idle = '1', diff --git a/firmware/source/samplebuffer.hpp b/firmware/source/samplebuffer.hpp index d13023a..8328770 100644 --- a/firmware/source/samplebuffer.hpp +++ b/firmware/source/samplebuffer.hpp @@ -2,7 +2,7 @@ * @file samplebuffer.hpp * @brief Manages ADC/DAC buffer data. * - * Copyright (C) 2021 Clyne Sullivan + * Copyright (C) 2023 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. @@ -20,25 +20,79 @@ using Sample = uint16_t; constexpr unsigned int MAX_SAMPLE_BUFFER_BYTESIZE = sizeof(Sample) * 8192; constexpr unsigned int MAX_SAMPLE_BUFFER_SIZE = MAX_SAMPLE_BUFFER_BYTESIZE / sizeof(Sample); +/** + * Manages a buffer of sample data from the ADC or DAC with facilities to + * work with separate halves of the total buffer (which is necessary when + * streaming data to or from the buffer). + */ class SampleBuffer { public: + // Manage the sample data memory at 'buffer'. SampleBuffer(Sample *buffer); + /** + * Fill the current buffer with midpoint (2048/0V) values. + */ void clear(); + /** + * Copy 'srcsize' samples from 'data' into the first half of the current + * buffer. Also do equivalent of setModified(). + */ void modify(Sample *data, unsigned int srcsize); + + /** + * Copy 'srcsize' samples from 'data' into the second half of the current + * buffer. Also do equivalent of setMidmodified(). + */ void midmodify(Sample *data, unsigned int srcsize); + + /** + * Set modified buffer pointer to first half of the current buffer. + */ void setModified(); + + /** + * Set modified buffer pointer to second half of the current buffer. + */ void setMidmodified(); + + /** + * Return pointer to most recently modified buffer portion. + * Clears this internal pointer when called. + */ Sample *modified(); + /** + * Returns pointer to first half of current buffer. + */ Sample *data(); + + /** + * Returns pointer to second half of current buffer. + */ Sample *middata(); + + /** + * Returns uint8_t-casted pointer to the current buffer. + */ uint8_t *bytedata(); + /** + * Sets the total working size of the current buffer. Current buffer must + * be able to accommodate. + */ void setSize(unsigned int size); + + /** + * Returns the current total working size (number of samples). + */ unsigned int size() const; + + /** + * Returns the current total working size (number of bytes). + */ unsigned int bytesize() const; private: diff --git a/firmware/source/samples.hpp b/firmware/source/samples.hpp index 6551e25..8e60775 100644 --- a/firmware/source/samples.hpp +++ b/firmware/source/samples.hpp @@ -2,7 +2,7 @@ * @file samples.hpp * @brief Provides sample buffers for inputs and outputs. * - * Copyright (C) 2021 Clyne Sullivan + * Copyright (C) 2023 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. @@ -14,6 +14,8 @@ #include "samplebuffer.hpp" +// Define sample buffers for the input and output signals and the signal +// generator. class Samples { public: diff --git a/firmware/source/sclock.hpp b/firmware/source/sclock.hpp index d5b93df..c72805d 100644 --- a/firmware/source/sclock.hpp +++ b/firmware/source/sclock.hpp @@ -2,7 +2,7 @@ * @file sclock.hpp * @brief Manages sampling rate clock speeds. * - * Copyright (C) 2021 Clyne Sullivan + * Copyright (C) 2023 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. @@ -19,6 +19,7 @@ class SClock { public: + // These are the supported sampling rates. GUI keeps its own enumeration. enum class Rate : unsigned int { R8K = 0, R16K, @@ -28,11 +29,32 @@ public: R96K }; + /** + * Initializes the sample clock hardware. + */ static void begin(); + + /** + * Starts the sample rate clock if it is not already running. + */ static void start(); + + /** + * Indicate that the caller no longer needs the sample clock. + * This decrements an internal counter that is incremented by start() + * calls; if the counter reaches zero, the clock will actually stop. + */ static void stop(); + /** + * Sets the desired sampling rate, used for the next start() call. + */ static void setRate(Rate rate); + + /** + * Gets the desired sampling rate (SClock::Rate value) casted to an + * unsigned int. + */ static unsigned int getRate(); private: