Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/emlib/src/em_acmp.c@144:ef7eb2e8f9f7, 2016-09-02 (annotated)
- Committer:
- <>
- Date:
- Fri Sep 02 15:07:44 2016 +0100
- Revision:
- 144:ef7eb2e8f9f7
- Parent:
- 50:a417edff4437
This updates the lib to the mbed lib v125
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| <> | 144:ef7eb2e8f9f7 | 1 | /***************************************************************************//** |
| <> | 144:ef7eb2e8f9f7 | 2 | * @file em_acmp.c |
| <> | 144:ef7eb2e8f9f7 | 3 | * @brief Analog Comparator (ACMP) Peripheral API |
| <> | 144:ef7eb2e8f9f7 | 4 | * @version 4.2.1 |
| <> | 144:ef7eb2e8f9f7 | 5 | ******************************************************************************* |
| <> | 144:ef7eb2e8f9f7 | 6 | * @section License |
| <> | 144:ef7eb2e8f9f7 | 7 | * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b> |
| <> | 144:ef7eb2e8f9f7 | 8 | ******************************************************************************* |
| <> | 144:ef7eb2e8f9f7 | 9 | * |
| <> | 144:ef7eb2e8f9f7 | 10 | * Permission is granted to anyone to use this software for any purpose, |
| <> | 144:ef7eb2e8f9f7 | 11 | * including commercial applications, and to alter it and redistribute it |
| <> | 144:ef7eb2e8f9f7 | 12 | * freely, subject to the following restrictions: |
| <> | 144:ef7eb2e8f9f7 | 13 | * |
| <> | 144:ef7eb2e8f9f7 | 14 | * 1. The origin of this software must not be misrepresented; you must not |
| <> | 144:ef7eb2e8f9f7 | 15 | * claim that you wrote the original software. |
| <> | 144:ef7eb2e8f9f7 | 16 | * 2. Altered source versions must be plainly marked as such, and must not be |
| <> | 144:ef7eb2e8f9f7 | 17 | * misrepresented as being the original software. |
| <> | 144:ef7eb2e8f9f7 | 18 | * 3. This notice may not be removed or altered from any source distribution. |
| <> | 144:ef7eb2e8f9f7 | 19 | * |
| <> | 144:ef7eb2e8f9f7 | 20 | * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no |
| <> | 144:ef7eb2e8f9f7 | 21 | * obligation to support this Software. Silicon Labs is providing the |
| <> | 144:ef7eb2e8f9f7 | 22 | * Software "AS IS", with no express or implied warranties of any kind, |
| <> | 144:ef7eb2e8f9f7 | 23 | * including, but not limited to, any implied warranties of merchantability |
| <> | 144:ef7eb2e8f9f7 | 24 | * or fitness for any particular purpose or warranties against infringement |
| <> | 144:ef7eb2e8f9f7 | 25 | * of any proprietary rights of a third party. |
| <> | 144:ef7eb2e8f9f7 | 26 | * |
| <> | 144:ef7eb2e8f9f7 | 27 | * Silicon Labs will not be liable for any consequential, incidental, or |
| <> | 144:ef7eb2e8f9f7 | 28 | * special damages, or any other relief, or for any claim by any third party, |
| <> | 144:ef7eb2e8f9f7 | 29 | * arising from your use of this Software. |
| <> | 144:ef7eb2e8f9f7 | 30 | * |
| <> | 144:ef7eb2e8f9f7 | 31 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 32 | |
| <> | 144:ef7eb2e8f9f7 | 33 | |
| <> | 144:ef7eb2e8f9f7 | 34 | #include "em_acmp.h" |
| <> | 144:ef7eb2e8f9f7 | 35 | #if defined(ACMP_COUNT) && (ACMP_COUNT > 0) |
| <> | 144:ef7eb2e8f9f7 | 36 | |
| <> | 144:ef7eb2e8f9f7 | 37 | #include <stdbool.h> |
| <> | 144:ef7eb2e8f9f7 | 38 | #include "em_bus.h" |
| <> | 144:ef7eb2e8f9f7 | 39 | #include "em_assert.h" |
| <> | 144:ef7eb2e8f9f7 | 40 | |
| <> | 144:ef7eb2e8f9f7 | 41 | /***************************************************************************//** |
| <> | 144:ef7eb2e8f9f7 | 42 | * @addtogroup EM_Library |
| <> | 144:ef7eb2e8f9f7 | 43 | * @{ |
| <> | 144:ef7eb2e8f9f7 | 44 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 45 | |
| <> | 144:ef7eb2e8f9f7 | 46 | /***************************************************************************//** |
| <> | 144:ef7eb2e8f9f7 | 47 | * @addtogroup ACMP |
| <> | 144:ef7eb2e8f9f7 | 48 | * @brief Analog comparator (ACMP) Peripheral API |
| <> | 144:ef7eb2e8f9f7 | 49 | * @{ |
| <> | 144:ef7eb2e8f9f7 | 50 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 51 | |
| <> | 144:ef7eb2e8f9f7 | 52 | /******************************************************************************* |
| <> | 144:ef7eb2e8f9f7 | 53 | ******************************* DEFINES *********************************** |
| <> | 144:ef7eb2e8f9f7 | 54 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 55 | |
| <> | 144:ef7eb2e8f9f7 | 56 | /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */ |
| <> | 144:ef7eb2e8f9f7 | 57 | |
| <> | 144:ef7eb2e8f9f7 | 58 | |
| <> | 144:ef7eb2e8f9f7 | 59 | /** Validation of ACMP register block pointer reference |
| <> | 144:ef7eb2e8f9f7 | 60 | * for assert statements. */ |
| <> | 144:ef7eb2e8f9f7 | 61 | #if (ACMP_COUNT == 1) |
| <> | 144:ef7eb2e8f9f7 | 62 | #define ACMP_REF_VALID(ref) ((ref) == ACMP0) |
| <> | 144:ef7eb2e8f9f7 | 63 | #elif (ACMP_COUNT == 2) |
| <> | 144:ef7eb2e8f9f7 | 64 | #define ACMP_REF_VALID(ref) (((ref) == ACMP0) || ((ref) == ACMP1)) |
| <> | 144:ef7eb2e8f9f7 | 65 | #else |
| <> | 144:ef7eb2e8f9f7 | 66 | #error Undefined number of analog comparators (ACMP). |
| <> | 144:ef7eb2e8f9f7 | 67 | #endif |
| <> | 144:ef7eb2e8f9f7 | 68 | |
| <> | 144:ef7eb2e8f9f7 | 69 | /** The maximum value that can be inserted in the route location register |
| <> | 144:ef7eb2e8f9f7 | 70 | * for the specific device. */ |
| <> | 144:ef7eb2e8f9f7 | 71 | #if defined(_ACMP_ROUTE_LOCATION_LOC3) |
| <> | 144:ef7eb2e8f9f7 | 72 | #define _ACMP_ROUTE_LOCATION_MAX _ACMP_ROUTE_LOCATION_LOC3 |
| <> | 144:ef7eb2e8f9f7 | 73 | #elif defined(_ACMP_ROUTE_LOCATION_LOC2) |
| <> | 144:ef7eb2e8f9f7 | 74 | #define _ACMP_ROUTE_LOCATION_MAX _ACMP_ROUTE_LOCATION_LOC2 |
| <> | 144:ef7eb2e8f9f7 | 75 | #elif defined(_ACMP_ROUTE_LOCATION_LOC1) |
| <> | 144:ef7eb2e8f9f7 | 76 | #define _ACMP_ROUTE_LOCATION_MAX _ACMP_ROUTE_LOCATION_LOC1 |
| <> | 144:ef7eb2e8f9f7 | 77 | #elif defined(_ACMP_ROUTELOC0_OUTLOC_LOC31) |
| <> | 144:ef7eb2e8f9f7 | 78 | #define _ACMP_ROUTE_LOCATION_MAX _ACMP_ROUTELOC0_OUTLOC_LOC31 |
| <> | 144:ef7eb2e8f9f7 | 79 | #else |
| <> | 144:ef7eb2e8f9f7 | 80 | #error Undefined max route locations |
| <> | 144:ef7eb2e8f9f7 | 81 | #endif |
| <> | 144:ef7eb2e8f9f7 | 82 | |
| <> | 144:ef7eb2e8f9f7 | 83 | /** @endcond */ |
| <> | 144:ef7eb2e8f9f7 | 84 | |
| <> | 144:ef7eb2e8f9f7 | 85 | /******************************************************************************* |
| <> | 144:ef7eb2e8f9f7 | 86 | ************************** GLOBAL FUNCTIONS ******************************* |
| <> | 144:ef7eb2e8f9f7 | 87 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 88 | |
| <> | 144:ef7eb2e8f9f7 | 89 | /***************************************************************************//** |
| <> | 144:ef7eb2e8f9f7 | 90 | * @brief |
| <> | 144:ef7eb2e8f9f7 | 91 | * Sets up the ACMP for use in capacative sense applications. |
| <> | 144:ef7eb2e8f9f7 | 92 | * |
| <> | 144:ef7eb2e8f9f7 | 93 | * @details |
| <> | 144:ef7eb2e8f9f7 | 94 | * This function sets up the ACMP for use in capacacitve sense applications. |
| <> | 144:ef7eb2e8f9f7 | 95 | * To use the capacative sense functionality in the ACMP you need to use |
| <> | 144:ef7eb2e8f9f7 | 96 | * the PRS output of the ACMP module to count the number of oscillations |
| <> | 144:ef7eb2e8f9f7 | 97 | * in the capacative sense circuit (possibly using a TIMER). |
| <> | 144:ef7eb2e8f9f7 | 98 | * |
| <> | 144:ef7eb2e8f9f7 | 99 | * @note |
| <> | 144:ef7eb2e8f9f7 | 100 | * A basic example of capacative sensing can be found in the STK BSP |
| <> | 144:ef7eb2e8f9f7 | 101 | * (capsense demo). |
| <> | 144:ef7eb2e8f9f7 | 102 | * |
| <> | 144:ef7eb2e8f9f7 | 103 | * @param[in] acmp |
| <> | 144:ef7eb2e8f9f7 | 104 | * Pointer to ACMP peripheral register block. |
| <> | 144:ef7eb2e8f9f7 | 105 | * |
| <> | 144:ef7eb2e8f9f7 | 106 | * @param[in] init |
| <> | 144:ef7eb2e8f9f7 | 107 | * Pointer to initialization structure used to configure ACMP for capacative |
| <> | 144:ef7eb2e8f9f7 | 108 | * sensing operation. |
| <> | 144:ef7eb2e8f9f7 | 109 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 110 | void ACMP_CapsenseInit(ACMP_TypeDef *acmp, const ACMP_CapsenseInit_TypeDef *init) |
| <> | 144:ef7eb2e8f9f7 | 111 | { |
| <> | 144:ef7eb2e8f9f7 | 112 | /* Make sure the module exists on the selected chip */ |
| <> | 144:ef7eb2e8f9f7 | 113 | EFM_ASSERT(ACMP_REF_VALID(acmp)); |
| <> | 144:ef7eb2e8f9f7 | 114 | |
| <> | 144:ef7eb2e8f9f7 | 115 | /* Make sure that vddLevel is within bounds */ |
| <> | 144:ef7eb2e8f9f7 | 116 | #if defined(_ACMP_INPUTSEL_VDDLEVEL_MASK) |
| <> | 144:ef7eb2e8f9f7 | 117 | EFM_ASSERT(init->vddLevel < 64); |
| <> | 144:ef7eb2e8f9f7 | 118 | #else |
| <> | 144:ef7eb2e8f9f7 | 119 | EFM_ASSERT(init->vddLevelLow < 64); |
| <> | 144:ef7eb2e8f9f7 | 120 | EFM_ASSERT(init->vddLevelHigh < 64); |
| <> | 144:ef7eb2e8f9f7 | 121 | #endif |
| <> | 144:ef7eb2e8f9f7 | 122 | |
| <> | 144:ef7eb2e8f9f7 | 123 | /* Make sure biasprog is within bounds */ |
| <> | 144:ef7eb2e8f9f7 | 124 | EFM_ASSERT(init->biasProg <= |
| <> | 144:ef7eb2e8f9f7 | 125 | (_ACMP_CTRL_BIASPROG_MASK >> _ACMP_CTRL_BIASPROG_SHIFT)); |
| <> | 144:ef7eb2e8f9f7 | 126 | |
| <> | 144:ef7eb2e8f9f7 | 127 | /* Set control register. No need to set interrupt modes */ |
| <> | 144:ef7eb2e8f9f7 | 128 | acmp->CTRL = (init->fullBias << _ACMP_CTRL_FULLBIAS_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 129 | #if defined(_ACMP_CTRL_HALFBIAS_MASK) |
| <> | 144:ef7eb2e8f9f7 | 130 | | (init->halfBias << _ACMP_CTRL_HALFBIAS_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 131 | #endif |
| <> | 144:ef7eb2e8f9f7 | 132 | | (init->biasProg << _ACMP_CTRL_BIASPROG_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 133 | #if defined(_ACMP_CTRL_WARMTIME_MASK) |
| <> | 144:ef7eb2e8f9f7 | 134 | | (init->warmTime << _ACMP_CTRL_WARMTIME_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 135 | #endif |
| <> | 144:ef7eb2e8f9f7 | 136 | #if defined(_ACMP_CTRL_HYSTSEL_MASK) |
| <> | 144:ef7eb2e8f9f7 | 137 | | (init->hysteresisLevel << _ACMP_CTRL_HYSTSEL_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 138 | #endif |
| <> | 144:ef7eb2e8f9f7 | 139 | #if defined(_ACMP_CTRL_ACCURACY_MASK) |
| <> | 144:ef7eb2e8f9f7 | 140 | | ACMP_CTRL_ACCURACY_HIGH |
| <> | 144:ef7eb2e8f9f7 | 141 | #endif |
| <> | 144:ef7eb2e8f9f7 | 142 | ; |
| <> | 144:ef7eb2e8f9f7 | 143 | |
| <> | 144:ef7eb2e8f9f7 | 144 | #if defined(_ACMP_HYSTERESIS0_MASK) |
| <> | 144:ef7eb2e8f9f7 | 145 | acmp->HYSTERESIS0 = (init->vddLevelHigh << _ACMP_HYSTERESIS0_DIVVA_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 146 | | (init->hysteresisLevel_0 << _ACMP_HYSTERESIS0_HYST_SHIFT); |
| <> | 144:ef7eb2e8f9f7 | 147 | acmp->HYSTERESIS1 = (init->vddLevelLow << _ACMP_HYSTERESIS1_DIVVA_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 148 | | (init->hysteresisLevel_1 << _ACMP_HYSTERESIS1_HYST_SHIFT); |
| <> | 144:ef7eb2e8f9f7 | 149 | #endif |
| <> | 144:ef7eb2e8f9f7 | 150 | |
| <> | 144:ef7eb2e8f9f7 | 151 | /* Select capacative sensing mode by selecting a resistor and enabling it */ |
| <> | 144:ef7eb2e8f9f7 | 152 | acmp->INPUTSEL = (init->resistor << _ACMP_INPUTSEL_CSRESSEL_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 153 | | ACMP_INPUTSEL_CSRESEN |
| <> | 144:ef7eb2e8f9f7 | 154 | #if defined(_ACMP_INPUTSEL_LPREF_MASK) |
| <> | 144:ef7eb2e8f9f7 | 155 | | (init->lowPowerReferenceEnabled << _ACMP_INPUTSEL_LPREF_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 156 | #endif |
| <> | 144:ef7eb2e8f9f7 | 157 | #if defined(_ACMP_INPUTSEL_VDDLEVEL_MASK) |
| <> | 144:ef7eb2e8f9f7 | 158 | | (init->vddLevel << _ACMP_INPUTSEL_VDDLEVEL_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 159 | #endif |
| <> | 144:ef7eb2e8f9f7 | 160 | #if defined(ACMP_INPUTSEL_NEGSEL_CAPSENSE) |
| <> | 144:ef7eb2e8f9f7 | 161 | | ACMP_INPUTSEL_NEGSEL_CAPSENSE |
| <> | 144:ef7eb2e8f9f7 | 162 | #else |
| <> | 144:ef7eb2e8f9f7 | 163 | | ACMP_INPUTSEL_VASEL_VDD |
| <> | 144:ef7eb2e8f9f7 | 164 | | ACMP_INPUTSEL_NEGSEL_VADIV |
| <> | 144:ef7eb2e8f9f7 | 165 | #endif |
| <> | 144:ef7eb2e8f9f7 | 166 | ; |
| <> | 144:ef7eb2e8f9f7 | 167 | |
| <> | 144:ef7eb2e8f9f7 | 168 | /* Enable ACMP if requested. */ |
| <> | 144:ef7eb2e8f9f7 | 169 | BUS_RegBitWrite(&(acmp->CTRL), _ACMP_CTRL_EN_SHIFT, init->enable); |
| <> | 144:ef7eb2e8f9f7 | 170 | } |
| <> | 144:ef7eb2e8f9f7 | 171 | |
| <> | 144:ef7eb2e8f9f7 | 172 | /***************************************************************************//** |
| <> | 144:ef7eb2e8f9f7 | 173 | * @brief |
| <> | 144:ef7eb2e8f9f7 | 174 | * Sets the ACMP channel used for capacative sensing. |
| <> | 144:ef7eb2e8f9f7 | 175 | * |
| <> | 144:ef7eb2e8f9f7 | 176 | * @note |
| <> | 144:ef7eb2e8f9f7 | 177 | * A basic example of capacative sensing can be found in the STK BSP |
| <> | 144:ef7eb2e8f9f7 | 178 | * (capsense demo). |
| <> | 144:ef7eb2e8f9f7 | 179 | * |
| <> | 144:ef7eb2e8f9f7 | 180 | * @param[in] acmp |
| <> | 144:ef7eb2e8f9f7 | 181 | * Pointer to ACMP peripheral register block. |
| <> | 144:ef7eb2e8f9f7 | 182 | * |
| <> | 144:ef7eb2e8f9f7 | 183 | * @param[in] channel |
| <> | 144:ef7eb2e8f9f7 | 184 | * The ACMP channel to use for capacative sensing (Possel). |
| <> | 144:ef7eb2e8f9f7 | 185 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 186 | void ACMP_CapsenseChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef channel) |
| <> | 144:ef7eb2e8f9f7 | 187 | { |
| <> | 144:ef7eb2e8f9f7 | 188 | /* Make sure the module exists on the selected chip */ |
| <> | 144:ef7eb2e8f9f7 | 189 | EFM_ASSERT(ACMP_REF_VALID(acmp)); |
| <> | 144:ef7eb2e8f9f7 | 190 | |
| <> | 144:ef7eb2e8f9f7 | 191 | #if defined(_ACMP_INPUTSEL_POSSEL_CH7) |
| <> | 144:ef7eb2e8f9f7 | 192 | /* Make sure that only external channels are used */ |
| <> | 144:ef7eb2e8f9f7 | 193 | EFM_ASSERT(channel <= _ACMP_INPUTSEL_POSSEL_CH7); |
| <> | 144:ef7eb2e8f9f7 | 194 | #elif defined(_ACMP_INPUTSEL_POSSEL_BUS4XCH31) |
| <> | 144:ef7eb2e8f9f7 | 195 | /* Make sure that only external channels are used */ |
| <> | 144:ef7eb2e8f9f7 | 196 | EFM_ASSERT(channel <= _ACMP_INPUTSEL_POSSEL_BUS4XCH31); |
| <> | 144:ef7eb2e8f9f7 | 197 | #endif |
| <> | 144:ef7eb2e8f9f7 | 198 | |
| <> | 144:ef7eb2e8f9f7 | 199 | /* Set channel as positive channel in ACMP */ |
| <> | 144:ef7eb2e8f9f7 | 200 | BUS_RegMaskedWrite(&acmp->INPUTSEL, _ACMP_INPUTSEL_POSSEL_MASK, |
| <> | 144:ef7eb2e8f9f7 | 201 | channel << _ACMP_INPUTSEL_POSSEL_SHIFT); |
| <> | 144:ef7eb2e8f9f7 | 202 | } |
| <> | 144:ef7eb2e8f9f7 | 203 | |
| <> | 144:ef7eb2e8f9f7 | 204 | /***************************************************************************//** |
| <> | 144:ef7eb2e8f9f7 | 205 | * @brief |
| <> | 144:ef7eb2e8f9f7 | 206 | * Disables the ACMP. |
| <> | 144:ef7eb2e8f9f7 | 207 | * |
| <> | 144:ef7eb2e8f9f7 | 208 | * @param[in] acmp |
| <> | 144:ef7eb2e8f9f7 | 209 | * Pointer to ACMP peripheral register block. |
| <> | 144:ef7eb2e8f9f7 | 210 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 211 | void ACMP_Disable(ACMP_TypeDef *acmp) |
| <> | 144:ef7eb2e8f9f7 | 212 | { |
| <> | 144:ef7eb2e8f9f7 | 213 | /* Make sure the module exists on the selected chip */ |
| <> | 144:ef7eb2e8f9f7 | 214 | EFM_ASSERT(ACMP_REF_VALID(acmp)); |
| <> | 144:ef7eb2e8f9f7 | 215 | |
| <> | 144:ef7eb2e8f9f7 | 216 | acmp->CTRL &= ~ACMP_CTRL_EN; |
| <> | 144:ef7eb2e8f9f7 | 217 | } |
| <> | 144:ef7eb2e8f9f7 | 218 | |
| <> | 144:ef7eb2e8f9f7 | 219 | /***************************************************************************//** |
| <> | 144:ef7eb2e8f9f7 | 220 | * @brief |
| <> | 144:ef7eb2e8f9f7 | 221 | * Enables the ACMP. |
| <> | 144:ef7eb2e8f9f7 | 222 | * |
| <> | 144:ef7eb2e8f9f7 | 223 | * @param[in] acmp |
| <> | 144:ef7eb2e8f9f7 | 224 | * Pointer to ACMP peripheral register block. |
| <> | 144:ef7eb2e8f9f7 | 225 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 226 | void ACMP_Enable(ACMP_TypeDef *acmp) |
| <> | 144:ef7eb2e8f9f7 | 227 | { |
| <> | 144:ef7eb2e8f9f7 | 228 | /* Make sure the module exists on the selected chip */ |
| <> | 144:ef7eb2e8f9f7 | 229 | EFM_ASSERT(ACMP_REF_VALID(acmp)); |
| <> | 144:ef7eb2e8f9f7 | 230 | |
| <> | 144:ef7eb2e8f9f7 | 231 | acmp->CTRL |= ACMP_CTRL_EN; |
| <> | 144:ef7eb2e8f9f7 | 232 | } |
| <> | 144:ef7eb2e8f9f7 | 233 | |
| <> | 144:ef7eb2e8f9f7 | 234 | /***************************************************************************//** |
| <> | 144:ef7eb2e8f9f7 | 235 | * @brief |
| <> | 144:ef7eb2e8f9f7 | 236 | * Reset ACMP to same state as after a HW reset. |
| <> | 144:ef7eb2e8f9f7 | 237 | * |
| <> | 144:ef7eb2e8f9f7 | 238 | * @note |
| <> | 144:ef7eb2e8f9f7 | 239 | * The ROUTE register is NOT reset by this function, in order to allow for |
| <> | 144:ef7eb2e8f9f7 | 240 | * centralized setup of this feature. |
| <> | 144:ef7eb2e8f9f7 | 241 | * |
| <> | 144:ef7eb2e8f9f7 | 242 | * @param[in] acmp |
| <> | 144:ef7eb2e8f9f7 | 243 | * Pointer to the ACMP peripheral register block. |
| <> | 144:ef7eb2e8f9f7 | 244 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 245 | void ACMP_Reset(ACMP_TypeDef *acmp) |
| <> | 144:ef7eb2e8f9f7 | 246 | { |
| <> | 144:ef7eb2e8f9f7 | 247 | /* Make sure the module exists on the selected chip */ |
| <> | 144:ef7eb2e8f9f7 | 248 | EFM_ASSERT(ACMP_REF_VALID(acmp)); |
| <> | 144:ef7eb2e8f9f7 | 249 | |
| <> | 144:ef7eb2e8f9f7 | 250 | acmp->CTRL = _ACMP_CTRL_RESETVALUE; |
| <> | 144:ef7eb2e8f9f7 | 251 | acmp->INPUTSEL = _ACMP_INPUTSEL_RESETVALUE; |
| <> | 144:ef7eb2e8f9f7 | 252 | #if defined(_ACMP_HYSTERESIS0_HYST_MASK) |
| <> | 144:ef7eb2e8f9f7 | 253 | acmp->HYSTERESIS0 = _ACMP_HYSTERESIS0_RESETVALUE; |
| <> | 144:ef7eb2e8f9f7 | 254 | acmp->HYSTERESIS1 = _ACMP_HYSTERESIS1_RESETVALUE; |
| <> | 144:ef7eb2e8f9f7 | 255 | #endif |
| <> | 144:ef7eb2e8f9f7 | 256 | acmp->IEN = _ACMP_IEN_RESETVALUE; |
| <> | 144:ef7eb2e8f9f7 | 257 | acmp->IFC = _ACMP_IF_MASK; |
| <> | 144:ef7eb2e8f9f7 | 258 | } |
| <> | 144:ef7eb2e8f9f7 | 259 | |
| <> | 144:ef7eb2e8f9f7 | 260 | /***************************************************************************//** |
| <> | 144:ef7eb2e8f9f7 | 261 | * @brief |
| <> | 144:ef7eb2e8f9f7 | 262 | * Sets up GPIO output from the ACMP. |
| <> | 144:ef7eb2e8f9f7 | 263 | * |
| <> | 144:ef7eb2e8f9f7 | 264 | * @note |
| <> | 144:ef7eb2e8f9f7 | 265 | * GPIO must be enabled in the CMU before this function call, i.e. |
| <> | 144:ef7eb2e8f9f7 | 266 | * @verbatim CMU_ClockEnable(cmuClock_GPIO, true); @endverbatim |
| <> | 144:ef7eb2e8f9f7 | 267 | * |
| <> | 144:ef7eb2e8f9f7 | 268 | * @param[in] acmp |
| <> | 144:ef7eb2e8f9f7 | 269 | * Pointer to the ACMP peripheral register block. |
| <> | 144:ef7eb2e8f9f7 | 270 | * |
| <> | 144:ef7eb2e8f9f7 | 271 | * @param location |
| <> | 144:ef7eb2e8f9f7 | 272 | * The pin location to use. See the datasheet for location to pin mappings. |
| <> | 144:ef7eb2e8f9f7 | 273 | * |
| <> | 144:ef7eb2e8f9f7 | 274 | * @param enable |
| <> | 144:ef7eb2e8f9f7 | 275 | * Enable or disable pin output. |
| <> | 144:ef7eb2e8f9f7 | 276 | * |
| <> | 144:ef7eb2e8f9f7 | 277 | * @param invert |
| <> | 144:ef7eb2e8f9f7 | 278 | * Invert output. |
| <> | 144:ef7eb2e8f9f7 | 279 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 280 | void ACMP_GPIOSetup(ACMP_TypeDef *acmp, uint32_t location, bool enable, bool invert) |
| <> | 144:ef7eb2e8f9f7 | 281 | { |
| <> | 144:ef7eb2e8f9f7 | 282 | /* Make sure the module exists on the selected chip */ |
| <> | 144:ef7eb2e8f9f7 | 283 | EFM_ASSERT(ACMP_REF_VALID(acmp)); |
| <> | 144:ef7eb2e8f9f7 | 284 | |
| <> | 144:ef7eb2e8f9f7 | 285 | /* Sanity checking of location */ |
| <> | 144:ef7eb2e8f9f7 | 286 | EFM_ASSERT(location <= _ACMP_ROUTE_LOCATION_MAX); |
| <> | 144:ef7eb2e8f9f7 | 287 | |
| <> | 144:ef7eb2e8f9f7 | 288 | /* Set GPIO inversion */ |
| <> | 144:ef7eb2e8f9f7 | 289 | BUS_RegMaskedWrite(&acmp->CTRL, _ACMP_CTRL_GPIOINV_MASK, |
| <> | 144:ef7eb2e8f9f7 | 290 | invert << _ACMP_CTRL_GPIOINV_SHIFT); |
| <> | 144:ef7eb2e8f9f7 | 291 | |
| <> | 144:ef7eb2e8f9f7 | 292 | #if defined(_ACMP_ROUTE_MASK) |
| <> | 144:ef7eb2e8f9f7 | 293 | acmp->ROUTE = (location << _ACMP_ROUTE_LOCATION_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 294 | | (enable << _ACMP_ROUTE_ACMPPEN_SHIFT); |
| <> | 144:ef7eb2e8f9f7 | 295 | #endif |
| <> | 144:ef7eb2e8f9f7 | 296 | #if defined(_ACMP_ROUTELOC0_MASK) |
| <> | 144:ef7eb2e8f9f7 | 297 | acmp->ROUTELOC0 = location << _ACMP_ROUTELOC0_OUTLOC_SHIFT; |
| <> | 144:ef7eb2e8f9f7 | 298 | acmp->ROUTEPEN = enable ? ACMP_ROUTEPEN_OUTPEN : 0; |
| <> | 144:ef7eb2e8f9f7 | 299 | #endif |
| <> | 144:ef7eb2e8f9f7 | 300 | } |
| <> | 144:ef7eb2e8f9f7 | 301 | |
| <> | 144:ef7eb2e8f9f7 | 302 | /***************************************************************************//** |
| <> | 144:ef7eb2e8f9f7 | 303 | * @brief |
| <> | 144:ef7eb2e8f9f7 | 304 | * Sets which channels should be used in ACMP comparisons. |
| <> | 144:ef7eb2e8f9f7 | 305 | * |
| <> | 144:ef7eb2e8f9f7 | 306 | * @param[in] acmp |
| <> | 144:ef7eb2e8f9f7 | 307 | * Pointer to the ACMP peripheral register block. |
| <> | 144:ef7eb2e8f9f7 | 308 | * |
| <> | 144:ef7eb2e8f9f7 | 309 | * @param negSel |
| <> | 144:ef7eb2e8f9f7 | 310 | * Channel to use on the negative input to the ACMP. |
| <> | 144:ef7eb2e8f9f7 | 311 | * |
| <> | 144:ef7eb2e8f9f7 | 312 | * @param posSel |
| <> | 144:ef7eb2e8f9f7 | 313 | * Channel to use on the positive input to the ACMP. |
| <> | 144:ef7eb2e8f9f7 | 314 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 315 | void ACMP_ChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef negSel, |
| <> | 144:ef7eb2e8f9f7 | 316 | ACMP_Channel_TypeDef posSel) |
| <> | 144:ef7eb2e8f9f7 | 317 | { |
| <> | 144:ef7eb2e8f9f7 | 318 | /* Make sure the module exists on the selected chip */ |
| <> | 144:ef7eb2e8f9f7 | 319 | EFM_ASSERT(ACMP_REF_VALID(acmp)); |
| <> | 144:ef7eb2e8f9f7 | 320 | |
| <> | 144:ef7eb2e8f9f7 | 321 | /* Make sure that posSel and negSel channel selectors are valid. */ |
| <> | 144:ef7eb2e8f9f7 | 322 | #if defined(_ACMP_INPUTSEL_NEGSEL_DAC0CH1) |
| <> | 144:ef7eb2e8f9f7 | 323 | EFM_ASSERT(negSel <= _ACMP_INPUTSEL_NEGSEL_DAC0CH1); |
| <> | 144:ef7eb2e8f9f7 | 324 | #elif defined(_ACMP_INPUTSEL_NEGSEL_CAPSENSE) |
| <> | 144:ef7eb2e8f9f7 | 325 | EFM_ASSERT(negSel <= _ACMP_INPUTSEL_NEGSEL_CAPSENSE); |
| <> | 144:ef7eb2e8f9f7 | 326 | #endif |
| <> | 144:ef7eb2e8f9f7 | 327 | |
| <> | 144:ef7eb2e8f9f7 | 328 | #if defined(_ACMP_INPUTSEL_POSSEL_CH7) |
| <> | 144:ef7eb2e8f9f7 | 329 | EFM_ASSERT(posSel <= _ACMP_INPUTSEL_POSSEL_CH7); |
| <> | 144:ef7eb2e8f9f7 | 330 | #endif |
| <> | 144:ef7eb2e8f9f7 | 331 | |
| <> | 144:ef7eb2e8f9f7 | 332 | acmp->INPUTSEL = (acmp->INPUTSEL & ~(_ACMP_INPUTSEL_POSSEL_MASK |
| <> | 144:ef7eb2e8f9f7 | 333 | | _ACMP_INPUTSEL_NEGSEL_MASK)) |
| <> | 144:ef7eb2e8f9f7 | 334 | | (negSel << _ACMP_INPUTSEL_NEGSEL_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 335 | | (posSel << _ACMP_INPUTSEL_POSSEL_SHIFT); |
| <> | 144:ef7eb2e8f9f7 | 336 | } |
| <> | 144:ef7eb2e8f9f7 | 337 | |
| <> | 144:ef7eb2e8f9f7 | 338 | /***************************************************************************//** |
| <> | 144:ef7eb2e8f9f7 | 339 | * @brief |
| <> | 144:ef7eb2e8f9f7 | 340 | * Initialize ACMP. |
| <> | 144:ef7eb2e8f9f7 | 341 | * |
| <> | 144:ef7eb2e8f9f7 | 342 | * @param[in] acmp |
| <> | 144:ef7eb2e8f9f7 | 343 | * Pointer to the ACMP peripheral register block. |
| <> | 144:ef7eb2e8f9f7 | 344 | * |
| <> | 144:ef7eb2e8f9f7 | 345 | * @param[in] init |
| <> | 144:ef7eb2e8f9f7 | 346 | * Pointer to initialization structure used to configure ACMP for capacative |
| <> | 144:ef7eb2e8f9f7 | 347 | * sensing operation. |
| <> | 144:ef7eb2e8f9f7 | 348 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 349 | void ACMP_Init(ACMP_TypeDef *acmp, const ACMP_Init_TypeDef *init) |
| <> | 144:ef7eb2e8f9f7 | 350 | { |
| <> | 144:ef7eb2e8f9f7 | 351 | /* Make sure the module exists on the selected chip */ |
| <> | 144:ef7eb2e8f9f7 | 352 | EFM_ASSERT(ACMP_REF_VALID(acmp)); |
| <> | 144:ef7eb2e8f9f7 | 353 | |
| <> | 144:ef7eb2e8f9f7 | 354 | /* Make sure biasprog is within bounds */ |
| <> | 144:ef7eb2e8f9f7 | 355 | EFM_ASSERT(init->biasProg < 16); |
| <> | 144:ef7eb2e8f9f7 | 356 | |
| <> | 144:ef7eb2e8f9f7 | 357 | /* Make sure the ACMP is disable since we might be changing the |
| <> | 144:ef7eb2e8f9f7 | 358 | * ACMP power source */ |
| <> | 144:ef7eb2e8f9f7 | 359 | BUS_RegBitWrite(&acmp->CTRL, _ACMP_CTRL_EN_SHIFT, 0); |
| <> | 144:ef7eb2e8f9f7 | 360 | |
| <> | 144:ef7eb2e8f9f7 | 361 | /* Set control register. No need to set interrupt modes */ |
| <> | 144:ef7eb2e8f9f7 | 362 | acmp->CTRL = (init->fullBias << _ACMP_CTRL_FULLBIAS_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 363 | #if defined(_ACMP_CTRL_HALFBIAS_MASK) |
| <> | 144:ef7eb2e8f9f7 | 364 | | (init->halfBias << _ACMP_CTRL_HALFBIAS_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 365 | #endif |
| <> | 144:ef7eb2e8f9f7 | 366 | | (init->biasProg << _ACMP_CTRL_BIASPROG_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 367 | | (init->interruptOnFallingEdge << _ACMP_CTRL_IFALL_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 368 | | (init->interruptOnRisingEdge << _ACMP_CTRL_IRISE_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 369 | #if defined(_ACMP_CTRL_INPUTRANGE_MASK) |
| <> | 144:ef7eb2e8f9f7 | 370 | | (init->inputRange << _ACMP_CTRL_INPUTRANGE_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 371 | #endif |
| <> | 144:ef7eb2e8f9f7 | 372 | #if defined(_ACMP_CTRL_ACCURACY_MASK) |
| <> | 144:ef7eb2e8f9f7 | 373 | | (init->accuracy << _ACMP_CTRL_ACCURACY_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 374 | #endif |
| <> | 144:ef7eb2e8f9f7 | 375 | #if defined(_ACMP_CTRL_PWRSEL_MASK) |
| <> | 144:ef7eb2e8f9f7 | 376 | | (init->powerSource << _ACMP_CTRL_PWRSEL_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 377 | #endif |
| <> | 144:ef7eb2e8f9f7 | 378 | #if defined(_ACMP_CTRL_WARMTIME_MASK) |
| <> | 144:ef7eb2e8f9f7 | 379 | | (init->warmTime << _ACMP_CTRL_WARMTIME_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 380 | #endif |
| <> | 144:ef7eb2e8f9f7 | 381 | #if defined(_ACMP_CTRL_HYSTSEL_MASK) |
| <> | 144:ef7eb2e8f9f7 | 382 | | (init->hysteresisLevel << _ACMP_CTRL_HYSTSEL_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 383 | #endif |
| <> | 144:ef7eb2e8f9f7 | 384 | | (init->inactiveValue << _ACMP_CTRL_INACTVAL_SHIFT); |
| <> | 144:ef7eb2e8f9f7 | 385 | |
| <> | 144:ef7eb2e8f9f7 | 386 | acmp->INPUTSEL = (0) |
| <> | 144:ef7eb2e8f9f7 | 387 | #if defined(_ACMP_INPUTSEL_VLPSEL_MASK) |
| <> | 144:ef7eb2e8f9f7 | 388 | | (init->vlpInput << _ACMP_INPUTSEL_VLPSEL_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 389 | #endif |
| <> | 144:ef7eb2e8f9f7 | 390 | #if defined(_ACMP_INPUTSEL_LPREF_MASK) |
| <> | 144:ef7eb2e8f9f7 | 391 | | (init->lowPowerReferenceEnabled << _ACMP_INPUTSEL_LPREF_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 392 | #endif |
| <> | 144:ef7eb2e8f9f7 | 393 | #if defined(_ACMP_INPUTSEL_VDDLEVEL_MASK) |
| <> | 144:ef7eb2e8f9f7 | 394 | | (init->vddLevel << _ACMP_INPUTSEL_VDDLEVEL_SHIFT) |
| <> | 144:ef7eb2e8f9f7 | 395 | #endif |
| <> | 144:ef7eb2e8f9f7 | 396 | ; |
| <> | 144:ef7eb2e8f9f7 | 397 | |
| <> | 144:ef7eb2e8f9f7 | 398 | /* Enable ACMP if requested. */ |
| <> | 144:ef7eb2e8f9f7 | 399 | BUS_RegBitWrite(&(acmp->CTRL), _ACMP_CTRL_EN_SHIFT, init->enable); |
| <> | 144:ef7eb2e8f9f7 | 400 | } |
| <> | 144:ef7eb2e8f9f7 | 401 | |
| <> | 144:ef7eb2e8f9f7 | 402 | #if defined(_ACMP_INPUTSEL_VASEL_MASK) |
| <> | 144:ef7eb2e8f9f7 | 403 | /***************************************************************************//** |
| <> | 144:ef7eb2e8f9f7 | 404 | * @brief |
| <> | 144:ef7eb2e8f9f7 | 405 | * Setup the VA Source. |
| <> | 144:ef7eb2e8f9f7 | 406 | * |
| <> | 144:ef7eb2e8f9f7 | 407 | * @param[in] acmp |
| <> | 144:ef7eb2e8f9f7 | 408 | * Pointer to the ACMP peripheral register block. |
| <> | 144:ef7eb2e8f9f7 | 409 | * |
| <> | 144:ef7eb2e8f9f7 | 410 | * @param[in] vaconfig |
| <> | 144:ef7eb2e8f9f7 | 411 | * Pointer to the structure used to configure the VA source. This structure |
| <> | 144:ef7eb2e8f9f7 | 412 | * contains the input source as well as the 2 divider values. |
| <> | 144:ef7eb2e8f9f7 | 413 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 414 | void ACMP_VASetup(ACMP_TypeDef *acmp, const ACMP_VAConfig_TypeDef *vaconfig) |
| <> | 144:ef7eb2e8f9f7 | 415 | { |
| <> | 144:ef7eb2e8f9f7 | 416 | EFM_ASSERT(vaconfig->div0 < 64); |
| <> | 144:ef7eb2e8f9f7 | 417 | EFM_ASSERT(vaconfig->div1 < 64); |
| <> | 144:ef7eb2e8f9f7 | 418 | |
| <> | 144:ef7eb2e8f9f7 | 419 | BUS_RegMaskedWrite(&acmp->INPUTSEL, _ACMP_INPUTSEL_VASEL_MASK, |
| <> | 144:ef7eb2e8f9f7 | 420 | vaconfig->input << _ACMP_INPUTSEL_VASEL_SHIFT); |
| <> | 144:ef7eb2e8f9f7 | 421 | BUS_RegMaskedWrite(&acmp->HYSTERESIS0, _ACMP_HYSTERESIS0_DIVVA_MASK, |
| <> | 144:ef7eb2e8f9f7 | 422 | vaconfig->div0 << _ACMP_HYSTERESIS0_DIVVA_SHIFT); |
| <> | 144:ef7eb2e8f9f7 | 423 | BUS_RegMaskedWrite(&acmp->HYSTERESIS1, _ACMP_HYSTERESIS1_DIVVA_MASK, |
| <> | 144:ef7eb2e8f9f7 | 424 | vaconfig->div1 << _ACMP_HYSTERESIS1_DIVVA_SHIFT); |
| <> | 144:ef7eb2e8f9f7 | 425 | } |
| <> | 144:ef7eb2e8f9f7 | 426 | #endif |
| <> | 144:ef7eb2e8f9f7 | 427 | |
| <> | 144:ef7eb2e8f9f7 | 428 | #if defined(_ACMP_INPUTSEL_VBSEL_MASK) |
| <> | 144:ef7eb2e8f9f7 | 429 | /***************************************************************************//** |
| <> | 144:ef7eb2e8f9f7 | 430 | * @brief |
| <> | 144:ef7eb2e8f9f7 | 431 | * Setup the VB Source. |
| <> | 144:ef7eb2e8f9f7 | 432 | * |
| <> | 144:ef7eb2e8f9f7 | 433 | * @param[in] acmp |
| <> | 144:ef7eb2e8f9f7 | 434 | * Pointer to the ACMP peripheral register block. |
| <> | 144:ef7eb2e8f9f7 | 435 | * |
| <> | 144:ef7eb2e8f9f7 | 436 | * @param[in] vbconfig |
| <> | 144:ef7eb2e8f9f7 | 437 | * Pointer to the structure used to configure the VB source. This structure |
| <> | 144:ef7eb2e8f9f7 | 438 | * contains the input source as well as the 2 divider values. |
| <> | 144:ef7eb2e8f9f7 | 439 | ******************************************************************************/ |
| <> | 144:ef7eb2e8f9f7 | 440 | void ACMP_VBSetup(ACMP_TypeDef *acmp, const ACMP_VBConfig_TypeDef *vbconfig) |
| <> | 144:ef7eb2e8f9f7 | 441 | { |
| <> | 144:ef7eb2e8f9f7 | 442 | EFM_ASSERT(vbconfig->div0 < 64); |
| <> | 144:ef7eb2e8f9f7 | 443 | EFM_ASSERT(vbconfig->div1 < 64); |
| <> | 144:ef7eb2e8f9f7 | 444 | |
| <> | 144:ef7eb2e8f9f7 | 445 | BUS_RegMaskedWrite(&acmp->INPUTSEL, _ACMP_INPUTSEL_VBSEL_MASK, |
| <> | 144:ef7eb2e8f9f7 | 446 | vbconfig->input << _ACMP_INPUTSEL_VBSEL_SHIFT); |
| <> | 144:ef7eb2e8f9f7 | 447 | BUS_RegMaskedWrite(&acmp->HYSTERESIS0, _ACMP_HYSTERESIS0_DIVVB_MASK, |
| <> | 144:ef7eb2e8f9f7 | 448 | vbconfig->div0 << _ACMP_HYSTERESIS0_DIVVB_SHIFT); |
| <> | 144:ef7eb2e8f9f7 | 449 | BUS_RegMaskedWrite(&acmp->HYSTERESIS1, _ACMP_HYSTERESIS1_DIVVB_MASK, |
| <> | 144:ef7eb2e8f9f7 | 450 | vbconfig->div1 << _ACMP_HYSTERESIS1_DIVVB_SHIFT); |
| <> | 144:ef7eb2e8f9f7 | 451 | } |
| <> | 144:ef7eb2e8f9f7 | 452 | #endif |
| <> | 144:ef7eb2e8f9f7 | 453 | |
| <> | 144:ef7eb2e8f9f7 | 454 | /** @} (end addtogroup ACMP) */ |
| <> | 144:ef7eb2e8f9f7 | 455 | /** @} (end addtogroup EM_Library) */ |
| <> | 144:ef7eb2e8f9f7 | 456 | #endif /* defined(ACMP_COUNT) && (ACMP_COUNT > 0) */ |
