Merge branch 'master' of https://github.com/texane/stlink
[fw/stlink] / example / libstm32l_discovery / src / stm32l1xx_comp.c
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32l1xx_comp.c\r
4   * @author  MCD Application Team\r
5   * @version V1.0.0\r
6   * @date    31-December-2010\r
7   * @brief   This file provides firmware functions to manage the following \r
8   *          functionalities of the comparators (COMP1 and COMP2) peripheral: \r
9   *           - Comparators configuration\r
10   *           - Window mode control\r
11   *           - Internal Reference Voltage (VREFINT) output\r
12   *\r
13   *  @verbatim\r
14   *\r
15   *          ===================================================================\r
16   *                                 How to use this driver\r
17   *          ===================================================================\r
18   *                 \r
19   *          The device integrates two analog comparators COMP1 and COMP2:            \r
20   *             - COMP1 is a fixed threshold (VREFINT) that shares the non inverting\r
21   *               input with the ADC channels.\r
22   *\r
23   *             - COMP2 is a rail-to-rail comparator whose the inverting input \r
24   *               can be selected among: DAC_OUT1, DAC_OUT2, 1/4 VREFINT,\r
25   *               1/2 VERFINT, 3/4 VREFINT, VREFINT, PB3 and whose the output\r
26   *               can be redirected to embedded timers: TIM2, TIM3, TIM4, TIM10\r
27   *\r
28   *             - The two comparators COMP1 and COMP2 can be combined in window\r
29   *               mode.\r
30   *\r
31   * @note\r
32   *          1- Comparator APB clock must be enabled to get write access\r
33   *             to comparator register using\r
34   *             RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP, ENABLE);\r
35   *\r
36   *          2- COMP1 comparator and ADC can't be used at the same time since\r
37   *             they share the same ADC switch matrix (analog switches).\r
38   *\r
39   *          3- When an I/O is used as comparator input, the corresponding GPIO \r
40   *             registers should be configured in analog mode.\r
41   *\r
42   *          4- Comparators outputs (CMP1OUT and CMP2OUT) are not mapped on\r
43   *             GPIO pin. They are only internal.\r
44   *             To get the comparator output level, use COMP_GetOutputLevel()\r
45   *\r
46   *          5- COMP1 and COMP2 outputs are internally connected to EXTI Line 21\r
47   *             and EXTI Line 22 respectively.\r
48   *             Interrupts can be used by configuring the EXTI Line using the \r
49   *             EXTI peripheral driver.\r
50   *\r
51   *          6- After enabling the comparator (COMP1 or COMP2), user should wait\r
52   *             for start-up time (tSTART) to get right output levels.\r
53   *             Please refer to product datasheet for more information on tSTART.  \r
54   *\r
55   *          7- Comparators cannot be used to exit the device from Sleep or Stop \r
56   *             mode when the internal reference voltage is switched off using \r
57   *             the PWR_UltraLowPowerCmd() function (ULP bit in the PWR_CR register).\r
58   *\r
59   *  @endverbatim\r
60   *    \r
61   ******************************************************************************\r
62   * @attention\r
63   *\r
64   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
65   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
66   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
67   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
68   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
69   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
70   *\r
71   * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>\r
72   ******************************************************************************  \r
73   */ \r
74 \r
75 /* Includes ------------------------------------------------------------------*/\r
76 #include "stm32l1xx_comp.h"\r
77 \r
78 /** @addtogroup STM32L1xx_StdPeriph_Driver\r
79   * @{\r
80   */\r
81 \r
82 /** @defgroup COMP \r
83   * @brief COMP driver modules\r
84   * @{\r
85   */ \r
86 \r
87 /* Private typedef -----------------------------------------------------------*/\r
88 /* Private define ------------------------------------------------------------*/\r
89 /* Private macro -------------------------------------------------------------*/\r
90 /* Private variables ---------------------------------------------------------*/\r
91 /* Private function prototypes -----------------------------------------------*/\r
92 /* Private functions ---------------------------------------------------------*/\r
93 \r
94 /** @defgroup COMP_Private_Functions\r
95   * @{\r
96   */\r
97 \r
98 /** @defgroup COMP_Group1 Initialization and Configuration functions\r
99  *  @brief   Initialization and Configuration functions \r
100  *\r
101 @verbatim   \r
102  ===============================================================================\r
103                         Initialization and Configuration functions\r
104  ===============================================================================  \r
105 \r
106 @endverbatim\r
107   * @{\r
108   */\r
109    \r
110 /**\r
111   * @brief  Deinitializes COMP peripheral registers to their default reset values.\r
112   * @param  None\r
113   * @retval None\r
114   */\r
115 void COMP_DeInit(void)\r
116 {\r
117   COMP->CSR = ((uint32_t)0x00000000);    /*!< Set COMP->CSR to reset value */\r
118 }\r
119 \r
120 /**\r
121   * @brief  Initializes the COMP2 peripheral according to the specified parameters\r
122   *         in the COMP_InitStruct:\r
123   *           - COMP_InvertingInput specify the inverting input of COMP2\r
124   *           - COMP_OutputSelect connect the output of COMP2 to selected timer\r
125   *             input (Input capture / Output Compare Reference Clear)\r
126   *           - COMP_Speed configures COMP2 speed for optimum speed/consumption ratio\r
127   * @note   This function configures only COMP2.\r
128   * @note   COMP2 comparator is enabled as soon as the INSEL[2:0] bits are \r
129   *         different from "000".\r
130   * @param  COMP_InitStruct: pointer to an COMP_InitTypeDef structure that contains \r
131   *         the configuration information for the specified COMP peripheral.\r
132   * @retval None\r
133   */\r
134 void COMP_Init(COMP_InitTypeDef* COMP_InitStruct)\r
135 {\r
136   uint32_t tmpreg = 0;\r
137   \r
138   /* Check the parameters */\r
139   assert_param(IS_COMP_INVERTING_INPUT(COMP_InitStruct->COMP_InvertingInput));\r
140   assert_param(IS_COMP_OUTPUT(COMP_InitStruct->COMP_OutputSelect));\r
141   assert_param(IS_COMP_SPEED(COMP_InitStruct->COMP_Speed));\r
142 \r
143   /*!< Get the COMP CSR value */\r
144   tmpreg = COMP->CSR;\r
145 \r
146   /*!< Clear the  INSEL[2:0], OUTSEL[1:0] and SPEED bits */ \r
147   tmpreg &= (uint32_t) (~(uint32_t) (COMP_CSR_OUTSEL | COMP_CSR_INSEL | COMP_CSR_SPEED));\r
148   \r
149   /*!< Configure COMP: speed, inversion input selection and output redirection */\r
150   /*!< Set SPEED bit according to COMP_InitStruct->COMP_Speed value */\r
151   /*!< Set INSEL bits according to COMP_InitStruct->COMP_InvertingInput value */ \r
152   /*!< Set OUTSEL bits according to COMP_InitStruct->COMP_OutputSelect value */  \r
153   tmpreg |= (uint32_t)((COMP_InitStruct->COMP_Speed | COMP_InitStruct->COMP_InvertingInput \r
154                         | COMP_InitStruct->COMP_OutputSelect));\r
155 \r
156   /*!< The COMP2 comparator is enabled as soon as the INSEL[2:0] bits value are \r
157      different from "000" */\r
158   /*!< Write to COMP_CSR register */\r
159   COMP->CSR = tmpreg;  \r
160 }\r
161 \r
162 /**\r
163   * @brief  Enable or disable the COMP1 peripheral.\r
164   *         After enabling COMP1, the following functions should be called to \r
165   *         connect the selected GPIO input to COMP1 non inverting input:\r
166   *          - Enable switch control mode using SYSCFG_RISwitchControlModeCmd()\r
167   *          - Close VCOMP switch using SYSCFG_RIIOSwitchConfig()\r
168   *          - Close the I/O switch number n corresponding to the I/O \r
169   *            using SYSCFG_RIIOSwitchConfig()\r
170   * @param  NewState: new state of the COMP1 peripheral.\r
171   *         This parameter can be: ENABLE or DISABLE.\r
172   * @note   This function enables/disables only the COMP1.\r
173   * @retval None\r
174   */\r
175 void COMP_Cmd(FunctionalState NewState)\r
176 {\r
177   /* Check the parameter */\r
178   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
179 \r
180   if (NewState != DISABLE)\r
181   {\r
182     /* Enable the COMP1 */\r
183     COMP->CSR |= (uint32_t) COMP_CSR_CMP1EN;\r
184   }\r
185   else\r
186   {\r
187     /* Disable the COMP1  */\r
188     COMP->CSR &= (uint32_t)(~COMP_CSR_CMP1EN);\r
189   }\r
190 }\r
191 \r
192 /**\r
193   * @brief  Return the output level (high or low) of the selected comparator:\r
194   *         - Comparator output is low when the non-inverting input is at a lower\r
195   *           voltage than the inverting input\r
196   *         - Comparator output is high when the non-inverting input is at a higher\r
197   *           voltage than the inverting input\r
198   * @note   Comparators outputs aren't available on GPIO (outputs levels are \r
199   *         only internal). The COMP1 and COMP2 outputs are connected internally \r
200   *         to the EXTI Line 21 and Line 22 respectively.  \r
201   * @param  COMP_Selection: the selected comparator. \r
202   *   This parameter can be one of the following values:\r
203   *     @arg COMP_Selection_COMP1: COMP1 selected\r
204   *     @arg COMP_Selection_COMP2: COMP2 selected  \r
205   * @retval Returns the selected comparator output level.\r
206   */\r
207 uint8_t COMP_GetOutputLevel(uint32_t COMP_Selection)\r
208 {\r
209   uint8_t compout = 0x0;\r
210 \r
211   /* Check the parameters */\r
212   assert_param(IS_COMP_ALL_PERIPH(COMP_Selection));\r
213 \r
214   /* Check if Comparator 1 is selected */\r
215   if(COMP_Selection == COMP_Selection_COMP1)\r
216   {\r
217     /* Check if comparator 1 output level is high */\r
218     if((COMP->CSR & COMP_CSR_CMP1OUT) != (uint8_t) RESET)\r
219     {\r
220       /* Get Comparator 1 output level */\r
221       compout = (uint8_t) COMP_OutputLevel_High;\r
222     }\r
223     /* comparator 1 output level is low */\r
224     else\r
225     {\r
226       /* Get Comparator 1 output level */\r
227       compout = (uint8_t) COMP_OutputLevel_Low;\r
228     }\r
229   }\r
230   /* Comparator 2 is selected */\r
231   else\r
232   {\r
233     /* Check if comparator 2 output level is high */\r
234     if((COMP->CSR & COMP_CSR_CMP2OUT) != (uint8_t) RESET)\r
235     {\r
236       /* Get Comparator output level */\r
237       compout = (uint8_t) COMP_OutputLevel_High;\r
238     }\r
239     /* comparator 2 output level is low */\r
240     else\r
241     {\r
242       /* Get Comparator 2 output level */\r
243       compout = (uint8_t) COMP_OutputLevel_Low;\r
244     }\r
245   }\r
246   /* Return the comparator output level */\r
247   return (uint8_t)(compout);\r
248 }\r
249 \r
250 /**\r
251   * @}\r
252   */\r
253 \r
254 /** @defgroup COMP_Group2 Window mode control function\r
255  *  @brief   Window mode control function \r
256  *\r
257 @verbatim   \r
258  ===============================================================================\r
259                               Window mode control function\r
260  ===============================================================================  \r
261 \r
262 @endverbatim\r
263   * @{\r
264   */\r
265 \r
266 /**\r
267   * @brief  Enables or disables the window mode.\r
268   *         In window mode:\r
269   *          - COMP1 inverting input is fixed to VREFINT defining the first\r
270   *            threshold\r
271   *          - COMP2 inverting input is configurable (DAC_OUT1, DAC_OUT2, VREFINT\r
272   *            sub-multiples, PB3) defining the second threshold\r
273   *          - COMP1 and COMP2 non inverting inputs are connected together.\r
274   * @note   In window mode, only the Group 6 (PB4 or PB5) can be used as\r
275   *         non-inverting inputs.\r
276   * param   NewState: new state of the window mode. \r
277   *   This parameter can be ENABLE or DISABLE.\r
278   * @retval None\r
279   */\r
280 void COMP_WindowCmd(FunctionalState NewState)\r
281 {\r
282   /* Check the parameters */\r
283   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
284   \r
285   if (NewState != DISABLE)\r
286   {\r
287     /* Enable the window mode */\r
288     COMP->CSR |= (uint32_t) COMP_CSR_WNDWE;\r
289   }\r
290   else\r
291   {\r
292     /* Disable the window mode */\r
293     COMP->CSR &= (uint32_t)(~COMP_CSR_WNDWE);\r
294   }\r
295 }\r
296 \r
297 /**\r
298   * @}\r
299   */\r
300 \r
301 /** @defgroup COMP_Group3 Internal Reference Voltage output function\r
302  *  @brief   Internal Reference Voltage (VREFINT) output function \r
303  *\r
304 @verbatim   \r
305  ===============================================================================\r
306              Internal Reference Voltage (VREFINT) output function\r
307  ===============================================================================  \r
308 \r
309 @endverbatim\r
310   * @{\r
311   */\r
312 \r
313 /**\r
314   * @brief  Enables or disables the output of internal reference voltage (VREFINT).\r
315   *         The VREFINT output can be routed to any I/O in group 3: CH8 (PB0) or\r
316   *         CH9 (PB1).\r
317   *         To correctly use this function, the SYSCFG_RIIOSwitchConfig() function\r
318   *         should be called after.\r
319   * @param  NewState: new state of the Vrefint output.\r
320   *         This parameter can be: ENABLE or DISABLE.\r
321   * @retval None\r
322   */\r
323 void COMP_VrefintOutputCmd(FunctionalState NewState)\r
324 {\r
325   /* Check the parameters */\r
326   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
327 \r
328   if (NewState != DISABLE)\r
329   {\r
330     /* Enable the output of internal reference voltage */\r
331     COMP->CSR |= (uint32_t) COMP_CSR_VREFOUTEN;\r
332   }\r
333   else\r
334   {\r
335     /* Disable the output of internal reference voltage */\r
336     COMP->CSR &= (uint32_t) (~COMP_CSR_VREFOUTEN);\r
337   }\r
338 }\r
339 \r
340 /**\r
341   * @}\r
342   */\r
343 \r
344 /**\r
345   * @}\r
346   */\r
347 \r
348 /**\r
349   * @}\r
350   */\r
351 \r
352 /**\r
353   * @}\r
354   */\r
355 \r
356 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/\r