mbed library sources. Supersedes mbed-src.

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

Committer:
<>
Date:
Tue Nov 08 17:45:16 2016 +0000
Revision:
150:02e0a0aed4ec
Parent:
149:156823d33999
Child:
161:2cc1468da177
This updates the lib to the mbed lib v129

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