added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Sep 02 15:07:44 2016 +0100
Revision:
144:ef7eb2e8f9f7
Parent:
50:a417edff4437
This updates the lib to the mbed lib v125

Who changed what in which revision?

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