不韋 呂 / UITDSP_ADDA2

Dependents:   UITDSP_ADDA_Example2

InternalADC.hpp

Committer:
MikamiUitOpen
Date:
2015-03-16
Revision:
1:e997f4e94491

File content as of revision 1:e997f4e94491:

//--------------------------------------------------------------
//  Class for Internal ADC using Ticker for trigger -- Header
//
//  2015/02/23, Copyright (c) 2015 MIKAMI, Naoki
//--------------------------------------------------------------

#ifndef INTERNAL_ADC_HPP
#define INTERNAL_ADC_HPP

#include "mbed.h"

namespace Mikami
{
    class InternalADC
    {
    private:
        // Following object of AnalogIn class will be
        // initialized by menber initializer
        AnalogIn adc_;
        // Following two objects of AnalogIn class will be
        // initailized by regular executable statements
        AnalogIn* adc2_;
        AnalogIn* adc3_;
        
        Ticker timer_;

        // Channel of ADC1
        uint8_t ch1_, ch2_, ch3_;

        // Exctract channel number
        uint8_t GetChannelNumber(PinName pin)
        {
            uint8_t ch = 0;
            if ((pin & 0x30) == 0x00) ch = pin;
            if ((pin & 0x30) == 0x10) ch = (pin & 0x01) + 8;
            if ((pin & 0x30) == 0x20) ch = (pin & 0x07) + 10;
            return ch;
        }

        // for inhibition of copy constructor
        InternalADC(const InternalADC&);
        // for inhibition of substitute operator
        InternalADC& operator=(const InternalADC&);

    protected:
        // for normalize   
        static const float AMP_ = 1.0f/2048.0f;

        ADC_TypeDef* const myAdc_;

        // Wait until completion of AD conversion
        void WaitDone()
        { while((myAdc_->SR & ADC_SR_EOC) == RESET); }

    public:

        // Constructor
        //      pin1:       Pin Name for input as A0, A1, etc.
        //      pin2:       If use 2nd channel set this parameter
        //      pin3:       If use 3rd channel set this parameter
        InternalADC(PinName pin1, PinName pin2 = NC, PinName pin3 = NC);
                 
        // Set sampling period, specifiying the period in micro-seconds
        void SetSamplingPeriod(int us)
        {   timer_.attach_us(this, &InternalADC::SoftStart, us); }
        
        // Read ADC with waiting, range: [0, 0x0FFF]
        virtual uint16_t Read_u16()
        {
            WaitDone();
            return myAdc_->DR;   
        }

        // Read ADC with waiting, range: [-1.0f, 1.0f]
        virtual float Read()
        {
            WaitDone();
            return AMP_*((int16_t)myAdc_->DR - 2048);
        }

        // Select channel
        void Select1stChannel() { myAdc_->SQR3 = ch1_; }
        void Select2ndChannel()
        {
            if (adc2_ == NULL)
            {
                fprintf(stderr, "\r\n2nd channel is not assigned to any pin.\r\n");
                return;
            }
            myAdc_->SQR3 = ch2_;
        }
        void Select3rdChannel()
        {
            if (adc3_ == NULL)
            {
                fprintf(stderr, "\r\n3rd channel is not assigned to any pin.\r\n");
                return;
            }
            myAdc_->SQR3 = ch3_;
        }
        
        // Software start
        void SoftStart()
        {   myAdc_->CR2 |= ADC_CR2_SWSTART; }
        
        uint32_t ReadSQR3() { return myAdc_->SQR3; }
    };
}
#endif  // INTERNAL_ADC_HPP