#ifndef _ADC_H_
#define _ADC_H_
//----------------------------------------------------------------------------
///
/// \brief  Just a simple adc
///
///         See implementation for further information.
///
/// \date   20121125
/// \author Maximilian Seesslen <development@seesslen.net>
///
//----------------------------------------------------------------------------


//---Includes-----------------------------------------------------------------


//---Own------------------------------


//---Forward declarations-----------------------------------------------------


#if defined (MCU_PLATFORM_STM32)
   #define ADC_HANDLE_TYPE    ADC_HandleTypeDef
   #include <HALWrapper/stm32_dma.h>       // SPI wants that
   #include <HALWrapper/stm32_adc.h>
#else
   #define ADC_HANDLE_TYPE    void
#endif

#include <stdint.h>


//---Declaration--------------------------------------------------------------


extern int adcKeeper;

typedef int32_t temperature_t;

/*
enum EAdcChannel
{
   eAdcChannelNone=0,
   eAdcChannel0=1,
   eAdcChannel1,
   eAdcChannel2,
   eAdcChannel3,
   eAdcChannel4,
   eAdcChannel5,
   eAdcChannel6,
   eAdcChannel7,
   eAdcChannel8,
   eAdcChannel9,
   eAdcChannel10,
   eAdcChannel11,
   eAdcChannel12,
   eAdcChannel13,
   eAdcChannel14,
   eAdcChannel15,
   eAdcChannelTemperature,
   eAdcChannelVBat,
   eAdcChannelVRef,
};
*/
typedef uint32_t EAdcChannel;

/* STMF3 headers start with ADC_CHANNEL_1 which is actually channel 0
 * according to pin naming and datasheet. This might change in future stm
 * software releases.
 * Other MCU revisions start at ADC_CHANNEL_0 which is ok.
 */
#if ! defined ( ADC_CHANNEL_0 )
   #define eAdcChannelNone    ADC_CHANNEL_1
   #define eAdcChannel0       ADC_CHANNEL_1
   #define eAdcChannel1       ADC_CHANNEL_2
   #define eAdcChannel2       ADC_CHANNEL_3
   #define eAdcChannel3       ADC_CHANNEL_4
   #define eAdcChannel4       ADC_CHANNEL_5
   #define eAdcChannel5       ADC_CHANNEL_6
   #define eAdcChannel6       ADC_CHANNEL_7
   #define eAdcChannel7       ADC_CHANNEL_8
   #define eAdcChannel8       ADC_CHANNEL_9
   #define eAdcChannel9       ADC_CHANNEL_10
   #define eAdcChannel10      ADC_CHANNEL_11
   #define eAdcChannel11      ADC_CHANNEL_12
   #define eAdcChannel12      ADC_CHANNEL_13
   #define eAdcChannel13      ADC_CHANNEL_14
   #define eAdcChannel14      ADC_CHANNEL_15
   #define eAdcChannel15      ADC_CHANNEL_16
#else
   #define eAdcChannelNone    ADC_CHANNEL_0
   #define eAdcChannel0       ADC_CHANNEL_0
   #define eAdcChannel1       ADC_CHANNEL_1
   #define eAdcChannel2       ADC_CHANNEL_2
   #define eAdcChannel3       ADC_CHANNEL_3
   #define eAdcChannel4       ADC_CHANNEL_4
   #define eAdcChannel5       ADC_CHANNEL_5
   #define eAdcChannel6       ADC_CHANNEL_6
   #define eAdcChannel7       ADC_CHANNEL_7
   #define eAdcChannel8       ADC_CHANNEL_8
   #define eAdcChannel9       ADC_CHANNEL_9
   #define eAdcChannel10      ADC_CHANNEL_10
   #define eAdcChannel11      ADC_CHANNEL_11
   #define eAdcChannel12      ADC_CHANNEL_12
   #define eAdcChannel13      ADC_CHANNEL_13
   #define eAdcChannel14      ADC_CHANNEL_14
   #define eAdcChannel15      ADC_CHANNEL_15
   #define eAdcChannel16      ADC_CHANNEL_16
#endif
#define eAdcChannelTemperature   ADC_CHANNEL_TEMPSENSOR
#define eAdcChannelVBat          ADC_CHANNEL_VBAT
#define eAdcChannelVRef          ADC_CHANNEL_VREFINT

#define channelEnumToDefine(pin) (pin)

//#if defined ( ADC_CHANNEL_TEMPSENSOR )
//[eAdcChannelTemperature]=ADC_CHANNEL_TEMPSENSOR,
//#else
//[eAdcChannelTemperature]=0,
//#endif
//#if defined ( ADC_CHANNEL_VBAT )
//    [eAdcChannelVBat]=ADC_CHANNEL_VBAT,
//#else
//    [eAdcChannelVBat]=0,
//#endif
//    [eAdcChannelVRef]=ADC_CHANNEL_VREFINT,
//};


struct SAdcConfig;
/*{
   ADC_TypeDef* instance;
   IRQn_Type irqn;
};
*/

class CAdc
{

    private:
         //const SAdcConfig &m_configData;
         //temperature_t m_temperature;
         //int m_vRef;
         EAdcChannel currentChannel=-1;
         ADC_HANDLE_TYPE *m_pHandler;
         //uint32_t m_adcValue;

    public:
         CAdc( const SAdcConfig &configData );
        ~CAdc();

        int initAdcInjection();
        int configChannel( EAdcChannel channel );
        int switchChannel( EAdcChannel channel );
        void addChannel( EAdcChannel channel );
        int getAdcValue();
        temperature_t getTemperature();
        int getVRef();
        //bool isAdc(EAdc _eAdc)
        // { return(eAdc==_eAdc); }
        // from CInterrupt:
        void interrupt();
        temperature_t calculateTemperature();
        int calculateVRef();
        int accuireAdcValue();

        int updateTemperature();
        static int calculateTemperature(int tempRaw, int vRefRaw);

      ADC_HANDLE_TYPE *getHandler()
      {
         return(m_pHandler);
      }

         #if ! STM32
         void setAdcValue( int value);
         #endif

};


//---fin----------------------------------------------------------------------
#endif // ? ! _ADC_H_
