]> code.bitgloo.com Git - clyne/stmdsp.git/commitdiff
firmware reorganize; added more sample rates
authorClyne Sullivan <clyne@bitgloo.com>
Thu, 12 Nov 2020 14:45:16 +0000 (09:45 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Thu, 12 Nov 2020 14:45:16 +0000 (09:45 -0500)
gui/wxmain.cpp
source/adc.cpp
source/adc.hpp
source/dac.cpp
source/dac.hpp
source/elf_load.cpp
source/elf_load.hpp
source/main.cpp
source/usbserial.cpp
source/usbserial.hpp

index cdbc06d05e6b98829f2258ccfb42b82badd4bcd3..26297019ef8e44364893b933cb502738a248f01b 100644 (file)
@@ -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.");
     }
index c8da25ff8277cc7a69a423991c2d0f84f525f7ba..c8d97afc0c20e7487359920506757f8e22fb1b84 100644 (file)
 
 #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<std::array<uint32_t, 4>, 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<unsigned int>(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<int>(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);
     }
 }
 
index 1431aa11bd6d9da8f27d214129b3f112972f2cab..a7390599f9226fc586663ccda8a281872f1b7e9a 100644 (file)
 
 #include "hal.h"
 
-namespace adc
+#include <array>
+
+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<std::array<uint32_t, 4>, 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_
 
index ed4dce167f6c8f3fc883f670a945b5492bcc19f6..ed08461748793f10b037f2cbc01b4c6b5e3119d0 100644 (file)
@@ -9,67 +9,63 @@
  * If not, see <https://www.gnu.org/licenses/>.
  */
 
-#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);
     }
 }
 
index dec1b36aac0499a76be3a9e4328cf6f693a8d744..542b4a14f90748288e1835d317d80d7126b1c19e 100644 (file)
 #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_
 
index 79cd4feccf680cbe28f270037865dbfac6aff7a6..0e41d6aedf9a95d258605146cbe43e0c0f7705c6 100644 (file)
@@ -23,9 +23,9 @@ constexpr static auto ptr_from_offset(void *base, uint32_t offset)
     return reinterpret_cast<T>(reinterpret_cast<uint8_t *>(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<Elf32_Ehdr *>(elf_data);
@@ -54,8 +54,8 @@ entry_t load(void *elf_data)
     }
 
 
-    return loaded ? reinterpret_cast<entry_t>(ehdr->e_entry) : nullptr;
+    return loaded ? reinterpret_cast<Entry>(ehdr->e_entry) : nullptr;
 }
 
-} // namespace elf
+} // namespace ELF
 
index faa74d236d545ba47fccfdefafb0120726bef6a6..619dada288dc3cb3a460730ebfca2709e8be836b 100644 (file)
 #include <cstddef>
 #include <cstdint>
 
-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_
index 8948b8e94206e957f9c204302adb2396940b99f2..f635953eecbaae59c086cce958be483598f744c0 100644 (file)
@@ -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<dacsample_t, CACHE_SIZE_ALIGN(dacsample_t, MAX_SIGGEN_BUFFER_SIZE)> 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<char>(run_status),
-                            static_cast<char>(error_queue_pop())
+                        unsigned char buf[2] = {
+                            static_cast<unsigned char>(run_status),
+                            static_cast<unsigned char>(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<unsigned char>(adc::get_rate());
-                            usbserial::write(&r, 1);
+                            unsigned char r = static_cast<unsigned char>(ADC::getRate());
+                            USBSerial::write(&r, 1);
                         } else {
-                            adc::set_rate(static_cast<adc::rate>(cmd[1]));
+                            ADC::setRate(static_cast<ADC::Rate>(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<unsigned char>(dac_sample_count / 2 & 0xFF),
                             static_cast<unsigned char>(((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" {
index ec2fc5d575a9fa12c46de62b40d15885f4d3d9f1..c24be2f15ae43d31137347861027731d7057e782 100644 (file)
 
 #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<BaseSequentialStream *>(sdud);
-        return streamRead(bss, static_cast<uint8_t *>(buffer), count);
-    }
-    
-    size_t write(const void *buffer, size_t count)
-    {
-        auto bss = reinterpret_cast<BaseSequentialStream *>(sdud);
-        return streamWrite(bss, static_cast<const uint8_t *>(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<BaseSequentialStream *>(m_driver);
+    return streamRead(bss, buffer, count);
+}
+
+size_t USBSerial::write(const unsigned char *buffer, size_t count)
+{
+    auto bss = reinterpret_cast<BaseSequentialStream *>(m_driver);
+    return streamWrite(bss, buffer, count);
 }
 
index 4c33d51072282dd0b214fc8cb08f8ecb09fbcc7f..828fc56ac7d52a333d15a875c1e5c77f02ca7065 100644 (file)
 #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_