mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Thu Dec 07 14:01:42 2017 +0000
Revision:
179:b0033dcd6934
Parent:
161:2cc1468da177
mbed-dev library. Release version 157

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2 * @file em_adc.c
<> 144:ef7eb2e8f9f7 3 * @brief Analog to Digital Converter (ADC) Peripheral API
AnnaBridge 179:b0033dcd6934 4 * @version 5.3.3
<> 144:ef7eb2e8f9f7 5 *******************************************************************************
AnnaBridge 179:b0033dcd6934 6 * # License
<> 150:02e0a0aed4ec 7 * <b>Copyright 2016 Silicon Laboratories, Inc. 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 #include "em_adc.h"
AnnaBridge 179:b0033dcd6934 34 #if defined(ADC_COUNT) && (ADC_COUNT > 0)
<> 144:ef7eb2e8f9f7 35
<> 150:02e0a0aed4ec 36 #include "em_assert.h"
<> 144:ef7eb2e8f9f7 37 #include "em_cmu.h"
<> 144:ef7eb2e8f9f7 38 #include <stddef.h>
<> 144:ef7eb2e8f9f7 39
<> 144:ef7eb2e8f9f7 40 /***************************************************************************//**
<> 150:02e0a0aed4ec 41 * @addtogroup emlib
<> 144:ef7eb2e8f9f7 42 * @{
<> 144:ef7eb2e8f9f7 43 ******************************************************************************/
<> 144:ef7eb2e8f9f7 44
<> 144:ef7eb2e8f9f7 45 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 46 * @addtogroup ADC
<> 144:ef7eb2e8f9f7 47 * @brief Analog to Digital Converter (ADC) Peripheral API
<> 150:02e0a0aed4ec 48 * @details
<> 150:02e0a0aed4ec 49 * This module contains functions to control the ADC peripheral of Silicon
<> 150:02e0a0aed4ec 50 * Labs 32-bit MCUs and SoCs. The ADC is used to convert analog signals into a
<> 150:02e0a0aed4ec 51 * digital representation.
<> 144:ef7eb2e8f9f7 52 * @{
<> 144:ef7eb2e8f9f7 53 ******************************************************************************/
<> 144:ef7eb2e8f9f7 54
<> 144:ef7eb2e8f9f7 55 /*******************************************************************************
<> 144:ef7eb2e8f9f7 56 ******************************* DEFINES ***********************************
<> 144:ef7eb2e8f9f7 57 ******************************************************************************/
<> 144:ef7eb2e8f9f7 58
<> 144:ef7eb2e8f9f7 59 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 60
<> 144:ef7eb2e8f9f7 61 /** Validation of ADC register block pointer reference for assert statements. */
AnnaBridge 179:b0033dcd6934 62 #if (ADC_COUNT == 1)
<> 144:ef7eb2e8f9f7 63 #define ADC_REF_VALID(ref) ((ref) == ADC0)
AnnaBridge 179:b0033dcd6934 64 #elif (ADC_COUNT == 2)
AnnaBridge 179:b0033dcd6934 65 #define ADC_REF_VALID(ref) (((ref) == ADC0) || ((ref) == ADC1))
AnnaBridge 179:b0033dcd6934 66 #endif
<> 144:ef7eb2e8f9f7 67
<> 144:ef7eb2e8f9f7 68 /** Max ADC clock */
AnnaBridge 179:b0033dcd6934 69 #if defined(_SILICON_LABS_32B_SERIES_0)
<> 144:ef7eb2e8f9f7 70 #define ADC_MAX_CLOCK 13000000
<> 144:ef7eb2e8f9f7 71 #else
<> 144:ef7eb2e8f9f7 72 #define ADC_MAX_CLOCK 16000000
<> 144:ef7eb2e8f9f7 73 #endif
<> 144:ef7eb2e8f9f7 74
<> 144:ef7eb2e8f9f7 75 /** Min ADC clock */
<> 144:ef7eb2e8f9f7 76 #define ADC_MIN_CLOCK 32000
<> 144:ef7eb2e8f9f7 77
<> 144:ef7eb2e8f9f7 78 /** Helper defines for selecting ADC calibration and DEVINFO register fields. */
AnnaBridge 179:b0033dcd6934 79 #if defined(_DEVINFO_ADC0CAL0_1V25_GAIN_MASK)
<> 144:ef7eb2e8f9f7 80 #define DEVINFO_ADC0_GAIN1V25_MASK _DEVINFO_ADC0CAL0_1V25_GAIN_MASK
AnnaBridge 179:b0033dcd6934 81 #elif defined(_DEVINFO_ADC0CAL0_GAIN1V25_MASK)
<> 144:ef7eb2e8f9f7 82 #define DEVINFO_ADC0_GAIN1V25_MASK _DEVINFO_ADC0CAL0_GAIN1V25_MASK
<> 144:ef7eb2e8f9f7 83 #endif
<> 144:ef7eb2e8f9f7 84
AnnaBridge 179:b0033dcd6934 85 #if defined(_DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT)
<> 144:ef7eb2e8f9f7 86 #define DEVINFO_ADC0_GAIN1V25_SHIFT _DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT
AnnaBridge 179:b0033dcd6934 87 #elif defined(_DEVINFO_ADC0CAL0_GAIN1V25_SHIFT)
<> 144:ef7eb2e8f9f7 88 #define DEVINFO_ADC0_GAIN1V25_SHIFT _DEVINFO_ADC0CAL0_GAIN1V25_SHIFT
<> 144:ef7eb2e8f9f7 89 #endif
<> 144:ef7eb2e8f9f7 90
AnnaBridge 179:b0033dcd6934 91 #if defined(_DEVINFO_ADC0CAL0_1V25_OFFSET_MASK)
<> 144:ef7eb2e8f9f7 92 #define DEVINFO_ADC0_OFFSET1V25_MASK _DEVINFO_ADC0CAL0_1V25_OFFSET_MASK
AnnaBridge 179:b0033dcd6934 93 #elif defined(_DEVINFO_ADC0CAL0_OFFSET1V25_MASK)
<> 144:ef7eb2e8f9f7 94 #define DEVINFO_ADC0_OFFSET1V25_MASK _DEVINFO_ADC0CAL0_OFFSET1V25_MASK
<> 144:ef7eb2e8f9f7 95 #endif
<> 144:ef7eb2e8f9f7 96
AnnaBridge 179:b0033dcd6934 97 #if defined(_DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT)
<> 144:ef7eb2e8f9f7 98 #define DEVINFO_ADC0_OFFSET1V25_SHIFT _DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT
AnnaBridge 179:b0033dcd6934 99 #elif defined(_DEVINFO_ADC0CAL0_OFFSET1V25_SHIFT)
<> 144:ef7eb2e8f9f7 100 #define DEVINFO_ADC0_OFFSET1V25_SHIFT _DEVINFO_ADC0CAL0_OFFSET1V25_SHIFT
<> 144:ef7eb2e8f9f7 101 #endif
<> 144:ef7eb2e8f9f7 102
AnnaBridge 179:b0033dcd6934 103 #if defined(_DEVINFO_ADC0CAL0_2V5_GAIN_MASK)
<> 144:ef7eb2e8f9f7 104 #define DEVINFO_ADC0_GAIN2V5_MASK _DEVINFO_ADC0CAL0_2V5_GAIN_MASK
AnnaBridge 179:b0033dcd6934 105 #elif defined(_DEVINFO_ADC0CAL0_GAIN2V5_MASK)
<> 144:ef7eb2e8f9f7 106 #define DEVINFO_ADC0_GAIN2V5_MASK _DEVINFO_ADC0CAL0_GAIN2V5_MASK
<> 144:ef7eb2e8f9f7 107 #endif
<> 144:ef7eb2e8f9f7 108
AnnaBridge 179:b0033dcd6934 109 #if defined(_DEVINFO_ADC0CAL0_2V5_GAIN_SHIFT)
<> 144:ef7eb2e8f9f7 110 #define DEVINFO_ADC0_GAIN2V5_SHIFT _DEVINFO_ADC0CAL0_2V5_GAIN_SHIFT
AnnaBridge 179:b0033dcd6934 111 #elif defined(_DEVINFO_ADC0CAL0_GAIN2V5_SHIFT)
<> 144:ef7eb2e8f9f7 112 #define DEVINFO_ADC0_GAIN2V5_SHIFT _DEVINFO_ADC0CAL0_GAIN2V5_SHIFT
<> 144:ef7eb2e8f9f7 113 #endif
<> 144:ef7eb2e8f9f7 114
AnnaBridge 179:b0033dcd6934 115 #if defined(_DEVINFO_ADC0CAL0_2V5_OFFSET_MASK)
<> 144:ef7eb2e8f9f7 116 #define DEVINFO_ADC0_OFFSET2V5_MASK _DEVINFO_ADC0CAL0_2V5_OFFSET_MASK
AnnaBridge 179:b0033dcd6934 117 #elif defined(_DEVINFO_ADC0CAL0_OFFSET2V5_MASK)
<> 144:ef7eb2e8f9f7 118 #define DEVINFO_ADC0_OFFSET2V5_MASK _DEVINFO_ADC0CAL0_OFFSET2V5_MASK
<> 144:ef7eb2e8f9f7 119 #endif
<> 144:ef7eb2e8f9f7 120
AnnaBridge 179:b0033dcd6934 121 #if defined(_DEVINFO_ADC0CAL0_2V5_OFFSET_SHIFT)
<> 144:ef7eb2e8f9f7 122 #define DEVINFO_ADC0_OFFSET2V5_SHIFT _DEVINFO_ADC0CAL0_2V5_OFFSET_SHIFT
AnnaBridge 179:b0033dcd6934 123 #elif defined(_DEVINFO_ADC0CAL0_OFFSET2V5_SHIFT)
<> 144:ef7eb2e8f9f7 124 #define DEVINFO_ADC0_OFFSET2V5_SHIFT _DEVINFO_ADC0CAL0_OFFSET2V5_SHIFT
<> 144:ef7eb2e8f9f7 125 #endif
<> 144:ef7eb2e8f9f7 126
AnnaBridge 179:b0033dcd6934 127 #if defined(_DEVINFO_ADC0CAL1_VDD_GAIN_MASK)
<> 144:ef7eb2e8f9f7 128 #define DEVINFO_ADC0_GAINVDD_MASK _DEVINFO_ADC0CAL1_VDD_GAIN_MASK
AnnaBridge 179:b0033dcd6934 129 #elif defined(_DEVINFO_ADC0CAL1_GAINVDD_MASK)
<> 144:ef7eb2e8f9f7 130 #define DEVINFO_ADC0_GAINVDD_MASK _DEVINFO_ADC0CAL1_GAINVDD_MASK
<> 144:ef7eb2e8f9f7 131 #endif
<> 144:ef7eb2e8f9f7 132
AnnaBridge 179:b0033dcd6934 133 #if defined(_DEVINFO_ADC0CAL1_VDD_GAIN_SHIFT)
<> 144:ef7eb2e8f9f7 134 #define DEVINFO_ADC0_GAINVDD_SHIFT _DEVINFO_ADC0CAL1_VDD_GAIN_SHIFT
AnnaBridge 179:b0033dcd6934 135 #elif defined(_DEVINFO_ADC0CAL1_GAINVDD_SHIFT)
<> 144:ef7eb2e8f9f7 136 #define DEVINFO_ADC0_GAINVDD_SHIFT _DEVINFO_ADC0CAL1_GAINVDD_SHIFT
<> 144:ef7eb2e8f9f7 137 #endif
<> 144:ef7eb2e8f9f7 138
AnnaBridge 179:b0033dcd6934 139 #if defined(_DEVINFO_ADC0CAL1_VDD_OFFSET_MASK)
<> 144:ef7eb2e8f9f7 140 #define DEVINFO_ADC0_OFFSETVDD_MASK _DEVINFO_ADC0CAL1_VDD_OFFSET_MASK
AnnaBridge 179:b0033dcd6934 141 #elif defined(_DEVINFO_ADC0CAL1_OFFSETVDD_MASK)
<> 144:ef7eb2e8f9f7 142 #define DEVINFO_ADC0_OFFSETVDD_MASK _DEVINFO_ADC0CAL1_OFFSETVDD_MASK
<> 144:ef7eb2e8f9f7 143 #endif
<> 144:ef7eb2e8f9f7 144
AnnaBridge 179:b0033dcd6934 145 #if defined(_DEVINFO_ADC0CAL1_VDD_OFFSET_SHIFT)
<> 144:ef7eb2e8f9f7 146 #define DEVINFO_ADC0_OFFSETVDD_SHIFT _DEVINFO_ADC0CAL1_VDD_OFFSET_SHIFT
AnnaBridge 179:b0033dcd6934 147 #elif defined(_DEVINFO_ADC0CAL1_OFFSETVDD_SHIFT)
<> 144:ef7eb2e8f9f7 148 #define DEVINFO_ADC0_OFFSETVDD_SHIFT _DEVINFO_ADC0CAL1_OFFSETVDD_SHIFT
<> 144:ef7eb2e8f9f7 149 #endif
<> 144:ef7eb2e8f9f7 150
AnnaBridge 179:b0033dcd6934 151 #if defined(_DEVINFO_ADC0CAL1_5VDIFF_GAIN_MASK)
<> 144:ef7eb2e8f9f7 152 #define DEVINFO_ADC0_GAIN5VDIFF_MASK _DEVINFO_ADC0CAL1_5VDIFF_GAIN_MASK
AnnaBridge 179:b0033dcd6934 153 #elif defined(_DEVINFO_ADC0CAL1_GAIN5VDIFF_MASK)
<> 144:ef7eb2e8f9f7 154 #define DEVINFO_ADC0_GAIN5VDIFF_MASK _DEVINFO_ADC0CAL1_GAIN5VDIFF_MASK
<> 144:ef7eb2e8f9f7 155 #endif
<> 144:ef7eb2e8f9f7 156
AnnaBridge 179:b0033dcd6934 157 #if defined(_DEVINFO_ADC0CAL1_5VDIFF_GAIN_SHIFT)
<> 144:ef7eb2e8f9f7 158 #define DEVINFO_ADC0_GAIN5VDIFF_SHIFT _DEVINFO_ADC0CAL1_5VDIFF_GAIN_SHIFT
AnnaBridge 179:b0033dcd6934 159 #elif defined(_DEVINFO_ADC0CAL1_GAIN5VDIFF_SHIFT)
<> 144:ef7eb2e8f9f7 160 #define DEVINFO_ADC0_GAIN5VDIFF_SHIFT _DEVINFO_ADC0CAL1_GAIN5VDIFF_SHIFT
<> 144:ef7eb2e8f9f7 161 #endif
<> 144:ef7eb2e8f9f7 162
AnnaBridge 179:b0033dcd6934 163 #if defined(_DEVINFO_ADC0CAL1_5VDIFF_OFFSET_MASK)
<> 144:ef7eb2e8f9f7 164 #define DEVINFO_ADC0_OFFSET5VDIFF_MASK _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_MASK
AnnaBridge 179:b0033dcd6934 165 #elif defined(_DEVINFO_ADC0CAL1_OFFSET5VDIFF_MASK)
<> 144:ef7eb2e8f9f7 166 #define DEVINFO_ADC0_OFFSET5VDIFF_MASK _DEVINFO_ADC0CAL1_OFFSET5VDIFF_MASK
<> 144:ef7eb2e8f9f7 167 #endif
<> 144:ef7eb2e8f9f7 168
AnnaBridge 179:b0033dcd6934 169 #if defined(_DEVINFO_ADC0CAL1_5VDIFF_OFFSET_SHIFT)
<> 144:ef7eb2e8f9f7 170 #define DEVINFO_ADC0_OFFSET5VDIFF_SHIFT _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_SHIFT
AnnaBridge 179:b0033dcd6934 171 #elif defined(_DEVINFO_ADC0CAL1_OFFSET5VDIFF_SHIFT)
<> 144:ef7eb2e8f9f7 172 #define DEVINFO_ADC0_OFFSET5VDIFF_SHIFT _DEVINFO_ADC0CAL1_OFFSET5VDIFF_SHIFT
<> 144:ef7eb2e8f9f7 173 #endif
<> 144:ef7eb2e8f9f7 174
AnnaBridge 179:b0033dcd6934 175 #if defined(_DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_MASK)
<> 144:ef7eb2e8f9f7 176 #define DEVINFO_ADC0_OFFSET2XVDD_MASK _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_MASK
AnnaBridge 179:b0033dcd6934 177 #elif defined(_DEVINFO_ADC0CAL2_OFFSET2XVDD_MASK)
<> 144:ef7eb2e8f9f7 178 #define DEVINFO_ADC0_OFFSET2XVDD_MASK _DEVINFO_ADC0CAL2_OFFSET2XVDD_MASK
<> 144:ef7eb2e8f9f7 179 #endif
<> 144:ef7eb2e8f9f7 180
AnnaBridge 179:b0033dcd6934 181 #if defined(_DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_SHIFT)
<> 144:ef7eb2e8f9f7 182 #define DEVINFO_ADC0_OFFSET2XVDD_SHIFT _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_SHIFT
AnnaBridge 179:b0033dcd6934 183 #elif defined(_DEVINFO_ADC0CAL2_OFFSET2XVDD_SHIFT)
<> 144:ef7eb2e8f9f7 184 #define DEVINFO_ADC0_OFFSET2XVDD_SHIFT _DEVINFO_ADC0CAL2_OFFSET2XVDD_SHIFT
<> 144:ef7eb2e8f9f7 185 #endif
<> 144:ef7eb2e8f9f7 186
AnnaBridge 179:b0033dcd6934 187 #if defined(_SILICON_LABS_32B_SERIES_1)
<> 150:02e0a0aed4ec 188 #define FIX_ADC_TEMP_BIAS_EN
<> 150:02e0a0aed4ec 189 #endif
AnnaBridge 179:b0033dcd6934 190
<> 144:ef7eb2e8f9f7 191 /** @endcond */
<> 144:ef7eb2e8f9f7 192
<> 144:ef7eb2e8f9f7 193 /*******************************************************************************
<> 144:ef7eb2e8f9f7 194 *************************** LOCAL FUNCTIONS *******************************
<> 144:ef7eb2e8f9f7 195 ******************************************************************************/
<> 144:ef7eb2e8f9f7 196
<> 144:ef7eb2e8f9f7 197 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 198
<> 144:ef7eb2e8f9f7 199 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 200 * @brief
<> 144:ef7eb2e8f9f7 201 * Load ADC calibration register for a selected reference and conversion mode.
<> 144:ef7eb2e8f9f7 202 *
<> 144:ef7eb2e8f9f7 203 * @details
<> 144:ef7eb2e8f9f7 204 * During production, calibration values are stored in the device
<> 144:ef7eb2e8f9f7 205 * information page for internal references. Notice that for external references,
<> 144:ef7eb2e8f9f7 206 * calibration values must be determined explicitly, and this function
<> 144:ef7eb2e8f9f7 207 * will not modify the calibration register for external references.
<> 144:ef7eb2e8f9f7 208 *
<> 144:ef7eb2e8f9f7 209 * @param[in] adc
<> 144:ef7eb2e8f9f7 210 * Pointer to ADC peripheral register block.
<> 144:ef7eb2e8f9f7 211 *
<> 144:ef7eb2e8f9f7 212 * @param[in] ref
<> 144:ef7eb2e8f9f7 213 * Reference to load calibrated values for. No values are loaded for
<> 144:ef7eb2e8f9f7 214 * external references.
<> 144:ef7eb2e8f9f7 215 *
<> 144:ef7eb2e8f9f7 216 * @param[in] setScanCal
<> 144:ef7eb2e8f9f7 217 * Select scan mode (true) or single mode (false) calibration load.
<> 144:ef7eb2e8f9f7 218 ******************************************************************************/
<> 144:ef7eb2e8f9f7 219 static void ADC_LoadDevinfoCal(ADC_TypeDef *adc,
<> 144:ef7eb2e8f9f7 220 ADC_Ref_TypeDef ref,
<> 144:ef7eb2e8f9f7 221 bool setScanCal)
<> 144:ef7eb2e8f9f7 222 {
<> 144:ef7eb2e8f9f7 223 uint32_t calReg;
<> 144:ef7eb2e8f9f7 224 uint32_t newCal;
<> 144:ef7eb2e8f9f7 225 uint32_t mask;
<> 144:ef7eb2e8f9f7 226 uint32_t shift;
AnnaBridge 179:b0033dcd6934 227 __IM uint32_t * diCalReg;
<> 144:ef7eb2e8f9f7 228
AnnaBridge 179:b0033dcd6934 229 if (setScanCal) {
<> 144:ef7eb2e8f9f7 230 shift = _ADC_CAL_SCANOFFSET_SHIFT;
<> 144:ef7eb2e8f9f7 231 mask = ~(_ADC_CAL_SCANOFFSET_MASK
AnnaBridge 179:b0033dcd6934 232 #if defined(_ADC_CAL_SCANOFFSETINV_MASK)
<> 144:ef7eb2e8f9f7 233 | _ADC_CAL_SCANOFFSETINV_MASK
<> 144:ef7eb2e8f9f7 234 #endif
<> 144:ef7eb2e8f9f7 235 | _ADC_CAL_SCANGAIN_MASK);
AnnaBridge 179:b0033dcd6934 236 } else {
<> 144:ef7eb2e8f9f7 237 shift = _ADC_CAL_SINGLEOFFSET_SHIFT;
<> 144:ef7eb2e8f9f7 238 mask = ~(_ADC_CAL_SINGLEOFFSET_MASK
AnnaBridge 179:b0033dcd6934 239 #if defined(_ADC_CAL_SINGLEOFFSETINV_MASK)
<> 144:ef7eb2e8f9f7 240 | _ADC_CAL_SINGLEOFFSETINV_MASK
<> 144:ef7eb2e8f9f7 241 #endif
<> 144:ef7eb2e8f9f7 242 | _ADC_CAL_SINGLEGAIN_MASK);
<> 144:ef7eb2e8f9f7 243 }
<> 144:ef7eb2e8f9f7 244
<> 144:ef7eb2e8f9f7 245 calReg = adc->CAL & mask;
<> 144:ef7eb2e8f9f7 246 newCal = 0;
<> 144:ef7eb2e8f9f7 247
AnnaBridge 179:b0033dcd6934 248 if (adc == ADC0) {
AnnaBridge 179:b0033dcd6934 249 diCalReg = &DEVINFO->ADC0CAL0;
AnnaBridge 179:b0033dcd6934 250 }
AnnaBridge 179:b0033dcd6934 251 #if defined(ADC1)
AnnaBridge 179:b0033dcd6934 252 else if (adc == ADC1) {
AnnaBridge 179:b0033dcd6934 253 diCalReg = &DEVINFO->ADC1CAL0;
AnnaBridge 179:b0033dcd6934 254 }
AnnaBridge 179:b0033dcd6934 255 #endif
AnnaBridge 179:b0033dcd6934 256 else {
AnnaBridge 179:b0033dcd6934 257 return;
AnnaBridge 179:b0033dcd6934 258 }
AnnaBridge 179:b0033dcd6934 259
AnnaBridge 179:b0033dcd6934 260 switch (ref) {
<> 144:ef7eb2e8f9f7 261 case adcRef1V25:
AnnaBridge 179:b0033dcd6934 262 newCal |= ((diCalReg[0] & DEVINFO_ADC0_GAIN1V25_MASK)
<> 144:ef7eb2e8f9f7 263 >> DEVINFO_ADC0_GAIN1V25_SHIFT)
<> 144:ef7eb2e8f9f7 264 << _ADC_CAL_SINGLEGAIN_SHIFT;
AnnaBridge 179:b0033dcd6934 265 newCal |= ((diCalReg[0] & DEVINFO_ADC0_OFFSET1V25_MASK)
<> 144:ef7eb2e8f9f7 266 >> DEVINFO_ADC0_OFFSET1V25_SHIFT)
<> 144:ef7eb2e8f9f7 267 << _ADC_CAL_SINGLEOFFSET_SHIFT;
AnnaBridge 179:b0033dcd6934 268 #if defined(_ADC_CAL_SINGLEOFFSETINV_MASK)
AnnaBridge 179:b0033dcd6934 269 newCal |= ((diCalReg[0] & _DEVINFO_ADC0CAL0_NEGSEOFFSET1V25_MASK)
<> 144:ef7eb2e8f9f7 270 >> _DEVINFO_ADC0CAL0_NEGSEOFFSET1V25_SHIFT)
<> 144:ef7eb2e8f9f7 271 << _ADC_CAL_SINGLEOFFSETINV_SHIFT;
<> 144:ef7eb2e8f9f7 272 #endif
<> 144:ef7eb2e8f9f7 273 break;
<> 144:ef7eb2e8f9f7 274
<> 144:ef7eb2e8f9f7 275 case adcRef2V5:
AnnaBridge 179:b0033dcd6934 276 newCal |= ((diCalReg[0] & DEVINFO_ADC0_GAIN2V5_MASK)
<> 144:ef7eb2e8f9f7 277 >> DEVINFO_ADC0_GAIN2V5_SHIFT)
<> 144:ef7eb2e8f9f7 278 << _ADC_CAL_SINGLEGAIN_SHIFT;
AnnaBridge 179:b0033dcd6934 279 newCal |= ((diCalReg[0] & DEVINFO_ADC0_OFFSET2V5_MASK)
<> 144:ef7eb2e8f9f7 280 >> DEVINFO_ADC0_OFFSET2V5_SHIFT)
<> 144:ef7eb2e8f9f7 281 << _ADC_CAL_SINGLEOFFSET_SHIFT;
AnnaBridge 179:b0033dcd6934 282 #if defined(_ADC_CAL_SINGLEOFFSETINV_MASK)
AnnaBridge 179:b0033dcd6934 283 newCal |= ((diCalReg[0] & _DEVINFO_ADC0CAL0_NEGSEOFFSET2V5_MASK)
<> 144:ef7eb2e8f9f7 284 >> _DEVINFO_ADC0CAL0_NEGSEOFFSET2V5_SHIFT)
<> 144:ef7eb2e8f9f7 285 << _ADC_CAL_SINGLEOFFSETINV_SHIFT;
<> 144:ef7eb2e8f9f7 286 #endif
<> 144:ef7eb2e8f9f7 287 break;
<> 144:ef7eb2e8f9f7 288
<> 144:ef7eb2e8f9f7 289 case adcRefVDD:
AnnaBridge 179:b0033dcd6934 290 newCal |= ((diCalReg[1] & DEVINFO_ADC0_GAINVDD_MASK)
<> 144:ef7eb2e8f9f7 291 >> DEVINFO_ADC0_GAINVDD_SHIFT)
<> 144:ef7eb2e8f9f7 292 << _ADC_CAL_SINGLEGAIN_SHIFT;
AnnaBridge 179:b0033dcd6934 293 newCal |= ((diCalReg[1] & DEVINFO_ADC0_OFFSETVDD_MASK)
<> 144:ef7eb2e8f9f7 294 >> DEVINFO_ADC0_OFFSETVDD_SHIFT)
AnnaBridge 179:b0033dcd6934 295 << _ADC_CAL_SINGLEOFFSET_SHIFT;
AnnaBridge 179:b0033dcd6934 296 #if defined(_ADC_CAL_SINGLEOFFSETINV_MASK)
AnnaBridge 179:b0033dcd6934 297 newCal |= ((diCalReg[1] & _DEVINFO_ADC0CAL1_NEGSEOFFSETVDD_MASK)
<> 144:ef7eb2e8f9f7 298 >> _DEVINFO_ADC0CAL1_NEGSEOFFSETVDD_SHIFT)
<> 144:ef7eb2e8f9f7 299 << _ADC_CAL_SINGLEOFFSETINV_SHIFT;
<> 144:ef7eb2e8f9f7 300 #endif
<> 144:ef7eb2e8f9f7 301 break;
<> 144:ef7eb2e8f9f7 302
<> 144:ef7eb2e8f9f7 303 case adcRef5VDIFF:
AnnaBridge 179:b0033dcd6934 304 newCal |= ((diCalReg[1] & DEVINFO_ADC0_GAIN5VDIFF_MASK)
<> 144:ef7eb2e8f9f7 305 >> DEVINFO_ADC0_GAIN5VDIFF_SHIFT)
<> 144:ef7eb2e8f9f7 306 << _ADC_CAL_SINGLEGAIN_SHIFT;
AnnaBridge 179:b0033dcd6934 307 newCal |= ((diCalReg[1] & DEVINFO_ADC0_OFFSET5VDIFF_MASK)
<> 144:ef7eb2e8f9f7 308 >> DEVINFO_ADC0_OFFSET5VDIFF_SHIFT)
<> 144:ef7eb2e8f9f7 309 << _ADC_CAL_SINGLEOFFSET_SHIFT;
AnnaBridge 179:b0033dcd6934 310 #if defined(_ADC_CAL_SINGLEOFFSETINV_MASK)
AnnaBridge 179:b0033dcd6934 311 newCal |= ((diCalReg[1] & _DEVINFO_ADC0CAL1_NEGSEOFFSET5VDIFF_MASK)
<> 144:ef7eb2e8f9f7 312 >> _DEVINFO_ADC0CAL1_NEGSEOFFSET5VDIFF_SHIFT)
<> 144:ef7eb2e8f9f7 313 << _ADC_CAL_SINGLEOFFSETINV_SHIFT;
<> 144:ef7eb2e8f9f7 314 #endif
<> 144:ef7eb2e8f9f7 315 break;
<> 144:ef7eb2e8f9f7 316
<> 144:ef7eb2e8f9f7 317 case adcRef2xVDD:
<> 144:ef7eb2e8f9f7 318 /* There is no gain calibration for this reference */
AnnaBridge 179:b0033dcd6934 319 newCal |= ((diCalReg[2] & DEVINFO_ADC0_OFFSET2XVDD_MASK)
<> 144:ef7eb2e8f9f7 320 >> DEVINFO_ADC0_OFFSET2XVDD_SHIFT)
<> 144:ef7eb2e8f9f7 321 << _ADC_CAL_SINGLEOFFSET_SHIFT;
AnnaBridge 179:b0033dcd6934 322 #if defined(_ADC_CAL_SINGLEOFFSETINV_MASK)
AnnaBridge 179:b0033dcd6934 323 newCal |= ((diCalReg[2] & _DEVINFO_ADC0CAL2_NEGSEOFFSET2XVDD_MASK)
<> 144:ef7eb2e8f9f7 324 >> _DEVINFO_ADC0CAL2_NEGSEOFFSET2XVDD_SHIFT)
<> 144:ef7eb2e8f9f7 325 << _ADC_CAL_SINGLEOFFSETINV_SHIFT;
<> 144:ef7eb2e8f9f7 326 #endif
<> 144:ef7eb2e8f9f7 327 break;
<> 144:ef7eb2e8f9f7 328
AnnaBridge 179:b0033dcd6934 329 #if defined(_ADC_SINGLECTRLX_VREFSEL_VDDXWATT)
<> 144:ef7eb2e8f9f7 330 case adcRefVddxAtt:
AnnaBridge 179:b0033dcd6934 331 newCal |= ((diCalReg[1] & DEVINFO_ADC0_GAINVDD_MASK)
<> 144:ef7eb2e8f9f7 332 >> DEVINFO_ADC0_GAINVDD_SHIFT)
<> 144:ef7eb2e8f9f7 333 << _ADC_CAL_SINGLEGAIN_SHIFT;
AnnaBridge 179:b0033dcd6934 334 newCal |= ((diCalReg[1] & DEVINFO_ADC0_OFFSETVDD_MASK)
<> 144:ef7eb2e8f9f7 335 >> DEVINFO_ADC0_OFFSETVDD_SHIFT)
<> 144:ef7eb2e8f9f7 336 << _ADC_CAL_SINGLEOFFSET_SHIFT;
AnnaBridge 179:b0033dcd6934 337 newCal |= ((diCalReg[1] & _DEVINFO_ADC0CAL1_NEGSEOFFSETVDD_MASK)
<> 144:ef7eb2e8f9f7 338 >> _DEVINFO_ADC0CAL1_NEGSEOFFSETVDD_SHIFT)
<> 144:ef7eb2e8f9f7 339 << _ADC_CAL_SINGLEOFFSETINV_SHIFT;
<> 144:ef7eb2e8f9f7 340 break;
<> 144:ef7eb2e8f9f7 341 #endif
<> 144:ef7eb2e8f9f7 342
<> 144:ef7eb2e8f9f7 343 /* For external references, the calibration must be determined for the
<> 144:ef7eb2e8f9f7 344 specific application and set by the user. Calibration data is also not
<> 144:ef7eb2e8f9f7 345 available for the internal references adcRefVBGR, adcRefVEntropy and
<> 144:ef7eb2e8f9f7 346 adcRefVBGRlow. */
<> 144:ef7eb2e8f9f7 347 default:
<> 144:ef7eb2e8f9f7 348 newCal = 0;
<> 144:ef7eb2e8f9f7 349 break;
<> 144:ef7eb2e8f9f7 350 }
<> 144:ef7eb2e8f9f7 351
<> 144:ef7eb2e8f9f7 352 adc->CAL = calReg | (newCal << shift);
<> 144:ef7eb2e8f9f7 353 }
<> 144:ef7eb2e8f9f7 354
<> 144:ef7eb2e8f9f7 355 /** @endcond */
<> 144:ef7eb2e8f9f7 356
<> 144:ef7eb2e8f9f7 357 /*******************************************************************************
<> 144:ef7eb2e8f9f7 358 ************************** GLOBAL FUNCTIONS *******************************
<> 144:ef7eb2e8f9f7 359 ******************************************************************************/
<> 144:ef7eb2e8f9f7 360
<> 144:ef7eb2e8f9f7 361 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 362 * @brief
<> 144:ef7eb2e8f9f7 363 * Initialize ADC.
<> 144:ef7eb2e8f9f7 364 *
<> 144:ef7eb2e8f9f7 365 * @details
<> 144:ef7eb2e8f9f7 366 * Initializes common parts for both single conversion and scan sequence.
<> 144:ef7eb2e8f9f7 367 * In addition, single and/or scan control configuration must be done, please
<> 150:02e0a0aed4ec 368 * refer to @ref ADC_InitSingle() and @ref ADC_InitScan() respectively.
<> 150:02e0a0aed4ec 369 * For ADC architectures with the ADCn->SCANINPUTSEL register, use
<> 150:02e0a0aed4ec 370 * @ref ADC_ScanSingleEndedInputAdd() to configure single-ended scan inputs or
<> 150:02e0a0aed4ec 371 * @ref ADC_ScanDifferentialInputAdd() to configure differential scan inputs.
<> 150:02e0a0aed4ec 372 * @ref ADC_ScanInputClear() is also provided for applications that need to update
<> 150:02e0a0aed4ec 373 * the input configuration.
<> 144:ef7eb2e8f9f7 374 *
<> 144:ef7eb2e8f9f7 375 * @note
<> 144:ef7eb2e8f9f7 376 * This function will stop any ongoing conversion.
<> 144:ef7eb2e8f9f7 377 *
<> 144:ef7eb2e8f9f7 378 * @param[in] adc
<> 144:ef7eb2e8f9f7 379 * Pointer to ADC peripheral register block.
<> 144:ef7eb2e8f9f7 380 *
<> 144:ef7eb2e8f9f7 381 * @param[in] init
<> 144:ef7eb2e8f9f7 382 * Pointer to ADC initialization structure.
<> 144:ef7eb2e8f9f7 383 ******************************************************************************/
<> 144:ef7eb2e8f9f7 384 void ADC_Init(ADC_TypeDef *adc, const ADC_Init_TypeDef *init)
<> 144:ef7eb2e8f9f7 385 {
<> 144:ef7eb2e8f9f7 386 uint32_t tmp;
<> 150:02e0a0aed4ec 387 uint8_t presc = init->prescale;
<> 144:ef7eb2e8f9f7 388
<> 144:ef7eb2e8f9f7 389 EFM_ASSERT(ADC_REF_VALID(adc));
<> 144:ef7eb2e8f9f7 390
AnnaBridge 179:b0033dcd6934 391 if (presc == 0) {
<> 150:02e0a0aed4ec 392 /* Assume maximum ADC clock for prescaler 0 */
<> 150:02e0a0aed4ec 393 presc = ADC_PrescaleCalc(ADC_MAX_CLOCK, 0);
AnnaBridge 179:b0033dcd6934 394 } else {
<> 150:02e0a0aed4ec 395 /* Check prescaler bounds against ADC_MAX_CLOCK and ADC_MIN_CLOCK */
<> 150:02e0a0aed4ec 396 #if defined(_ADC_CTRL_ADCCLKMODE_MASK)
<> 150:02e0a0aed4ec 397 if (ADC0->CTRL & ADC_CTRL_ADCCLKMODE_SYNC)
<> 150:02e0a0aed4ec 398 #endif
<> 150:02e0a0aed4ec 399 {
<> 150:02e0a0aed4ec 400 EFM_ASSERT(presc >= ADC_PrescaleCalc(ADC_MAX_CLOCK, 0));
<> 150:02e0a0aed4ec 401 EFM_ASSERT(presc <= ADC_PrescaleCalc(ADC_MIN_CLOCK, 0));
<> 150:02e0a0aed4ec 402 }
<> 150:02e0a0aed4ec 403 }
<> 150:02e0a0aed4ec 404
<> 144:ef7eb2e8f9f7 405 /* Make sure conversion is not in progress */
<> 144:ef7eb2e8f9f7 406 adc->CMD = ADC_CMD_SINGLESTOP | ADC_CMD_SCANSTOP;
<> 144:ef7eb2e8f9f7 407
<> 144:ef7eb2e8f9f7 408 tmp = ((uint32_t)(init->ovsRateSel) << _ADC_CTRL_OVSRSEL_SHIFT)
<> 144:ef7eb2e8f9f7 409 | (((uint32_t)(init->timebase) << _ADC_CTRL_TIMEBASE_SHIFT)
AnnaBridge 179:b0033dcd6934 410 & _ADC_CTRL_TIMEBASE_MASK)
<> 150:02e0a0aed4ec 411 | (((uint32_t)(presc) << _ADC_CTRL_PRESC_SHIFT)
AnnaBridge 179:b0033dcd6934 412 & _ADC_CTRL_PRESC_MASK)
AnnaBridge 179:b0033dcd6934 413 #if defined (_ADC_CTRL_LPFMODE_MASK)
<> 144:ef7eb2e8f9f7 414 | ((uint32_t)(init->lpfMode) << _ADC_CTRL_LPFMODE_SHIFT)
<> 144:ef7eb2e8f9f7 415 #endif
<> 144:ef7eb2e8f9f7 416 | ((uint32_t)(init->warmUpMode) << _ADC_CTRL_WARMUPMODE_SHIFT);
<> 144:ef7eb2e8f9f7 417
AnnaBridge 179:b0033dcd6934 418 if (init->tailgate) {
<> 144:ef7eb2e8f9f7 419 tmp |= ADC_CTRL_TAILGATE;
<> 144:ef7eb2e8f9f7 420 }
<> 144:ef7eb2e8f9f7 421 adc->CTRL = tmp;
<> 144:ef7eb2e8f9f7 422
<> 144:ef7eb2e8f9f7 423 /* Set ADC EM2 clock configuration */
AnnaBridge 179:b0033dcd6934 424 #if defined(_ADC_CTRL_ADCCLKMODE_MASK)
<> 144:ef7eb2e8f9f7 425 BUS_RegMaskedWrite(&ADC0->CTRL,
<> 144:ef7eb2e8f9f7 426 _ADC_CTRL_ADCCLKMODE_MASK | _ADC_CTRL_ASYNCCLKEN_MASK,
<> 150:02e0a0aed4ec 427 init->em2ClockConfig);
<> 144:ef7eb2e8f9f7 428 #endif
<> 144:ef7eb2e8f9f7 429
AnnaBridge 179:b0033dcd6934 430 #if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
<> 161:2cc1468da177 431 /* A debugger can trigger the SCANUF interrupt on EFM32xG1 or EFR32xG1 */
<> 144:ef7eb2e8f9f7 432 ADC_IntClear(adc, ADC_IFC_SCANUF);
<> 144:ef7eb2e8f9f7 433 #endif
<> 144:ef7eb2e8f9f7 434 }
<> 144:ef7eb2e8f9f7 435
AnnaBridge 179:b0033dcd6934 436 #if defined(_ADC_SCANINPUTSEL_MASK)
<> 144:ef7eb2e8f9f7 437 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 438 * @brief
<> 144:ef7eb2e8f9f7 439 * Clear ADC scan input configuration.
<> 144:ef7eb2e8f9f7 440 *
<> 144:ef7eb2e8f9f7 441 * @param[in] scanInit
<> 144:ef7eb2e8f9f7 442 * Struct to hold the scan configuration, input configuration.
<> 144:ef7eb2e8f9f7 443 ******************************************************************************/
<> 144:ef7eb2e8f9f7 444 void ADC_ScanInputClear(ADC_InitScan_TypeDef *scanInit)
<> 144:ef7eb2e8f9f7 445 {
<> 144:ef7eb2e8f9f7 446 /* Clear input configuration */
<> 144:ef7eb2e8f9f7 447
<> 144:ef7eb2e8f9f7 448 /* Select none */
<> 150:02e0a0aed4ec 449 scanInit->scanInputConfig.scanInputSel = ADC_SCANINPUTSEL_NONE;
<> 144:ef7eb2e8f9f7 450 scanInit->scanInputConfig.scanInputEn = 0;
<> 144:ef7eb2e8f9f7 451
<> 144:ef7eb2e8f9f7 452 /* Default alternative negative inputs */
<> 144:ef7eb2e8f9f7 453 scanInit->scanInputConfig.scanNegSel = _ADC_SCANNEGSEL_RESETVALUE;
<> 144:ef7eb2e8f9f7 454 }
<> 144:ef7eb2e8f9f7 455
<> 144:ef7eb2e8f9f7 456 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 457 * @brief
<> 144:ef7eb2e8f9f7 458 * Initialize ADC scan single-ended input configuration.
<> 144:ef7eb2e8f9f7 459 *
<> 144:ef7eb2e8f9f7 460 * @details
<> 144:ef7eb2e8f9f7 461 * Set configuration for ADC scan conversion with single-ended inputs. The
<> 144:ef7eb2e8f9f7 462 * ADC_InitScan_TypeDef struct updated from this function should be passed to
<> 144:ef7eb2e8f9f7 463 * ADC_InitScan().
<> 144:ef7eb2e8f9f7 464 *
<> 144:ef7eb2e8f9f7 465 * @param[in] inputGroup
<> 144:ef7eb2e8f9f7 466 * ADC scan input group. See section 25.3.4 in the reference manual for
<> 144:ef7eb2e8f9f7 467 * more information.
<> 144:ef7eb2e8f9f7 468 *
<> 144:ef7eb2e8f9f7 469 * @param[in] singleEndedSel
<> 144:ef7eb2e8f9f7 470 * APORT select.
<> 144:ef7eb2e8f9f7 471 *
<> 144:ef7eb2e8f9f7 472 * @return
<> 144:ef7eb2e8f9f7 473 * Scan ID of selected ADC input. ee section 25.3.4 in the reference manual for
<> 144:ef7eb2e8f9f7 474 * more information. Note that the returned integer represents the bit position
<> 144:ef7eb2e8f9f7 475 * in ADCn_SCANMASK set by this function. The accumulated mask is stored in
<> 144:ef7eb2e8f9f7 476 * scanInit->scanInputConfig->scanInputEn.
<> 144:ef7eb2e8f9f7 477 ******************************************************************************/
<> 144:ef7eb2e8f9f7 478 uint32_t ADC_ScanSingleEndedInputAdd(ADC_InitScan_TypeDef *scanInit,
<> 144:ef7eb2e8f9f7 479 ADC_ScanInputGroup_TypeDef inputGroup,
<> 144:ef7eb2e8f9f7 480 ADC_PosSel_TypeDef singleEndedSel)
<> 144:ef7eb2e8f9f7 481 {
<> 144:ef7eb2e8f9f7 482 uint32_t currentSel;
<> 144:ef7eb2e8f9f7 483 uint32_t newSel;
<> 144:ef7eb2e8f9f7 484 uint32_t scanId;
<> 144:ef7eb2e8f9f7 485
<> 144:ef7eb2e8f9f7 486 scanInit->diff = false;
<> 144:ef7eb2e8f9f7 487
<> 144:ef7eb2e8f9f7 488 /* Check for unsupported APORTs */
<> 144:ef7eb2e8f9f7 489 EFM_ASSERT((singleEndedSel <= adcPosSelAPORT0YCH0) || (singleEndedSel >= adcPosSelAPORT0YCH15));
<> 144:ef7eb2e8f9f7 490
<> 144:ef7eb2e8f9f7 491 /* Decode the input group select by shifting right by 3 */
<> 144:ef7eb2e8f9f7 492 newSel = singleEndedSel >> 3;
<> 144:ef7eb2e8f9f7 493
<> 144:ef7eb2e8f9f7 494 currentSel = (scanInit->scanInputConfig.scanInputSel >> (inputGroup * 8)) & 0xFF;
<> 144:ef7eb2e8f9f7 495
<> 144:ef7eb2e8f9f7 496 /* If none selected */
AnnaBridge 179:b0033dcd6934 497 if (currentSel == ADC_SCANINPUTSEL_GROUP_NONE) {
<> 144:ef7eb2e8f9f7 498 scanInit->scanInputConfig.scanInputSel &= ~(0xFF << (inputGroup * 8));
<> 144:ef7eb2e8f9f7 499 scanInit->scanInputConfig.scanInputSel |= (newSel << (inputGroup * 8));
AnnaBridge 179:b0033dcd6934 500 } else if (currentSel == newSel) {
<> 144:ef7eb2e8f9f7 501 /* Ok, but do nothing. */
AnnaBridge 179:b0033dcd6934 502 } else {
<> 144:ef7eb2e8f9f7 503 /* Invalid channel range. A range is already selected for this group. */
<> 144:ef7eb2e8f9f7 504 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 505 }
<> 144:ef7eb2e8f9f7 506
<> 144:ef7eb2e8f9f7 507 /* Update and return scan input enable mask (SCANMASK) */
<> 144:ef7eb2e8f9f7 508 scanId = (inputGroup * 8) + (singleEndedSel & 0x7);
<> 144:ef7eb2e8f9f7 509 EFM_ASSERT(scanId < 32);
<> 144:ef7eb2e8f9f7 510 scanInit->scanInputConfig.scanInputEn |= 0x1 << scanId;
<> 144:ef7eb2e8f9f7 511 return scanId;
<> 144:ef7eb2e8f9f7 512 }
<> 144:ef7eb2e8f9f7 513
<> 144:ef7eb2e8f9f7 514 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 515 * @brief
<> 144:ef7eb2e8f9f7 516 * Initialize ADC scan differential input configuration.
<> 144:ef7eb2e8f9f7 517 *
<> 144:ef7eb2e8f9f7 518 * @details
<> 144:ef7eb2e8f9f7 519 * Set configuration for ADC scan conversion with differential inputs. The
<> 144:ef7eb2e8f9f7 520 * ADC_InitScan_TypeDef struct updated by this function should be passed to
<> 144:ef7eb2e8f9f7 521 * ADC_InitScan().
<> 144:ef7eb2e8f9f7 522 *
<> 144:ef7eb2e8f9f7 523 * @param[in] scanInit
<> 144:ef7eb2e8f9f7 524 * Struct to hold the scan and input configuration.
<> 144:ef7eb2e8f9f7 525 *
<> 144:ef7eb2e8f9f7 526 * @param[in] inputGroup
<> 144:ef7eb2e8f9f7 527 * ADC scan input group. See section 25.3.4 in the reference manual for
<> 144:ef7eb2e8f9f7 528 * more information.
<> 144:ef7eb2e8f9f7 529 *
<> 144:ef7eb2e8f9f7 530 * @param[in] posSel
<> 144:ef7eb2e8f9f7 531 * APORT bus pair select. The negative terminal is implicitly selected by
<> 144:ef7eb2e8f9f7 532 * the positive terminal.
<> 144:ef7eb2e8f9f7 533 *
<> 144:ef7eb2e8f9f7 534 * @param[in] negInput
<> 144:ef7eb2e8f9f7 535 * ADC scan alternative negative input. Set to adcScanNegInputDefault to select
<> 144:ef7eb2e8f9f7 536 * default negative input (implicit from posSel).
<> 144:ef7eb2e8f9f7 537 *
<> 144:ef7eb2e8f9f7 538 * @return
<> 144:ef7eb2e8f9f7 539 * Scan ID of selected ADC input. ee section 25.3.4 in the reference manual for
<> 144:ef7eb2e8f9f7 540 * more information. Note that the returned integer represents the bit position
<> 144:ef7eb2e8f9f7 541 * in ADCn_SCANMASK set by this function. The accumulated mask is stored in
<> 144:ef7eb2e8f9f7 542 * scanInit->scanInputConfig->scanInputEn.
<> 144:ef7eb2e8f9f7 543 ******************************************************************************/
<> 144:ef7eb2e8f9f7 544 uint32_t ADC_ScanDifferentialInputAdd(ADC_InitScan_TypeDef *scanInit,
<> 144:ef7eb2e8f9f7 545 ADC_ScanInputGroup_TypeDef inputGroup,
<> 144:ef7eb2e8f9f7 546 ADC_PosSel_TypeDef posSel,
<> 144:ef7eb2e8f9f7 547 ADC_ScanNegInput_TypeDef negInput)
<> 144:ef7eb2e8f9f7 548 {
<> 144:ef7eb2e8f9f7 549 uint32_t negInputRegMask = 0;
<> 144:ef7eb2e8f9f7 550 uint32_t negInputRegShift = 0;
<> 144:ef7eb2e8f9f7 551 uint32_t negInputRegVal = 0;
<> 144:ef7eb2e8f9f7 552 uint32_t scanId = 0;
<> 144:ef7eb2e8f9f7 553
<> 144:ef7eb2e8f9f7 554 /* Do a single ended init, then update for differential scan. */
<> 144:ef7eb2e8f9f7 555 scanId = ADC_ScanSingleEndedInputAdd(scanInit, inputGroup, posSel);
<> 144:ef7eb2e8f9f7 556
<> 144:ef7eb2e8f9f7 557 /* Reset to differential mode */
<> 144:ef7eb2e8f9f7 558 scanInit->diff = true;
<> 144:ef7eb2e8f9f7 559
<> 144:ef7eb2e8f9f7 560 /* Set negative ADC input, unless the default is selected. */
AnnaBridge 179:b0033dcd6934 561 if (negInput != adcScanNegInputDefault) {
AnnaBridge 179:b0033dcd6934 562 if (scanId == 0) {
<> 144:ef7eb2e8f9f7 563 negInputRegMask = _ADC_SCANNEGSEL_INPUT0NEGSEL_MASK;
<> 144:ef7eb2e8f9f7 564 negInputRegShift = _ADC_SCANNEGSEL_INPUT0NEGSEL_SHIFT;
<> 144:ef7eb2e8f9f7 565 EFM_ASSERT(inputGroup == 0);
AnnaBridge 179:b0033dcd6934 566 } else if (scanId == 2) {
<> 144:ef7eb2e8f9f7 567 negInputRegMask = _ADC_SCANNEGSEL_INPUT2NEGSEL_MASK;
<> 144:ef7eb2e8f9f7 568 negInputRegShift = _ADC_SCANNEGSEL_INPUT2NEGSEL_SHIFT;
<> 144:ef7eb2e8f9f7 569 EFM_ASSERT(inputGroup == 0);
AnnaBridge 179:b0033dcd6934 570 } else if (scanId == 4) {
<> 144:ef7eb2e8f9f7 571 negInputRegMask = _ADC_SCANNEGSEL_INPUT4NEGSEL_MASK;
<> 144:ef7eb2e8f9f7 572 negInputRegShift = _ADC_SCANNEGSEL_INPUT4NEGSEL_SHIFT;
<> 144:ef7eb2e8f9f7 573 EFM_ASSERT(inputGroup == 0);
AnnaBridge 179:b0033dcd6934 574 } else if (scanId == 6) {
<> 144:ef7eb2e8f9f7 575 negInputRegMask = _ADC_SCANNEGSEL_INPUT6NEGSEL_MASK;
<> 144:ef7eb2e8f9f7 576 negInputRegShift = _ADC_SCANNEGSEL_INPUT6NEGSEL_SHIFT;
<> 144:ef7eb2e8f9f7 577 EFM_ASSERT(inputGroup == 0);
AnnaBridge 179:b0033dcd6934 578 } else if (scanId == 9) {
<> 144:ef7eb2e8f9f7 579 negInputRegMask = _ADC_SCANNEGSEL_INPUT9NEGSEL_MASK;
<> 144:ef7eb2e8f9f7 580 negInputRegShift = _ADC_SCANNEGSEL_INPUT9NEGSEL_SHIFT;
<> 144:ef7eb2e8f9f7 581 EFM_ASSERT(inputGroup == 1);
AnnaBridge 179:b0033dcd6934 582 } else if (scanId == 11) {
<> 144:ef7eb2e8f9f7 583 negInputRegMask = _ADC_SCANNEGSEL_INPUT11NEGSEL_MASK;
<> 144:ef7eb2e8f9f7 584 negInputRegShift = _ADC_SCANNEGSEL_INPUT11NEGSEL_SHIFT;
<> 144:ef7eb2e8f9f7 585 EFM_ASSERT(inputGroup == 1);
AnnaBridge 179:b0033dcd6934 586 } else if (scanId == 13) {
<> 144:ef7eb2e8f9f7 587 negInputRegMask = _ADC_SCANNEGSEL_INPUT13NEGSEL_MASK;
<> 144:ef7eb2e8f9f7 588 negInputRegShift = _ADC_SCANNEGSEL_INPUT13NEGSEL_SHIFT;
<> 144:ef7eb2e8f9f7 589 EFM_ASSERT(inputGroup == 1);
AnnaBridge 179:b0033dcd6934 590 } else if (scanId == 15) {
<> 144:ef7eb2e8f9f7 591 negInputRegMask = _ADC_SCANNEGSEL_INPUT15NEGSEL_MASK;
<> 144:ef7eb2e8f9f7 592 negInputRegShift = _ADC_SCANNEGSEL_INPUT15NEGSEL_SHIFT;
<> 144:ef7eb2e8f9f7 593 EFM_ASSERT(inputGroup == 1);
AnnaBridge 179:b0033dcd6934 594 } else {
<> 144:ef7eb2e8f9f7 595 /* There is not negative input option for this positive input (negInput is posInput + 1). */
<> 144:ef7eb2e8f9f7 596 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 597 }
<> 144:ef7eb2e8f9f7 598
<> 144:ef7eb2e8f9f7 599 /* Find ADC_SCANNEGSEL_CHxNSEL value for positive input 0, 2, 4 and 6 */
AnnaBridge 179:b0033dcd6934 600 if (inputGroup == 0) {
AnnaBridge 179:b0033dcd6934 601 switch (negInput) {
<> 144:ef7eb2e8f9f7 602 case adcScanNegInput1:
<> 144:ef7eb2e8f9f7 603 negInputRegVal = _ADC_SCANNEGSEL_INPUT0NEGSEL_INPUT1;
<> 144:ef7eb2e8f9f7 604 break;
<> 144:ef7eb2e8f9f7 605
<> 144:ef7eb2e8f9f7 606 case adcScanNegInput3:
<> 144:ef7eb2e8f9f7 607 negInputRegVal = _ADC_SCANNEGSEL_INPUT0NEGSEL_INPUT3;
<> 144:ef7eb2e8f9f7 608 break;
<> 144:ef7eb2e8f9f7 609
<> 144:ef7eb2e8f9f7 610 case adcScanNegInput5:
<> 144:ef7eb2e8f9f7 611 negInputRegVal = _ADC_SCANNEGSEL_INPUT0NEGSEL_INPUT5;
<> 144:ef7eb2e8f9f7 612 break;
<> 144:ef7eb2e8f9f7 613
<> 144:ef7eb2e8f9f7 614 case adcScanNegInput7:
<> 144:ef7eb2e8f9f7 615 negInputRegVal = _ADC_SCANNEGSEL_INPUT0NEGSEL_INPUT7;
<> 144:ef7eb2e8f9f7 616 break;
<> 144:ef7eb2e8f9f7 617
<> 144:ef7eb2e8f9f7 618 default:
<> 144:ef7eb2e8f9f7 619 /* Invalid selection. Options are input 1, 3, 5 and 7. */
<> 144:ef7eb2e8f9f7 620 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 621 break;
<> 144:ef7eb2e8f9f7 622 }
AnnaBridge 179:b0033dcd6934 623 } else if (inputGroup == 1) {
<> 144:ef7eb2e8f9f7 624 /* Find ADC_SCANNEGSEL_CHxNSEL value for positive input 9, 11, 13 and 15 */
AnnaBridge 179:b0033dcd6934 625 switch (negInput) {
<> 144:ef7eb2e8f9f7 626 case adcScanNegInput8:
<> 144:ef7eb2e8f9f7 627 negInputRegVal = _ADC_SCANNEGSEL_INPUT9NEGSEL_INPUT8;
<> 144:ef7eb2e8f9f7 628 break;
<> 144:ef7eb2e8f9f7 629
<> 144:ef7eb2e8f9f7 630 case adcScanNegInput10:
<> 144:ef7eb2e8f9f7 631 negInputRegVal = _ADC_SCANNEGSEL_INPUT9NEGSEL_INPUT10;
<> 144:ef7eb2e8f9f7 632 break;
<> 144:ef7eb2e8f9f7 633
<> 144:ef7eb2e8f9f7 634 case adcScanNegInput12:
<> 144:ef7eb2e8f9f7 635 negInputRegVal = _ADC_SCANNEGSEL_INPUT9NEGSEL_INPUT12;
<> 144:ef7eb2e8f9f7 636 break;
<> 144:ef7eb2e8f9f7 637
<> 144:ef7eb2e8f9f7 638 case adcScanNegInput14:
<> 144:ef7eb2e8f9f7 639 negInputRegVal = _ADC_SCANNEGSEL_INPUT9NEGSEL_INPUT14;
<> 144:ef7eb2e8f9f7 640 break;
<> 144:ef7eb2e8f9f7 641
<> 144:ef7eb2e8f9f7 642 default:
<> 144:ef7eb2e8f9f7 643 /* Invalid selection. Options are input 8, 10, 12 and 14. */
<> 144:ef7eb2e8f9f7 644 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 645 break;
<> 144:ef7eb2e8f9f7 646 }
AnnaBridge 179:b0033dcd6934 647 } else {
<> 144:ef7eb2e8f9f7 648 /* No alternative negative input for input group > 1 */
<> 144:ef7eb2e8f9f7 649 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 650 }
<> 144:ef7eb2e8f9f7 651
<> 144:ef7eb2e8f9f7 652 /* Update config */
<> 144:ef7eb2e8f9f7 653 scanInit->scanInputConfig.scanNegSel &= ~negInputRegMask;
<> 144:ef7eb2e8f9f7 654 scanInit->scanInputConfig.scanNegSel |= negInputRegVal << negInputRegShift;
<> 144:ef7eb2e8f9f7 655 }
<> 144:ef7eb2e8f9f7 656 return scanId;
<> 144:ef7eb2e8f9f7 657 }
<> 144:ef7eb2e8f9f7 658 #endif
<> 144:ef7eb2e8f9f7 659
<> 144:ef7eb2e8f9f7 660 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 661 * @brief
<> 144:ef7eb2e8f9f7 662 * Initialize ADC scan sequence.
<> 144:ef7eb2e8f9f7 663 *
<> 144:ef7eb2e8f9f7 664 * @details
<> 144:ef7eb2e8f9f7 665 * Please refer to ADC_Start() for starting scan sequence.
<> 144:ef7eb2e8f9f7 666 *
<> 144:ef7eb2e8f9f7 667 * When selecting an external reference, the gain and offset calibration
<> 144:ef7eb2e8f9f7 668 * must be set explicitly (CAL register). For other references, the
<> 144:ef7eb2e8f9f7 669 * calibration is updated with values defined during manufacturing.
<> 150:02e0a0aed4ec 670 * For ADC architectures with the ADCn->SCANINPUTSEL register, use
<> 150:02e0a0aed4ec 671 * @ref ADC_ScanSingleEndedInputAdd() to configure single-ended scan inputs or
<> 150:02e0a0aed4ec 672 * @ref ADC_ScanDifferentialInputAdd() to configure differential scan inputs.
<> 150:02e0a0aed4ec 673 * @ref ADC_ScanInputClear() is also provided for applications that need to update
<> 150:02e0a0aed4ec 674 * the input configuration.
<> 144:ef7eb2e8f9f7 675 *
<> 144:ef7eb2e8f9f7 676 * @note
<> 144:ef7eb2e8f9f7 677 * This function will stop any ongoing scan sequence.
<> 144:ef7eb2e8f9f7 678 *
<> 144:ef7eb2e8f9f7 679 * @param[in] adc
<> 144:ef7eb2e8f9f7 680 * Pointer to ADC peripheral register block.
<> 144:ef7eb2e8f9f7 681 *
<> 144:ef7eb2e8f9f7 682 * @param[in] init
<> 144:ef7eb2e8f9f7 683 * Pointer to ADC initialization structure.
<> 144:ef7eb2e8f9f7 684 ******************************************************************************/
<> 144:ef7eb2e8f9f7 685 void ADC_InitScan(ADC_TypeDef *adc, const ADC_InitScan_TypeDef *init)
<> 144:ef7eb2e8f9f7 686 {
<> 144:ef7eb2e8f9f7 687 uint32_t tmp;
<> 144:ef7eb2e8f9f7 688
<> 144:ef7eb2e8f9f7 689 EFM_ASSERT(ADC_REF_VALID(adc));
<> 144:ef7eb2e8f9f7 690
<> 144:ef7eb2e8f9f7 691 /* Make sure scan sequence is not in progress */
<> 144:ef7eb2e8f9f7 692 adc->CMD = ADC_CMD_SCANSTOP;
<> 144:ef7eb2e8f9f7 693
<> 144:ef7eb2e8f9f7 694 /* Load calibration data for selected reference */
<> 144:ef7eb2e8f9f7 695 ADC_LoadDevinfoCal(adc, init->reference, true);
<> 144:ef7eb2e8f9f7 696
<> 144:ef7eb2e8f9f7 697 tmp = 0
AnnaBridge 179:b0033dcd6934 698 #if defined (_ADC_SCANCTRL_PRSSEL_MASK)
<> 144:ef7eb2e8f9f7 699 | (init->prsSel << _ADC_SCANCTRL_PRSSEL_SHIFT)
<> 144:ef7eb2e8f9f7 700 #endif
<> 144:ef7eb2e8f9f7 701 | (init->acqTime << _ADC_SCANCTRL_AT_SHIFT)
AnnaBridge 179:b0033dcd6934 702 #if defined (_ADC_SCANCTRL_INPUTMASK_MASK)
<> 144:ef7eb2e8f9f7 703 | init->input
<> 144:ef7eb2e8f9f7 704 #endif
<> 144:ef7eb2e8f9f7 705 | (init->resolution << _ADC_SCANCTRL_RES_SHIFT);
<> 144:ef7eb2e8f9f7 706
AnnaBridge 179:b0033dcd6934 707 if (init->prsEnable) {
<> 144:ef7eb2e8f9f7 708 tmp |= ADC_SCANCTRL_PRSEN;
<> 144:ef7eb2e8f9f7 709 }
<> 144:ef7eb2e8f9f7 710
AnnaBridge 179:b0033dcd6934 711 if (init->leftAdjust) {
<> 144:ef7eb2e8f9f7 712 tmp |= ADC_SCANCTRL_ADJ_LEFT;
<> 144:ef7eb2e8f9f7 713 }
<> 144:ef7eb2e8f9f7 714
AnnaBridge 179:b0033dcd6934 715 #if defined(_ADC_SCANCTRL_INPUTMASK_MASK)
<> 144:ef7eb2e8f9f7 716 if (init->diff)
AnnaBridge 179:b0033dcd6934 717 #elif defined(_ADC_SCANINPUTSEL_MASK)
<> 144:ef7eb2e8f9f7 718 if (init->diff)
<> 144:ef7eb2e8f9f7 719 #endif
<> 144:ef7eb2e8f9f7 720 {
<> 144:ef7eb2e8f9f7 721 tmp |= ADC_SCANCTRL_DIFF;
<> 144:ef7eb2e8f9f7 722 }
<> 144:ef7eb2e8f9f7 723
AnnaBridge 179:b0033dcd6934 724 if (init->rep) {
AnnaBridge 179:b0033dcd6934 725 #if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
<> 161:2cc1468da177 726 /* Scan repeat mode does not work on EFM32JG1, EFM32PG1 or EFR32xG1x devices.
<> 161:2cc1468da177 727 * The errata is called ADC_E211 in the errata document. */
<> 161:2cc1468da177 728 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 729 #endif
<> 144:ef7eb2e8f9f7 730 tmp |= ADC_SCANCTRL_REP;
<> 144:ef7eb2e8f9f7 731 }
<> 144:ef7eb2e8f9f7 732
<> 144:ef7eb2e8f9f7 733 /* Set scan reference. Check if reference configuraion is extended to SCANCTRLX. */
AnnaBridge 179:b0033dcd6934 734 #if defined (_ADC_SCANCTRLX_VREFSEL_MASK)
AnnaBridge 179:b0033dcd6934 735 if (init->reference & ADC_CTRLX_VREFSEL_REG) {
<> 144:ef7eb2e8f9f7 736 /* Select extension register */
<> 144:ef7eb2e8f9f7 737 tmp |= ADC_SCANCTRL_REF_CONF;
AnnaBridge 179:b0033dcd6934 738 } else {
<> 144:ef7eb2e8f9f7 739 tmp |= init->reference << _ADC_SCANCTRL_REF_SHIFT;
<> 144:ef7eb2e8f9f7 740 }
<> 144:ef7eb2e8f9f7 741 #else
<> 144:ef7eb2e8f9f7 742 tmp |= init->reference << _ADC_SCANCTRL_REF_SHIFT;
<> 144:ef7eb2e8f9f7 743 #endif
<> 144:ef7eb2e8f9f7 744
AnnaBridge 179:b0033dcd6934 745 #if defined(_ADC_SCANCTRL_INPUTMASK_MASK)
<> 144:ef7eb2e8f9f7 746 tmp |= init->input;
<> 144:ef7eb2e8f9f7 747 #endif
<> 144:ef7eb2e8f9f7 748
<> 144:ef7eb2e8f9f7 749 adc->SCANCTRL = tmp;
<> 144:ef7eb2e8f9f7 750
<> 144:ef7eb2e8f9f7 751 /* Update SINGLECTRLX for reference select and PRS select */
AnnaBridge 179:b0033dcd6934 752 #if defined (_ADC_SCANCTRLX_MASK)
<> 144:ef7eb2e8f9f7 753 tmp = adc->SCANCTRLX & ~(_ADC_SCANCTRLX_VREFSEL_MASK
AnnaBridge 179:b0033dcd6934 754 | _ADC_SCANCTRLX_PRSSEL_MASK
AnnaBridge 179:b0033dcd6934 755 | _ADC_SCANCTRLX_FIFOOFACT_MASK);
AnnaBridge 179:b0033dcd6934 756 if (init->reference & ADC_CTRLX_VREFSEL_REG) {
<> 144:ef7eb2e8f9f7 757 tmp |= (init->reference & ~ADC_CTRLX_VREFSEL_REG) << _ADC_SCANCTRLX_VREFSEL_SHIFT;
<> 144:ef7eb2e8f9f7 758 }
<> 144:ef7eb2e8f9f7 759
<> 144:ef7eb2e8f9f7 760 tmp |= init->prsSel << _ADC_SCANCTRLX_PRSSEL_SHIFT;
<> 144:ef7eb2e8f9f7 761
AnnaBridge 179:b0033dcd6934 762 if (init->fifoOverwrite) {
<> 144:ef7eb2e8f9f7 763 tmp |= ADC_SCANCTRLX_FIFOOFACT_OVERWRITE;
<> 144:ef7eb2e8f9f7 764 }
<> 144:ef7eb2e8f9f7 765
<> 144:ef7eb2e8f9f7 766 adc->SCANCTRLX = tmp;
<> 144:ef7eb2e8f9f7 767 #endif
<> 144:ef7eb2e8f9f7 768
AnnaBridge 179:b0033dcd6934 769 #if defined(_ADC_CTRL_SCANDMAWU_MASK)
<> 144:ef7eb2e8f9f7 770 BUS_RegBitWrite(&adc->CTRL, _ADC_CTRL_SCANDMAWU_SHIFT, init->scanDmaEm2Wu);
<> 144:ef7eb2e8f9f7 771 #endif
<> 144:ef7eb2e8f9f7 772
<> 144:ef7eb2e8f9f7 773 /* Write scan input configuration */
AnnaBridge 179:b0033dcd6934 774 #if defined(_ADC_SCANINPUTSEL_MASK)
<> 150:02e0a0aed4ec 775 /* Check for valid scan input configuration. Use @ref ADC_ScanInputClear()
<> 150:02e0a0aed4ec 776 @ref ADC_ScanSingleEndedInputAdd() and @ref ADC_ScanDifferentialInputAdd() to set
<> 150:02e0a0aed4ec 777 scan input configuration. */
<> 150:02e0a0aed4ec 778 EFM_ASSERT(init->scanInputConfig.scanInputSel != ADC_SCANINPUTSEL_NONE);
<> 144:ef7eb2e8f9f7 779 adc->SCANINPUTSEL = init->scanInputConfig.scanInputSel;
<> 144:ef7eb2e8f9f7 780 adc->SCANMASK = init->scanInputConfig.scanInputEn;
<> 144:ef7eb2e8f9f7 781 adc->SCANNEGSEL = init->scanInputConfig.scanNegSel;
<> 144:ef7eb2e8f9f7 782 #endif
<> 144:ef7eb2e8f9f7 783
<> 144:ef7eb2e8f9f7 784 /* Assert for any APORT bus conflicts programming errors */
AnnaBridge 179:b0033dcd6934 785 #if defined(_ADC_BUSCONFLICT_MASK)
<> 144:ef7eb2e8f9f7 786 tmp = adc->BUSREQ;
<> 144:ef7eb2e8f9f7 787 EFM_ASSERT(!(tmp & adc->BUSCONFLICT));
<> 144:ef7eb2e8f9f7 788 EFM_ASSERT(!(adc->STATUS & _ADC_STATUS_PROGERR_MASK));
<> 144:ef7eb2e8f9f7 789 #endif
<> 144:ef7eb2e8f9f7 790 }
<> 144:ef7eb2e8f9f7 791
<> 144:ef7eb2e8f9f7 792 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 793 * @brief
<> 144:ef7eb2e8f9f7 794 * Initialize single ADC sample conversion.
<> 144:ef7eb2e8f9f7 795 *
<> 144:ef7eb2e8f9f7 796 * @details
<> 144:ef7eb2e8f9f7 797 * Please refer to ADC_Start() for starting single conversion.
<> 144:ef7eb2e8f9f7 798 *
<> 144:ef7eb2e8f9f7 799 * When selecting an external reference, the gain and offset calibration
<> 144:ef7eb2e8f9f7 800 * must be set explicitly (CAL register). For other references, the
<> 144:ef7eb2e8f9f7 801 * calibration is updated with values defined during manufacturing.
<> 144:ef7eb2e8f9f7 802 *
<> 144:ef7eb2e8f9f7 803 * @note
<> 144:ef7eb2e8f9f7 804 * This function will stop any ongoing single conversion.
<> 144:ef7eb2e8f9f7 805 *
<> 150:02e0a0aed4ec 806 * @cond DOXYDOC_P2_DEVICE
<> 150:02e0a0aed4ec 807 * @note
<> 150:02e0a0aed4ec 808 * This function will set the BIASPROG_GPBIASACC bit when selecting the
<> 150:02e0a0aed4ec 809 * internal temperature sensor and clear the bit otherwise. Any
<> 150:02e0a0aed4ec 810 * application that depends on the state of the BIASPROG_GPBIASACC bit should
<> 150:02e0a0aed4ec 811 * modify it after a call to this function.
<> 150:02e0a0aed4ec 812 * @endcond
<> 150:02e0a0aed4ec 813 *
<> 144:ef7eb2e8f9f7 814 * @param[in] adc
<> 144:ef7eb2e8f9f7 815 * Pointer to ADC peripheral register block.
<> 144:ef7eb2e8f9f7 816 *
<> 144:ef7eb2e8f9f7 817 * @param[in] init
<> 144:ef7eb2e8f9f7 818 * Pointer to ADC initialization structure.
<> 144:ef7eb2e8f9f7 819 ******************************************************************************/
<> 144:ef7eb2e8f9f7 820 void ADC_InitSingle(ADC_TypeDef *adc, const ADC_InitSingle_TypeDef *init)
<> 144:ef7eb2e8f9f7 821 {
<> 144:ef7eb2e8f9f7 822 uint32_t tmp;
<> 144:ef7eb2e8f9f7 823
<> 144:ef7eb2e8f9f7 824 EFM_ASSERT(ADC_REF_VALID(adc));
<> 144:ef7eb2e8f9f7 825
<> 144:ef7eb2e8f9f7 826 /* Make sure single conversion is not in progress */
<> 144:ef7eb2e8f9f7 827 adc->CMD = ADC_CMD_SINGLESTOP;
<> 144:ef7eb2e8f9f7 828
<> 144:ef7eb2e8f9f7 829 /* Load calibration data for selected reference */
<> 144:ef7eb2e8f9f7 830 ADC_LoadDevinfoCal(adc, init->reference, false);
<> 144:ef7eb2e8f9f7 831
<> 144:ef7eb2e8f9f7 832 tmp = 0
AnnaBridge 179:b0033dcd6934 833 #if defined(_ADC_SINGLECTRL_PRSSEL_MASK)
<> 144:ef7eb2e8f9f7 834 | (init->prsSel << _ADC_SINGLECTRL_PRSSEL_SHIFT)
<> 144:ef7eb2e8f9f7 835 #endif
<> 144:ef7eb2e8f9f7 836 | (init->acqTime << _ADC_SINGLECTRL_AT_SHIFT)
AnnaBridge 179:b0033dcd6934 837 #if defined(_ADC_SINGLECTRL_INPUTSEL_MASK)
<> 144:ef7eb2e8f9f7 838 | (init->input << _ADC_SINGLECTRL_INPUTSEL_SHIFT)
<> 144:ef7eb2e8f9f7 839 #endif
AnnaBridge 179:b0033dcd6934 840 #if defined(_ADC_SINGLECTRL_POSSEL_MASK)
<> 144:ef7eb2e8f9f7 841 | (init->posSel << _ADC_SINGLECTRL_POSSEL_SHIFT)
<> 144:ef7eb2e8f9f7 842 #endif
AnnaBridge 179:b0033dcd6934 843 #if defined(_ADC_SINGLECTRL_NEGSEL_MASK)
<> 144:ef7eb2e8f9f7 844 | (init->negSel << _ADC_SINGLECTRL_NEGSEL_SHIFT)
<> 144:ef7eb2e8f9f7 845 #endif
<> 144:ef7eb2e8f9f7 846 | ((uint32_t)(init->resolution) << _ADC_SINGLECTRL_RES_SHIFT);
<> 144:ef7eb2e8f9f7 847
AnnaBridge 179:b0033dcd6934 848 if (init->prsEnable) {
<> 144:ef7eb2e8f9f7 849 tmp |= ADC_SINGLECTRL_PRSEN;
<> 144:ef7eb2e8f9f7 850 }
<> 144:ef7eb2e8f9f7 851
AnnaBridge 179:b0033dcd6934 852 if (init->leftAdjust) {
<> 144:ef7eb2e8f9f7 853 tmp |= ADC_SINGLECTRL_ADJ_LEFT;
<> 144:ef7eb2e8f9f7 854 }
<> 144:ef7eb2e8f9f7 855
AnnaBridge 179:b0033dcd6934 856 if (init->diff) {
<> 144:ef7eb2e8f9f7 857 tmp |= ADC_SINGLECTRL_DIFF;
<> 144:ef7eb2e8f9f7 858 }
<> 144:ef7eb2e8f9f7 859
AnnaBridge 179:b0033dcd6934 860 if (init->rep) {
<> 144:ef7eb2e8f9f7 861 tmp |= ADC_SINGLECTRL_REP;
<> 144:ef7eb2e8f9f7 862 }
<> 144:ef7eb2e8f9f7 863
AnnaBridge 179:b0033dcd6934 864 #if defined(_ADC_SINGLECTRL_POSSEL_TEMP)
<> 150:02e0a0aed4ec 865 /* Force at least 8 cycle acquisition time when reading internal temperature
<> 150:02e0a0aed4ec 866 * sensor with 1.25V reference */
<> 150:02e0a0aed4ec 867 if ((init->posSel == adcPosSelTEMP)
AnnaBridge 179:b0033dcd6934 868 && (init->reference == adcRef1V25)
AnnaBridge 179:b0033dcd6934 869 && (init->acqTime < adcAcqTime8)) {
<> 150:02e0a0aed4ec 870 tmp = (tmp & ~_ADC_SINGLECTRL_AT_MASK)
AnnaBridge 179:b0033dcd6934 871 | (adcAcqTime8 << _ADC_SINGLECTRL_AT_SHIFT);
<> 150:02e0a0aed4ec 872 }
<> 150:02e0a0aed4ec 873 #endif
<> 150:02e0a0aed4ec 874
<> 144:ef7eb2e8f9f7 875 /* Set single reference. Check if reference configuraion is extended to SINGLECTRLX. */
AnnaBridge 179:b0033dcd6934 876 #if defined (_ADC_SINGLECTRLX_MASK)
AnnaBridge 179:b0033dcd6934 877 if (init->reference & ADC_CTRLX_VREFSEL_REG) {
<> 144:ef7eb2e8f9f7 878 /* Select extension register */
<> 144:ef7eb2e8f9f7 879 tmp |= ADC_SINGLECTRL_REF_CONF;
AnnaBridge 179:b0033dcd6934 880 } else {
<> 144:ef7eb2e8f9f7 881 tmp |= (init->reference << _ADC_SINGLECTRL_REF_SHIFT);
<> 144:ef7eb2e8f9f7 882 }
<> 144:ef7eb2e8f9f7 883 #else
<> 144:ef7eb2e8f9f7 884 tmp |= (init->reference << _ADC_SINGLECTRL_REF_SHIFT);
<> 144:ef7eb2e8f9f7 885 #endif
<> 144:ef7eb2e8f9f7 886 adc->SINGLECTRL = tmp;
<> 144:ef7eb2e8f9f7 887
<> 144:ef7eb2e8f9f7 888 /* Update SINGLECTRLX for reference select and PRS select */
AnnaBridge 179:b0033dcd6934 889 #if defined (_ADC_SINGLECTRLX_VREFSEL_MASK)
AnnaBridge 179:b0033dcd6934 890 tmp = adc->SINGLECTRLX & ~(_ADC_SINGLECTRLX_VREFSEL_MASK
AnnaBridge 179:b0033dcd6934 891 | _ADC_SINGLECTRLX_PRSSEL_MASK
AnnaBridge 179:b0033dcd6934 892 | _ADC_SINGLECTRLX_FIFOOFACT_MASK);
AnnaBridge 179:b0033dcd6934 893 if (init->reference & ADC_CTRLX_VREFSEL_REG) {
<> 144:ef7eb2e8f9f7 894 tmp |= ((init->reference & ~ADC_CTRLX_VREFSEL_REG) << _ADC_SINGLECTRLX_VREFSEL_SHIFT);
<> 144:ef7eb2e8f9f7 895 }
<> 144:ef7eb2e8f9f7 896
<> 144:ef7eb2e8f9f7 897 tmp |= ((init->prsSel << _ADC_SINGLECTRLX_PRSSEL_SHIFT));
<> 144:ef7eb2e8f9f7 898
AnnaBridge 179:b0033dcd6934 899 if (init->fifoOverwrite) {
<> 144:ef7eb2e8f9f7 900 tmp |= ADC_SINGLECTRLX_FIFOOFACT_OVERWRITE;
<> 144:ef7eb2e8f9f7 901 }
<> 144:ef7eb2e8f9f7 902
<> 144:ef7eb2e8f9f7 903 adc->SINGLECTRLX = tmp;
<> 144:ef7eb2e8f9f7 904 #endif
<> 144:ef7eb2e8f9f7 905
<> 144:ef7eb2e8f9f7 906 /* Set DMA availability in EM2 */
AnnaBridge 179:b0033dcd6934 907 #if defined(_ADC_CTRL_SINGLEDMAWU_MASK)
<> 150:02e0a0aed4ec 908 BUS_RegBitWrite(&adc->CTRL, _ADC_CTRL_SINGLEDMAWU_SHIFT, init->singleDmaEm2Wu);
<> 150:02e0a0aed4ec 909 #endif
<> 150:02e0a0aed4ec 910
AnnaBridge 179:b0033dcd6934 911 #if defined(_ADC_BIASPROG_GPBIASACC_MASK) && defined(FIX_ADC_TEMP_BIAS_EN)
AnnaBridge 179:b0033dcd6934 912 if (init->posSel == adcPosSelTEMP) {
<> 150:02e0a0aed4ec 913 /* ADC should always use low accuracy setting when reading the internal
<> 150:02e0a0aed4ec 914 * temperature sensor on platform 2 generation 1 devices. Using high
<> 150:02e0a0aed4ec 915 * accuracy setting can introduce a glitch. */
<> 150:02e0a0aed4ec 916 BUS_RegBitWrite(&adc->BIASPROG, _ADC_BIASPROG_GPBIASACC_SHIFT, 1);
AnnaBridge 179:b0033dcd6934 917 } else {
<> 150:02e0a0aed4ec 918 BUS_RegBitWrite(&adc->BIASPROG, _ADC_BIASPROG_GPBIASACC_SHIFT, 0);
<> 150:02e0a0aed4ec 919 }
<> 144:ef7eb2e8f9f7 920 #endif
<> 144:ef7eb2e8f9f7 921
<> 144:ef7eb2e8f9f7 922 /* Assert for any APORT bus conflicts programming errors */
AnnaBridge 179:b0033dcd6934 923 #if defined(_ADC_BUSCONFLICT_MASK)
<> 144:ef7eb2e8f9f7 924 tmp = adc->BUSREQ;
<> 144:ef7eb2e8f9f7 925 EFM_ASSERT(!(tmp & adc->BUSCONFLICT));
<> 144:ef7eb2e8f9f7 926 EFM_ASSERT(!(adc->STATUS & _ADC_STATUS_PROGERR_MASK));
<> 144:ef7eb2e8f9f7 927 #endif
<> 144:ef7eb2e8f9f7 928 }
<> 144:ef7eb2e8f9f7 929
AnnaBridge 179:b0033dcd6934 930 #if defined(_ADC_SCANDATAX_MASK)
<> 144:ef7eb2e8f9f7 931 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 932 * @brief
<> 144:ef7eb2e8f9f7 933 * Get scan result and scan select ID.
<> 144:ef7eb2e8f9f7 934 *
<> 144:ef7eb2e8f9f7 935 * @note
<> 144:ef7eb2e8f9f7 936 * Only use if scan data valid. This function does not check the DV flag.
<> 144:ef7eb2e8f9f7 937 * The return value is intended to be used as a index for the scan select ID.
<> 144:ef7eb2e8f9f7 938 *
<> 144:ef7eb2e8f9f7 939 * @param[in] adc
<> 144:ef7eb2e8f9f7 940 * Pointer to ADC peripheral register block.
<> 144:ef7eb2e8f9f7 941 *
<> 144:ef7eb2e8f9f7 942 * @param[out] scanId
<> 144:ef7eb2e8f9f7 943 * Scan select ID of first data in scan FIFO.
<> 144:ef7eb2e8f9f7 944 *
<> 144:ef7eb2e8f9f7 945 * @return
<> 144:ef7eb2e8f9f7 946 * First scan data in scan FIFO.
<> 144:ef7eb2e8f9f7 947 ******************************************************************************/
<> 144:ef7eb2e8f9f7 948 uint32_t ADC_DataIdScanGet(ADC_TypeDef *adc, uint32_t *scanId)
<> 144:ef7eb2e8f9f7 949 {
<> 144:ef7eb2e8f9f7 950 uint32_t scanData;
<> 144:ef7eb2e8f9f7 951
<> 144:ef7eb2e8f9f7 952 /* Pop data FIFO with scan ID */
<> 144:ef7eb2e8f9f7 953 scanData = adc->SCANDATAX;
<> 144:ef7eb2e8f9f7 954 *scanId = (scanData & _ADC_SCANDATAX_SCANINPUTID_MASK) >> _ADC_SCANDATAX_SCANINPUTID_SHIFT;
<> 144:ef7eb2e8f9f7 955 return (scanData & _ADC_SCANDATAX_DATA_MASK) >> _ADC_SCANDATAX_DATA_SHIFT;
<> 144:ef7eb2e8f9f7 956 }
<> 144:ef7eb2e8f9f7 957 #endif
<> 144:ef7eb2e8f9f7 958
<> 144:ef7eb2e8f9f7 959 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 960 * @brief
<> 144:ef7eb2e8f9f7 961 * Calculate prescaler value used to determine ADC clock.
<> 144:ef7eb2e8f9f7 962 *
<> 144:ef7eb2e8f9f7 963 * @details
<> 144:ef7eb2e8f9f7 964 * The ADC clock is given by: HFPERCLK / (prescale + 1).
<> 144:ef7eb2e8f9f7 965 *
<> 144:ef7eb2e8f9f7 966 * @param[in] adcFreq ADC frequency wanted. The frequency will automatically
<> 144:ef7eb2e8f9f7 967 * be adjusted to be within valid range according to reference manual.
<> 144:ef7eb2e8f9f7 968 *
<> 144:ef7eb2e8f9f7 969 * @param[in] hfperFreq Frequency in Hz of reference HFPER clock. Set to 0 to
<> 144:ef7eb2e8f9f7 970 * use currently defined HFPER clock setting.
<> 144:ef7eb2e8f9f7 971 *
<> 144:ef7eb2e8f9f7 972 * @return
<> 144:ef7eb2e8f9f7 973 * Prescaler value to use for ADC in order to achieve a clock value
<> 144:ef7eb2e8f9f7 974 * <= @p adcFreq.
<> 144:ef7eb2e8f9f7 975 ******************************************************************************/
<> 144:ef7eb2e8f9f7 976 uint8_t ADC_PrescaleCalc(uint32_t adcFreq, uint32_t hfperFreq)
<> 144:ef7eb2e8f9f7 977 {
<> 144:ef7eb2e8f9f7 978 uint32_t ret;
<> 144:ef7eb2e8f9f7 979
<> 144:ef7eb2e8f9f7 980 /* Make sure selected ADC clock is within valid range */
AnnaBridge 179:b0033dcd6934 981 if (adcFreq > ADC_MAX_CLOCK) {
<> 144:ef7eb2e8f9f7 982 adcFreq = ADC_MAX_CLOCK;
AnnaBridge 179:b0033dcd6934 983 } else if (adcFreq < ADC_MIN_CLOCK) {
<> 144:ef7eb2e8f9f7 984 adcFreq = ADC_MIN_CLOCK;
<> 144:ef7eb2e8f9f7 985 }
<> 144:ef7eb2e8f9f7 986
<> 144:ef7eb2e8f9f7 987 /* Use current HFPER frequency? */
AnnaBridge 179:b0033dcd6934 988 if (!hfperFreq) {
<> 144:ef7eb2e8f9f7 989 hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
<> 144:ef7eb2e8f9f7 990 }
<> 144:ef7eb2e8f9f7 991
<> 144:ef7eb2e8f9f7 992 ret = (hfperFreq + adcFreq - 1) / adcFreq;
AnnaBridge 179:b0033dcd6934 993 if (ret) {
<> 144:ef7eb2e8f9f7 994 ret--;
<> 144:ef7eb2e8f9f7 995 }
<> 144:ef7eb2e8f9f7 996
<> 144:ef7eb2e8f9f7 997 return (uint8_t)ret;
<> 144:ef7eb2e8f9f7 998 }
<> 144:ef7eb2e8f9f7 999
<> 144:ef7eb2e8f9f7 1000 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1001 * @brief
<> 144:ef7eb2e8f9f7 1002 * Reset ADC to same state as after a HW reset.
<> 144:ef7eb2e8f9f7 1003 *
<> 144:ef7eb2e8f9f7 1004 * @note
<> 144:ef7eb2e8f9f7 1005 * The ROUTE register is NOT reset by this function, in order to allow for
<> 144:ef7eb2e8f9f7 1006 * centralized setup of this feature.
<> 144:ef7eb2e8f9f7 1007 *
<> 144:ef7eb2e8f9f7 1008 * @param[in] adc
<> 144:ef7eb2e8f9f7 1009 * Pointer to ADC peripheral register block.
<> 144:ef7eb2e8f9f7 1010 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1011 void ADC_Reset(ADC_TypeDef *adc)
<> 144:ef7eb2e8f9f7 1012 {
<> 144:ef7eb2e8f9f7 1013 /* Stop conversions, before resetting other registers. */
<> 144:ef7eb2e8f9f7 1014 adc->CMD = ADC_CMD_SINGLESTOP | ADC_CMD_SCANSTOP;
<> 144:ef7eb2e8f9f7 1015 adc->SINGLECTRL = _ADC_SINGLECTRL_RESETVALUE;
AnnaBridge 179:b0033dcd6934 1016 #if defined(_ADC_SINGLECTRLX_MASK)
<> 144:ef7eb2e8f9f7 1017 adc->SINGLECTRLX = _ADC_SINGLECTRLX_RESETVALUE;
<> 144:ef7eb2e8f9f7 1018 #endif
<> 144:ef7eb2e8f9f7 1019 adc->SCANCTRL = _ADC_SCANCTRL_RESETVALUE;
AnnaBridge 179:b0033dcd6934 1020 #if defined(_ADC_SCANCTRLX_MASK)
<> 144:ef7eb2e8f9f7 1021 adc->SCANCTRLX = _ADC_SCANCTRLX_RESETVALUE;
<> 144:ef7eb2e8f9f7 1022 #endif
<> 144:ef7eb2e8f9f7 1023 adc->CTRL = _ADC_CTRL_RESETVALUE;
<> 144:ef7eb2e8f9f7 1024 adc->IEN = _ADC_IEN_RESETVALUE;
<> 144:ef7eb2e8f9f7 1025 adc->IFC = _ADC_IFC_MASK;
<> 144:ef7eb2e8f9f7 1026 adc->BIASPROG = _ADC_BIASPROG_RESETVALUE;
AnnaBridge 179:b0033dcd6934 1027 #if defined(_ADC_SCANMASK_MASK)
<> 144:ef7eb2e8f9f7 1028 adc->SCANMASK = _ADC_SCANMASK_RESETVALUE;
<> 144:ef7eb2e8f9f7 1029 #endif
AnnaBridge 179:b0033dcd6934 1030 #if defined(_ADC_SCANINPUTSEL_MASK)
<> 144:ef7eb2e8f9f7 1031 adc->SCANINPUTSEL = _ADC_SCANINPUTSEL_RESETVALUE;
<> 144:ef7eb2e8f9f7 1032 #endif
AnnaBridge 179:b0033dcd6934 1033 #if defined(_ADC_SCANNEGSEL_MASK)
<> 144:ef7eb2e8f9f7 1034 adc->SCANNEGSEL = _ADC_SCANNEGSEL_RESETVALUE;
<> 144:ef7eb2e8f9f7 1035 #endif
<> 144:ef7eb2e8f9f7 1036
<> 144:ef7eb2e8f9f7 1037 /* Clear data FIFOs */
AnnaBridge 179:b0033dcd6934 1038 #if defined(_ADC_SINGLEFIFOCLEAR_MASK)
<> 144:ef7eb2e8f9f7 1039 adc->SINGLEFIFOCLEAR |= ADC_SINGLEFIFOCLEAR_SINGLEFIFOCLEAR;
<> 144:ef7eb2e8f9f7 1040 adc->SCANFIFOCLEAR |= ADC_SCANFIFOCLEAR_SCANFIFOCLEAR;
<> 144:ef7eb2e8f9f7 1041 #endif
<> 144:ef7eb2e8f9f7 1042
<> 144:ef7eb2e8f9f7 1043 /* Load calibration values for the 1V25 internal reference. */
<> 144:ef7eb2e8f9f7 1044 ADC_LoadDevinfoCal(adc, adcRef1V25, false);
<> 144:ef7eb2e8f9f7 1045 ADC_LoadDevinfoCal(adc, adcRef1V25, true);
<> 144:ef7eb2e8f9f7 1046
AnnaBridge 179:b0033dcd6934 1047 #if defined(_ADC_SCANINPUTSEL_MASK)
<> 144:ef7eb2e8f9f7 1048 /* Do not reset route register, setting should be done independently */
<> 144:ef7eb2e8f9f7 1049 #endif
<> 144:ef7eb2e8f9f7 1050 }
<> 144:ef7eb2e8f9f7 1051
<> 144:ef7eb2e8f9f7 1052 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1053 * @brief
<> 144:ef7eb2e8f9f7 1054 * Calculate timebase value in order to get a timebase providing at least 1us.
<> 144:ef7eb2e8f9f7 1055 *
<> 144:ef7eb2e8f9f7 1056 * @param[in] hfperFreq Frequency in Hz of reference HFPER clock. Set to 0 to
<> 144:ef7eb2e8f9f7 1057 * use currently defined HFPER clock setting.
<> 144:ef7eb2e8f9f7 1058 *
<> 144:ef7eb2e8f9f7 1059 * @return
<> 144:ef7eb2e8f9f7 1060 * Timebase value to use for ADC in order to achieve at least 1 us.
<> 144:ef7eb2e8f9f7 1061 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1062 uint8_t ADC_TimebaseCalc(uint32_t hfperFreq)
<> 144:ef7eb2e8f9f7 1063 {
AnnaBridge 179:b0033dcd6934 1064 if (!hfperFreq) {
<> 144:ef7eb2e8f9f7 1065 hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
<> 144:ef7eb2e8f9f7 1066
<> 144:ef7eb2e8f9f7 1067 /* Just in case, make sure we get non-zero freq for below calculation */
AnnaBridge 179:b0033dcd6934 1068 if (!hfperFreq) {
<> 144:ef7eb2e8f9f7 1069 hfperFreq = 1;
<> 144:ef7eb2e8f9f7 1070 }
<> 144:ef7eb2e8f9f7 1071 }
AnnaBridge 179:b0033dcd6934 1072 #if defined(_SILICON_LABS_32B_SERIES_0) \
AnnaBridge 179:b0033dcd6934 1073 && (defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY))
<> 144:ef7eb2e8f9f7 1074 /* Handle errata on Giant Gecko, max TIMEBASE is 5 bits wide or max 0x1F */
<> 144:ef7eb2e8f9f7 1075 /* cycles. This will give a warmp up time of e.g. 0.645us, not the */
<> 144:ef7eb2e8f9f7 1076 /* required 1us when operating at 48MHz. One must also increase acqTime */
<> 144:ef7eb2e8f9f7 1077 /* to compensate for the missing clock cycles, adding up to 1us in total.*/
<> 144:ef7eb2e8f9f7 1078 /* See reference manual for details. */
AnnaBridge 179:b0033dcd6934 1079 if ( hfperFreq > 32000000 ) {
<> 144:ef7eb2e8f9f7 1080 hfperFreq = 32000000;
<> 144:ef7eb2e8f9f7 1081 }
<> 144:ef7eb2e8f9f7 1082 #endif
<> 144:ef7eb2e8f9f7 1083 /* Determine number of HFPERCLK cycle >= 1us */
<> 144:ef7eb2e8f9f7 1084 hfperFreq += 999999;
<> 144:ef7eb2e8f9f7 1085 hfperFreq /= 1000000;
<> 144:ef7eb2e8f9f7 1086
<> 144:ef7eb2e8f9f7 1087 /* Return timebase value (N+1 format) */
<> 144:ef7eb2e8f9f7 1088 return (uint8_t)(hfperFreq - 1);
<> 144:ef7eb2e8f9f7 1089 }
<> 144:ef7eb2e8f9f7 1090
<> 144:ef7eb2e8f9f7 1091 /** @} (end addtogroup ADC) */
<> 150:02e0a0aed4ec 1092 /** @} (end addtogroup emlib) */
<> 144:ef7eb2e8f9f7 1093 #endif /* defined(ADC_COUNT) && (ADC_COUNT > 0) */