1 /**
2 ******************************************************************************
3 * @file    HAL_comp.c
4 * @author  AE Team
5 * @version V1.0.0
6 * @date    02/08/2017
7 * @brief   This file provides firmware functions to manage the following
8 *          functionalities of the 2 analog comparators (COMP1, COMP2) peripheral:
9 *           + Comparators configuration
10 *           + Window mode control
11 *
12 @verbatim
13 
14 ==============================================================================
15 ##### COMP Peripheral features #####
16 ==============================================================================
17 [..]
18 The device integrates 2 analog comparators COMP1, COMP2:
19 (#) The non inverting input and inverting input can be set to GPIO pins
20 as shown in table1. COMP Inputs below.
21 
22 (#) The COMP output can be redirected to embedded timers (TIM1, TIM2, TIM3...)
23 Refer to table 2. COMP Outputs redirection to embedded timers below.
24 
25 (#) The seven comparators have interrupt capability with wake-up
26 from Sleep and Stop modes (through the EXTI controller):
27 (++) COMP1 is internally connected to EXTI Line 21
28 (++) COMP2 is internally connected to EXTI Line 22
29 
30 [..] Table 1. COMP Inputs
31 +--------------------------------------------------+
32 |                 |                | COMP1 | COMP2 |
33 |-----------------|----------------|---------------|
34 |                 | 1/4 VREFINT    |  OK   |  OK   |
35 |                 | 1/2 VREFINT    |  OK   |  OK   |
36 |                 | 3/4 VREFINT    |  OK   |  OK   |
37 | Inverting Input | VREFINT        |  OK   |  OK   |
38 |                 | DAC1 OUT (PA4) |  OK   |  OK   |
39 |                 | DAC2 OUT (PA5) |  OK   |  OK   |
40 |                 | IO1            |  PA0  |  PA2  |
41 |                 | IO2            |  PA6  |  PA6  |
42 |-----------------|----------------|-------|-------|
43 |  Non Inverting  | IO1            |  PA0  |  PA0  |
44 |    Input        | IO2            |  PA1  |  PA1  |
45 |    		         | IO3            |  PA2  |  PA2  |
46 |    		         | IO4            |  PA3  |  PA3  |
47 |    		         | IO5            |  PA4  |  PA4  |
48 |    		         | IO6            |  PA5  |  PA5  |
49 |    		         | IO7            |  PA6  |  PA6  |
50 |    		         | IO8            |  PA7  |  PA7  |
51 +--------------------------------------------------+
52 
53 
54 [..] Table 2. COMP Outputs redirection to embedded timers
55 +---------------------------------+
56 |     COMP1      |     COMP2      |
57 |----------------|----------------|
58 |  TIM1 BKIN     |  TIM1 BKIN     |
59 |                |                |
60 |  TIM1 OCREFCLR |  TIM1 OCREFCLR |
61 |                |                |
62 |  TIM1 IC1      |  TIM1 IC1      |
63 |                |                |
64 |  TIM2 IC4      |  TIM2 IC4      |
65 |                |                |
66 |  TIM2 OCREFCLR |  TIM2 OCREFCLR |
67 |                |                |
68 |  TIM3 IC1      |  TIM3 IC1      |
69 |                |                |
70 |  TIM3 OCREFCLR |  TIM3 OCREFCLR |
71 +---------------------------------+
72 
73 
74 ##### How to use this driver #####
75 ==============================================================================
76 [..]
77 This driver provides functions to configure and program the Comparators
78 of all microcontroller devices.
79 
80 To use the comparator, perform the following steps:
81 
82 (#) Enable the SYSCFG APB clock to get write access to comparator
83 register using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
84 
85 (#) Configure the comparator input in analog mode using GPIO_Init()
86 
87 (#) Configure the comparator output in alternate function mode
88 using GPIO_Init() and use GPIO_PinAFConfig() function to map the
89 comparator output to the GPIO pin
90 
91 (#) Configure the comparator using COMP_Init() function:
92 (++) Select the inverting input
93 (++) Select the non-inverting input
94 (++) Select the output polarity
95 (++) Select the output redirection
96 (++) Select the hysteresis level
97 (++) Select the power mode
98 
99 (#) Enable the comparator using COMP_Cmd() function
100 
101 (#) If required enable the COMP interrupt by configuring and enabling
102 EXTI line in Interrupt mode and selecting the desired sensitivity
103 level using EXTI_Init() function. After that enable the comparator
104 interrupt vector using NVIC_Init() function.
105 
106 @endverbatim
107 *
108 ******************************************************************************
109 * @attention
110 *
111 * <h2><center>&copy; COPYRIGHT 2015 MindMotion</center></h2>
112 *
113 *
114 * Unless required by applicable law or agreed to in writing, software
115 * distributed under the License is distributed on an "AS IS" BASIS,
116 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
117 * See the License for the specific language governing permissions and
118 * limitations under the License.
119 *
120 ******************************************************************************
121 */
122 
123 /* Includes ------------------------------------------------------------------*/
124 #include "HAL_comp.h"
125 
126 /** @addtogroup
127 * @{
128 */
129 
130 /** @defgroup COMP
131 * @brief COMP driver modules
132 * @{
133 */
134 
135 /* Private typedef -----------------------------------------------------------*/
136 /* Private define ------------------------------------------------------------*/
137 /* CSR register Mask */
138 #define COMP_CSR_CLEAR_MASK              ((uint32_t)0x00000003)
139 
140 /*!< COMPx output level */
141 #define COMP_CSR_COMPxOUT              ((uint32_t)0x40000000)
142 
143 /*!< COMPx lock */
144 #define COMP_CSR_COMPxLOCK             ((uint32_t)0x80000000)
145 
146 
147 /**********************  Bit definition for COMP_CSR register  ****************/
148 #define COMP_CSR_COMPxEN               ((uint32_t)0x00000001) /*!< COMPx enable */
149 #define COMP_CSR_COMP1SW1              ((uint32_t)0x00000002) /*!< COMP1 SW1 switch control */
150 #define COMP_CSR_COMPxMODE             ((uint32_t)0x0000000C) /*!< COMPx power mode */
151 
152 /* Private macro -------------------------------------------------------------*/
153 /* Private variables ---------------------------------------------------------*/
154 /* Private function prototypes -----------------------------------------------*/
155 /* Private functions ---------------------------------------------------------*/
156 
157 /** @defgroup COMP_Private_Functions
158 * @{
159 */
160 
161 /** @defgroup COMP_Group1 Initialization and Configuration functions
162 *  @brief   Initialization and Configuration functions
163 *
164 @verbatim
165 ===============================================================================
166 ##### Initialization and Configuration functions #####
167 ===============================================================================
168 
169 @endverbatim
170 * @{
171 */
172 
173 /**
174 * @brief  Deinitializes COMP peripheral registers to their default reset values.
175 * @note   Deinitialization can't be performed if the COMP configuration is locked.
176 *         To unlock the configuration, perform a system reset.
177 * @param  COMP_Selection: the selected comparator.
178 *          This parameter can be COMP_Selection_COMPx where x can be 1 to 7
179 *          to select the COMP peripheral.
180 * @param  None
181 * @retval None
182 */
COMP_DeInit(uint32_t COMP_Selection)183 void COMP_DeInit(uint32_t COMP_Selection)
184 {
185   /*!< Set COMP_CSR register to reset value */
186   *(__IO uint32_t *) (COMP_BASE + COMP_Selection) = ((uint32_t)0x00000000);
187 }
188 
189 /**
190 * @brief  Initializes the COMP peripheral according to the specified parameters
191 *         in COMP_InitStruct
192 * @note   If the selected comparator is locked, initialization can't be performed.
193 *         To unlock the configuration, perform a system reset.
194 * @note   By default, PA1 is selected as COMP1 non inverting input.
195 *         To use PA4 as COMP1 non inverting input call COMP_SwitchCmd() after COMP_Init()
196 * @param  COMP_Selection: the selected comparator.
197 *          This parameter can be COMP_Selection_COMPx where x can be 1 to 2
198 *          to select the COMP peripheral.
199 * @param  COMP_InitStruct: pointer to an COMP_InitTypeDef structure that contains
200 *         the configuration information for the specified COMP peripheral.
201 *           - COMP_InvertingInput specifies the inverting input of COMP
202 *           - COMP_NonInvertingInput specifies the non inverting input of COMP
203 *           - COMP_Output connect COMP output to selected timer
204 *             input (Input capture / Output Compare Reference Clear / Break Input)
205 *           - COMP_BlankingSrce specifies the blanking source of COMP
206 *           - COMP_OutputPol select output polarity
207 *           - COMP_Hysteresis configures COMP hysteresis value
208 *           - COMP_Mode configures COMP power mode
209 * @retval None
210 */
COMP_Init(uint32_t COMP_Selection,COMP_InitTypeDef * COMP_InitStruct)211 void COMP_Init(uint32_t COMP_Selection, COMP_InitTypeDef* COMP_InitStruct)
212 {
213   uint32_t tmpreg = 0;
214 
215   /* Check the parameters */
216   assert_param(IS_COMP_ALL_PERIPH(COMP_Selection));
217   assert_param(IS_COMP_INVERTING_INPUT(COMP_InitStruct->COMP_InvertingInput));
218   assert_param(IS_COMP_NONINVERTING_INPUT(COMP_InitStruct->COMP_NonInvertingInput));
219   assert_param(IS_COMP_OUTPUT(COMP_InitStruct->COMP_Output));
220   assert_param(IS_COMP_BLANKING_SOURCE(COMP_InitStruct->COMP_BlankingSrce));
221   assert_param(IS_COMP_OUTPUT_POL(COMP_InitStruct->COMP_OutputPol));
222   assert_param(IS_COMP_HYSTERESIS(COMP_InitStruct->COMP_Hysteresis));
223   assert_param(IS_COMP_MODE(COMP_InitStruct->COMP_Mode));
224 
225   /*!< Get the COMPx_CSR register value */
226   tmpreg = *(__IO uint32_t *) (COMP_BASE + COMP_Selection);
227 
228   /*!< Clear the COMP1SW1, COMPxINSEL, COMPxOUTSEL, COMPxPOL, COMPxHYST and COMPxMODE bits */
229   tmpreg &= (uint32_t) (COMP_CSR_CLEAR_MASK);
230 
231   /*!< Configure COMP: inverting input, output redirection, hysteresis value and power mode */
232   /*!< Set COMPxINSEL bits according to COMP_InitStruct->COMP_InvertingInput value */
233   /*!< Set COMPxNONINSEL bits according to COMP_InitStruct->COMP_NonInvertingInput value */
234   /*!< Set COMPxBLANKING bits according to COMP_InitStruct->COMP_BlankingSrce value */
235   /*!< Set COMPxOUTSEL bits according to COMP_InitStruct->COMP_Output value */
236   /*!< Set COMPxPOL bit according to COMP_InitStruct->COMP_OutputPol value */
237   /*!< Set COMPxHYST bits according to COMP_InitStruct->COMP_Hysteresis value */
238   /*!< Set COMPxMODE bits according to COMP_InitStruct->COMP_Mode value */
239   tmpreg |= (uint32_t)(COMP_InitStruct->COMP_InvertingInput | COMP_InitStruct->COMP_NonInvertingInput |
240                        COMP_InitStruct->COMP_Output | COMP_InitStruct->COMP_OutputPol | COMP_InitStruct->COMP_BlankingSrce |
241                          COMP_InitStruct->COMP_Hysteresis | COMP_InitStruct->COMP_Mode);
242 
243   /*!< Write to COMPx_CSR register */
244   *(__IO uint32_t *) (COMP_BASE + COMP_Selection) = tmpreg;
245 }
246 
247 /**
248 * @brief  Fills each COMP_InitStruct member with its default value.
249 * @param  COMP_InitStruct: pointer to an COMP_InitTypeDef structure which will
250 *         be initialized.
251 * @retval None
252 */
COMP_StructInit(COMP_InitTypeDef * COMP_InitStruct)253 void COMP_StructInit(COMP_InitTypeDef* COMP_InitStruct)
254 {
255   COMP_InitStruct->COMP_InvertingInput = COMP_InvertingInput_1_4VREFINT;
256   COMP_InitStruct->COMP_NonInvertingInput = COMP_NonInvertingInput_IO1;
257   COMP_InitStruct->COMP_Output = COMP_Output_None;
258   COMP_InitStruct->COMP_BlankingSrce = COMP_BlankingSrce_None;
259   COMP_InitStruct->COMP_OutputPol = COMP_OutputPol_NonInverted;
260   COMP_InitStruct->COMP_Hysteresis = COMP_Hysteresis_No;
261   COMP_InitStruct->COMP_Mode = COMP_Mode_UltraLowPower;
262 }
263 
264 /**
265 * @brief  Enable or disable the COMP peripheral.
266 * @note   If the selected comparator is locked, enable/disable can't be performed.
267 *         To unlock the configuration, perform a system reset.
268 * @param  COMP_Selection: the selected comparator.
269 *          This parameter can be COMP_Selection_COMPx where x can be 1 to 2
270 *          to select the COMP peripheral.
271 * @param  NewState: new state of the COMP peripheral.
272 *         This parameter can be: ENABLE or DISABLE.
273 *         When enabled, the comparator compares the non inverting input with
274 *                       the inverting input and the comparison result is available
275 *                       on comparator output.
276 *         When disabled, the comparator doesn't perform comparison and the
277 *                        output level is low.
278 * @retval None
279 */
COMP_Cmd(uint32_t COMP_Selection,FunctionalState NewState)280 void COMP_Cmd(uint32_t COMP_Selection, FunctionalState NewState)
281 {
282   /* Check the parameters */
283   assert_param(IS_COMP_ALL_PERIPH(COMP_Selection));
284   assert_param(IS_FUNCTIONAL_STATE(NewState));
285 
286   if (NewState != DISABLE)
287   {
288     /* Enable the selected COMPx peripheral */
289     *(__IO uint32_t *) (COMP_BASE + COMP_Selection) |= (uint32_t) (COMP_CSR_COMPxEN);
290   }
291   else
292   {
293     /* Disable the selected COMP peripheral  */
294     *(__IO uint32_t *) (COMP_BASE + COMP_Selection) &= (uint32_t)(~COMP_CSR_COMPxEN);
295   }
296 }
297 
298 /**
299 * @brief  Close or Open the SW1 switch.
300 * @note   If the COMP1 is locked, Close/Open the SW1 switch can't be performed.
301 *         To unlock the configuration, perform a system reset.
302 * @note   This switch is solely intended to redirect signals onto high
303 *         impedance input, such as COMP1 non-inverting input (highly resistive switch)
304 * @param  NewState: New state of the analog switch.
305 *   This parameter can be
306 *     ENABLE so the SW1 is closed; PA1 is connected to PA4
307 *     or DISABLE so the SW1 switch is open; PA1 is disconnected from PA4
308 * @retval None
309 */
COMP_SwitchCmd(uint32_t COMP_Selection,FunctionalState NewState)310 void COMP_SwitchCmd(uint32_t COMP_Selection, FunctionalState NewState)
311 {
312   /* Check the parameter */
313   assert_param(IS_FUNCTIONAL_STATE(NewState));
314 
315   if (NewState != DISABLE)
316   {
317     /* Close SW1 switch */
318     *(__IO uint32_t *) (COMP_BASE + COMP_Selection) |= (uint32_t) (COMP_CSR_COMP1SW1);
319   }
320   else
321   {
322     /* Open SW1 switch */
323     *(__IO uint32_t *) (COMP_BASE + COMP_Selection) &= (uint32_t)(~COMP_CSR_COMP1SW1);
324   }
325 }
326 
327 /**
328 * @brief  Return the output level (high or low) of the selected comparator.
329 *         The output level depends on the selected polarity.
330 *         If the polarity is not inverted:
331 *           - Comparator output is low when the non-inverting input is at a lower
332 *             voltage than the inverting input
333 *           - Comparator output is high when the non-inverting input is at a higher
334 *             voltage than the inverting input
335 *         If the polarity is inverted:
336 *           - Comparator output is high when the non-inverting input is at a lower
337 *             voltage than the inverting input
338 *           - Comparator output is low when the non-inverting input is at a higher
339 *             voltage than the inverting input
340 * @param  COMP_Selection: the selected comparator.
341 *          This parameter can be COMP_Selection_COMPx where x can be 1 to 2
342 *          to select the COMP peripheral.
343 * @retval Returns the selected comparator output level: low or high.
344 *
345 */
COMP_GetOutputLevel(uint32_t COMP_Selection)346 uint32_t COMP_GetOutputLevel(uint32_t COMP_Selection)
347 {
348   uint32_t compout = 0x0;
349 
350   /* Check the parameters */
351   assert_param(IS_COMP_ALL_PERIPH(COMP_Selection));
352 
353   /* Check if selected comparator output is high */
354   if ((*(__IO uint32_t *) (COMP_BASE + COMP_Selection) & (COMP_CSR_COMPxOUT)) != 0)
355   {
356     compout = COMP_OutputLevel_High;
357   }
358   else
359   {
360     compout = COMP_OutputLevel_Low;
361   }
362 
363   /* Return the comparator output level */
364   return (uint32_t)(compout);
365 }
366 
367 /**
368 * @}
369 */
370 
371 
372 /** @defgroup COMP_Group3 COMP configuration locking function
373 *  @brief   COMP1, COMP2 configuration locking function
374 *           COMP1, COMP2 configuration can be locked each separately.
375 *           Unlocking is performed by system reset.
376 *
377 @verbatim
378 ===============================================================================
379 ##### Configuration Lock function #####
380 ===============================================================================
381 
382 @endverbatim
383 * @{
384 */
385 
386 /**
387 * @brief  Lock the selected comparator (COMP1/COMP2) configuration.
388 * @note   Locking the configuration means that all control bits are read-only.
389 *         To unlock the comparator configuration, perform a system reset.
390 * @param  COMP_Selection: the selected comparator.
391 *          This parameter can be COMP_Selection_COMPx where x can be 1 to 7
392 *          to select the COMP peripheral.
393 * @retval None
394 */
COMP_LockConfig(uint32_t COMP_Selection)395 void COMP_LockConfig(uint32_t COMP_Selection)
396 {
397   /* Check the parameter */
398   assert_param(IS_COMP_ALL_PERIPH(COMP_Selection));
399 
400   /* Set the lock bit corresponding to selected comparator */
401   *(__IO uint32_t *) (COMP_BASE + COMP_Selection) |= (uint32_t) (COMP_CSR_COMPxLOCK);
402 }
403 
404 /**
405 * @}
406 */
407 
408 /**
409 * @}
410 */
411 
412 /**
413 * @}
414 */
415 
416 /**
417 * @}
418 */
419 
420 /*-------------------------(C) COPYRIGHT 2017 MindMotion ----------------------*/
421