Added one channel mode

Dependents:   CW_Decoder_using_FFT_on_F446

Fork of F446_AD_DA by 不韋 呂

Files at this revision

API Documentation at this revision

Comitter:
kenjiArai
Date:
Sun Feb 05 07:59:14 2017 +0000
Parent:
3:d1da91aec62f
Commit message:
added one channel mode (only A0/PA_0 input)

Changed in this revision

F446_ADC.cpp Show annotated file Show diff for this revision Revisions of this file
F446_ADC.hpp Show annotated file Show diff for this revision Revisions of this file
F446_ADC_Interrupt.hpp Show annotated file Show diff for this revision Revisions of this file
--- a/F446_ADC.cpp	Mon Jan 30 08:12:44 2017 +0000
+++ b/F446_ADC.cpp	Sun Feb 05 07:59:14 2017 +0000
@@ -9,6 +9,14 @@
 //
 //  2016/11/12, Copyright (c) 2016 MIKAMI, Naoki
 //----------------------------------------------------------
+/*
+ *  Modified by Kenji Arai
+ *      http://www.page.sannet.ne.jp/kenjia/index.html
+ *      http://mbed.org/users/kenjiArai/
+ *
+ *      Started:  Feburary  1st, 2017
+ *      Revised:  Feburary  1st, 2017
+ */
 
 #include "F446_ADC.hpp"
 
@@ -89,4 +97,73 @@
         myTim->PSC = psc;           // Prescaler
         myTim->CR1 = TIM_CR1_CEN;   // Enable TIM8
     }
+
+//------------------------------------------------------------------------------
+
+    AdcSingle::AdcSingle(int frequency)
+    {
+        // ADC input is assigned PA0
+        __HAL_RCC_GPIOA_CLK_ENABLE();
+        GPIO_InitTypeDef gpioInit;
+        gpioInit.Pin = GPIO_PIN_0;
+        gpioInit.Mode = GPIO_MODE_ANALOG;
+        gpioInit.Pull = GPIO_NOPULL;
+        gpioInit.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+        HAL_GPIO_Init(GPIOA, &gpioInit);
+
+        // ADC2 (port:PA0)
+        __HAL_RCC_ADC2_CLK_ENABLE();
+        ADC2->CR1 = 0x0;
+        ADC2->CR2 = ADC_EXTERNALTRIGCONVEDGE_RISING // Ext. trigger + rising eggde
+                  | ADC_EXTERNALTRIGCONV_T8_TRGO    // Ext. trigger Timer8 TRGO event
+                  | ADC_CR2_ADON;                   // ADC を有効にする
+        ADC2->SQR3 = 0x0;                           // CH0 を使う
+        
+        // ADC 共通の設定
+        ADC->CCR = 0x0;     // 念のため
+
+        // AD 変換器の外部トリガに使うタイマ (TIM8) の設定
+        SetTim8(frequency);
+    }
+
+    void AdcSingle::Read(float &ad)
+    {
+        WaitDone();
+        ad = ToFloat(ADC2->DR);
+    }
+
+    void AdcSingle::Read(uint16_t &ad)
+    {
+        WaitDone();
+        ad = ADC2->DR;
+    }
+
+    void AdcSingle::SetTim8(int frequency)
+    {
+        __HAL_RCC_TIM8_CLK_ENABLE();    // Supply clock. See "stm32f4xx_hal_rcc.h"
+        SystemCoreClockUpdate();        // Update core clock. See "system_stm32f4xx.h"
+        TIM_TypeDef* const myTim = TIM8;
+
+        myTim->CR2 = TIM_CR2_MMS_1; // Update event: as trigger out
+
+    	uint32_t psc = 0;
+        uint16_t mul = 1;
+        uint32_t arr;
+        while (true)
+        {
+            arr = SystemCoreClock/(mul*frequency);
+            if (arr <= 65536) break;
+            psc++;
+            mul++;
+            if (psc > 65535)
+            {
+                fprintf(stderr, "Sampling frequency: too low.\r\n");
+                while (true) {}
+            }
+        }
+        myTim->ARR = arr - 1;       // Auto-reload
+        myTim->PSC = psc;           // Prescaler
+        myTim->CR1 = TIM_CR1_CEN;   // Enable TIM8
+    }
 }
+
--- a/F446_ADC.hpp	Mon Jan 30 08:12:44 2017 +0000
+++ b/F446_ADC.hpp	Sun Feb 05 07:59:14 2017 +0000
@@ -11,6 +11,14 @@
 //
 //  2017/01/30, Copyright (c) 2017 MIKAMI, Naoki
 //----------------------------------------------------------
+/*
+ *  Modified by Kenji Arai
+ *      http://www.page.sannet.ne.jp/kenjia/index.html
+ *      http://mbed.org/users/kenjiArai/
+ *
+ *      Started:  Feburary  1st, 2017
+ *      Revised:  Feburary  1st, 2017
+ */
 
 #include "mbed.h"
 
@@ -20,11 +28,11 @@
 
 #include "F446_DAC.hpp"
 
+namespace Mikami
+{
 #ifndef F446_ADC_DUAL_HPP
 #define F446_ADC_DUAL_HPP
 
-namespace Mikami
-{
     class AdcDual
     {
     public:
@@ -60,5 +68,44 @@
         // for inhibition of substitute operator
         AdcDual& operator=(const AdcDual&);     
     };
+
+#endif  // F446_ADC_DUAL_HPP
+
+#ifndef F446_ADC_SINGLE_HPP
+#define F446_ADC_SINGLE_HPP
+
+    class AdcSingle
+    {
+    public:
+        // Constructor
+        //      frequency: sampling frequency
+        explicit AdcSingle(int frequency);
+
+        virtual void Read(float &ad);
+
+        virtual void Read(uint16_t &ad);
+
+    protected:
+        float ToFloat(uint16_t x)
+        {   return AMP_*(x - 2048); }
+    
+    private:
+        static const float AMP_ = 1.0f/2048.0f;
+        static const uint32_t EOC2_ = ADC_CSR_EOC2;
+        
+        // waiting ADC conversion
+        void WaitDone()
+        {   while((ADC->CSR & EOC2_) != EOC2_); }
+
+        // Set timer(TIM() for trigger for ADC
+        void SetTim8(int frequency);
+
+        // for inhibition of copy constructor
+        AdcSingle(const AdcSingle&);
+        // for inhibition of substitute operator
+        AdcSingle& operator=(const AdcSingle&);     
+    };
+
+#endif  // F446_ADC_SINGLE_HPP
 }
-#endif  // F446_ADC_DUAL_HPP
+
--- a/F446_ADC_Interrupt.hpp	Mon Jan 30 08:12:44 2017 +0000
+++ b/F446_ADC_Interrupt.hpp	Sun Feb 05 07:59:14 2017 +0000
@@ -9,13 +9,14 @@
 //  2016/11/12, Copyright (c) 2016 MIKAMI, Naoki
 //----------------------------------------------------------
 
-#ifndef F446_ADC_DUAL_INTERRUPT_HPP
-#define F446_ADC_DUAL_INTERRUPT_HPP
-
 #include "F446_ADC.hpp"
 
 namespace Mikami
 {
+
+#ifndef F446_ADC_DUAL_INTERRUPT_HPP
+#define F446_ADC_DUAL_INTERRUPT_HPP
+
     class AdcDual_Intr : public AdcDual
     {
     public:
@@ -52,5 +53,47 @@
         // for inhibition of substitute operator
         AdcDual_Intr& operator=(const AdcDual_Intr&);     
     };
+
+#endif  // F446_ADC_DUAL_INTERRUPT_HPP
+
+//------------------------------------------------------------------------------
+
+#ifndef F446_ADC_SINGLE_INTERRUPT_HPP
+#define F446_ADC_SINGLE_INTERRUPT_HPP
+
+    class AdcSingle_Intr : public AdcSingle
+    {
+    public:
+        AdcSingle_Intr(int frequency) : AdcSingle(frequency)
+        {   ADC2->CR1 |= ADC_CR1_EOCIE; }
+
+        virtual void Read(float &ad)
+        {
+            ad = ToFloat(ADC2->DR);
+        }
+
+        virtual void Read(uint16_t &ad)
+        {
+            ad = ADC2->DR;
+        }
+
+        // Set interrupt vector and enable IRQ of ADC
+        void SetIntrVec(void (*Func)())
+        {
+            NVIC_SetVector(ADC_IRQn, (uint32_t)Func);   // See "cmsis_nvic.h"
+            NVIC_EnableIRQ(ADC_IRQn);                   // See "core_cm4.h"
+        }
+        
+        void DisableAdcIntr()
+        {   NVIC_DisableIRQ(ADC_IRQn); }
+        
+    private:
+        // for inhibition of copy constructor
+        AdcSingle_Intr(const AdcSingle_Intr&);
+        // for inhibition of substitute operator
+        AdcSingle_Intr& operator=(const AdcSingle_Intr&);     
+    };
+#endif  // F446_ADC_SINGLE_INTERRUPT_HPP
+
 }
-#endif  // F446_ADC_DUAL_INTERRUPT_HPP
+