]> git.sur5r.net Git - freertos/blob
ef116fbce056f9ea8360de24fa40493d4eecb00b
[freertos] /
1 /***************************************************************************//**\r
2  * @file em_acmp.h\r
3  * @brief Analog Comparator (ACMP) peripheral API\r
4  * @version 4.0.0\r
5  *******************************************************************************\r
6  * @section License\r
7  * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>\r
8  *******************************************************************************\r
9  *\r
10  * Permission is granted to anyone to use this software for any purpose,\r
11  * including commercial applications, and to alter it and redistribute it\r
12  * freely, subject to the following restrictions:\r
13  *\r
14  * 1. The origin of this software must not be misrepresented; you must not\r
15  *    claim that you wrote the original software.\r
16  * 2. Altered source versions must be plainly marked as such, and must not be\r
17  *    misrepresented as being the original software.\r
18  * 3. This notice may not be removed or altered from any source distribution.\r
19  *\r
20  * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no\r
21  * obligation to support this Software. Silicon Labs is providing the\r
22  * Software "AS IS", with no express or implied warranties of any kind,\r
23  * including, but not limited to, any implied warranties of merchantability\r
24  * or fitness for any particular purpose or warranties against infringement\r
25  * of any proprietary rights of a third party.\r
26  *\r
27  * Silicon Labs will not be liable for any consequential, incidental, or\r
28  * special damages, or any other relief, or for any claim by any third party,\r
29  * arising from your use of this Software.\r
30  *\r
31  ******************************************************************************/\r
32 \r
33 \r
34 #ifndef __SILICON_LABS_EM_ACMP_H_\r
35 #define __SILICON_LABS_EM_ACMP_H_\r
36 \r
37 #include "em_device.h"\r
38 #if defined(ACMP_COUNT) && (ACMP_COUNT > 0)\r
39 \r
40 #include <stdint.h>\r
41 #include <stdbool.h>\r
42 \r
43 #ifdef __cplusplus\r
44 extern "C" {\r
45 #endif\r
46 \r
47 /***************************************************************************//**\r
48  * @addtogroup EM_Library\r
49  * @{\r
50  ******************************************************************************/\r
51 \r
52 /***************************************************************************//**\r
53  * @addtogroup ACMP\r
54  * @{\r
55  ******************************************************************************/\r
56 \r
57 /*******************************************************************************\r
58  ********************************   ENUMS   ************************************\r
59  ******************************************************************************/\r
60 \r
61 /** Resistor values used for capacative sense. See the datasheet for your\r
62  *  device for details on each resistor value. */\r
63 typedef enum\r
64 {\r
65   /** resistor value 0 */\r
66   acmpResistor0 = _ACMP_INPUTSEL_CSRESSEL_RES0,\r
67   /** resistor value 1 */\r
68   acmpResistor1 = _ACMP_INPUTSEL_CSRESSEL_RES1,\r
69   /** resistor value 2 */\r
70   acmpResistor2 = _ACMP_INPUTSEL_CSRESSEL_RES2,\r
71   /** resistor value 3 */\r
72   acmpResistor3 = _ACMP_INPUTSEL_CSRESSEL_RES3\r
73 } ACMP_CapsenseResistor_TypeDef;\r
74 \r
75 /** Hysteresis level. See datasheet for your device for details on each\r
76  *  level. */\r
77 typedef enum\r
78 {\r
79   acmpHysteresisLevel0 = _ACMP_CTRL_HYSTSEL_HYST0, /**< Hysteresis level 0 */\r
80   acmpHysteresisLevel1 = _ACMP_CTRL_HYSTSEL_HYST1, /**< Hysteresis level 1 */\r
81   acmpHysteresisLevel2 = _ACMP_CTRL_HYSTSEL_HYST2, /**< Hysteresis level 2 */\r
82   acmpHysteresisLevel3 = _ACMP_CTRL_HYSTSEL_HYST3, /**< Hysteresis level 3 */\r
83   acmpHysteresisLevel4 = _ACMP_CTRL_HYSTSEL_HYST4, /**< Hysteresis level 4 */\r
84   acmpHysteresisLevel5 = _ACMP_CTRL_HYSTSEL_HYST5, /**< Hysteresis level 5 */\r
85   acmpHysteresisLevel6 = _ACMP_CTRL_HYSTSEL_HYST6, /**< Hysteresis level 6 */\r
86   acmpHysteresisLevel7 = _ACMP_CTRL_HYSTSEL_HYST7  /**< Hysteresis level 7 */\r
87 } ACMP_HysteresisLevel_TypeDef;\r
88 \r
89 /** ACMP warmup time. The delay is measured in HFPERCLK cycles and should\r
90  *  be at least 10 us. */\r
91 typedef enum\r
92 {\r
93   /** 4 HFPERCLK cycles warmup */\r
94   acmpWarmTime4   = _ACMP_CTRL_WARMTIME_4CYCLES,\r
95   /** 8 HFPERCLK cycles warmup */\r
96   acmpWarmTime8   = _ACMP_CTRL_WARMTIME_8CYCLES,\r
97   /** 16 HFPERCLK cycles warmup */\r
98   acmpWarmTime16  = _ACMP_CTRL_WARMTIME_16CYCLES,\r
99   /** 32 HFPERCLK cycles warmup */\r
100   acmpWarmTime32  = _ACMP_CTRL_WARMTIME_32CYCLES,\r
101   /** 64 HFPERCLK cycles warmup */\r
102   acmpWarmTime64  = _ACMP_CTRL_WARMTIME_64CYCLES,\r
103   /** 128 HFPERCLK cycles warmup */\r
104   acmpWarmTime128 = _ACMP_CTRL_WARMTIME_128CYCLES,\r
105   /** 256 HFPERCLK cycles warmup */\r
106   acmpWarmTime256 = _ACMP_CTRL_WARMTIME_256CYCLES,\r
107   /** 512 HFPERCLK cycles warmup */\r
108   acmpWarmTime512 = _ACMP_CTRL_WARMTIME_512CYCLES\r
109 } ACMP_WarmTime_TypeDef;\r
110 \r
111 /** ACMP inputs. Note that scaled VDD and bandgap references can only be used\r
112  *  as negative inputs. */\r
113 typedef enum\r
114 {\r
115   /** Channel 0 */\r
116   acmpChannel0    = _ACMP_INPUTSEL_NEGSEL_CH0,\r
117   /** Channel 1 */\r
118   acmpChannel1    = _ACMP_INPUTSEL_NEGSEL_CH1,\r
119   /** Channel 2 */\r
120   acmpChannel2    = _ACMP_INPUTSEL_NEGSEL_CH2,\r
121   /** Channel 3 */\r
122   acmpChannel3    = _ACMP_INPUTSEL_NEGSEL_CH3,\r
123   /** Channel 4 */\r
124   acmpChannel4    = _ACMP_INPUTSEL_NEGSEL_CH4,\r
125   /** Channel 5 */\r
126   acmpChannel5    = _ACMP_INPUTSEL_NEGSEL_CH5,\r
127   /** Channel 6 */\r
128   acmpChannel6    = _ACMP_INPUTSEL_NEGSEL_CH6,\r
129   /** Channel 7 */\r
130   acmpChannel7    = _ACMP_INPUTSEL_NEGSEL_CH7,\r
131   /** 1.25V internal reference */\r
132   acmpChannel1V25 = _ACMP_INPUTSEL_NEGSEL_1V25,\r
133   /** 2.5V internal reference */\r
134   acmpChannel2V5  = _ACMP_INPUTSEL_NEGSEL_2V5,\r
135   /** Scaled VDD reference */\r
136   acmpChannelVDD  = _ACMP_INPUTSEL_NEGSEL_VDD,\r
137 \r
138 #if defined( _ACMP_INPUTSEL_NEGSEL_DAC0CH0 )\r
139   /** DAC0 channel 0 */\r
140   acmpChannelDAC0Ch0 = _ACMP_INPUTSEL_NEGSEL_DAC0CH0,\r
141 #endif\r
142 \r
143 #if defined( _ACMP_INPUTSEL_NEGSEL_DAC0CH1 )\r
144   /** DAC0 channel 1 */\r
145   acmpChannelDAC0Ch1 = _ACMP_INPUTSEL_NEGSEL_DAC0CH1,\r
146 #endif\r
147 \r
148 #if defined( _ACMP_INPUTSEL_NEGSEL_CAPSENSE )\r
149   /** Capacitive sense mode */\r
150   acmpChannelCapSense = _ACMP_INPUTSEL_NEGSEL_CAPSENSE,\r
151 #endif\r
152 } ACMP_Channel_TypeDef;\r
153 \r
154 /*******************************************************************************\r
155  ******************************   STRUCTS   ************************************\r
156  ******************************************************************************/\r
157 \r
158 /** Capsense initialization structure. */\r
159 typedef struct\r
160 {\r
161   /** Full bias current. See the ACMP chapter about bias and response time in\r
162    *  the reference manual for details. */\r
163   bool                          fullBias;\r
164 \r
165   /** Half bias current. See the ACMP chapter about bias and response time in\r
166    *  the reference manual for details. */\r
167   bool                          halfBias;\r
168 \r
169   /** Bias current. See the ACMP chapter about bias and response time in the\r
170    *  reference manual for details. Valid values are in the range 0-7. */\r
171   uint32_t                      biasProg;\r
172 \r
173   /** Warmup time. This is measured in HFPERCLK cycles and should be\r
174    *  about 10us in wall clock time. */\r
175   ACMP_WarmTime_TypeDef         warmTime;\r
176 \r
177   /** Hysteresis level */\r
178   ACMP_HysteresisLevel_TypeDef  hysteresisLevel;\r
179 \r
180   /** Resistor used in the capacative sensing circuit. For values see\r
181    *  your device datasheet. */\r
182   ACMP_CapsenseResistor_TypeDef resistor;\r
183 \r
184   /** Low power reference enabled. This setting, if enabled, reduces the\r
185    *  power used by the VDD and bandgap references. */\r
186   bool                          lowPowerReferenceEnabled;\r
187 \r
188   /** Vdd reference value. VDD_SCALED = VDD × VDDLEVEL × 50mV/3.8V.\r
189    *  Valid values are in the range 0-63. */\r
190   uint32_t                      vddLevel;\r
191 \r
192   /** If true, ACMP is being enabled after configuration. */\r
193   bool                          enable;\r
194 } ACMP_CapsenseInit_TypeDef;\r
195 \r
196 /** Default config for capacitive sense mode initialization. */\r
197 #define ACMP_CAPSENSE_INIT_DEFAULT                        \\r
198   { false,              /* fullBias */                    \\r
199     false,              /* halfBias */                    \\r
200     0x7,                /* biasProg */                    \\r
201     acmpWarmTime512,    /* 512 cycle warmup to be safe */ \\r
202     acmpHysteresisLevel5,                                 \\r
203     acmpResistor3,                                        \\r
204     false,              /* low power reference */         \\r
205     0x3D,               /* VDD level */                   \\r
206     true                /* Enable after init. */          \\r
207   }\r
208 \r
209 /** ACMP initialization structure. */\r
210 typedef struct\r
211 {\r
212   /** Full bias current. See the ACMP chapter about bias and response time in\r
213    *  the reference manual for details. */\r
214   bool                         fullBias;\r
215 \r
216   /** Half bias current. See the ACMP chapter about bias and response time in\r
217    *  the reference manual for details. */\r
218   bool                         halfBias;\r
219 \r
220   /** Bias current. See the ACMP chapter about bias and response time in the\r
221    *  reference manual for details. Valid values are in the range 0-7. */\r
222   uint32_t                     biasProg;\r
223 \r
224   /** Enable setting the interrupt flag on falling edge */\r
225   bool                         interruptOnFallingEdge;\r
226 \r
227   /** Enable setting the interrupt flag on rising edge */\r
228   bool                         interruptOnRisingEdge;\r
229 \r
230   /** Warmup time. This is measured in HFPERCLK cycles and should be\r
231    *  about 10us in wall clock time. */\r
232   ACMP_WarmTime_TypeDef        warmTime;\r
233 \r
234   /** Hysteresis level */\r
235   ACMP_HysteresisLevel_TypeDef hysteresisLevel;\r
236 \r
237   /** Inactive value emitted by the ACMP during warmup */\r
238   bool                         inactiveValue;\r
239 \r
240   /** Low power reference enabled. This setting, if enabled, reduces the\r
241    *  power used by the VDD and bandgap references. */\r
242   bool                         lowPowerReferenceEnabled;\r
243 \r
244   /** Vdd reference value. VDD_SCALED = VDD × VDDLEVEL × 50mV/3.8V.\r
245    *  Valid values are in the range 0-63. */\r
246   uint32_t                     vddLevel;\r
247 \r
248   /** If true, ACMP is being enabled after configuration. */\r
249   bool                         enable;\r
250 } ACMP_Init_TypeDef;\r
251 \r
252 /** Default config for ACMP regular initialization. */\r
253 #define ACMP_INIT_DEFAULT                                                     \\r
254   { false,              /* fullBias */                                        \\r
255     false,              /* halfBias */                                        \\r
256     0x7,                /* biasProg */                                        \\r
257     false,              /* No interrupt on falling edge. */                   \\r
258     false,              /* No interrupt on rising edge. */                    \\r
259     acmpWarmTime512,    /* 512 cycle warmup to be safe */                     \\r
260     acmpHysteresisLevel5,                                                     \\r
261     false,              /* Disabled emitting inactive value during warmup. */ \\r
262     false,              /* low power reference */                             \\r
263     0x3D,               /* VDD level */                                       \\r
264     true                /* Enable after init. */                              \\r
265   }\r
266 \r
267 \r
268 /*******************************************************************************\r
269  *****************************   PROTOTYPES   **********************************\r
270  ******************************************************************************/\r
271 \r
272 void ACMP_CapsenseInit(ACMP_TypeDef *acmp, const ACMP_CapsenseInit_TypeDef *init);\r
273 void ACMP_CapsenseChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef channel);\r
274 void ACMP_ChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef negSel, ACMP_Channel_TypeDef posSel);\r
275 void ACMP_Disable(ACMP_TypeDef *acmp);\r
276 void ACMP_Enable(ACMP_TypeDef *acmp);\r
277 void ACMP_GPIOSetup(ACMP_TypeDef *acmp, uint32_t location, bool enable, bool invert);\r
278 void ACMP_Init(ACMP_TypeDef *acmp, const ACMP_Init_TypeDef *init);\r
279 void ACMP_Reset(ACMP_TypeDef *acmp);\r
280 \r
281 /***************************************************************************//**\r
282  * @brief\r
283  *   Clear one or more pending ACMP interrupts.\r
284  *\r
285  * @param[in] acmp\r
286  *   Pointer to ACMP peripheral register block.\r
287  *\r
288  * @param[in] flags\r
289  *   Pending ACMP interrupt source to clear. Use a bitwise logic OR combination\r
290  *   of valid interrupt flags for the ACMP module (ACMP_IF_nnn).\r
291  ******************************************************************************/\r
292 __STATIC_INLINE void ACMP_IntClear(ACMP_TypeDef *acmp, uint32_t flags)\r
293 {\r
294   acmp->IFC = flags;\r
295 }\r
296 \r
297 \r
298 /***************************************************************************//**\r
299  * @brief\r
300  *   Disable one or more ACMP interrupts.\r
301  *\r
302  * @param[in] acmp\r
303  *   Pointer to ACMP peripheral register block.\r
304  *\r
305  * @param[in] flags\r
306  *   ACMP interrupt sources to disable. Use a bitwise logic OR combination of\r
307  *   valid interrupt flags for the ACMP module (ACMP_IF_nnn).\r
308  ******************************************************************************/\r
309 __STATIC_INLINE void ACMP_IntDisable(ACMP_TypeDef *acmp, uint32_t flags)\r
310 {\r
311   acmp->IEN &= ~(flags);\r
312 }\r
313 \r
314 \r
315 /***************************************************************************//**\r
316  * @brief\r
317  *   Enable one or more ACMP interrupts.\r
318  *\r
319  * @note\r
320  *   Depending on the use, a pending interrupt may already be set prior to\r
321  *   enabling the interrupt. Consider using ACMP_IntClear() prior to enabling\r
322  *   if such a pending interrupt should be ignored.\r
323  *\r
324  * @param[in] acmp\r
325  *   Pointer to ACMP peripheral register block.\r
326  *\r
327  * @param[in] flags\r
328  *   ACMP interrupt sources to enable. Use a bitwise logic OR combination of\r
329  *   valid interrupt flags for the ACMP module (ACMP_IF_nnn).\r
330  ******************************************************************************/\r
331 __STATIC_INLINE void ACMP_IntEnable(ACMP_TypeDef *acmp, uint32_t flags)\r
332 {\r
333   acmp->IEN |= flags;\r
334 }\r
335 \r
336 \r
337 /***************************************************************************//**\r
338  * @brief\r
339  *   Get pending ACMP interrupt flags.\r
340  *\r
341  * @note\r
342  *   The event bits are not cleared by the use of this function.\r
343  *\r
344  * @param[in] acmp\r
345  *   Pointer to ACMP peripheral register block.\r
346  *\r
347  * @return\r
348  *   ACMP interrupt sources pending. A bitwise logic OR combination of valid\r
349  *   interrupt flags for the ACMP module (ACMP_IF_nnn).\r
350  ******************************************************************************/\r
351 __STATIC_INLINE uint32_t ACMP_IntGet(ACMP_TypeDef *acmp)\r
352 {\r
353   return(acmp->IF);\r
354 }\r
355 \r
356 \r
357 /***************************************************************************//**\r
358  * @brief\r
359  *   Get enabled and pending ACMP interrupt flags.\r
360  *   Useful for handling more interrupt sources in the same interrupt handler.\r
361  *\r
362  * @param[in] acmp\r
363  *   Pointer to ACMP peripheral register block.\r
364  *\r
365  * @note\r
366  *   Interrupt flags are not cleared by the use of this function.\r
367  *\r
368  * @return\r
369  *   Pending and enabled ACMP interrupt sources.\r
370  *   The return value is the bitwise AND combination of\r
371  *   - the OR combination of enabled interrupt sources in ACMPx_IEN_nnn\r
372  *     register (ACMPx_IEN_nnn) and\r
373  *   - the OR combination of valid interrupt flags of the ACMP module\r
374  *     (ACMPx_IF_nnn).\r
375  ******************************************************************************/\r
376 __STATIC_INLINE uint32_t ACMP_IntGetEnabled(ACMP_TypeDef *acmp)\r
377 {\r
378   uint32_t tmp;\r
379 \r
380   /* Store ACMPx->IEN in temporary variable in order to define explicit order\r
381    * of volatile accesses. */\r
382   tmp = acmp->IEN;\r
383 \r
384   /* Bitwise AND of pending and enabled interrupts */\r
385   return acmp->IF & tmp;\r
386 }\r
387 \r
388 \r
389 /***************************************************************************//**\r
390  * @brief\r
391  *   Set one or more pending ACMP interrupts from SW.\r
392  *\r
393  * @param[in] acmp\r
394  *   Pointer to ACMP peripheral register block.\r
395  *\r
396  * @param[in] flags\r
397  *   ACMP interrupt sources to set to pending. Use a bitwise logic OR\r
398  *   combination of valid interrupt flags for the ACMP module (ACMP_IF_nnn).\r
399  ******************************************************************************/\r
400 __STATIC_INLINE void ACMP_IntSet(ACMP_TypeDef *acmp, uint32_t flags)\r
401 {\r
402   acmp->IFS = flags;\r
403 }\r
404 \r
405 /** @} (end addtogroup ACMP) */\r
406 /** @} (end addtogroup EM_Library) */\r
407 \r
408 #ifdef __cplusplus\r
409 }\r
410 #endif\r
411 \r
412 #endif /* defined(ACMP_COUNT) && (ACMP_COUNT > 0) */\r
413 #endif /* __SILICON_LABS_EM_ACMP_H_ */\r