From 0fde1b98eee06eda8333ae4099a6731a05a14482 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Thu, 12 Nov 2020 09:45:16 -0500 Subject: [PATCH] firmware reorganize; added more sample rates --- gui/wxmain.cpp | 13 ++- source/adc.cpp | 211 +++++++++++++++++++------------------------ source/adc.hpp | 57 ++++++++---- source/dac.cpp | 84 ++++++++--------- source/dac.hpp | 22 ++++- source/elf_load.cpp | 8 +- source/elf_load.hpp | 6 +- source/main.cpp | 92 ++++++++++--------- source/usbserial.cpp | 66 +++++++------- source/usbserial.hpp | 19 ++-- 10 files changed, 297 insertions(+), 281 deletions(-) diff --git a/gui/wxmain.cpp b/gui/wxmain.cpp index cdbc06d..2629701 100644 --- a/gui/wxmain.cpp +++ b/gui/wxmain.cpp @@ -69,16 +69,15 @@ MainFrame::MainFrame() : wxFrame(nullptr, wxID_ANY, "stmdspgui", wxPoint(50, 50) auto comp = new wxButton(panelToolbar, Id::MCodeCompile, "Compile"); static const wxString srateValues[] = { "16 kS/s", + "20 kS/s", + "32 kS/s", "48 kS/s", - "96 kS/s", - "100 kS/s", - "200 kS/s", - "1 MS/s", - "2 MS/s" + "60 kS/s", + "96 kS/s" }; m_rate_select = new wxComboBox(panelToolbar, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, - 7, srateValues, wxCB_READONLY); + 6, srateValues, wxCB_READONLY); m_rate_select->Disable(); sizerToolbar->Add(comp, 0, wxLEFT, 4); @@ -410,7 +409,6 @@ void MainFrame::onRunConnect(wxCommandEvent& ce) delete m_device; m_device = nullptr; - m_rate_select->Disable(); menuItem->SetItemLabel("&Connect"); m_status_bar->SetStatusText("Failed to connect."); } @@ -420,6 +418,7 @@ void MainFrame::onRunConnect(wxCommandEvent& ce) } else { delete m_device; m_device = nullptr; + m_rate_select->Disable(); menuItem->SetItemLabel("&Connect"); m_status_bar->SetStatusText("Disconnected."); } diff --git a/source/adc.cpp b/source/adc.cpp index c8da25f..c8d97af 100644 --- a/source/adc.cpp +++ b/source/adc.cpp @@ -11,19 +11,17 @@ #include "adc.hpp" -constexpr static const auto adcd = &ADCD1; -constexpr static const auto gptd = &GPTD6; +ADCDriver *ADC::m_driver = &ADCD1; +GPTDriver *ADC::m_timer = &GPTD6; -constexpr static const ADCConfig adc_config = { +const ADCConfig ADC::m_config = { .difsel = 0 }; -static void adc_read_callback(ADCDriver *); - -static ADCConversionGroup adc_group_config = { - .circular = false, +ADCConversionGroup ADC::m_group_config = { + .circular = true, .num_channels = 1, - .end_cb = adc_read_callback, + .end_cb = ADC::conversionCallback, .error_cb = nullptr, .cfgr = ADC_CFGR_EXTEN_RISING | ADC_CFGR_EXTSEL_SRC(13), /* TIM4_TRGO */ .cfgr2 = 0,//ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_0 | ADC_CFGR2_OVSS_1, // Oversampling 2x @@ -37,132 +35,111 @@ static ADCConversionGroup adc_group_config = { } }; -constexpr static const GPTConfig gpt_config = { +const GPTConfig ADC::m_timer_config = { .frequency = 36000000, .callback = nullptr, .cr2 = TIM_CR2_MMS_1, /* TRGO */ .dier = 0 }; -#define ADC_CCR_PRESC_DIV1 (0) -#define ADC_SAMPLE_RATE_SETTINGS_COUNT (7) -static uint32_t adc_sample_rate_settings[] = { - // Rate PLLSAI2N ADC_PRESC ADC_SMPR GPT_DIV - /* 16k */ 8, ADC_CCR_PRESC_DIV10, ADC_SMPR_SMP_12P5, 2250, - /* 48k */ 24, ADC_CCR_PRESC_DIV10, ADC_SMPR_SMP_12P5, 750, - /* 96k */ 48, ADC_CCR_PRESC_DIV10, ADC_SMPR_SMP_12P5, 375, - /* 100k */ 40, ADC_CCR_PRESC_DIV8, ADC_SMPR_SMP_12P5, 360, - /* 400k */ 40, ADC_CCR_PRESC_DIV2, ADC_SMPR_SMP_12P5, 90, - /* 1M */ 38, ADC_CCR_PRESC_DIV1, ADC_SMPR_SMP_6P5, 36, - /* 2M */ 76, ADC_CCR_PRESC_DIV1, ADC_SMPR_SMP_6P5, 18 -}; +std::array, 6> ADC::m_rate_presets = {{ + // Rate PLLSAI2N ADC_PRESC ADC_SMPR GPT_DIV + {/* 16k */ 8, ADC_CCR_PRESC_DIV10, ADC_SMPR_SMP_12P5, 2250}, + {/* 20k */ 10, ADC_CCR_PRESC_DIV10, ADC_SMPR_SMP_12P5, 1800}, + {/* 32k */ 16, ADC_CCR_PRESC_DIV10, ADC_SMPR_SMP_12P5, 1125}, + {/* 48k */ 24, ADC_CCR_PRESC_DIV10, ADC_SMPR_SMP_12P5, 750}, + {/* 60k */ 30, ADC_CCR_PRESC_DIV10, ADC_SMPR_SMP_12P5, 600}, + {/* 96k */ 48, ADC_CCR_PRESC_DIV10, ADC_SMPR_SMP_12P5, 375} +}}; -static bool adc_is_read_finished = false; -static adcsample_t *adc_current_buffer = nullptr; -static size_t adc_current_buffer_size = 0; -static adc::operation_t adc_operation_func = nullptr; -static unsigned int adc_gpt_divisor = 1; +adcsample_t *ADC::m_current_buffer = nullptr; +size_t ADC::m_current_buffer_size = 0; +ADC::Operation ADC::m_operation = nullptr; -namespace adc +unsigned int ADC::m_timer_divisor = 2; + +void ADC::begin() { - void init() - { - palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG); - - gptStart(gptd, &gpt_config); - adcStart(adcd, &adc_config); - adcSTM32EnableVREF(adcd); - - set_rate(rate::R96K); - } + palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG); - void set_rate(rate new_rate) - { - auto index = static_cast(new_rate); - auto plln = adc_sample_rate_settings[index * 4] << RCC_PLLSAI2CFGR_PLLSAI2N_Pos; - auto presc = adc_sample_rate_settings[index * 4 + 1] << ADC_CCR_PRESC_Pos; - auto smp = adc_sample_rate_settings[index * 4 + 2]; - adc_gpt_divisor = adc_sample_rate_settings[index * 4 + 3]; - - adcStop(adcd); - - // Adjust PLLSAI2 - RCC->CR &= ~(RCC_CR_PLLSAI2ON); - while ((RCC->CR & RCC_CR_PLLSAI2RDY) == RCC_CR_PLLSAI2RDY); - RCC->PLLSAI2CFGR = (RCC->PLLSAI2CFGR & ~(RCC_PLLSAI2CFGR_PLLSAI2N_Msk)) | plln; - RCC->CR |= RCC_CR_PLLSAI2ON; - - // Set ADC prescaler - adcd->adcc->CCR = (adcd->adcc->CCR & ~(ADC_CCR_PRESC_Msk)) | presc; - // Set sampling time - adc_group_config.smpr[0] = ADC_SMPR1_SMP_AN5(smp); - adcStart(adcd, &adc_config); - } - - unsigned int get_rate() - { - for (unsigned int i = 0; i < ADC_SAMPLE_RATE_SETTINGS_COUNT; i++) { - if (adc_gpt_divisor == adc_sample_rate_settings[i * 3 + 3]) - return i; - } - - return 0xFF; - } + adcStart(m_driver, &m_config); + adcSTM32EnableVREF(m_driver); + gptStart(m_timer, &m_timer_config); - unsigned int get_gpt_divisor() - { - return adc_gpt_divisor; - } - - adcsample_t *read(adcsample_t *buffer, size_t count) - { - adc_is_read_finished = false; - adc_group_config.circular = false; - adcStartConversion(adcd, &adc_group_config, buffer, count); - gptStartContinuous(gptd, adc_gpt_divisor); - while (!adc_is_read_finished); - return buffer; - } + setRate(Rate::R96K); +} - void read_start(operation_t operation_func, adcsample_t *buffer, size_t count) - { - adc_current_buffer = buffer; - adc_current_buffer_size = count; - adc_operation_func = operation_func; - adc_group_config.circular = true; - adcStartConversion(adcd, &adc_group_config, buffer, count); - gptStartContinuous(gptd, adc_gpt_divisor); - } +void ADC::start(adcsample_t *buffer, size_t count, Operation operation) +{ + m_current_buffer = buffer; + m_current_buffer_size = count; + m_operation = operation; - void read_set_operation_func(operation_t operation_func) - { - adc_operation_func = operation_func; - } - - void read_stop() - { - gptStopTimer(gptd); - adcStopConversion(adcd); - adc_group_config.circular = false; - adc_current_buffer = nullptr; - adc_current_buffer_size = 0; - adc_operation_func = nullptr; + adcStartConversion(m_driver, &m_group_config, buffer, count); + gptStartContinuous(m_timer, m_timer_divisor); +} + +void ADC::stop() +{ + gptStopTimer(m_timer); + adcStopConversion(m_driver); + + m_current_buffer = nullptr; + m_current_buffer_size = 0; + m_operation = nullptr; +} + +void ADC::setRate(ADC::Rate rate) +{ + auto& preset = m_rate_presets[static_cast(rate)]; + auto plln = preset[0] << RCC_PLLSAI2CFGR_PLLSAI2N_Pos; + auto presc = preset[1] << ADC_CCR_PRESC_Pos; + auto smp = preset[2]; + m_timer_divisor = preset[3]; + + adcStop(m_driver); + + // Adjust PLLSAI2 + RCC->CR &= ~(RCC_CR_PLLSAI2ON); + while ((RCC->CR & RCC_CR_PLLSAI2RDY) == RCC_CR_PLLSAI2RDY); + RCC->PLLSAI2CFGR = (RCC->PLLSAI2CFGR & ~(RCC_PLLSAI2CFGR_PLLSAI2N_Msk)) | plln; + RCC->CR |= RCC_CR_PLLSAI2ON; + // Set ADC prescaler + m_driver->adcc->CCR = (m_driver->adcc->CCR & ~(ADC_CCR_PRESC_Msk)) | presc; + // Set sampling time + m_group_config.smpr[0] = ADC_SMPR1_SMP_AN5(smp); + + adcStart(m_driver, &m_config); +} + +void ADC::setOperation(ADC::Operation operation) +{ + m_operation = operation; +} + +int ADC::getRate() +{ + for (unsigned int i = 0; i < m_rate_presets.size(); i++) { + if (m_timer_divisor == m_rate_presets[i][3]) + return i; } + + return -1; +} + +unsigned int ADC::getTimerDivisor() +{ + return m_timer_divisor; } -void adc_read_callback(ADCDriver *driver) +void ADC::conversionCallback(ADCDriver *driver) { - if (adc_group_config.circular) { - if (adc_operation_func != nullptr) { - auto half_size = adc_current_buffer_size / 2; - if (adcIsBufferComplete(driver)) - adc_operation_func(adc_current_buffer + half_size, half_size); - else - adc_operation_func(adc_current_buffer, half_size); - } - } else { - gptStopTimer(gptd); - adc_is_read_finished = true; + if (m_operation != nullptr) { + auto half_size = m_current_buffer_size / 2; + if (adcIsBufferComplete(driver)) + m_operation(m_current_buffer + half_size, half_size); + else + m_operation(m_current_buffer, half_size); } } diff --git a/source/adc.hpp b/source/adc.hpp index 1431aa1..a739059 100644 --- a/source/adc.hpp +++ b/source/adc.hpp @@ -14,29 +14,52 @@ #include "hal.h" -namespace adc +#include + +class ADC { - using operation_t = void (*)(adcsample_t *buffer, size_t count); +public: + using Operation = void (*)(adcsample_t *buffer, size_t count); - enum class rate : unsigned int { + enum class Rate : int { + //R8K = 0, R16K = 0, + R20K, + R32K, R48K, - R96K, - R100K, - R400K, - R1M, - R2M + R60K, + R96K }; - void init(); - void set_rate(rate new_rate); - unsigned int get_rate(); - unsigned int get_gpt_divisor(); - adcsample_t *read(adcsample_t *buffer, size_t count); - void read_start(operation_t operation_func, adcsample_t *buffer, size_t count); - void read_set_operation_func(operation_t operation_func); - void read_stop(); -} + static void begin(); + + static void start(adcsample_t *buffer, size_t count, Operation operation); + static void stop(); + + static void setRate(Rate rate); + static void setOperation(Operation operation); + + static int getRate(); + static unsigned int getTimerDivisor(); + +private: + static ADCDriver *m_driver; + static GPTDriver *m_timer; + + static const ADCConfig m_config; + static /*const*/ ADCConversionGroup m_group_config; + static const GPTConfig m_timer_config; + + static std::array, 6> m_rate_presets; + + static adcsample_t *m_current_buffer; + static size_t m_current_buffer_size; + static Operation m_operation; + + static unsigned int m_timer_divisor; + + static void conversionCallback(ADCDriver *); +}; #endif // STMDSP_ADC_HPP_ diff --git a/source/dac.cpp b/source/dac.cpp index ed4dce1..ed08461 100644 --- a/source/dac.cpp +++ b/source/dac.cpp @@ -9,67 +9,63 @@ * If not, see . */ -#include "adc.hpp" +#include "adc.hpp" // ADC::getTimerDivisor #include "dac.hpp" -constexpr static const auto dacd = &DACD1; -constexpr static const auto dacd2 = &DACD2; -constexpr static const auto gptd = &GPTD7; +DACDriver *DAC::m_driver[2] = { + &DACD1, &DACD2 +}; +GPTDriver *DAC::m_timer = &GPTD7; +int DAC::m_timer_user_count = 0; -constexpr static const DACConfig dac_config = { +const DACConfig DAC::m_config = { .init = 0, .datamode = DAC_DHRM_12BIT_RIGHT, .cr = 0 }; -constexpr static const DACConversionGroup dac_group_config = { - .num_channels = 1, - .end_cb = nullptr, - .error_cb = nullptr, - .trigger = DAC_TRG(2) +const DACConversionGroup DAC::m_group_config = { + .num_channels = 1, + .end_cb = nullptr, + .error_cb = nullptr, + .trigger = DAC_TRG(2) }; -constexpr static const GPTConfig gpt_config = { - .frequency = 36000000, - .callback = nullptr, - .cr2 = TIM_CR2_MMS_1, /* TRGO */ - .dier = 0 +const GPTConfig DAC::m_timer_config = { + .frequency = 36000000, + .callback = nullptr, + .cr2 = TIM_CR2_MMS_1, /* TRGO */ + .dier = 0 }; -static unsigned int dacs_running = 0; - -namespace dac +void DAC::begin() { - void init() - { - palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); - palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); - - dacStart(dacd, &dac_config); - dacStart(dacd2, &dac_config); - gptStart(gptd, &gpt_config); - } + palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); - void write_start(unsigned int channel, dacsample_t *buffer, size_t count) - { - if (channel < 2) { - dacStartConversion(channel == 0 ? dacd : dacd2, &dac_group_config, buffer, count); + dacStart(m_driver[0], &m_config); + dacStart(m_driver[1], &m_config); + gptStart(m_timer, &m_timer_config); +} - if (dacs_running == 0) - gptStartContinuous(gptd, adc::get_gpt_divisor()); - dacs_running |= 1 << channel; - } +void DAC::start(int channel, dacsample_t *buffer, size_t count) +{ + if (channel >= 0 && channel < 2) { + dacStartConversion(m_driver[channel], &m_group_config, buffer, count); + + if (m_timer_user_count == 0) + gptStartContinuous(m_timer, ADC::getTimerDivisor()); + m_timer_user_count++; } - - void write_stop(unsigned int channel) - { - if (channel < 2) { - dacStopConversion(channel == 0 ? dacd : dacd2); +} + +void DAC::stop(int channel) +{ + if (channel >= 0 && channel < 2) { + dacStopConversion(m_driver[channel]); - dacs_running &= ~(1 << channel); - if (dacs_running == 0) - gptStopTimer(gptd); - } + if (--m_timer_user_count == 0) + gptStopTimer(m_timer); } } diff --git a/source/dac.hpp b/source/dac.hpp index dec1b36..542b4a1 100644 --- a/source/dac.hpp +++ b/source/dac.hpp @@ -13,13 +13,25 @@ #define STMDSP_DAC_HPP_ #include "hal.h" +#undef DAC -namespace dac +class DAC { - void init(); - void write_start(unsigned int channel, dacsample_t *buffer, size_t count); - void write_stop(unsigned int channel); -} +public: + static void begin(); + + static void start(int channel, dacsample_t *buffer, size_t count); + static void stop(int channel); + +private: + static DACDriver *m_driver[2]; + static GPTDriver *m_timer; + static int m_timer_user_count; + + static const DACConfig m_config; + static const DACConversionGroup m_group_config; + static const GPTConfig m_timer_config; +}; #endif // STMDSP_DAC_HPP_ diff --git a/source/elf_load.cpp b/source/elf_load.cpp index 79cd4fe..0e41d6a 100644 --- a/source/elf_load.cpp +++ b/source/elf_load.cpp @@ -23,9 +23,9 @@ constexpr static auto ptr_from_offset(void *base, uint32_t offset) return reinterpret_cast(reinterpret_cast(base) + offset); } -namespace elf { +namespace ELF { -entry_t load(void *elf_data) +Entry load(void *elf_data) { // Check the ELF's header signature auto ehdr = reinterpret_cast(elf_data); @@ -54,8 +54,8 @@ entry_t load(void *elf_data) } - return loaded ? reinterpret_cast(ehdr->e_entry) : nullptr; + return loaded ? reinterpret_cast(ehdr->e_entry) : nullptr; } -} // namespace elf +} // namespace ELF diff --git a/source/elf_load.hpp b/source/elf_load.hpp index faa74d2..619dada 100644 --- a/source/elf_load.hpp +++ b/source/elf_load.hpp @@ -15,11 +15,11 @@ #include #include -namespace elf +namespace ELF { - using entry_t = uint16_t *(*)(uint16_t *, size_t); + using Entry = uint16_t *(*)(uint16_t *, size_t); - entry_t load(void *elf_data); + Entry load(void *elf_data); } #endif // ELF_LOAD_HPP_ diff --git a/source/main.cpp b/source/main.cpp index 8948b8e..f635953 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -22,7 +22,7 @@ constexpr unsigned int MAX_ELF_FILE_SIZE = 8 * 1024; constexpr unsigned int MAX_ERROR_QUEUE_SIZE = 8; constexpr unsigned int MAX_SAMPLE_BUFFER_SIZE = 6000; // operate on buffers size this / 2 -constexpr unsigned int MAX_SIGGEN_BUFFER_SIZE = 3000; +constexpr unsigned int MAX_SIGGEN_BUFFER_SIZE = MAX_SAMPLE_BUFFER_SIZE / 2; enum class RunStatus : char { @@ -84,8 +84,8 @@ CC_ALIGN(CACHE_LINE_SIZE) #endif static std::array dac2_samples; -static uint8_t elf_file_store[MAX_ELF_FILE_SIZE]; -static elf::entry_t elf_entry = nullptr; +static unsigned char elf_file_store[MAX_ELF_FILE_SIZE]; +static ELF::Entry elf_entry = nullptr; static void signal_operate(adcsample_t *buffer, size_t count); static void signal_operate_measure(adcsample_t *buffer, size_t count); @@ -104,9 +104,9 @@ int main() palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL); palClearPad(GPIOA, 5); - adc::init(); - dac::init(); - usbserial::init(); + ADC::begin(); + DAC::begin(); + USBSerial::begin(); // Start the conversion manager thread chTMObjectInit(&conversion_time_measurement); @@ -125,22 +125,24 @@ void main_loop() { while (1) { - if (usbserial::is_active()) { + if (USBSerial::isActive()) { // Attempt to receive a command packet - if (char cmd[3]; usbserial::read(&cmd, 1) > 0) { + if (unsigned char cmd[3]; USBSerial::read(&cmd[0], 1) > 0) { // Packet received, first byte represents the desired command/action switch (cmd[0]) { case 'a': - usbserial::write(adc_samples.data(), adc_sample_count * sizeof(adcsample_t)); + USBSerial::write((uint8_t *)adc_samples.data(), + adc_sample_count * sizeof(adcsample_t)); break; case 'A': - usbserial::read(&adc_samples[0], adc_sample_count * sizeof(adcsample_t)); + USBSerial::read((uint8_t *)&adc_samples[0], + adc_sample_count * sizeof(adcsample_t)); break; case 'B': if (run_status == RunStatus::Idle) { - if (usbserial::read(&cmd[1], 2) == 2) { + if (USBSerial::read(&cmd[1], 2) == 2) { unsigned int count = cmd[1] | (cmd[2] << 8); if (count <= MAX_SAMPLE_BUFFER_SIZE / 2) { adc_sample_count = count * 2; @@ -157,14 +159,16 @@ void main_loop() break; case 'd': - usbserial::write(dac_samples.data(), dac_sample_count * sizeof(dacsample_t)); + USBSerial::write((uint8_t *)dac_samples.data(), + dac_sample_count * sizeof(dacsample_t)); break; case 'D': - if (usbserial::read(&cmd[1], 2) == 2) { + if (USBSerial::read(&cmd[1], 2) == 2) { unsigned int count = cmd[1] | (cmd[2] << 8); if (count <= MAX_SIGGEN_BUFFER_SIZE) { dac2_sample_count = count; - usbserial::read(&dac2_samples[0], dac2_sample_count * sizeof(dacsample_t)); + USBSerial::read((uint8_t *)&dac2_samples[0], + dac2_sample_count * sizeof(dacsample_t)); } else { error_queue_add(Error::BadParam); } @@ -176,12 +180,12 @@ void main_loop() // 'E' - Reads in and loads the compiled conversion code binary from USB. case 'E': if (run_status == RunStatus::Idle) { - if (usbserial::read(&cmd[1], 2) == 2) { + if (USBSerial::read(&cmd[1], 2) == 2) { // Only load the binary if it can fit in the memory reserved for it. unsigned int size = cmd[1] | (cmd[2] << 8); if (size < sizeof(elf_file_store)) { - usbserial::read(elf_file_store, size); - elf_entry = elf::load(elf_file_store); + USBSerial::read(elf_file_store, size); + elf_entry = ELF::load(elf_file_store); if (elf_entry == nullptr) error_queue_add(Error::BadUserCodeLoad); @@ -203,17 +207,17 @@ void main_loop() // 'i' - Sends an identifying string to confirm that this is the stmdsp device. case 'i': - usbserial::write("stmdsp", 6); + USBSerial::write((uint8_t *)"stmdsp", 6); break; // 'I' - Sends the current run status. case 'I': { - char buf[2] = { - static_cast(run_status), - static_cast(error_queue_pop()) + unsigned char buf[2] = { + static_cast(run_status), + static_cast(error_queue_pop()) }; - usbserial::write(buf, sizeof(buf)); + USBSerial::write(buf, sizeof(buf)); } break; @@ -223,8 +227,8 @@ void main_loop() if (run_status == RunStatus::Idle) { run_status = RunStatus::Running; dac_samples.fill(0); - adc::read_start(signal_operate_measure, &adc_samples[0], adc_sample_count); - dac::write_start(0, &dac_samples[0], dac_sample_count); + ADC::start(&adc_samples[0], adc_sample_count, signal_operate_measure); + DAC::start(0, &dac_samples[0], dac_sample_count); } else { error_queue_add(Error::NotIdle); } @@ -233,7 +237,7 @@ void main_loop() // 'm' - Returns the last measured sample processing time, presumably in processor // ticks. case 'm': - usbserial::write(&conversion_time_measurement.last, sizeof(rtcnt_t)); + USBSerial::write((uint8_t *)&conversion_time_measurement.last, sizeof(rtcnt_t)); break; // 'R' - Begin continuous sampling/conversion of the ADC. Samples will go through @@ -242,20 +246,20 @@ void main_loop() if (run_status == RunStatus::Idle) { run_status = RunStatus::Running; dac_samples.fill(0); - adc::read_start(signal_operate, &adc_samples[0], adc_sample_count); - dac::write_start(0, &dac_samples[0], dac_sample_count); + ADC::start(&adc_samples[0], adc_sample_count, signal_operate); + DAC::start(0, &dac_samples[0], dac_sample_count); } else { error_queue_add(Error::NotIdle); } break; case 'r': - if (usbserial::read(&cmd[1], 1) == 1) { + if (USBSerial::read(&cmd[1], 1) == 1) { if (cmd[1] == 0xFF) { - unsigned char r = static_cast(adc::get_rate()); - usbserial::write(&r, 1); + unsigned char r = static_cast(ADC::getRate()); + USBSerial::write(&r, 1); } else { - adc::set_rate(static_cast(cmd[1])); + ADC::setRate(static_cast(cmd[1])); } } else { error_queue_add(Error::BadParamSize); @@ -265,8 +269,8 @@ void main_loop() // 'S' - Stops the continuous sampling/conversion. case 'S': if (run_status == RunStatus::Running) { - dac::write_stop(0); - adc::read_stop(); + DAC::stop(0); + ADC::stop(); run_status = RunStatus::Idle; } break; @@ -281,28 +285,28 @@ void main_loop() static_cast(dac_sample_count / 2 & 0xFF), static_cast(((dac_sample_count / 2) >> 8) & 0xFF) }; - usbserial::write(buf, 2); + USBSerial::write(buf, 2); unsigned int total = dac_sample_count / 2 * sizeof(dacsample_t); unsigned int offset = 0; unsigned char unused; while (total > 512) { - usbserial::write(samps + offset, 512); - while (usbserial::read(&unused, 1) == 0); + USBSerial::write(samps + offset, 512); + while (USBSerial::read(&unused, 1) == 0); offset += 512; total -= 512; } - usbserial::write(samps + offset, total); - while (usbserial::read(&unused, 1) == 0); + USBSerial::write(samps + offset, total); + while (USBSerial::read(&unused, 1) == 0); } else { - usbserial::write("\0\0", 2); + USBSerial::write((uint8_t *)"\0\0", 2); } break; case 'W': - dac::write_start(1, &dac2_samples[0], dac2_sample_count); + DAC::start(1, &dac2_samples[0], dac2_sample_count); break; case 'w': - dac::write_stop(1); + DAC::stop(1); break; default: @@ -318,8 +322,8 @@ void main_loop() void conversion_abort() { elf_entry = nullptr; - dac::write_stop(0); - adc::read_stop(); + DAC::stop(0); + ADC::stop(); error_queue_add(Error::ConversionAborted); } @@ -380,7 +384,7 @@ void signal_operate(adcsample_t *buffer, [[maybe_unused]] size_t count) void signal_operate_measure(adcsample_t *buffer, [[maybe_unused]] size_t count) { chMBPostI(&conversionMB, buffer == &adc_samples[0] ? MSG_CONVFIRST_MEASURE : MSG_CONVSECOND_MEASURE); - adc::read_set_operation_func(signal_operate); + ADC::setOperation(signal_operate); } extern "C" { diff --git a/source/usbserial.cpp b/source/usbserial.cpp index ec2fc5d..c24be2f 100644 --- a/source/usbserial.cpp +++ b/source/usbserial.cpp @@ -11,42 +11,42 @@ #include "usbserial.hpp" -#include "usbcfg.h" +SerialUSBDriver *USBSerial::m_driver = &SDU1; -constexpr static const auto sdud = &SDU1; +void USBSerial::begin() +{ + palSetPadMode(GPIOA, 11, PAL_MODE_ALTERNATE(10)); + palSetPadMode(GPIOA, 12, PAL_MODE_ALTERNATE(10)); + + sduObjectInit(m_driver); + sduStart(m_driver, &serusbcfg); + + // Reconnect bus so device can re-enumerate on reset + usbDisconnectBus(serusbcfg.usbp); + chThdSleepMilliseconds(1500); + usbStart(serusbcfg.usbp, &usbcfg); + usbConnectBus(serusbcfg.usbp); +} -namespace usbserial +bool USBSerial::isActive() { - void init() - { - palSetPadMode(GPIOA, 11, PAL_MODE_ALTERNATE(10)); - palSetPadMode(GPIOA, 12, PAL_MODE_ALTERNATE(10)); - - sduObjectInit(sdud); - sduStart(sdud, &serusbcfg); - - // Reconnect bus so device can re-enumerate on reset - usbDisconnectBus(serusbcfg.usbp); - chThdSleepMilliseconds(1500); - usbStart(serusbcfg.usbp, &usbcfg); - usbConnectBus(serusbcfg.usbp); - } - - bool is_active() - { - return sdud->config->usbp->state == USB_ACTIVE; - } - - size_t read(void *buffer, size_t count) - { - auto bss = reinterpret_cast(sdud); - return streamRead(bss, static_cast(buffer), count); - } - - size_t write(const void *buffer, size_t count) - { - auto bss = reinterpret_cast(sdud); - return streamWrite(bss, static_cast(buffer), count); + if (auto config = m_driver->config; config != nullptr) { + if (auto usbp = config->usbp; usbp != nullptr) + return usbp->state == USB_ACTIVE; } + + return false; +} + +size_t USBSerial::read(unsigned char *buffer, size_t count) +{ + auto bss = reinterpret_cast(m_driver); + return streamRead(bss, buffer, count); +} + +size_t USBSerial::write(const unsigned char *buffer, size_t count) +{ + auto bss = reinterpret_cast(m_driver); + return streamWrite(bss, buffer, count); } diff --git a/source/usbserial.hpp b/source/usbserial.hpp index 4c33d51..828fc56 100644 --- a/source/usbserial.hpp +++ b/source/usbserial.hpp @@ -12,16 +12,21 @@ #ifndef STMDSP_USBSERIAL_HPP_ #define STMDSP_USBSERIAL_HPP_ -#include "hal.h" +#include "usbcfg.h" -namespace usbserial +class USBSerial { - void init(); - bool is_active(); +public: + static void begin(); - size_t read(void *buffer, size_t count); - size_t write(const void *buffer, size_t count); -} + static bool isActive(); + + static size_t read(unsigned char *buffer, size_t count); + static size_t write(const unsigned char *buffer, size_t count); + +private: + static SerialUSBDriver *m_driver; +}; #endif // STMDSP_USBSERIAL_HPP_