1 /*!
2  * \file      adc-board.c
3  *
4  * \brief     Target board ADC driver implementation
5  *
6  * \copyright Revised BSD License, see section \ref LICENSE.
7  *
8  * \code
9  *                ______                              _
10  *               / _____)             _              | |
11  *              ( (____  _____ ____ _| |_ _____  ____| |__
12  *               \____ \| ___ |    (_   _) ___ |/ ___)  _ \
13  *               _____) ) ____| | | || |_| ____( (___| | | |
14  *              (______/|_____)_|_|_| \__)_____)\____)_| |_|
15  *              (C)2013-2017 Semtech
16  *
17  * \endcode
18  *
19  * \author    Miguel Luis ( Semtech )
20  *
21  * \author    Gregory Cristian ( Semtech )
22  */
23 #include "stm32l4xx.h"
24 #include "board-config.h"
25 #include "adc-board.h"
26 
27 //
28 // DEFINED HERE UP UNTIL THE HAL DRIVERS AREN'T UPDATED
29 //
30 /**
31   * @brief Disable the ADC peripheral.
32   * @param __HANDLE__ ADC handle.
33   * @retval None
34   */
35 #define ADC_DISABLE(__HANDLE__)                                          \
36   do{                                                                          \
37          (__HANDLE__)->Instance->CR |= ADC_CR_ADDIS;                           \
38           __HAL_ADC_CLEAR_FLAG((__HANDLE__), (ADC_FLAG_EOSMP | ADC_FLAG_RDY)); \
39   } while(0)
40 
41 ADC_HandleTypeDef AdcHandle;
42 
AdcMcuInit(Adc_t * obj,PinNames adcInput)43 void AdcMcuInit( Adc_t *obj, PinNames adcInput )
44 {
45     AdcHandle.Instance = ADC1;
46 
47     __HAL_RCC_ADC_CLK_ENABLE( );
48 
49     HAL_ADC_DeInit( &AdcHandle );
50 
51     if( adcInput != NC )
52     {
53         GpioInit( &obj->AdcInput, adcInput, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
54     }
55 }
56 
AdcMcuConfig(void)57 void AdcMcuConfig( void )
58 {
59     // Configure ADC
60     AdcHandle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV1;
61     AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;
62     AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
63     AdcHandle.Init.ContinuousConvMode    = DISABLE;
64     AdcHandle.Init.DiscontinuousConvMode = DISABLE;
65     AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;
66     AdcHandle.Init.ExternalTrigConv      = ADC_SOFTWARE_START;
67     AdcHandle.Init.DMAContinuousRequests = DISABLE;
68     AdcHandle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;
69     AdcHandle.Init.NbrOfConversion       = 1;
70     AdcHandle.Init.LowPowerAutoWait      = DISABLE;
71     HAL_ADC_Init( &AdcHandle );
72 }
73 
AdcMcuReadChannel(Adc_t * obj,uint32_t channel)74 uint16_t AdcMcuReadChannel( Adc_t *obj, uint32_t channel )
75 {
76     ADC_ChannelConfTypeDef adcConf = { 0 };
77     uint16_t adcData = 0;
78 
79     // Enable HSI
80     __HAL_RCC_HSI_ENABLE( );
81 
82     // Wait till HSI is ready
83     while( __HAL_RCC_GET_FLAG( RCC_FLAG_HSIRDY ) == RESET )
84     {
85     }
86 
87     __HAL_RCC_ADC_CLK_ENABLE( );
88 
89     // Calibrate ADC if any calibraiton hardware
90     HAL_ADCEx_Calibration_Start( &AdcHandle, ADC_SINGLE_ENDED );
91 
92     adcConf.Channel = channel;
93     adcConf.Rank = ADC_REGULAR_RANK_1;
94     adcConf.SamplingTime = ADC_SAMPLETIME_92CYCLES_5;
95 
96     HAL_ADC_ConfigChannel( &AdcHandle, &adcConf );
97 
98     // Start ADC Software Conversion
99     HAL_ADC_Start( &AdcHandle );
100 
101     HAL_ADC_PollForConversion( &AdcHandle, HAL_MAX_DELAY );
102 
103     adcData = HAL_ADC_GetValue( &AdcHandle );
104 
105     ADC_DISABLE( &AdcHandle );
106 
107     __HAL_RCC_ADC_CLK_DISABLE( );
108 
109     // Disable HSI
110     __HAL_RCC_HSI_DISABLE( );
111 
112     return adcData;
113 }
114