2nd pot; some doc; smooth WAV playback

master
Clyne 4 years ago
parent d2f50fb925
commit f1773b634e

@ -49,7 +49,7 @@ const char *makefile_text_l4 =
#endif #endif
"arm-none-eabi-g++ -x c++ -Os -std=c++20 -fno-exceptions -fno-rtti " "arm-none-eabi-g++ -x c++ -Os -std=c++20 -fno-exceptions -fno-rtti "
"-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 " "-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 "
"-nostartfiles -I$1/cmsis" "-nostartfiles -I$1/cmsis "
"-Wl,-Ttext-segment=0x10000000 -Wl,-zmax-page-size=512 -Wl,-eprocess_data_entry " "-Wl,-Ttext-segment=0x10000000 -Wl,-zmax-page-size=512 -Wl,-eprocess_data_entry "
"$0 -o $0.o" NEWLINE "$0 -o $0.o" NEWLINE
COPY " $0.o $0.orig.o" NEWLINE COPY " $0.o $0.orig.o" NEWLINE
@ -168,12 +168,22 @@ asm("vsqrt.f32 s0, s0; bx lr");
return 0; return 0;
} }
auto readalt() { auto readpot1() {
Sample s;
asm("push {r4-r6}; eor r0, r0; svc 3; mov %0, r0; pop {r4-r6}" : "=&r"(s));
return s;
}
auto readpot2() {
Sample s; Sample s;
asm("push {r4-r6}; svc 3; mov %0, r0; pop {r4-r6}" : "=&r"(s)); asm("push {r4-r6}; mov r0, #1; svc 3; mov %0, r0; pop {r4-r6}" : "=&r"(s));
return s; return s;
} }
void puts(const char *s) {
// 's' will already be in r0.
asm("push {r4-r6}; svc 4; pop {r4-r6}");
}
// End stmdspgui header code // End stmdspgui header code
)cpp"; )cpp";

@ -48,18 +48,16 @@ void MainFrame::onRunStart(wxCommandEvent& ce)
m_device->continuous_start_measure(); m_device->continuous_start_measure();
m_timer_performance->StartOnce(1000); m_timer_performance->StartOnce(1000);
} else { } else {
if (m_device->is_siggening() && m_wav_clip) { auto reqSpeedExact =
// TODO Confirm need for factor of 500 m_device->get_buffer_size()
m_timer_wavclip->Start(m_device->get_buffer_size() * 500 / / static_cast<float>(srateNums[m_rate_select->GetSelection()])
srateNums[m_rate_select->GetSelection()]); * 1000.f * 0.5f;
} else if (m_conv_result_log) { int reqSpeed = reqSpeedExact;
m_timer_record->Start(m_device->get_buffer_size() /
srateNums[m_rate_select->GetSelection()] * if (m_device->is_siggening() && m_wav_clip)
800 / 1000); m_timer_wavclip->Start(reqSpeed);
} else if (m_run_draw_samples->IsChecked()) { if (m_conv_result_log || m_run_draw_samples->IsChecked())
m_timer_record->Start(m_device->get_buffer_size() / m_timer_record->Start(reqSpeed);
srateNums[m_rate_select->GetSelection()]);
}
m_device->continuous_start(); m_device->continuous_start();
} }

@ -2,7 +2,7 @@
* @file adc.cpp * @file adc.cpp
* @brief Manages signal reading through the ADC. * @brief Manages signal reading through the ADC.
* *
* 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 * Distributed under the GNU GPL v3 or later. You should have received a copy of
* the GNU General Public License along with this program. * the GNU General Public License along with this program.
@ -69,7 +69,7 @@ static void readAltCallback(ADCDriver *)
} }
ADCConversionGroup ADC::m_group_config2 = { ADCConversionGroup ADC::m_group_config2 = {
.circular = false, .circular = false,
.num_channels = 1, .num_channels = 2,
.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 */
@ -88,10 +88,10 @@ ADCConversionGroup ADC::m_group_config2 = {
.awd3cr = 0, .awd3cr = 0,
#endif #endif
.smpr = { .smpr = {
ADC_SMPR1_SMP_AN1(ADC_SMPR_SMP_12P5), 0 ADC_SMPR1_SMP_AN1(ADC_SMPR_SMP_12P5) | ADC_SMPR1_SMP_AN2(ADC_SMPR_SMP_12P5), 0
}, },
.sqr = { .sqr = {
ADC_SQR1_SQ1_N(ADC_CHANNEL_IN1), ADC_SQR1_SQ1_N(ADC_CHANNEL_IN1) | ADC_SQR1_SQ2_N(ADC_CHANNEL_IN2),
0, 0, 0 0, 0, 0
}, },
}; };
@ -107,6 +107,7 @@ void ADC::begin()
#else #else
palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG); // Algorithm in palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG); // Algorithm in
palSetPadMode(GPIOC, 0, PAL_MODE_INPUT_ANALOG); // Potentiometer 1 palSetPadMode(GPIOC, 0, PAL_MODE_INPUT_ANALOG); // Potentiometer 1
palSetPadMode(GPIOC, 1, PAL_MODE_INPUT_ANALOG); // Potentiometer 2
#endif #endif
adcStart(m_driver, &m_config); adcStart(m_driver, &m_config);
@ -135,15 +136,15 @@ void ADC::stop()
adcsample_t ADC::readAlt(unsigned int id) adcsample_t ADC::readAlt(unsigned int id)
{ {
if (id != 0) if (id > 1)
return 0; return 0;
static adcsample_t result[32] = {}; static adcsample_t result[16] = {};
readAltDone = false; readAltDone = false;
adcStartConversion(m_driver2, &m_group_config2, result, 32); adcStartConversion(m_driver2, &m_group_config2, result, 8);
while (!readAltDone) while (!readAltDone)
; __WFI();
adcStopConversion(m_driver2); adcStopConversion(m_driver2);
return result[0]; return result[id];
} }
void ADC::setRate(SClock::Rate rate) void ADC::setRate(SClock::Rate rate)

@ -2,7 +2,7 @@
* @file adc.hpp * @file adc.hpp
* @brief Manages signal reading through the ADC. * @brief Manages signal reading through the ADC.
* *
* 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 * Distributed under the GNU GPL v3 or later. You should have received a copy of
* the GNU General Public License along with this program. * the GNU General Public License along with this program.

@ -2,7 +2,7 @@
* @file dac.cpp * @file dac.cpp
* @brief Manages signal creation using the DAC. * @brief Manages signal creation using the DAC.
* *
* 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 * Distributed under the GNU GPL v3 or later. You should have received a copy of
* the GNU General Public License along with this program. * the GNU General Public License along with this program.
@ -22,9 +22,16 @@ const DACConfig DAC::m_config = {
.cr = 0 .cr = 0
}; };
static int dacIsDone = -1;
static void dacEndCallback(DACDriver *dacd)
{
if (dacd == &DACD2)
dacIsDone = dacIsBufferComplete(dacd) ? 1 : 0;
}
const DACConversionGroup DAC::m_group_config = { const DACConversionGroup DAC::m_group_config = {
.num_channels = 1, .num_channels = 1,
.end_cb = nullptr, .end_cb = dacEndCallback,
.error_cb = nullptr, .error_cb = nullptr,
#if defined(TARGET_PLATFORM_H7) #if defined(TARGET_PLATFORM_H7)
.trigger = 5 // TIM6_TRGO .trigger = 5 // TIM6_TRGO
@ -45,11 +52,18 @@ void DAC::begin()
void DAC::start(int channel, dacsample_t *buffer, size_t count) void DAC::start(int channel, dacsample_t *buffer, size_t count)
{ {
if (channel >= 0 && channel < 2) { if (channel >= 0 && channel < 2) {
if (channel == 1)
dacIsDone = -1;
dacStartConversion(m_driver[channel], &m_group_config, buffer, count); dacStartConversion(m_driver[channel], &m_group_config, buffer, count);
SClock::start(); SClock::start();
} }
} }
int DAC::sigGenWantsMore()
{
return dacIsDone;
}
void DAC::stop(int channel) void DAC::stop(int channel)
{ {
if (channel >= 0 && channel < 2) { if (channel >= 0 && channel < 2) {

@ -2,7 +2,7 @@
* @file dac.hpp * @file dac.hpp
* @brief Manages signal creation using the DAC. * @brief Manages signal creation using the DAC.
* *
* 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 * Distributed under the GNU GPL v3 or later. You should have received a copy of
* the GNU General Public License along with this program. * the GNU General Public License along with this program.
@ -23,6 +23,8 @@ public:
static void start(int channel, dacsample_t *buffer, size_t count); static void start(int channel, dacsample_t *buffer, size_t count);
static void stop(int channel); static void stop(int channel);
static int sigGenWantsMore();
private: private:
static DACDriver *m_driver[2]; static DACDriver *m_driver[2];

@ -2,7 +2,7 @@
* @file elf_load.cpp * @file elf_load.cpp
* @brief Loads ELF binary data into memory for execution. * @brief Loads ELF binary data into memory for execution.
* *
* 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 * Distributed under the GNU GPL v3 or later. You should have received a copy of
* the GNU General Public License along with this program. * the GNU General Public License along with this program.

@ -2,7 +2,7 @@
* @file elf_load.hpp * @file elf_load.hpp
* @brief Loads ELF binary data into memory for execution. * @brief Loads ELF binary data into memory for execution.
* *
* 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 * Distributed under the GNU GPL v3 or later. You should have received a copy of
* the GNU General Public License along with this program. * the GNU General Public License along with this program.

@ -2,7 +2,7 @@
* @file main.cpp * @file main.cpp
* @brief Program entry point. * @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 * Distributed under the GNU GPL v3 or later. You should have received a copy of
* the GNU General Public License along with this program. * the GNU General Public License along with this program.
@ -26,8 +26,16 @@ static_assert(sizeof(dacsample_t) == sizeof(uint16_t));
#include <array> #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 enum class RunStatus : char
{ {
Idle = '1', Idle = '1',
@ -36,6 +44,8 @@ enum class RunStatus : char
}; };
static RunStatus run_status = RunStatus::Idle; static RunStatus run_status = RunStatus::Idle;
// Conversion threads messaging
//
#define MSG_CONVFIRST (1) #define MSG_CONVFIRST (1)
#define MSG_CONVSECOND (2) #define MSG_CONVSECOND (2)
#define MSG_CONVFIRST_MEASURE (3) #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_FIRST(m) (m & 1)
#define MSG_FOR_MEASURE(m) (m > 2) #define MSG_FOR_MEASURE(m) (m > 2)
static ErrorManager EM;
static msg_t conversionMBBuffer[2]; static msg_t conversionMBBuffer[2];
static MAILBOX_DECL(conversionMB, conversionMBBuffer, 2); static MAILBOX_DECL(conversionMB, conversionMBBuffer, 2);
// Thread for LED status and wakeup hold // Sample input and output buffers
__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;
#if defined(TARGET_PLATFORM_H7) #if defined(TARGET_PLATFORM_H7)
__attribute__((section(".convdata"))) __attribute__((section(".convdata")))
static SampleBuffer samplesIn (reinterpret_cast<Sample *>(0x38000000)); // 16k 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 static SampleBuffer samplesSigGen (reinterpret_cast<Sample *>(0x20010000)); // 16k
#endif #endif
// Algorithm binary storage
//
constexpr unsigned int MAX_ELF_FILE_SIZE = 16 * 1024;
static unsigned char elf_file_store[MAX_ELF_FILE_SIZE]; static unsigned char elf_file_store[MAX_ELF_FILE_SIZE];
__attribute__((section(".convdata"))) __attribute__((section(".convdata")))
static ELF::Entry elf_entry = nullptr; static ELF::Entry elf_entry = nullptr;
// Other variables
//
static ErrorManager EM;
static time_measurement_t conversion_time_measurement;
static char userMessageBuffer[128]; static char userMessageBuffer[128];
static unsigned char userMessageSize = 0; static unsigned char userMessageSize = 0;
// Functions
//
__attribute__((section(".convcode"))) __attribute__((section(".convcode")))
static void conversion_unprivileged_main(); static void conversion_unprivileged_main();
static void startThreads();
static void mpu_setup(); static void mpuSetup();
static void abortAlgorithmFromISR(); static void abortAlgorithmFromISR();
static void signal_operate(adcsample_t *buffer, size_t count); static void signalOperate(adcsample_t *buffer, size_t count);
static void signal_operate_measure(adcsample_t *buffer, size_t count); static void signalOperateMeasure(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
int main() int main()
{ {
// Initialize the RTOS // Initialize ChibiOS
halInit(); halInit();
chSysInit(); chSysInit();
SCB->CPACR |= 0xF << 20; // Enable FPU SCB->CPACR |= 0xF << 20; // Enable FPU
mpu_setup(); mpuSetup();
#if defined(TARGET_PLATFORM_L4) #if defined(TARGET_PLATFORM_L4)
palSetLineMode(LINE_LED_GREEN, PAL_MODE_OUTPUT_PUSHPULL); palSetLineMode(LINE_LED_GREEN, PAL_MODE_OUTPUT_PUSHPULL);
@ -140,7 +121,42 @@ int main()
SClock::setRate(SClock::Rate::R32K); SClock::setRate(SClock::Rate::R32K);
ADC::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( chThdCreateStatic(
monitorThreadWA, sizeof(monitorThreadWA), monitorThreadWA, sizeof(monitorThreadWA),
LOWPRIO, LOWPRIO,
@ -149,19 +165,17 @@ int main()
conversionThreadMonitorWA, sizeof(conversionThreadMonitorWA), conversionThreadMonitorWA, sizeof(conversionThreadMonitorWA),
NORMALPRIO + 1, NORMALPRIO + 1,
conversionThreadMonitor, nullptr); conversionThreadMonitor, nullptr);
auto conversionThreadUPWAEnd =
reinterpret_cast<uint32_t>(conversionThreadUPWA) + conversionThreadUPWASize;
conversionThreadHandle = chThdCreateStatic( conversionThreadHandle = chThdCreateStatic(
conversionThreadWA, sizeof(conversionThreadWA), conversionThreadWA, sizeof(conversionThreadWA),
HIGHPRIO, HIGHPRIO,
conversionThread, conversionThread,
reinterpret_cast<void *>(reinterpret_cast<uint32_t>(conversionThreadUPWA) + reinterpret_cast<void *>(conversionThreadUPWAEnd));
conversionThreadUPWASize));
chThdCreateStatic( chThdCreateStatic(
communicationThreadWA, sizeof(communicationThreadWA), communicationThreadWA, sizeof(communicationThreadWA),
NORMALPRIO, NORMALPRIO,
communicationThread, nullptr); communicationThread, nullptr);
chThdExit(0);
return 0;
} }
THD_FUNCTION(communicationThread, arg) THD_FUNCTION(communicationThread, arg)
@ -222,8 +236,22 @@ THD_FUNCTION(communicationThread, arg)
if (EM.assert(USBSerial::read(&cmd[1], 2) == 2, Error::BadParamSize)) { if (EM.assert(USBSerial::read(&cmd[1], 2) == 2, Error::BadParamSize)) {
unsigned int count = cmd[1] | (cmd[2] << 8); unsigned int count = cmd[1] | (cmd[2] << 8);
if (EM.assert(count <= MAX_SAMPLE_BUFFER_SIZE, Error::BadParam)) { if (EM.assert(count <= MAX_SAMPLE_BUFFER_SIZE, Error::BadParam)) {
samplesSigGen.setSize(count); if (run_status == RunStatus::Idle) {
USBSerial::read(samplesSigGen.bytedata(), samplesSigGen.bytesize()); 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; break;
@ -275,7 +303,7 @@ THD_FUNCTION(communicationThread, arg)
if (EM.assert(run_status == RunStatus::Idle, Error::NotIdle)) { if (EM.assert(run_status == RunStatus::Idle, Error::NotIdle)) {
run_status = RunStatus::Running; run_status = RunStatus::Running;
samplesOut.clear(); 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()); DAC::start(0, samplesOut.data(), samplesOut.size());
} }
break; break;
@ -293,7 +321,7 @@ THD_FUNCTION(communicationThread, arg)
if (EM.assert(run_status == RunStatus::Idle, Error::NotIdle)) { if (EM.assert(run_status == RunStatus::Idle, Error::NotIdle)) {
run_status = RunStatus::Running; run_status = RunStatus::Running;
samplesOut.clear(); samplesOut.clear();
ADC::start(samplesIn.data(), samplesIn.size(), signal_operate); ADC::start(samplesIn.data(), samplesIn.size(), signalOperate);
DAC::start(0, samplesOut.data(), samplesOut.size()); DAC::start(0, samplesOut.data(), samplesOut.size());
} }
break; break;
@ -488,7 +516,7 @@ void conversion_unprivileged_main()
} }
} }
void mpu_setup() void mpuSetup()
{ {
// Set up MPU for user algorithm // Set up MPU for user algorithm
#if defined(TARGET_PLATFORM_H7) #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(); 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(); chSysLockFromISR();
if (buffer == samplesIn.data()) { if (buffer == samplesIn.data()) {
@ -594,7 +622,7 @@ void signal_operate_measure(adcsample_t *buffer, [[maybe_unused]] size_t count)
} }
chSysUnlockFromISR(); chSysUnlockFromISR();
ADC::setOperation(signal_operate); ADC::setOperation(signalOperate);
} }
extern "C" { extern "C" {
@ -654,7 +682,7 @@ void port_syscall(struct port_extctx *ctxp, uint32_t n)
} }
break; break;
case 3: case 3:
ctxp->r0 = ADC::readAlt(0); ctxp->r0 = ADC::readAlt(ctxp->r0);
break; break;
case 4: case 4:
{ {

@ -1,3 +1,14 @@
/**
* @file samplebuffer.cpp
* @brief Manages ADC/DAC buffer data.
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "samplebuffer.hpp" #include "samplebuffer.hpp"
SampleBuffer::SampleBuffer(Sample *buffer) : SampleBuffer::SampleBuffer(Sample *buffer) :

@ -1,3 +1,14 @@
/**
* @file samplebuffer.hpp
* @brief Manages ADC/DAC buffer data.
*
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef SAMPLEBUFFER_HPP_ #ifndef SAMPLEBUFFER_HPP_
#define SAMPLEBUFFER_HPP_ #define SAMPLEBUFFER_HPP_

@ -1,3 +1,14 @@
/**
* @file sclock.cpp
* @brief Manages sampling rate clock speeds.
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "sclock.hpp" #include "sclock.hpp"
GPTDriver *SClock::m_timer = &GPTD6; GPTDriver *SClock::m_timer = &GPTD6;

@ -1,3 +1,14 @@
/**
* @file sclock.hpp
* @brief Manages sampling rate clock speeds.
*
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef SCLOCK_HPP_ #ifndef SCLOCK_HPP_
#define SCLOCK_HPP_ #define SCLOCK_HPP_

@ -2,7 +2,7 @@
* @file usbserial.cpp * @file usbserial.cpp
* @brief Wrapper for ChibiOS's SerialUSBDriver. * @brief Wrapper for ChibiOS's SerialUSBDriver.
* *
* 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 * Distributed under the GNU GPL v3 or later. You should have received a copy of
* the GNU General Public License along with this program. * the GNU General Public License along with this program.
@ -32,7 +32,7 @@ bool USBSerial::isActive()
{ {
if (auto config = m_driver->config; config != nullptr) { if (auto config = m_driver->config; config != nullptr) {
if (auto usbp = config->usbp; usbp != nullptr) if (auto usbp = config->usbp; usbp != nullptr)
return usbp->state == USB_ACTIVE; return usbp->state == USB_ACTIVE && !ibqIsEmptyI(&m_driver->ibqueue);
} }
return false; return false;

@ -2,7 +2,7 @@
* @file usbserial.hpp * @file usbserial.hpp
* @brief Wrapper for ChibiOS's SerialUSBDriver. * @brief Wrapper for ChibiOS's SerialUSBDriver.
* *
* 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 * Distributed under the GNU GPL v3 or later. You should have received a copy of
* the GNU General Public License along with this program. * the GNU General Public License along with this program.

Loading…
Cancel
Save