]> code.bitgloo.com Git - clyne/stmdsp.git/commitdiff
untested port cleanup; add sclock; up cpu to 480M
authorClyne Sullivan <clyne@bitgloo.com>
Sat, 23 Jan 2021 14:59:11 +0000 (09:59 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Sat, 23 Jan 2021 14:59:11 +0000 (09:59 -0500)
ChibiOS_20.3.2/os/hal/ports/STM32/STM32H7xx/hal_lld.h
cfg/mcuconf.h
source/adc.cpp
source/adc.hpp
source/dac.cpp
source/dac.hpp
source/main.cpp
source/sclock.cpp [new file with mode: 0644]
source/sclock.hpp [new file with mode: 0644]

index b1b9a427483d923eb41e2d4203824f49d9226011..af36372af3aa50dc9cc962b1cfd6bf89d45432ee 100644 (file)
 /**\r
  * @brief   PLL1 DIVP field.\r
  */\r
-#if ((STM32_PLL1_DIVP_VALUE >= 2) && (STM32_PLL1_DIVP_VALUE <= 128) &&      \\r
-     ((STM32_PLL1_DIVP_VALUE & 1U) == 0U)) ||                               \\r
+#if ((STM32_PLL1_DIVP_VALUE >= 1) && (STM32_PLL1_DIVP_VALUE <= 128) &&      \\r
+     ((STM32_PLL1_DIVP_VALUE & 1U) == 0U || STM32_PLL1_DIVP_VALUE == 1)) || \\r
     defined(__DOXYGEN__)\r
 #define STM32_PLL1_DIVP             ((STM32_PLL1_DIVP_VALUE - 1U) << 9U)\r
 #else\r
index 98da3a7c1c48da1f43ede704cc147b5e39c2762c..af176adda9438e9c4a927239a776479e1c1bcea5 100644 (file)
@@ -71,7 +71,7 @@
 #define STM32_HSI48_ENABLED                 TRUE\r
 #define STM32_HSE_ENABLED                   FALSE\r
 #define STM32_LSE_ENABLED                   FALSE\r
-#define STM32_HSIDIV                        STM32_HSIDIV_DIV8 // 8\r
+#define STM32_HSIDIV                        STM32_HSIDIV_DIV8 // HSI = 8MHz\r
 \r
 /*\r
  * PLLs static settings.\r
 #define STM32_PLL1_P_ENABLED                TRUE\r
 #define STM32_PLL1_Q_ENABLED                FALSE\r
 #define STM32_PLL1_R_ENABLED                FALSE\r
-#define STM32_PLL1_DIVM_VALUE               4   // 2\r
-#define STM32_PLL1_DIVN_VALUE               384 // 2(384)\r
+#define STM32_PLL1_DIVM_VALUE               4   // 8 / 4 = 2MHz\r
+#define STM32_PLL1_DIVN_VALUE               240 // = 2 * 240\r
 #define STM32_PLL1_FRACN_VALUE              0\r
-#define STM32_PLL1_DIVP_VALUE               2   // 384\r
+#define STM32_PLL1_DIVP_VALUE               1   // = 480MHz\r
 #define STM32_PLL1_DIVQ_VALUE               16\r
 #define STM32_PLL1_DIVR_VALUE               8\r
-#define STM32_PLL2_ENABLED                  TRUE\r
+#define STM32_PLL2_ENABLED                  TRUE  // PLL2 adjusted by adc.cpp\r
 #define STM32_PLL2_P_ENABLED                TRUE\r
 #define STM32_PLL2_Q_ENABLED                FALSE\r
 #define STM32_PLL2_R_ENABLED                FALSE\r
 #define STM32_PLL2_DIVM_VALUE               4\r
-#define STM32_PLL2_DIVN_VALUE               384\r
+#define STM32_PLL2_DIVN_VALUE               80\r
 #define STM32_PLL2_FRACN_VALUE              0\r
-#define STM32_PLL2_DIVP_VALUE               32\r
+#define STM32_PLL2_DIVP_VALUE               20\r
 #define STM32_PLL2_DIVQ_VALUE               8\r
 #define STM32_PLL2_DIVR_VALUE               8\r
 #define STM32_PLL3_ENABLED                  FALSE\r
 #define STM32_SW                            STM32_SW_PLL1_P_CK\r
 #define STM32_RTCSEL                        STM32_RTCSEL_LSI_CK\r
 #define STM32_D1CPRE                        STM32_D1CPRE_DIV1\r
-#define STM32_D1HPRE                        STM32_D1HPRE_DIV2\r
+#define STM32_D1HPRE                        STM32_D1HPRE_DIV2  // /2 = 240MHz\r
 #define STM32_D1PPRE3                       STM32_D1PPRE3_DIV2\r
-#define STM32_D2PPRE1                       STM32_D2PPRE1_DIV2 // 192\r
+#define STM32_D2PPRE1                       STM32_D2PPRE1_DIV2\r
 #define STM32_D2PPRE2                       STM32_D2PPRE2_DIV2\r
 #define STM32_D3PPRE4                       STM32_D3PPRE4_DIV2\r
 \r
 #define STM32_ADC_ADC3_IRQ_PRIORITY         5\r
 #define STM32_ADC_ADC12_CLOCK_MODE          ADC_CCR_CKMODE_AHB_DIV4\r
 #define STM32_ADC_ADC3_CLOCK_MODE           ADC_CCR_CKMODE_ADCCK\r
-#define STM32_ADC_ADC3_PRESC                (5 << ADC_CCR_PRESC_Pos) // div10\r
+#define STM32_ADC_ADC3_PRESC                (5 << ADC_CCR_PRESC_Pos) // /10\r
 \r
 /*\r
  * CAN driver system settings.\r
  */\r
 #define STM32_DAC_DUAL_MODE                 FALSE\r
 #define STM32_DAC_USE_DAC1_CH1              TRUE\r
-#define STM32_DAC_USE_DAC1_CH2              FALSE\r
+#define STM32_DAC_USE_DAC1_CH2              TRUE\r
 #define STM32_DAC_DAC1_CH1_IRQ_PRIORITY     10\r
 #define STM32_DAC_DAC1_CH2_IRQ_PRIORITY     10\r
 #define STM32_DAC_DAC1_CH1_DMA_PRIORITY     2\r
index a830017efdd1451683a72700ec4f105bafecebd6..ab06410b405b19972023f99bd1c7ee795c68f7b1 100644 (file)
 #include "adc.hpp"
 
 ADCDriver *ADC::m_driver = &ADCD3;
-GPTDriver *ADC::m_timer = &GPTD6;
 
 const ADCConfig ADC::m_config = {
     .difsel = 0,
     .calibration = 0,
 };
 
-ADCConversionGroup ADC::m_group_config = {
+const ADCConversionGroup ADC::m_group_config = {
     .circular = true,
     .num_channels = 1,
     .end_cb = ADC::conversionCallback,
     .error_cb = nullptr,
     .cfgr = ADC_CFGR_EXTEN_RISING | ADC_CFGR_EXTSEL_SRC(13),  /* TIM6_TRGO */
-    .cfgr2 = 0,//ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_0 | ADC_CFGR2_OVSS_1, // Oversampling 2x
+    .cfgr2 = ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_0 | ADC_CFGR2_OVSS_1, // Oversampling 2x
     .ccr = 0,
     .pcsel = 0,
     .ltr1 = 0, .htr1 = 0x0FFF,
@@ -40,38 +39,28 @@ ADCConversionGroup ADC::m_group_config = {
     },
 };
 
-const GPTConfig ADC::m_timer_config = {
-    .frequency = 4800000,
-    .callback = nullptr,
-    .cr2 = TIM_CR2_MMS_1, /* TRGO */
-    .dier = 0
-};
-
-std::array<std::array<uint32_t, 4>, 6> ADC::m_rate_presets = {{
-     // Rate   PLLSAI2N  R  OVERSAMPLE 2x?  GPT_DIV
-    {/* 8k  */ 16,       3, 1,              4500},
-    {/* 16k */ 32,       3, 1,              2250},
-    {/* 20k */ 40,       3, 1,              1800},
-    {/* 32k */ 64,       3, 1,              1125},
-    {/* 48k */ 24,       3, 0,               750},
-    {/* 96k */ 48,       3, 0,               375}
+std::array<std::array<uint32_t, 2>, 6> ADC::m_rate_presets = {{
+     // Rate   PLL N  PLL P
+    {/* 8k  */ 80,    20},
+    {/* 16k */ 80,    10},
+    {/* 20k */ 80,    8},
+    {/* 32k */ 80,    5},
+    {/* 48k */ 96,    4},
+    {/* 96k */ 96,    2}
 }};
 
 adcsample_t *ADC::m_current_buffer = nullptr;
 size_t ADC::m_current_buffer_size = 0;
 ADC::Operation ADC::m_operation = nullptr;
 
-unsigned int ADC::m_timer_divisor = 50;
-
 void ADC::begin()
 {
     palSetPadMode(GPIOF, 3, PAL_MODE_INPUT_ANALOG);
 
     adcStart(m_driver, &m_config);
     adcSTM32EnableVREF(m_driver);
-    gptStart(m_timer, &m_timer_config);
 
-    //setRate(Rate::R32K);
+    setRate(SClock::Rate::R32K);
 }
 
 void ADC::start(adcsample_t *buffer, size_t count, Operation operation)
@@ -81,12 +70,12 @@ void ADC::start(adcsample_t *buffer, size_t count, Operation operation)
     m_operation = operation;
 
     adcStartConversion(m_driver, &m_group_config, buffer, count);
-    gptStartContinuous(m_timer, m_timer_divisor);
+    SClock::start();
 }
 
 void ADC::stop()
 {
-    gptStopTimer(m_timer);
+    SClock::stop();
     adcStopConversion(m_driver);
 
     m_current_buffer = nullptr;
@@ -94,27 +83,25 @@ void ADC::stop()
     m_operation = nullptr;
 }
 
-void ADC::setRate(ADC::Rate rate)
+void ADC::setRate(SClock::Rate rate)
 {
-//    auto& preset = m_rate_presets[static_cast<int>(rate)];
-//    auto pllnr = (preset[0] << RCC_PLLSAI2CFGR_PLLSAI2N_Pos) |
-//                 (preset[1] << RCC_PLLSAI2CFGR_PLLSAI2R_Pos);
-//    bool oversample = preset[2] != 0;
-//    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 | RCC_PLLSAI2CFGR_PLLSAI2R_Msk)) | pllnr;
-//    RCC->CR |= RCC_CR_PLLSAI2ON;
-//    while ((RCC->CR & RCC_CR_PLLSAI2RDY) != RCC_CR_PLLSAI2RDY);
-//
-//    // Set 2x oversampling
-//    m_group_config.cfgr2 = oversample ? ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_0 | ADC_CFGR2_OVSS_1 : 0;
-//
-//    adcStart(m_driver, &m_config);
+    auto& preset = m_rate_presets[static_cast<unsigned int>(rate)];
+    auto pllbits = (preset[0] << RCC_PLL2DIVR_N2_Pos) |
+                   (preset[1] << RCC_PLL2DIVR_P2_Pos);
+
+    adcStop(m_driver);
+
+    // Adjust PLL2
+    RCC->CR &= ~(RCC_CR_PLL2ON);
+    while ((RCC->CR & RCC_CR_PLL2RDY) == RCC_CR_PLL2RDY);
+    auto pll2divr = RCC->PLL2DIVR &
+                    ~(RCC_PLL2DIVR_N2_Msk | RCC_PLL2DIVR_P2_Msk);
+    pll2divr |= pllbits;
+    RCC->PLL2DIVR = pll2divr;
+    RCC->CR |= RCC_CR_PLL2ON;
+    while ((RCC->CR & RCC_CR_PLL2RDY) != RCC_CR_PLL2RDY);
+
+    adcStart(m_driver, &m_config);
 }
 
 void ADC::setOperation(ADC::Operation operation)
@@ -122,21 +109,6 @@ 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::conversionCallback(ADCDriver *driver)
 {
     if (m_operation != nullptr) {
index 5f9dc23fe8fcc87cf94b37d3622e9033aa3c0ccd..96fe506a619eb6b97d3ed72f08bb07c4436a32b3 100644 (file)
@@ -13,6 +13,7 @@
 #define STMDSP_ADC_HPP_
 
 #include "hal.h"
+#include "sclock.hpp"
 
 #include <array>
 
@@ -21,42 +22,26 @@ class ADC
 public:
     using Operation = void (*)(adcsample_t *buffer, size_t count);
 
-    enum class Rate : int {
-        R8K = 0,
-        R16K,
-        R20K,
-        R32K,
-        R48K,
-        R96K
-    };
-    
     static void begin();
 
     static void start(adcsample_t *buffer, size_t count, Operation operation);
     static void stop();
 
-    static void setRate(Rate rate);
+    static void setRate(SClock::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 const ADCConversionGroup m_group_config;
 
-    static std::array<std::array<uint32_t, 4>, 6> m_rate_presets;
+    static std::array<std::array<uint32_t, 2>, 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 *);
 };
 
index 283d8a9ba21920cab6ba1a91d537394bad497d3c..2116dcb277fbafbd73eea18a5b98e0d24d91ffb8 100644 (file)
@@ -9,14 +9,12 @@
  * If not, see <https://www.gnu.org/licenses/>.
  */
 
-#include "adc.hpp" // ADC::getTimerDivisor
 #include "dac.hpp"
+#include "sclock.hpp"
 
 DACDriver *DAC::m_driver[2] = {
-    &DACD1, nullptr/*&DACD2*/
+    &DACD1, &DACD2
 };
-GPTDriver *DAC::m_timer = nullptr;//&GPTD7;
-int DAC::m_timer_user_count = 0;
 
 const DACConfig DAC::m_config = {
     .init = 0,
@@ -28,14 +26,7 @@ const DACConversionGroup DAC::m_group_config = {
     .num_channels = 1,
     .end_cb = nullptr,
     .error_cb = nullptr,
-    .trigger = 5
-};
-
-const GPTConfig DAC::m_timer_config = {
-    .frequency = 4800000,
-    .callback = nullptr,
-    .cr2 = TIM_CR2_MMS_1, /* TRGO */
-    .dier = 0
+    .trigger = 5 // TIM6_TRGO
 };
 
 void DAC::begin()
@@ -44,28 +35,22 @@ void DAC::begin()
     palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG);
 
     dacStart(m_driver[0], &m_config);
-    //dacStart(m_driver[1], &m_config);
-    //gptStart(m_timer, &m_timer_config);
+    dacStart(m_driver[1], &m_config);
 }
 
 void DAC::start(int channel, dacsample_t *buffer, size_t count)
 {
-    if (channel >= 0 && channel < 1) {
+    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++;
+        SClock::start();
     }
 }
 
 void DAC::stop(int channel)
 {
-    if (channel >= 0 && channel < 1) {
+    if (channel >= 0 && channel < 2) {
         dacStopConversion(m_driver[channel]);
-
-        //if (--m_timer_user_count == 0)
-        //    gptStopTimer(m_timer);
+        SClock::stop();
     }
 }
 
index 542b4a14f90748288e1835d317d80d7126b1c19e..e305c4be9fcc017e2c4956b17957a496e6f40546 100644 (file)
@@ -25,12 +25,9 @@ public:
 
 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 639f45546e4c25a7f0303bc55d7a04ad0fc5ec0f..bb980d0ba09006fedc85c60200371420068b8fb1 100644 (file)
@@ -21,6 +21,7 @@ static_assert(sizeof(dacsample_t) == sizeof(uint16_t));
 #include "adc.hpp"\r
 #include "dac.hpp"\r
 #include "elf_load.hpp"\r
+#include "sclock.hpp"\r
 #include "usbserial.hpp"\r
 \r
 #include <array>\r
@@ -206,10 +207,12 @@ void main_loop()
                 case 'r':\r
                     if (EM.assert(USBSerial::read(&cmd[1], 1) == 1, Error::BadParamSize)) {\r
                         if (cmd[1] == 0xFF) {\r
-                            unsigned char r = static_cast<unsigned char>(ADC::getRate());\r
+                            unsigned char r = SClock::getRate();\r
                             USBSerial::write(&r, 1);\r
                         } else {\r
-                            ADC::setRate(static_cast<ADC::Rate>(cmd[1]));\r
+                            auto r = static_cast<SClock::Rate>(cmd[1]);\r
+                            SClock::setRate(r);\r
+                            ADC::setRate(r);\r
                         }\r
                     }\r
                     break;\r
diff --git a/source/sclock.cpp b/source/sclock.cpp
new file mode 100644 (file)
index 0000000..795274d
--- /dev/null
@@ -0,0 +1,54 @@
+#include "sclock.hpp"
+
+GPTDriver *SClock::m_timer = &GPTD6;
+unsigned int SClock::m_div = 1;
+unsigned int SClock::m_runcount = 0;
+
+const GPTConfig SClock::m_timer_config = {
+    .frequency = 4800000,
+    .callback = nullptr,
+    .cr2 = TIM_CR2_MMS_1, /* TRGO */
+    .dier = 0
+};
+
+const std::array<unsigned int, 6> SClock::m_rate_divs = {{
+    /* 8k  */ 600,
+    /* 16k */ 300,
+    /* 20k */ 240,
+    /* 32k */ 150,
+    /* 48k */ 100,
+    /* 96k */ 50
+}};
+
+void SClock::begin()
+{
+    gptStart(m_timer, &m_timer_config);
+}
+
+void SClock::start()
+{
+    if (m_runcount++ == 0)
+        gptStartContinuous(m_timer, m_div);
+}
+
+void SClock::stop()
+{
+    if (--m_runcount == 0)
+        gptStopTimer(m_timer);
+}
+
+void SClock::setRate(SClock::Rate rate)
+{
+    m_div = m_rate_divs[static_cast<unsigned int>(rate)];
+}
+
+unsigned int SClock::getRate()
+{
+    for (unsigned int i = 0; i < m_rate_divs.size(); ++i) {
+        if (m_rate_divs[i] == m_div)
+            return i;
+    }
+
+    return static_cast<unsigned int>(-1);
+}
+
diff --git a/source/sclock.hpp b/source/sclock.hpp
new file mode 100644 (file)
index 0000000..960d9e3
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef SCLOCK_HPP_
+#define SCLOCK_HPP_
+
+#include "hal.h"
+
+#include <array>
+
+class SClock
+{
+public:
+    enum class Rate : unsigned int {
+        R8K = 0,
+        R16K,
+        R20K,
+        R32K,
+        R48K,
+        R96K
+    };
+
+    static void begin();
+    static void start();
+    static void stop();
+
+    static void setRate(Rate rate);
+    static unsigned int getRate();
+
+private:
+    static GPTDriver *m_timer;
+    static unsigned int m_div;
+    static unsigned int m_runcount;
+    static const GPTConfig m_timer_config;
+    static const std::array<unsigned int, 6> m_rate_divs;
+};
+
+#endif // SCLOCK_HPP_
+