mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
179:b0033dcd6934
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2 * @file em_lesense.c
<> 144:ef7eb2e8f9f7 3 * @brief Low Energy Sensor (LESENSE) Peripheral API
AnnaBridge 179:b0033dcd6934 4 * @version 5.3.3
<> 144:ef7eb2e8f9f7 5 *******************************************************************************
AnnaBridge 179:b0033dcd6934 6 * # License
<> 150:02e0a0aed4ec 7 * <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
<> 144:ef7eb2e8f9f7 8 *******************************************************************************
<> 144:ef7eb2e8f9f7 9 *
<> 144:ef7eb2e8f9f7 10 * Permission is granted to anyone to use this software for any purpose,
<> 144:ef7eb2e8f9f7 11 * including commercial applications, and to alter it and redistribute it
<> 144:ef7eb2e8f9f7 12 * freely, subject to the following restrictions:
<> 144:ef7eb2e8f9f7 13 *
<> 144:ef7eb2e8f9f7 14 * 1. The origin of this software must not be misrepresented; you must not
<> 144:ef7eb2e8f9f7 15 * claim that you wrote the original software.
<> 144:ef7eb2e8f9f7 16 * 2. Altered source versions must be plainly marked as such, and must not be
<> 144:ef7eb2e8f9f7 17 * misrepresented as being the original software.
<> 144:ef7eb2e8f9f7 18 * 3. This notice may not be removed or altered from any source distribution.
<> 144:ef7eb2e8f9f7 19 *
<> 144:ef7eb2e8f9f7 20 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
<> 144:ef7eb2e8f9f7 21 * obligation to support this Software. Silicon Labs is providing the
<> 144:ef7eb2e8f9f7 22 * Software "AS IS", with no express or implied warranties of any kind,
<> 144:ef7eb2e8f9f7 23 * including, but not limited to, any implied warranties of merchantability
<> 144:ef7eb2e8f9f7 24 * or fitness for any particular purpose or warranties against infringement
<> 144:ef7eb2e8f9f7 25 * of any proprietary rights of a third party.
<> 144:ef7eb2e8f9f7 26 *
<> 144:ef7eb2e8f9f7 27 * Silicon Labs will not be liable for any consequential, incidental, or
<> 144:ef7eb2e8f9f7 28 * special damages, or any other relief, or for any claim by any third party,
<> 144:ef7eb2e8f9f7 29 * arising from your use of this Software.
<> 144:ef7eb2e8f9f7 30 *
<> 144:ef7eb2e8f9f7 31 ******************************************************************************/
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 #include "em_lesense.h"
<> 161:2cc1468da177 34
<> 161:2cc1468da177 35 #if defined(LESENSE_COUNT) && (LESENSE_COUNT > 0)
<> 144:ef7eb2e8f9f7 36 #include "em_assert.h"
<> 144:ef7eb2e8f9f7 37 #include "em_bus.h"
<> 144:ef7eb2e8f9f7 38 #include "em_cmu.h"
<> 144:ef7eb2e8f9f7 39
<> 144:ef7eb2e8f9f7 40 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 41 #if !defined(UINT32_MAX)
<> 144:ef7eb2e8f9f7 42 #define UINT32_MAX ((uint32_t)(0xFFFFFFFF))
<> 144:ef7eb2e8f9f7 43 #endif
<> 144:ef7eb2e8f9f7 44 /** @endcond */
<> 144:ef7eb2e8f9f7 45
<> 144:ef7eb2e8f9f7 46 /***************************************************************************//**
<> 150:02e0a0aed4ec 47 * @addtogroup emlib
<> 144:ef7eb2e8f9f7 48 * @{
<> 144:ef7eb2e8f9f7 49 ******************************************************************************/
<> 144:ef7eb2e8f9f7 50
<> 144:ef7eb2e8f9f7 51 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 52 * @addtogroup LESENSE
<> 144:ef7eb2e8f9f7 53 * @brief Low Energy Sensor (LESENSE) Peripheral API
<> 150:02e0a0aed4ec 54 * @details
<> 150:02e0a0aed4ec 55 * This module contains functions to control the LESENSE peripheral of Silicon
<> 150:02e0a0aed4ec 56 * Labs 32-bit MCUs and SoCs. LESENSE is a low energy sensor interface capable
<> 150:02e0a0aed4ec 57 * of autonomously collecting and processing data from multiple sensors even
<> 150:02e0a0aed4ec 58 * when in EM2.
<> 144:ef7eb2e8f9f7 59 * @{
<> 144:ef7eb2e8f9f7 60 ******************************************************************************/
<> 144:ef7eb2e8f9f7 61
<> 161:2cc1468da177 62 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 161:2cc1468da177 63 #if defined(_LESENSE_ROUTE_MASK)
<> 161:2cc1468da177 64 #define GENERIC_LESENSE_ROUTE LESENSE->ROUTE
<> 161:2cc1468da177 65 #else
<> 161:2cc1468da177 66 #define GENERIC_LESENSE_ROUTE LESENSE->ROUTEPEN
<> 161:2cc1468da177 67 #endif
<> 161:2cc1468da177 68
<> 161:2cc1468da177 69 #if defined(_SILICON_LABS_32B_SERIES_0)
<> 161:2cc1468da177 70 /* DACOUT mode only available on channel 0,1,2,3,12,13,14,15 */
<> 161:2cc1468da177 71 #define DACOUT_SUPPORT 0xF00F
<> 161:2cc1468da177 72 #else
<> 161:2cc1468da177 73 /* DACOUT mode only available on channel 4,5,7,10,12,13 */
<> 161:2cc1468da177 74 #define DACOUT_SUPPORT 0x34B0
<> 161:2cc1468da177 75 #endif
<> 161:2cc1468da177 76 /** @endcond */
<> 161:2cc1468da177 77
<> 144:ef7eb2e8f9f7 78 /*******************************************************************************
<> 144:ef7eb2e8f9f7 79 ************************** LOCAL FUNCTIONS ********************************
<> 144:ef7eb2e8f9f7 80 ******************************************************************************/
<> 144:ef7eb2e8f9f7 81
<> 144:ef7eb2e8f9f7 82 /*******************************************************************************
<> 144:ef7eb2e8f9f7 83 ************************** GLOBAL FUNCTIONS *******************************
<> 144:ef7eb2e8f9f7 84 ******************************************************************************/
<> 144:ef7eb2e8f9f7 85
<> 144:ef7eb2e8f9f7 86 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 87 * @brief
<> 144:ef7eb2e8f9f7 88 * Initialize the LESENSE module.
<> 144:ef7eb2e8f9f7 89 *
<> 144:ef7eb2e8f9f7 90 * @details
<> 144:ef7eb2e8f9f7 91 * This function configures the main parameters of the LESENSE interface.
<> 144:ef7eb2e8f9f7 92 * Please refer to the initialization parameter type definition
<> 144:ef7eb2e8f9f7 93 * (@ref LESENSE_Init_TypeDef) for more details.
<> 144:ef7eb2e8f9f7 94 *
<> 144:ef7eb2e8f9f7 95 * @note
<> 144:ef7eb2e8f9f7 96 * @ref LESENSE_Init() has been designed for initializing LESENSE once in an
<> 144:ef7eb2e8f9f7 97 * operation cycle. Be aware of the effects of reconfiguration if using this
<> 144:ef7eb2e8f9f7 98 * function from multiple sources in your code. This function has not been
<> 144:ef7eb2e8f9f7 99 * designed to be re-entrant.
<> 144:ef7eb2e8f9f7 100 * Requesting reset by setting @p reqReset to true is required in each reset
<> 144:ef7eb2e8f9f7 101 * or power-on cycle in order to configure the default values of the RAM
<> 144:ef7eb2e8f9f7 102 * mapped LESENSE registers.
<> 144:ef7eb2e8f9f7 103 * Notice that GPIO pins used by the LESENSE module must be properly
<> 144:ef7eb2e8f9f7 104 * configured by the user explicitly, in order for the LESENSE to work as
<> 144:ef7eb2e8f9f7 105 * intended.
<> 144:ef7eb2e8f9f7 106 * (When configuring pins, one should remember to consider the sequence of
<> 144:ef7eb2e8f9f7 107 * configuration, in order to avoid unintended pulses/glitches on output
<> 144:ef7eb2e8f9f7 108 * pins.)
<> 144:ef7eb2e8f9f7 109 *
<> 144:ef7eb2e8f9f7 110 * @param[in] init
<> 144:ef7eb2e8f9f7 111 * LESENSE initialization structure.
<> 144:ef7eb2e8f9f7 112 *
<> 144:ef7eb2e8f9f7 113 * @param[in] reqReset
<> 144:ef7eb2e8f9f7 114 * Request to call @ref LESENSE_Reset() first in order to initialize all
<> 144:ef7eb2e8f9f7 115 * LESENSE registers with the default value.
<> 144:ef7eb2e8f9f7 116 ******************************************************************************/
<> 161:2cc1468da177 117 void LESENSE_Init(const LESENSE_Init_TypeDef * init, bool reqReset)
<> 144:ef7eb2e8f9f7 118 {
<> 144:ef7eb2e8f9f7 119 /* Sanity check of initialization values */
<> 144:ef7eb2e8f9f7 120 EFM_ASSERT((uint32_t)init->timeCtrl.startDelay < 4U);
<> 161:2cc1468da177 121 #if defined(_LESENSE_PERCTRL_DACPRESC_MASK)
<> 144:ef7eb2e8f9f7 122 EFM_ASSERT((uint32_t)init->perCtrl.dacPresc < 32U);
<> 161:2cc1468da177 123 #endif
<> 144:ef7eb2e8f9f7 124
<> 144:ef7eb2e8f9f7 125 /* Reset LESENSE registers if requested. */
AnnaBridge 179:b0033dcd6934 126 if (reqReset) {
<> 144:ef7eb2e8f9f7 127 LESENSE_Reset();
<> 144:ef7eb2e8f9f7 128 }
<> 144:ef7eb2e8f9f7 129
<> 144:ef7eb2e8f9f7 130 /* Set sensor start delay for each channel. */
<> 144:ef7eb2e8f9f7 131 LESENSE_StartDelaySet((uint32_t)init->timeCtrl.startDelay);
<> 161:2cc1468da177 132 #if defined(_LESENSE_TIMCTRL_AUXSTARTUP_MASK)
<> 161:2cc1468da177 133 /* Configure the AUXHRFCO startup delay. */
<> 161:2cc1468da177 134 LESENSE->TIMCTRL = (LESENSE->TIMCTRL & (~_LESENSE_TIMCTRL_AUXSTARTUP_MASK))
<> 161:2cc1468da177 135 | (init->timeCtrl.delayAuxStartup << _LESENSE_TIMCTRL_AUXSTARTUP_SHIFT);
<> 161:2cc1468da177 136 #endif
<> 144:ef7eb2e8f9f7 137
<> 144:ef7eb2e8f9f7 138 /* LESENSE core control configuration.
<> 144:ef7eb2e8f9f7 139 * Set PRS source, SCANCONF register usage strategy, interrupt and
<> 144:ef7eb2e8f9f7 140 * DMA trigger level condition, DMA wakeup condition, bias mode,
<> 144:ef7eb2e8f9f7 141 * enable/disable to sample both ACMPs simultaneously, enable/disable to store
<> 144:ef7eb2e8f9f7 142 * SCANRES in CNT_RES after each scan, enable/disable to always write to the
<> 144:ef7eb2e8f9f7 143 * result buffer, even if it is full, enable/disable LESENSE running in debug
<> 144:ef7eb2e8f9f7 144 * mode. */
<> 144:ef7eb2e8f9f7 145 LESENSE->CTRL =
<> 144:ef7eb2e8f9f7 146 ((uint32_t)init->coreCtrl.prsSel << _LESENSE_CTRL_PRSSEL_SHIFT)
<> 144:ef7eb2e8f9f7 147 | (uint32_t)init->coreCtrl.scanConfSel
<> 144:ef7eb2e8f9f7 148 | (uint32_t)init->coreCtrl.bufTrigLevel
<> 144:ef7eb2e8f9f7 149 | (uint32_t)init->coreCtrl.wakeupOnDMA
<> 161:2cc1468da177 150 #if defined(_LESENSE_CTRL_ACMP0INV_MASK)
<> 144:ef7eb2e8f9f7 151 | ((uint32_t)init->coreCtrl.invACMP0 << _LESENSE_CTRL_ACMP0INV_SHIFT)
<> 144:ef7eb2e8f9f7 152 | ((uint32_t)init->coreCtrl.invACMP1 << _LESENSE_CTRL_ACMP1INV_SHIFT)
<> 161:2cc1468da177 153 #endif
<> 144:ef7eb2e8f9f7 154 | ((uint32_t)init->coreCtrl.dualSample << _LESENSE_CTRL_DUALSAMPLE_SHIFT)
<> 144:ef7eb2e8f9f7 155 | ((uint32_t)init->coreCtrl.storeScanRes << _LESENSE_CTRL_STRSCANRES_SHIFT)
<> 144:ef7eb2e8f9f7 156 | ((uint32_t)init->coreCtrl.bufOverWr << _LESENSE_CTRL_BUFOW_SHIFT)
<> 144:ef7eb2e8f9f7 157 | ((uint32_t)init->coreCtrl.debugRun << _LESENSE_CTRL_DEBUGRUN_SHIFT);
<> 144:ef7eb2e8f9f7 158
<> 144:ef7eb2e8f9f7 159 /* Set scan mode in the CTRL register using the provided function, don't
<> 144:ef7eb2e8f9f7 160 * start scanning immediately. */
<> 144:ef7eb2e8f9f7 161 LESENSE_ScanModeSet((LESENSE_ScanMode_TypeDef)init->coreCtrl.scanStart, false);
<> 144:ef7eb2e8f9f7 162
<> 144:ef7eb2e8f9f7 163 /* LESENSE peripheral control configuration.
<> 144:ef7eb2e8f9f7 164 * Set DAC0 and DAC1 data source, conversion mode, output mode. Set DAC
<> 144:ef7eb2e8f9f7 165 * prescaler and reference. Set ACMP0 and ACMP1 control mode. Set ACMP and DAC
<> 144:ef7eb2e8f9f7 166 * duty cycle (warm up) mode. */
AnnaBridge 179:b0033dcd6934 167 LESENSE->PERCTRL = 0
AnnaBridge 179:b0033dcd6934 168 #if defined(_LESENSE_PERCTRL_DACCH0EN_MASK)
AnnaBridge 179:b0033dcd6934 169 | ((uint32_t)init->perCtrl.dacCh0En << _LESENSE_PERCTRL_DACCH0EN_SHIFT)
AnnaBridge 179:b0033dcd6934 170 | ((uint32_t)init->perCtrl.dacCh1En << _LESENSE_PERCTRL_DACCH1EN_SHIFT)
AnnaBridge 179:b0033dcd6934 171 #endif
AnnaBridge 179:b0033dcd6934 172 | ((uint32_t)init->perCtrl.dacCh0Data << _LESENSE_PERCTRL_DACCH0DATA_SHIFT)
AnnaBridge 179:b0033dcd6934 173 | ((uint32_t)init->perCtrl.dacCh1Data << _LESENSE_PERCTRL_DACCH1DATA_SHIFT)
<> 161:2cc1468da177 174 #if defined(_LESENSE_PERCTRL_DACCH0CONV_MASK)
AnnaBridge 179:b0033dcd6934 175 | ((uint32_t)init->perCtrl.dacCh0ConvMode << _LESENSE_PERCTRL_DACCH0CONV_SHIFT)
AnnaBridge 179:b0033dcd6934 176 | ((uint32_t)init->perCtrl.dacCh0OutMode << _LESENSE_PERCTRL_DACCH0OUT_SHIFT)
AnnaBridge 179:b0033dcd6934 177 | ((uint32_t)init->perCtrl.dacCh1ConvMode << _LESENSE_PERCTRL_DACCH1CONV_SHIFT)
AnnaBridge 179:b0033dcd6934 178 | ((uint32_t)init->perCtrl.dacCh1OutMode << _LESENSE_PERCTRL_DACCH1OUT_SHIFT)
AnnaBridge 179:b0033dcd6934 179 | ((uint32_t)init->perCtrl.dacPresc << _LESENSE_PERCTRL_DACPRESC_SHIFT)
AnnaBridge 179:b0033dcd6934 180 | (uint32_t)init->perCtrl.dacRef
<> 161:2cc1468da177 181 #endif
<> 161:2cc1468da177 182 #if defined(_LESENSE_PERCTRL_DACCONVTRIG_MASK)
AnnaBridge 179:b0033dcd6934 183 | ((uint32_t)init->perCtrl.dacStartupHalf << _LESENSE_PERCTRL_DACSTARTUP_SHIFT)
AnnaBridge 179:b0033dcd6934 184 | ((uint32_t)init->perCtrl.dacScan << _LESENSE_PERCTRL_DACCONVTRIG_SHIFT)
<> 161:2cc1468da177 185 #endif
AnnaBridge 179:b0033dcd6934 186 | ((uint32_t)init->perCtrl.acmp0Mode << _LESENSE_PERCTRL_ACMP0MODE_SHIFT)
AnnaBridge 179:b0033dcd6934 187 | ((uint32_t)init->perCtrl.acmp1Mode << _LESENSE_PERCTRL_ACMP1MODE_SHIFT)
AnnaBridge 179:b0033dcd6934 188 #if defined(_LESENSE_PERCTRL_ACMP0INV_MASK)
AnnaBridge 179:b0033dcd6934 189 | ((uint32_t)init->coreCtrl.invACMP0 << _LESENSE_PERCTRL_ACMP0INV_SHIFT)
AnnaBridge 179:b0033dcd6934 190 | ((uint32_t)init->coreCtrl.invACMP1 << _LESENSE_PERCTRL_ACMP1INV_SHIFT)
AnnaBridge 179:b0033dcd6934 191 #endif
AnnaBridge 179:b0033dcd6934 192 | (uint32_t)init->perCtrl.warmupMode;
<> 144:ef7eb2e8f9f7 193
<> 144:ef7eb2e8f9f7 194 /* LESENSE decoder general control configuration.
<> 144:ef7eb2e8f9f7 195 * Set decoder input source, select PRS input for decoder bits.
<> 144:ef7eb2e8f9f7 196 * Enable/disable the decoder to check the present state.
<> 144:ef7eb2e8f9f7 197 * Enable/disable decoder to channel interrupt mapping.
<> 144:ef7eb2e8f9f7 198 * Enable/disable decoder hysteresis on PRS output.
<> 144:ef7eb2e8f9f7 199 * Enable/disable decoder hysteresis on count events.
<> 144:ef7eb2e8f9f7 200 * Enable/disable decoder hysteresis on interrupt requests.
<> 144:ef7eb2e8f9f7 201 * Enable/disable count mode on LESPRS0 and LESPRS1. */
<> 144:ef7eb2e8f9f7 202 LESENSE->DECCTRL =
<> 144:ef7eb2e8f9f7 203 (uint32_t)init->decCtrl.decInput
<> 144:ef7eb2e8f9f7 204 | ((uint32_t)init->decCtrl.prsChSel0 << _LESENSE_DECCTRL_PRSSEL0_SHIFT)
<> 144:ef7eb2e8f9f7 205 | ((uint32_t)init->decCtrl.prsChSel1 << _LESENSE_DECCTRL_PRSSEL1_SHIFT)
<> 144:ef7eb2e8f9f7 206 | ((uint32_t)init->decCtrl.prsChSel2 << _LESENSE_DECCTRL_PRSSEL2_SHIFT)
<> 144:ef7eb2e8f9f7 207 | ((uint32_t)init->decCtrl.prsChSel3 << _LESENSE_DECCTRL_PRSSEL3_SHIFT)
<> 144:ef7eb2e8f9f7 208 | ((uint32_t)init->decCtrl.chkState << _LESENSE_DECCTRL_ERRCHK_SHIFT)
<> 144:ef7eb2e8f9f7 209 | ((uint32_t)init->decCtrl.intMap << _LESENSE_DECCTRL_INTMAP_SHIFT)
<> 144:ef7eb2e8f9f7 210 | ((uint32_t)init->decCtrl.hystPRS0 << _LESENSE_DECCTRL_HYSTPRS0_SHIFT)
<> 144:ef7eb2e8f9f7 211 | ((uint32_t)init->decCtrl.hystPRS1 << _LESENSE_DECCTRL_HYSTPRS1_SHIFT)
<> 144:ef7eb2e8f9f7 212 | ((uint32_t)init->decCtrl.hystPRS2 << _LESENSE_DECCTRL_HYSTPRS2_SHIFT)
<> 144:ef7eb2e8f9f7 213 | ((uint32_t)init->decCtrl.hystIRQ << _LESENSE_DECCTRL_HYSTIRQ_SHIFT)
<> 144:ef7eb2e8f9f7 214 | ((uint32_t)init->decCtrl.prsCount << _LESENSE_DECCTRL_PRSCNT_SHIFT);
<> 144:ef7eb2e8f9f7 215
<> 144:ef7eb2e8f9f7 216 /* Set initial LESENSE decoder state. */
<> 144:ef7eb2e8f9f7 217 LESENSE_DecoderStateSet((uint32_t)init->decCtrl.initState);
<> 144:ef7eb2e8f9f7 218
<> 144:ef7eb2e8f9f7 219 /* LESENSE bias control configuration. */
<> 144:ef7eb2e8f9f7 220 LESENSE->BIASCTRL = (uint32_t)init->coreCtrl.biasMode;
<> 144:ef7eb2e8f9f7 221 }
<> 144:ef7eb2e8f9f7 222
<> 144:ef7eb2e8f9f7 223 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 224 * @brief
<> 144:ef7eb2e8f9f7 225 * Set scan frequency for periodic scanning.
<> 144:ef7eb2e8f9f7 226 *
<> 144:ef7eb2e8f9f7 227 * @details
<> 144:ef7eb2e8f9f7 228 * This function only applies to LESENSE if period counter is being used as
<> 144:ef7eb2e8f9f7 229 * a trigger for scan start.
<> 144:ef7eb2e8f9f7 230 * The calculation is based on the following formula:
<> 144:ef7eb2e8f9f7 231 * Fscan = LFACLKles / ((1+PCTOP)*2^PCPRESC)
<> 144:ef7eb2e8f9f7 232 *
<> 144:ef7eb2e8f9f7 233 * @note
<> 144:ef7eb2e8f9f7 234 * Note that the calculation does not necessarily result in the requested
<> 144:ef7eb2e8f9f7 235 * scan frequency due to integer division. Check the return value for the
<> 144:ef7eb2e8f9f7 236 * resulted scan frequency.
<> 144:ef7eb2e8f9f7 237 *
<> 144:ef7eb2e8f9f7 238 * @param[in] refFreq
<> 144:ef7eb2e8f9f7 239 * Select reference LFACLK clock frequency in Hz. If set to 0, the current
<> 144:ef7eb2e8f9f7 240 * clock frequency is being used as a reference.
<> 144:ef7eb2e8f9f7 241 *
<> 144:ef7eb2e8f9f7 242 * @param[in] scanFreq
<> 144:ef7eb2e8f9f7 243 * Set the desired scan frequency in Hz.
<> 144:ef7eb2e8f9f7 244 *
<> 144:ef7eb2e8f9f7 245 * @return
<> 144:ef7eb2e8f9f7 246 * Frequency in Hz calculated and set by this function. Users can use this to
<> 144:ef7eb2e8f9f7 247 * compare the requested and set values.
<> 144:ef7eb2e8f9f7 248 ******************************************************************************/
<> 161:2cc1468da177 249 uint32_t LESENSE_ScanFreqSet(uint32_t refFreq, uint32_t scanFreq)
<> 144:ef7eb2e8f9f7 250 {
<> 144:ef7eb2e8f9f7 251 uint32_t tmp;
<> 144:ef7eb2e8f9f7 252 uint32_t pcPresc = 0UL; /* Period counter prescaler. */
<> 144:ef7eb2e8f9f7 253 uint32_t clkDiv = 1UL; /* Clock divisor value (2^pcPresc). */
<> 144:ef7eb2e8f9f7 254 uint32_t pcTop = 63UL; /* Period counter top value (max. 63). */
<> 144:ef7eb2e8f9f7 255 uint32_t calcScanFreq; /* Variable for testing the calculation algorithm. */
<> 144:ef7eb2e8f9f7 256
<> 144:ef7eb2e8f9f7 257 /* If refFreq is set to 0, the currently configured reference clock is
<> 144:ef7eb2e8f9f7 258 * assumed. */
AnnaBridge 179:b0033dcd6934 259 if (!refFreq) {
<> 144:ef7eb2e8f9f7 260 refFreq = CMU_ClockFreqGet(cmuClock_LESENSE);
<> 144:ef7eb2e8f9f7 261 }
<> 144:ef7eb2e8f9f7 262
<> 144:ef7eb2e8f9f7 263 /* Max. value of pcPresc is 128, thus using reference frequency less than
<> 144:ef7eb2e8f9f7 264 * 33554431Hz (33.554431MHz), the frequency calculation in the while loop
<> 144:ef7eb2e8f9f7 265 * below will not overflow. */
<> 144:ef7eb2e8f9f7 266 EFM_ASSERT(refFreq < ((uint32_t)UINT32_MAX / 128UL));
<> 144:ef7eb2e8f9f7 267
<> 144:ef7eb2e8f9f7 268 /* Sanity check of scan frequency value. */
<> 144:ef7eb2e8f9f7 269 EFM_ASSERT((scanFreq > 0U) && (scanFreq <= refFreq));
<> 144:ef7eb2e8f9f7 270
<> 144:ef7eb2e8f9f7 271 /* Calculate the minimum necessary prescaler value in order to provide the
<> 144:ef7eb2e8f9f7 272 * biggest possible resolution for setting scan frequency.
<> 144:ef7eb2e8f9f7 273 * Maximum number of calculation cycles is 7 (value of lesenseClkDiv_128). */
<> 144:ef7eb2e8f9f7 274 while ((refFreq / ((uint32_t)scanFreq * clkDiv) > (pcTop + 1UL))
AnnaBridge 179:b0033dcd6934 275 && (pcPresc < lesenseClkDiv_128)) {
<> 144:ef7eb2e8f9f7 276 ++pcPresc;
<> 144:ef7eb2e8f9f7 277 clkDiv = (uint32_t)1UL << pcPresc;
<> 144:ef7eb2e8f9f7 278 }
<> 144:ef7eb2e8f9f7 279
<> 144:ef7eb2e8f9f7 280 /* Calculate pcTop value. */
<> 144:ef7eb2e8f9f7 281 pcTop = ((uint32_t)refFreq / ((uint32_t)scanFreq * clkDiv)) - 1UL;
<> 144:ef7eb2e8f9f7 282
<> 144:ef7eb2e8f9f7 283 /* Clear current PCPRESC and PCTOP settings. Be aware of the effect of
<> 144:ef7eb2e8f9f7 284 * non-atomic Read-Modify-Write on LESENSE->TIMCRTL. */
<> 144:ef7eb2e8f9f7 285 tmp = LESENSE->TIMCTRL & (~_LESENSE_TIMCTRL_PCPRESC_MASK
<> 144:ef7eb2e8f9f7 286 & ~_LESENSE_TIMCTRL_PCTOP_MASK);
<> 144:ef7eb2e8f9f7 287
<> 144:ef7eb2e8f9f7 288 /* Set new values in tmp while reserving other settings. */
<> 144:ef7eb2e8f9f7 289 tmp |= ((uint32_t)pcPresc << _LESENSE_TIMCTRL_PCPRESC_SHIFT)
<> 144:ef7eb2e8f9f7 290 | ((uint32_t)pcTop << _LESENSE_TIMCTRL_PCTOP_SHIFT);
<> 144:ef7eb2e8f9f7 291
<> 144:ef7eb2e8f9f7 292 /* Set values in LESENSE_TIMCTRL register. */
<> 144:ef7eb2e8f9f7 293 LESENSE->TIMCTRL = tmp;
<> 144:ef7eb2e8f9f7 294
<> 144:ef7eb2e8f9f7 295 /* For testing the calculation algorithm. */
<> 144:ef7eb2e8f9f7 296 calcScanFreq = ((uint32_t)refFreq / ((uint32_t)(1UL + pcTop) * clkDiv));
<> 144:ef7eb2e8f9f7 297
<> 144:ef7eb2e8f9f7 298 return calcScanFreq;
<> 144:ef7eb2e8f9f7 299 }
<> 144:ef7eb2e8f9f7 300
<> 144:ef7eb2e8f9f7 301 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 302 * @brief
<> 144:ef7eb2e8f9f7 303 * Set scan mode of the LESENSE channels.
<> 144:ef7eb2e8f9f7 304 *
<> 144:ef7eb2e8f9f7 305 * @details
<> 144:ef7eb2e8f9f7 306 * This function configures how the scan start is being triggered. It can be
<> 144:ef7eb2e8f9f7 307 * used for re-configuring the scan mode while running the application but it
<> 144:ef7eb2e8f9f7 308 * is also used by LESENSE_Init() for initialization.
<> 144:ef7eb2e8f9f7 309 *
<> 144:ef7eb2e8f9f7 310 * @note
<> 144:ef7eb2e8f9f7 311 * Users can configure the scan mode by LESENSE_Init() function, but only with
<> 144:ef7eb2e8f9f7 312 * a significant overhead. This simple function serves the purpose of
<> 144:ef7eb2e8f9f7 313 * controlling this parameter after the channel has been configured.
<> 144:ef7eb2e8f9f7 314 * Please be aware the effects of the non-atomic Read-Modify-Write cycle!
<> 144:ef7eb2e8f9f7 315 *
<> 144:ef7eb2e8f9f7 316 * @param[in] scanMode
<> 144:ef7eb2e8f9f7 317 * Select where to map LESENSE alternate excitation channels.
<> 144:ef7eb2e8f9f7 318 * @li lesenseScanStartPeriodic - New scan is started each time the period
<> 144:ef7eb2e8f9f7 319 * counter overflows.
<> 144:ef7eb2e8f9f7 320 * @li lesenseScanStartOneShot - Single scan is performed when
<> 144:ef7eb2e8f9f7 321 * LESENSE_ScanStart() is called.
<> 144:ef7eb2e8f9f7 322 * @li lesenseScanStartPRS - New scan is triggered by pulse on PRS channel.
<> 144:ef7eb2e8f9f7 323 *
<> 144:ef7eb2e8f9f7 324 * @param[in] start
<> 144:ef7eb2e8f9f7 325 * If true, LESENSE_ScanStart() is immediately issued after configuration.
<> 144:ef7eb2e8f9f7 326 ******************************************************************************/
<> 161:2cc1468da177 327 void LESENSE_ScanModeSet(LESENSE_ScanMode_TypeDef scanMode,
<> 161:2cc1468da177 328 bool start)
<> 144:ef7eb2e8f9f7 329 {
<> 144:ef7eb2e8f9f7 330 uint32_t tmp; /* temporary storage of the CTRL register value */
<> 144:ef7eb2e8f9f7 331
<> 144:ef7eb2e8f9f7 332 /* Save the CTRL register value to tmp.
<> 144:ef7eb2e8f9f7 333 * Please be aware the effects of the non-atomic Read-Modify-Write cycle! */
<> 144:ef7eb2e8f9f7 334 tmp = LESENSE->CTRL & ~(_LESENSE_CTRL_SCANMODE_MASK);
<> 144:ef7eb2e8f9f7 335 /* Setting the requested scanMode to the CTRL register. Casting signed int
<> 144:ef7eb2e8f9f7 336 * (enum) to unsigned long (uint32_t). */
<> 144:ef7eb2e8f9f7 337 tmp |= (uint32_t)scanMode;
<> 144:ef7eb2e8f9f7 338
<> 144:ef7eb2e8f9f7 339 /* Write the new value to the CTRL register. */
<> 144:ef7eb2e8f9f7 340 LESENSE->CTRL = tmp;
<> 144:ef7eb2e8f9f7 341
<> 144:ef7eb2e8f9f7 342 /* Start sensor scanning if requested. */
AnnaBridge 179:b0033dcd6934 343 if (start) {
<> 144:ef7eb2e8f9f7 344 LESENSE_ScanStart();
<> 144:ef7eb2e8f9f7 345 }
<> 144:ef7eb2e8f9f7 346 }
<> 144:ef7eb2e8f9f7 347
<> 144:ef7eb2e8f9f7 348 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 349 * @brief
<> 144:ef7eb2e8f9f7 350 * Set start delay of sensor interaction on each channel.
<> 144:ef7eb2e8f9f7 351 *
<> 144:ef7eb2e8f9f7 352 * @details
<> 144:ef7eb2e8f9f7 353 * This function sets start delay of sensor interaction on each channel.
<> 144:ef7eb2e8f9f7 354 * It can be used for adjusting the start delay while running the application
<> 144:ef7eb2e8f9f7 355 * but it is also used by LESENSE_Init() for initialization.
<> 144:ef7eb2e8f9f7 356 *
<> 144:ef7eb2e8f9f7 357 * @note
<> 144:ef7eb2e8f9f7 358 * Users can configure the start delay by LESENSE_Init() function, but only
<> 144:ef7eb2e8f9f7 359 * with a significant overhead. This simple function serves the purpose of
<> 144:ef7eb2e8f9f7 360 * controlling this parameter after the channel has been configured.
<> 144:ef7eb2e8f9f7 361 * Please be aware the effects of the non-atomic Read-Modify-Write cycle!
<> 144:ef7eb2e8f9f7 362 *
<> 144:ef7eb2e8f9f7 363 * @param[in] startDelay
<> 144:ef7eb2e8f9f7 364 * Number of LFACLK cycles to delay. Valid range: 0-3 (2 bit).
<> 144:ef7eb2e8f9f7 365 ******************************************************************************/
<> 161:2cc1468da177 366 void LESENSE_StartDelaySet(uint8_t startDelay)
<> 144:ef7eb2e8f9f7 367 {
<> 144:ef7eb2e8f9f7 368 uint32_t tmp; /* temporary storage of the TIMCTRL register value */
<> 144:ef7eb2e8f9f7 369
<> 144:ef7eb2e8f9f7 370 /* Sanity check of startDelay. */
<> 144:ef7eb2e8f9f7 371 EFM_ASSERT(startDelay < 4U);
<> 144:ef7eb2e8f9f7 372
<> 144:ef7eb2e8f9f7 373 /* Save the TIMCTRL register value to tmp.
<> 144:ef7eb2e8f9f7 374 * Please be aware the effects of the non-atomic Read-Modify-Write cycle! */
<> 144:ef7eb2e8f9f7 375 tmp = LESENSE->TIMCTRL & ~(_LESENSE_TIMCTRL_STARTDLY_MASK);
<> 144:ef7eb2e8f9f7 376 /* Setting the requested startDelay to the TIMCTRL register. */
<> 144:ef7eb2e8f9f7 377 tmp |= (uint32_t)startDelay << _LESENSE_TIMCTRL_STARTDLY_SHIFT;
<> 144:ef7eb2e8f9f7 378
<> 144:ef7eb2e8f9f7 379 /* Write the new value to the TIMCTRL register. */
<> 144:ef7eb2e8f9f7 380 LESENSE->TIMCTRL = tmp;
<> 144:ef7eb2e8f9f7 381 }
<> 144:ef7eb2e8f9f7 382
<> 144:ef7eb2e8f9f7 383 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 384 * @brief
<> 144:ef7eb2e8f9f7 385 * Set clock division for LESENSE timers.
<> 144:ef7eb2e8f9f7 386 *
<> 144:ef7eb2e8f9f7 387 * @details
<> 144:ef7eb2e8f9f7 388 * Use this function to configure the clock division for the LESENSE timers
<> 144:ef7eb2e8f9f7 389 * used for excitation timing.
<> 144:ef7eb2e8f9f7 390 * The division setting is global, but the clock source can be selected for
<> 144:ef7eb2e8f9f7 391 * each channel using LESENSE_ChannelConfig() function, please refer to the
<> 144:ef7eb2e8f9f7 392 * documentation of it for more details.
<> 144:ef7eb2e8f9f7 393 *
<> 144:ef7eb2e8f9f7 394 * @note
<> 144:ef7eb2e8f9f7 395 * If AUXHFRCO is used for excitation timing, LFACLK can not exceed 500kHz.
<> 144:ef7eb2e8f9f7 396 * LFACLK can not exceed 50kHz if the ACMP threshold level (ACMPTHRES) is not
<> 144:ef7eb2e8f9f7 397 * equal for all channels.
<> 144:ef7eb2e8f9f7 398 *
<> 144:ef7eb2e8f9f7 399 * @param[in] clk
<> 144:ef7eb2e8f9f7 400 * Select clock to prescale.
<> 144:ef7eb2e8f9f7 401 * @li lesenseClkHF - set AUXHFRCO clock divisor for HF timer.
<> 144:ef7eb2e8f9f7 402 * @li lesenseClkLF - set LFACLKles clock divisor for LF timer.
<> 144:ef7eb2e8f9f7 403 *
<> 144:ef7eb2e8f9f7 404 * @param[in] clkDiv
<> 144:ef7eb2e8f9f7 405 * Clock divisor value. Valid range depends on the @p clk value.
<> 144:ef7eb2e8f9f7 406 ******************************************************************************/
<> 161:2cc1468da177 407 void LESENSE_ClkDivSet(LESENSE_ChClk_TypeDef clk,
<> 161:2cc1468da177 408 LESENSE_ClkPresc_TypeDef clkDiv)
<> 144:ef7eb2e8f9f7 409 {
<> 144:ef7eb2e8f9f7 410 uint32_t tmp;
<> 144:ef7eb2e8f9f7 411
<> 144:ef7eb2e8f9f7 412 /* Select clock to prescale */
AnnaBridge 179:b0033dcd6934 413 switch (clk) {
<> 144:ef7eb2e8f9f7 414 case lesenseClkHF:
<> 144:ef7eb2e8f9f7 415 /* Sanity check of clock divisor for HF clock. */
<> 144:ef7eb2e8f9f7 416 EFM_ASSERT((uint32_t)clkDiv <= lesenseClkDiv_8);
<> 144:ef7eb2e8f9f7 417
<> 144:ef7eb2e8f9f7 418 /* Clear current AUXPRESC settings. */
<> 144:ef7eb2e8f9f7 419 tmp = LESENSE->TIMCTRL & ~(_LESENSE_TIMCTRL_AUXPRESC_MASK);
<> 144:ef7eb2e8f9f7 420
<> 144:ef7eb2e8f9f7 421 /* Set new values in tmp while reserving other settings. */
<> 144:ef7eb2e8f9f7 422 tmp |= ((uint32_t)clkDiv << _LESENSE_TIMCTRL_AUXPRESC_SHIFT);
<> 144:ef7eb2e8f9f7 423
<> 144:ef7eb2e8f9f7 424 /* Set values in LESENSE_TIMCTRL register. */
<> 144:ef7eb2e8f9f7 425 LESENSE->TIMCTRL = tmp;
<> 144:ef7eb2e8f9f7 426 break;
<> 144:ef7eb2e8f9f7 427
<> 144:ef7eb2e8f9f7 428 case lesenseClkLF:
<> 144:ef7eb2e8f9f7 429 /* Clear current LFPRESC settings. */
<> 144:ef7eb2e8f9f7 430 tmp = LESENSE->TIMCTRL & ~(_LESENSE_TIMCTRL_LFPRESC_MASK);
<> 144:ef7eb2e8f9f7 431
<> 144:ef7eb2e8f9f7 432 /* Set new values in tmp while reserving other settings. */
<> 144:ef7eb2e8f9f7 433 tmp |= ((uint32_t)clkDiv << _LESENSE_TIMCTRL_LFPRESC_SHIFT);
<> 144:ef7eb2e8f9f7 434
<> 144:ef7eb2e8f9f7 435 /* Set values in LESENSE_TIMCTRL register. */
<> 144:ef7eb2e8f9f7 436 LESENSE->TIMCTRL = tmp;
<> 144:ef7eb2e8f9f7 437 break;
<> 144:ef7eb2e8f9f7 438
<> 144:ef7eb2e8f9f7 439 default:
<> 144:ef7eb2e8f9f7 440 EFM_ASSERT(0);
<> 144:ef7eb2e8f9f7 441 break;
<> 144:ef7eb2e8f9f7 442 }
<> 144:ef7eb2e8f9f7 443 }
<> 144:ef7eb2e8f9f7 444
<> 144:ef7eb2e8f9f7 445 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 446 * @brief
<> 144:ef7eb2e8f9f7 447 * Configure all (16) LESENSE sensor channels.
<> 144:ef7eb2e8f9f7 448 *
<> 144:ef7eb2e8f9f7 449 * @details
<> 144:ef7eb2e8f9f7 450 * This function configures all the sensor channels of LESENSE interface.
<> 144:ef7eb2e8f9f7 451 * Please refer to the configuration parameter type definition
<> 144:ef7eb2e8f9f7 452 * (LESENSE_ChAll_TypeDef) for more details.
<> 144:ef7eb2e8f9f7 453 *
<> 144:ef7eb2e8f9f7 454 * @note
<> 144:ef7eb2e8f9f7 455 * Channels can be configured individually using LESENSE_ChannelConfig()
<> 144:ef7eb2e8f9f7 456 * function.
<> 144:ef7eb2e8f9f7 457 * Notice that pins used by the LESENSE module must be properly configured
<> 144:ef7eb2e8f9f7 458 * by the user explicitly, in order for the LESENSE to work as intended.
<> 144:ef7eb2e8f9f7 459 * (When configuring pins, one should remember to consider the sequence of
<> 144:ef7eb2e8f9f7 460 * configuration, in order to avoid unintended pulses/glitches on output
<> 144:ef7eb2e8f9f7 461 * pins.)
<> 144:ef7eb2e8f9f7 462 *
<> 144:ef7eb2e8f9f7 463 * @param[in] confChAll
<> 144:ef7eb2e8f9f7 464 * Configuration structure for all (16) LESENSE sensor channels.
<> 144:ef7eb2e8f9f7 465 ******************************************************************************/
<> 161:2cc1468da177 466 void LESENSE_ChannelAllConfig(const LESENSE_ChAll_TypeDef * confChAll)
<> 144:ef7eb2e8f9f7 467 {
<> 144:ef7eb2e8f9f7 468 uint32_t i;
<> 144:ef7eb2e8f9f7 469
<> 144:ef7eb2e8f9f7 470 /* Iterate through all the 16 channels */
AnnaBridge 179:b0033dcd6934 471 for (i = 0U; i < LESENSE_NUM_CHANNELS; ++i) {
<> 144:ef7eb2e8f9f7 472 /* Configure scan channels. */
<> 144:ef7eb2e8f9f7 473 LESENSE_ChannelConfig(&confChAll->Ch[i], i);
<> 144:ef7eb2e8f9f7 474 }
<> 144:ef7eb2e8f9f7 475 }
<> 144:ef7eb2e8f9f7 476
<> 144:ef7eb2e8f9f7 477 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 478 * @brief
<> 144:ef7eb2e8f9f7 479 * Configure a single LESENSE sensor channel.
<> 144:ef7eb2e8f9f7 480 *
<> 144:ef7eb2e8f9f7 481 * @details
<> 144:ef7eb2e8f9f7 482 * This function configures a single sensor channel of the LESENSE interface.
<> 144:ef7eb2e8f9f7 483 * Please refer to the configuration parameter type definition
<> 144:ef7eb2e8f9f7 484 * (LESENSE_ChDesc_TypeDef) for more details.
<> 144:ef7eb2e8f9f7 485 *
<> 144:ef7eb2e8f9f7 486 * @note
<> 144:ef7eb2e8f9f7 487 * This function has been designed to minimize the effects of sensor channel
<> 144:ef7eb2e8f9f7 488 * reconfiguration while LESENSE is in operation, however one shall be aware
<> 144:ef7eb2e8f9f7 489 * of these effects and the right timing of calling this function.
<> 144:ef7eb2e8f9f7 490 * Parameter @p useAltEx must be true in the channel configuration in order to
<> 144:ef7eb2e8f9f7 491 * use alternate excitation pins.
<> 144:ef7eb2e8f9f7 492 *
<> 144:ef7eb2e8f9f7 493 * @param[in] confCh
<> 144:ef7eb2e8f9f7 494 * Configuration structure for a single LESENSE sensor channel.
<> 144:ef7eb2e8f9f7 495 *
<> 144:ef7eb2e8f9f7 496 * @param[in] chIdx
<> 144:ef7eb2e8f9f7 497 * Channel index to configure (0-15).
<> 144:ef7eb2e8f9f7 498 ******************************************************************************/
<> 161:2cc1468da177 499 void LESENSE_ChannelConfig(const LESENSE_ChDesc_TypeDef * confCh,
<> 161:2cc1468da177 500 uint32_t chIdx)
<> 144:ef7eb2e8f9f7 501 {
<> 144:ef7eb2e8f9f7 502 uint32_t tmp; /* Service variable. */
<> 144:ef7eb2e8f9f7 503
<> 144:ef7eb2e8f9f7 504 /* Sanity check of configuration parameters */
<> 161:2cc1468da177 505 EFM_ASSERT(chIdx < LESENSE_NUM_CHANNELS);
<> 161:2cc1468da177 506 EFM_ASSERT(confCh->exTime <= (_LESENSE_CH_TIMING_EXTIME_MASK >> _LESENSE_CH_TIMING_EXTIME_SHIFT));
<> 161:2cc1468da177 507 EFM_ASSERT(confCh->measDelay <= (_LESENSE_CH_TIMING_MEASUREDLY_MASK >> _LESENSE_CH_TIMING_MEASUREDLY_SHIFT));
<> 161:2cc1468da177 508 #if defined(_SILICON_LABS_32B_SERIES_0)
<> 161:2cc1468da177 509 // Sample delay on other devices are 8 bits which fits perfectly in uint8_t
<> 161:2cc1468da177 510 EFM_ASSERT(confCh->sampleDelay <= (_LESENSE_CH_TIMING_SAMPLEDLY_MASK >> _LESENSE_CH_TIMING_SAMPLEDLY_SHIFT));
<> 161:2cc1468da177 511 #endif
<> 161:2cc1468da177 512
<> 144:ef7eb2e8f9f7 513 /* Not a complete assert, as the max. value of acmpThres depends on other
<> 144:ef7eb2e8f9f7 514 * configuration parameters, check the parameter description of acmpThres for
<> 144:ef7eb2e8f9f7 515 * for more details! */
<> 144:ef7eb2e8f9f7 516 EFM_ASSERT(confCh->acmpThres < 4096U);
AnnaBridge 179:b0033dcd6934 517 if (confCh->chPinExMode == lesenseChPinExDACOut) {
<> 161:2cc1468da177 518 EFM_ASSERT((0x1 << chIdx) & DACOUT_SUPPORT);
<> 161:2cc1468da177 519 }
<> 161:2cc1468da177 520
<> 161:2cc1468da177 521 #if defined(_LESENSE_IDLECONF_CH0_DACCH0)
<> 144:ef7eb2e8f9f7 522 EFM_ASSERT(!(confCh->chPinIdleMode == lesenseChPinIdleDACCh1
<> 144:ef7eb2e8f9f7 523 && ((chIdx != 12U)
<> 144:ef7eb2e8f9f7 524 && (chIdx != 13U)
<> 144:ef7eb2e8f9f7 525 && (chIdx != 14U)
<> 144:ef7eb2e8f9f7 526 && (chIdx != 15U))));
<> 144:ef7eb2e8f9f7 527 EFM_ASSERT(!(confCh->chPinIdleMode == lesenseChPinIdleDACCh0
<> 144:ef7eb2e8f9f7 528 && ((chIdx != 0U)
<> 144:ef7eb2e8f9f7 529 && (chIdx != 1U)
<> 144:ef7eb2e8f9f7 530 && (chIdx != 2U)
<> 144:ef7eb2e8f9f7 531 && (chIdx != 3U))));
<> 161:2cc1468da177 532 #endif
<> 144:ef7eb2e8f9f7 533
<> 144:ef7eb2e8f9f7 534 /* Configure chIdx setup in LESENSE idle phase.
<> 144:ef7eb2e8f9f7 535 * Read-modify-write in order to support reconfiguration during LESENSE
<> 144:ef7eb2e8f9f7 536 * operation. */
<> 144:ef7eb2e8f9f7 537 tmp = (LESENSE->IDLECONF & ~((uint32_t)0x3UL << (chIdx * 2UL)));
<> 144:ef7eb2e8f9f7 538 tmp |= ((uint32_t)confCh->chPinIdleMode << (chIdx * 2UL));
<> 144:ef7eb2e8f9f7 539 LESENSE->IDLECONF = tmp;
<> 144:ef7eb2e8f9f7 540
<> 144:ef7eb2e8f9f7 541 /* Channel specific timing configuration on scan channel chIdx.
<> 144:ef7eb2e8f9f7 542 * Set excitation time, sampling delay, measurement delay. */
<> 144:ef7eb2e8f9f7 543 LESENSE_ChannelTimingSet(chIdx,
<> 161:2cc1468da177 544 confCh->exTime,
<> 161:2cc1468da177 545 confCh->sampleDelay,
<> 161:2cc1468da177 546 confCh->measDelay);
<> 144:ef7eb2e8f9f7 547
<> 144:ef7eb2e8f9f7 548 /* Channel specific configuration of clocks, sample mode, excitation pin mode
<> 144:ef7eb2e8f9f7 549 * alternate excitation usage and interrupt mode on scan channel chIdx in
<> 144:ef7eb2e8f9f7 550 * LESENSE_CHchIdx_INTERACT. */
<> 144:ef7eb2e8f9f7 551 LESENSE->CH[chIdx].INTERACT =
AnnaBridge 179:b0033dcd6934 552 ((uint32_t)confCh->exClk << _LESENSE_CH_INTERACT_EXCLK_SHIFT)
AnnaBridge 179:b0033dcd6934 553 | ((uint32_t)confCh->sampleClk << _LESENSE_CH_INTERACT_SAMPLECLK_SHIFT)
AnnaBridge 179:b0033dcd6934 554 | (uint32_t)confCh->sampleMode
AnnaBridge 179:b0033dcd6934 555 | (uint32_t)confCh->intMode
AnnaBridge 179:b0033dcd6934 556 | (uint32_t)confCh->chPinExMode
AnnaBridge 179:b0033dcd6934 557 | ((uint32_t)confCh->useAltEx << _LESENSE_CH_INTERACT_ALTEX_SHIFT);
<> 144:ef7eb2e8f9f7 558
<> 144:ef7eb2e8f9f7 559 /* Configure channel specific counter comparison mode, optional result
<> 144:ef7eb2e8f9f7 560 * forwarding to decoder, optional counter value storing and optional result
<> 144:ef7eb2e8f9f7 561 * inverting on scan channel chIdx in LESENSE_CHchIdx_EVAL. */
<> 144:ef7eb2e8f9f7 562 LESENSE->CH[chIdx].EVAL =
AnnaBridge 179:b0033dcd6934 563 (uint32_t)confCh->compMode
AnnaBridge 179:b0033dcd6934 564 | ((uint32_t)confCh->shiftRes << _LESENSE_CH_EVAL_DECODE_SHIFT)
AnnaBridge 179:b0033dcd6934 565 | ((uint32_t)confCh->storeCntRes << _LESENSE_CH_EVAL_STRSAMPLE_SHIFT)
AnnaBridge 179:b0033dcd6934 566 | ((uint32_t)confCh->invRes << _LESENSE_CH_EVAL_SCANRESINV_SHIFT)
<> 161:2cc1468da177 567 #if defined(_LESENSE_CH_EVAL_MODE_MASK)
AnnaBridge 179:b0033dcd6934 568 | ((uint32_t)confCh->evalMode << _LESENSE_CH_EVAL_MODE_SHIFT)
<> 161:2cc1468da177 569 #endif
AnnaBridge 179:b0033dcd6934 570 ;
<> 144:ef7eb2e8f9f7 571
<> 144:ef7eb2e8f9f7 572 /* Configure analog comparator (ACMP) threshold and decision threshold for
<> 144:ef7eb2e8f9f7 573 * counter separately with the function provided for that. */
<> 144:ef7eb2e8f9f7 574 LESENSE_ChannelThresSet(chIdx,
<> 161:2cc1468da177 575 confCh->acmpThres,
<> 161:2cc1468da177 576 confCh->cntThres);
<> 144:ef7eb2e8f9f7 577
<> 144:ef7eb2e8f9f7 578 /* Enable/disable interrupts on channel */
<> 161:2cc1468da177 579 BUS_RegBitWrite(&LESENSE->IEN, chIdx, confCh->enaInt);
<> 144:ef7eb2e8f9f7 580
<> 144:ef7eb2e8f9f7 581 /* Enable/disable CHchIdx pin. */
<> 161:2cc1468da177 582 BUS_RegBitWrite(&GENERIC_LESENSE_ROUTE, chIdx, confCh->enaPin);
<> 144:ef7eb2e8f9f7 583
<> 144:ef7eb2e8f9f7 584 /* Enable/disable scan channel chIdx. */
<> 161:2cc1468da177 585 BUS_RegBitWrite(&LESENSE->CHEN, chIdx, confCh->enaScanCh);
<> 144:ef7eb2e8f9f7 586 }
<> 144:ef7eb2e8f9f7 587
<> 144:ef7eb2e8f9f7 588 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 589 * @brief
<> 144:ef7eb2e8f9f7 590 * Configure the LESENSE alternate excitation modes.
<> 144:ef7eb2e8f9f7 591 *
<> 144:ef7eb2e8f9f7 592 * @details
<> 144:ef7eb2e8f9f7 593 * This function configures the alternate excitation channels of the LESENSE
<> 144:ef7eb2e8f9f7 594 * interface. Please refer to the configuration parameter type definition
<> 144:ef7eb2e8f9f7 595 * (LESENSE_ConfAltEx_TypeDef) for more details.
<> 144:ef7eb2e8f9f7 596 *
<> 144:ef7eb2e8f9f7 597 * @note
<> 144:ef7eb2e8f9f7 598 * Parameter @p useAltEx must be true in the channel configuration structrure
<> 144:ef7eb2e8f9f7 599 * (LESENSE_ChDesc_TypeDef) in order to use alternate excitation pins on the
<> 144:ef7eb2e8f9f7 600 * channel.
<> 144:ef7eb2e8f9f7 601 *
<> 144:ef7eb2e8f9f7 602 * @param[in] confAltEx
<> 144:ef7eb2e8f9f7 603 * Configuration structure for LESENSE alternate excitation pins.
<> 144:ef7eb2e8f9f7 604 ******************************************************************************/
<> 161:2cc1468da177 605 void LESENSE_AltExConfig(const LESENSE_ConfAltEx_TypeDef * confAltEx)
<> 144:ef7eb2e8f9f7 606 {
<> 144:ef7eb2e8f9f7 607 uint32_t i;
<> 144:ef7eb2e8f9f7 608 uint32_t tmp;
<> 144:ef7eb2e8f9f7 609
<> 144:ef7eb2e8f9f7 610 /* Configure alternate excitation mapping.
<> 144:ef7eb2e8f9f7 611 * Atomic read-modify-write using BUS_RegBitWrite function in order to
<> 144:ef7eb2e8f9f7 612 * support reconfiguration during LESENSE operation. */
<> 161:2cc1468da177 613 BUS_RegBitWrite(&LESENSE->CTRL,
<> 144:ef7eb2e8f9f7 614 _LESENSE_CTRL_ALTEXMAP_SHIFT,
<> 144:ef7eb2e8f9f7 615 confAltEx->altExMap);
<> 144:ef7eb2e8f9f7 616
AnnaBridge 179:b0033dcd6934 617 switch (confAltEx->altExMap) {
<> 144:ef7eb2e8f9f7 618 case lesenseAltExMapALTEX:
<> 144:ef7eb2e8f9f7 619 /* Iterate through the 8 possible alternate excitation pin descriptors. */
AnnaBridge 179:b0033dcd6934 620 for (i = 0U; i < 8U; ++i) {
<> 144:ef7eb2e8f9f7 621 /* Enable/disable alternate excitation pin i.
<> 144:ef7eb2e8f9f7 622 * Atomic read-modify-write using BUS_RegBitWrite function in order to
<> 144:ef7eb2e8f9f7 623 * support reconfiguration during LESENSE operation. */
<> 161:2cc1468da177 624 BUS_RegBitWrite(&GENERIC_LESENSE_ROUTE,
<> 144:ef7eb2e8f9f7 625 (16UL + i),
<> 144:ef7eb2e8f9f7 626 confAltEx->AltEx[i].enablePin);
<> 144:ef7eb2e8f9f7 627
<> 144:ef7eb2e8f9f7 628 /* Setup the idle phase state of alternate excitation pin i.
<> 144:ef7eb2e8f9f7 629 * Read-modify-write in order to support reconfiguration during LESENSE
<> 144:ef7eb2e8f9f7 630 * operation. */
<> 144:ef7eb2e8f9f7 631 tmp = (LESENSE->ALTEXCONF & ~((uint32_t)0x3UL << (i * 2UL)));
<> 144:ef7eb2e8f9f7 632 tmp |= ((uint32_t)confAltEx->AltEx[i].idleConf << (i * 2UL));
<> 144:ef7eb2e8f9f7 633 LESENSE->ALTEXCONF = tmp;
<> 144:ef7eb2e8f9f7 634
<> 144:ef7eb2e8f9f7 635 /* Enable/disable always excite on channel i */
<> 161:2cc1468da177 636 BUS_RegBitWrite(&LESENSE->ALTEXCONF,
<> 144:ef7eb2e8f9f7 637 (16UL + i),
<> 144:ef7eb2e8f9f7 638 confAltEx->AltEx[i].alwaysEx);
<> 144:ef7eb2e8f9f7 639 }
<> 144:ef7eb2e8f9f7 640 break;
<> 144:ef7eb2e8f9f7 641
<> 161:2cc1468da177 642 #if defined(_LESENSE_CTRL_ALTEXMAP_ACMP)
<> 144:ef7eb2e8f9f7 643 case lesenseAltExMapACMP:
<> 161:2cc1468da177 644 #else
<> 161:2cc1468da177 645 case lesenseAltExMapCH:
<> 161:2cc1468da177 646 #endif
<> 144:ef7eb2e8f9f7 647 /* Iterate through all the 16 alternate excitation channels */
AnnaBridge 179:b0033dcd6934 648 for (i = 0U; i < 16U; ++i) {
<> 144:ef7eb2e8f9f7 649 /* Enable/disable alternate ACMP excitation channel pin i. */
<> 144:ef7eb2e8f9f7 650 /* Atomic read-modify-write using BUS_RegBitWrite function in order to
<> 144:ef7eb2e8f9f7 651 * support reconfiguration during LESENSE operation. */
<> 161:2cc1468da177 652 BUS_RegBitWrite(&GENERIC_LESENSE_ROUTE,
<> 144:ef7eb2e8f9f7 653 i,
<> 144:ef7eb2e8f9f7 654 confAltEx->AltEx[i].enablePin);
<> 144:ef7eb2e8f9f7 655 }
<> 144:ef7eb2e8f9f7 656 break;
<> 144:ef7eb2e8f9f7 657 default:
<> 144:ef7eb2e8f9f7 658 /* Illegal value. */
<> 144:ef7eb2e8f9f7 659 EFM_ASSERT(0);
<> 144:ef7eb2e8f9f7 660 break;
<> 144:ef7eb2e8f9f7 661 }
<> 144:ef7eb2e8f9f7 662 }
<> 144:ef7eb2e8f9f7 663
<> 144:ef7eb2e8f9f7 664 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 665 * @brief
<> 144:ef7eb2e8f9f7 666 * Enable/disable LESENSE scan channel and the pin assigned to it.
<> 144:ef7eb2e8f9f7 667 *
<> 144:ef7eb2e8f9f7 668 * @details
<> 144:ef7eb2e8f9f7 669 * Use this function to enable/disable a selected LESENSE scan channel and the
<> 144:ef7eb2e8f9f7 670 * pin assigned to.
<> 144:ef7eb2e8f9f7 671 *
<> 144:ef7eb2e8f9f7 672 * @note
<> 144:ef7eb2e8f9f7 673 * Users can enable/disable scan channels and the channel pin by
<> 144:ef7eb2e8f9f7 674 * LESENSE_ChannelConfig() function, but only with a significant overhead.
<> 144:ef7eb2e8f9f7 675 * This simple function serves the purpose of controlling these parameters
<> 144:ef7eb2e8f9f7 676 * after the channel has been configured.
<> 144:ef7eb2e8f9f7 677 *
<> 144:ef7eb2e8f9f7 678 * @param[in] chIdx
<> 144:ef7eb2e8f9f7 679 * Identifier of the scan channel. Valid range: 0-15.
<> 144:ef7eb2e8f9f7 680 *
<> 144:ef7eb2e8f9f7 681 * @param[in] enaScanCh
<> 144:ef7eb2e8f9f7 682 * Enable/disable the selected scan channel by setting this parameter to
<> 144:ef7eb2e8f9f7 683 * true/false respectively.
<> 144:ef7eb2e8f9f7 684 *
<> 144:ef7eb2e8f9f7 685 * @param[in] enaPin
<> 144:ef7eb2e8f9f7 686 * Enable/disable the pin assigned to the channel selected by @p chIdx.
<> 144:ef7eb2e8f9f7 687 ******************************************************************************/
<> 161:2cc1468da177 688 void LESENSE_ChannelEnable(uint8_t chIdx,
<> 161:2cc1468da177 689 bool enaScanCh,
<> 161:2cc1468da177 690 bool enaPin)
<> 144:ef7eb2e8f9f7 691 {
<> 144:ef7eb2e8f9f7 692 /* Enable/disable the assigned pin of scan channel chIdx.
<> 144:ef7eb2e8f9f7 693 * Note: BUS_RegBitWrite() function is used for setting/clearing single
<> 144:ef7eb2e8f9f7 694 * bit peripheral register bitfields. Read the function description in
<> 144:ef7eb2e8f9f7 695 * em_bus.h for more details. */
<> 161:2cc1468da177 696 BUS_RegBitWrite(&GENERIC_LESENSE_ROUTE, chIdx, enaPin);
<> 144:ef7eb2e8f9f7 697
<> 144:ef7eb2e8f9f7 698 /* Enable/disable scan channel chIdx. */
<> 161:2cc1468da177 699 BUS_RegBitWrite(&LESENSE->CHEN, chIdx, enaScanCh);
<> 144:ef7eb2e8f9f7 700 }
<> 144:ef7eb2e8f9f7 701
<> 144:ef7eb2e8f9f7 702 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 703 * @brief
<> 144:ef7eb2e8f9f7 704 * Enable/disable LESENSE scan channel and the pin assigned to it.
<> 144:ef7eb2e8f9f7 705 *
<> 144:ef7eb2e8f9f7 706 * @details
<> 144:ef7eb2e8f9f7 707 * Use this function to enable/disable LESENSE scan channels and the pins
<> 144:ef7eb2e8f9f7 708 * assigned to them using a mask.
<> 144:ef7eb2e8f9f7 709 *
<> 144:ef7eb2e8f9f7 710 * @note
<> 144:ef7eb2e8f9f7 711 * Users can enable/disable scan channels and channel pins by using
<> 144:ef7eb2e8f9f7 712 * LESENSE_ChannelAllConfig() function, but only with a significant overhead.
<> 144:ef7eb2e8f9f7 713 * This simple function serves the purpose of controlling these parameters
<> 144:ef7eb2e8f9f7 714 * after the channel has been configured.
<> 144:ef7eb2e8f9f7 715 *
<> 144:ef7eb2e8f9f7 716 * @param[in] chMask
<> 144:ef7eb2e8f9f7 717 * Set the corresponding bit to 1 to enable, 0 to disable the selected scan
<> 144:ef7eb2e8f9f7 718 * channel.
<> 144:ef7eb2e8f9f7 719 *
<> 144:ef7eb2e8f9f7 720 * @param[in] pinMask
<> 144:ef7eb2e8f9f7 721 * Set the corresponding bit to 1 to enable, 0 to disable the pin on selected
<> 144:ef7eb2e8f9f7 722 * channel.
<> 144:ef7eb2e8f9f7 723 ******************************************************************************/
<> 144:ef7eb2e8f9f7 724 void LESENSE_ChannelEnableMask(uint16_t chMask, uint16_t pinMask)
<> 144:ef7eb2e8f9f7 725 {
<> 144:ef7eb2e8f9f7 726 /* Enable/disable all channels at once according to the mask. */
<> 144:ef7eb2e8f9f7 727 LESENSE->CHEN = chMask;
<> 144:ef7eb2e8f9f7 728 /* Enable/disable all channel pins at once according to the mask. */
<> 161:2cc1468da177 729 GENERIC_LESENSE_ROUTE = pinMask;
<> 144:ef7eb2e8f9f7 730 }
<> 144:ef7eb2e8f9f7 731
<> 144:ef7eb2e8f9f7 732 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 733 * @brief
<> 144:ef7eb2e8f9f7 734 * Set LESENSE channel timing parameters.
<> 144:ef7eb2e8f9f7 735 *
<> 144:ef7eb2e8f9f7 736 * @details
<> 144:ef7eb2e8f9f7 737 * Use this function to set timing parameters on a selected LESENSE channel.
<> 144:ef7eb2e8f9f7 738 *
<> 144:ef7eb2e8f9f7 739 * @note
<> 144:ef7eb2e8f9f7 740 * Users can configure the channel timing parameters by
<> 144:ef7eb2e8f9f7 741 * LESENSE_ChannelConfig() function, but only with a significant overhead.
<> 144:ef7eb2e8f9f7 742 * This simple function serves the purpose of controlling these parameters
<> 144:ef7eb2e8f9f7 743 * after the channel has been configured.
<> 144:ef7eb2e8f9f7 744 *
<> 144:ef7eb2e8f9f7 745 * @param[in] chIdx
<> 144:ef7eb2e8f9f7 746 * Identifier of the scan channel. Valid range: 0-15.
<> 144:ef7eb2e8f9f7 747 *
<> 144:ef7eb2e8f9f7 748 * @param[in] exTime
<> 144:ef7eb2e8f9f7 749 * Excitation time on chIdx. Excitation will last exTime+1 excitation clock
<> 144:ef7eb2e8f9f7 750 * cycles. Valid range: 0-63 (6 bits).
<> 144:ef7eb2e8f9f7 751 *
<> 144:ef7eb2e8f9f7 752 * @param[in] sampleDelay
<> 144:ef7eb2e8f9f7 753 * Sample delay on chIdx. Sampling will occur after sampleDelay+1 sample clock
<> 144:ef7eb2e8f9f7 754 * cycles. Valid range: 0-127 (7 bits).
<> 144:ef7eb2e8f9f7 755 *
<> 144:ef7eb2e8f9f7 756 * @param[in] measDelay
<> 144:ef7eb2e8f9f7 757 * Measure delay on chIdx. Sensor measuring is delayed for measDelay+1
<> 144:ef7eb2e8f9f7 758 * excitation clock cycles. Valid range: 0-127 (7 bits).
<> 144:ef7eb2e8f9f7 759 ******************************************************************************/
<> 161:2cc1468da177 760 void LESENSE_ChannelTimingSet(uint8_t chIdx,
<> 161:2cc1468da177 761 uint8_t exTime,
<> 161:2cc1468da177 762 uint8_t sampleDelay,
<> 161:2cc1468da177 763 uint16_t measDelay)
<> 144:ef7eb2e8f9f7 764 {
<> 144:ef7eb2e8f9f7 765 /* Sanity check of parameters. */
<> 161:2cc1468da177 766 EFM_ASSERT(exTime <= (_LESENSE_CH_TIMING_EXTIME_MASK >> _LESENSE_CH_TIMING_EXTIME_SHIFT));
<> 161:2cc1468da177 767 EFM_ASSERT(measDelay <= (_LESENSE_CH_TIMING_MEASUREDLY_MASK >> _LESENSE_CH_TIMING_MEASUREDLY_SHIFT));
<> 161:2cc1468da177 768 #if defined(_SILICON_LABS_32B_SERIES_0)
<> 161:2cc1468da177 769 // Sample delay on other devices are 8 bits which fits perfectly in uint8_t
<> 161:2cc1468da177 770 EFM_ASSERT(sampleDelay <= (_LESENSE_CH_TIMING_SAMPLEDLY_MASK >> _LESENSE_CH_TIMING_SAMPLEDLY_SHIFT));
<> 161:2cc1468da177 771 #endif
<> 144:ef7eb2e8f9f7 772
<> 144:ef7eb2e8f9f7 773 /* Channel specific timing configuration on scan channel chIdx.
<> 144:ef7eb2e8f9f7 774 * Setting excitation time, sampling delay, measurement delay. */
<> 144:ef7eb2e8f9f7 775 LESENSE->CH[chIdx].TIMING =
AnnaBridge 179:b0033dcd6934 776 ((uint32_t)exTime << _LESENSE_CH_TIMING_EXTIME_SHIFT)
AnnaBridge 179:b0033dcd6934 777 | ((uint32_t)sampleDelay << _LESENSE_CH_TIMING_SAMPLEDLY_SHIFT)
AnnaBridge 179:b0033dcd6934 778 | ((uint32_t)measDelay << _LESENSE_CH_TIMING_MEASUREDLY_SHIFT);
<> 144:ef7eb2e8f9f7 779 }
<> 144:ef7eb2e8f9f7 780
<> 144:ef7eb2e8f9f7 781 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 782 * @brief
<> 144:ef7eb2e8f9f7 783 * Set LESENSE channel threshold parameters.
<> 144:ef7eb2e8f9f7 784 *
<> 144:ef7eb2e8f9f7 785 * @details
<> 144:ef7eb2e8f9f7 786 * Use this function to set threshold parameters on a selected LESENSE
<> 144:ef7eb2e8f9f7 787 * channel.
<> 144:ef7eb2e8f9f7 788 *
<> 144:ef7eb2e8f9f7 789 * @note
<> 144:ef7eb2e8f9f7 790 * Users can configure the channel threshold parameters by
<> 144:ef7eb2e8f9f7 791 * LESENSE_ChannelConfig() function, but only with a significant overhead.
<> 144:ef7eb2e8f9f7 792 * This simple function serves the purpose of controlling these parameters
<> 144:ef7eb2e8f9f7 793 * after the channel has been configured.
<> 144:ef7eb2e8f9f7 794 *
<> 144:ef7eb2e8f9f7 795 * @param[in] chIdx
<> 144:ef7eb2e8f9f7 796 * Identifier of the scan channel. Valid range: 0-15.
<> 144:ef7eb2e8f9f7 797 *
<> 144:ef7eb2e8f9f7 798 * @param[in] acmpThres
<> 144:ef7eb2e8f9f7 799 * ACMP threshold.
<> 144:ef7eb2e8f9f7 800 * @li If perCtrl.dacCh0Data or perCtrl.dacCh1Data is set to
<> 144:ef7eb2e8f9f7 801 * #lesenseDACIfData, acmpThres defines the 12-bit DAC data in the
<> 144:ef7eb2e8f9f7 802 * corresponding data register of the DAC interface (DACn_CH0DATA and
<> 144:ef7eb2e8f9f7 803 * DACn_CH1DATA). In this case, the valid range is: 0-4095 (12 bits).
<> 144:ef7eb2e8f9f7 804 *
<> 144:ef7eb2e8f9f7 805 * @li If perCtrl.dacCh0Data or perCtrl.dacCh1Data is set to
<> 144:ef7eb2e8f9f7 806 * #lesenseACMPThres, acmpThres defines the 6-bit Vdd scaling factor of ACMP
<> 144:ef7eb2e8f9f7 807 * negative input (VDDLEVEL in ACMP_INPUTSEL register). In this case, the
<> 144:ef7eb2e8f9f7 808 * valid range is: 0-63 (6 bits).
<> 144:ef7eb2e8f9f7 809 *
<> 144:ef7eb2e8f9f7 810 * @param[in] cntThres
<> 144:ef7eb2e8f9f7 811 * Decision threshold for counter comparison.
<> 144:ef7eb2e8f9f7 812 * Valid range: 0-65535 (16 bits).
<> 144:ef7eb2e8f9f7 813 ******************************************************************************/
<> 161:2cc1468da177 814 void LESENSE_ChannelThresSet(uint8_t chIdx,
<> 161:2cc1468da177 815 uint16_t acmpThres,
<> 161:2cc1468da177 816 uint16_t cntThres)
<> 144:ef7eb2e8f9f7 817 {
<> 144:ef7eb2e8f9f7 818 uint32_t tmp; /* temporary storage */
<> 144:ef7eb2e8f9f7 819
<> 144:ef7eb2e8f9f7 820 /* Sanity check for acmpThres only, cntThres is 16bit value. */
<> 144:ef7eb2e8f9f7 821 EFM_ASSERT(acmpThres < 4096U);
<> 144:ef7eb2e8f9f7 822 /* Sanity check for LESENSE channel id. */
<> 161:2cc1468da177 823 EFM_ASSERT(chIdx < LESENSE_NUM_CHANNELS);
<> 144:ef7eb2e8f9f7 824
<> 144:ef7eb2e8f9f7 825 /* Save the INTERACT register value of channel chIdx to tmp.
<> 144:ef7eb2e8f9f7 826 * Please be aware the effects of the non-atomic Read-Modify-Write cycle! */
<> 161:2cc1468da177 827 tmp = LESENSE->CH[chIdx].INTERACT & ~(0xFFF);
<> 144:ef7eb2e8f9f7 828 /* Set the ACMP threshold value to the INTERACT register of channel chIdx. */
<> 161:2cc1468da177 829 tmp |= (uint32_t)acmpThres;
<> 144:ef7eb2e8f9f7 830 /* Write the new value to the INTERACT register. */
<> 144:ef7eb2e8f9f7 831 LESENSE->CH[chIdx].INTERACT = tmp;
<> 144:ef7eb2e8f9f7 832
<> 144:ef7eb2e8f9f7 833 /* Save the EVAL register value of channel chIdx to tmp.
<> 144:ef7eb2e8f9f7 834 * Please be aware the effects of the non-atomic Read-Modify-Write cycle! */
<> 144:ef7eb2e8f9f7 835 tmp = LESENSE->CH[chIdx].EVAL & ~(_LESENSE_CH_EVAL_COMPTHRES_MASK);
<> 144:ef7eb2e8f9f7 836 /* Set the counter threshold value to the INTERACT register of channel chIdx. */
<> 144:ef7eb2e8f9f7 837 tmp |= (uint32_t)cntThres << _LESENSE_CH_EVAL_COMPTHRES_SHIFT;
<> 144:ef7eb2e8f9f7 838 /* Write the new value to the EVAL register. */
<> 144:ef7eb2e8f9f7 839 LESENSE->CH[chIdx].EVAL = tmp;
<> 144:ef7eb2e8f9f7 840 }
<> 144:ef7eb2e8f9f7 841
<> 161:2cc1468da177 842 #if defined(_LESENSE_CH_EVAL_MODE_MASK)
<> 161:2cc1468da177 843 /***************************************************************************//**
<> 161:2cc1468da177 844 * @brief
<> 161:2cc1468da177 845 * Configure Sliding Window evaluation mode for a specific channel
<> 161:2cc1468da177 846 *
<> 161:2cc1468da177 847 * @details
<> 161:2cc1468da177 848 * This function will configure the evaluation mode, the initial
<> 161:2cc1468da177 849 * sensor measurement (COMPTHRES) and the window size. For other channel
<> 161:2cc1468da177 850 * related configuration see the @ref LESENSE_ChannelConfig() function.
<> 161:2cc1468da177 851 *
<> 161:2cc1468da177 852 * @warning
<> 161:2cc1468da177 853 * Beware that the step size and window size configuration are global to all
<> 161:2cc1468da177 854 * LESENSE channels and use the same register field in the hardware. This
<> 161:2cc1468da177 855 * means that any windowSize configuration passed to this function will
<> 161:2cc1468da177 856 * apply for all channels and override all other stepSize/windowSize
<> 161:2cc1468da177 857 * configurations.
<> 161:2cc1468da177 858 *
<> 161:2cc1468da177 859 * @param[in] chIdx
<> 161:2cc1468da177 860 * Identifier of the scan channel. Valid range: 0-15.
<> 161:2cc1468da177 861 *
<> 161:2cc1468da177 862 * @param[in] windowSize
<> 161:2cc1468da177 863 * Window size to be used on all channels.
<> 161:2cc1468da177 864 *
<> 161:2cc1468da177 865 * @param[in] initValue
<> 161:2cc1468da177 866 * The initial sensor value for the channel.
<> 161:2cc1468da177 867 ******************************************************************************/
<> 161:2cc1468da177 868 void LESENSE_ChannelSlidingWindow(uint8_t chIdx,
<> 161:2cc1468da177 869 uint32_t windowSize,
<> 161:2cc1468da177 870 uint32_t initValue)
<> 161:2cc1468da177 871 {
<> 161:2cc1468da177 872 LESENSE_CH_TypeDef * ch = &LESENSE->CH[chIdx];
<> 161:2cc1468da177 873
<> 161:2cc1468da177 874 LESENSE_WindowSizeSet(windowSize);
<> 161:2cc1468da177 875 ch->EVAL = (ch->EVAL & ~(_LESENSE_CH_EVAL_COMPTHRES_MASK | _LESENSE_CH_EVAL_MODE_MASK))
<> 161:2cc1468da177 876 | (initValue << _LESENSE_CH_EVAL_COMPTHRES_SHIFT)
<> 161:2cc1468da177 877 | LESENSE_CH_EVAL_MODE_SLIDINGWIN;
<> 161:2cc1468da177 878 }
<> 161:2cc1468da177 879
<> 161:2cc1468da177 880 /***************************************************************************//**
<> 161:2cc1468da177 881 * @brief
<> 161:2cc1468da177 882 * Configure step detection evaluation mode for a specific channel
<> 161:2cc1468da177 883 *
<> 161:2cc1468da177 884 * @details
<> 161:2cc1468da177 885 * This function will configure the evaluation mode, the initial
<> 161:2cc1468da177 886 * sensor measurement (COMPTHRES) and the window size. For other channel
<> 161:2cc1468da177 887 * related configuration see the @ref LESENSE_ChannelConfig() function.
<> 161:2cc1468da177 888 *
<> 161:2cc1468da177 889 * @warning
<> 161:2cc1468da177 890 * Beware that the step size and window size configuration are global to all
<> 161:2cc1468da177 891 * LESENSE channels and use the same register field in the hardware. This
<> 161:2cc1468da177 892 * means that any stepSize configuration passed to this function will
<> 161:2cc1468da177 893 * apply for all channels and override all other stepSize/windowSize
<> 161:2cc1468da177 894 * configurations.
<> 161:2cc1468da177 895 *
<> 161:2cc1468da177 896 * @param[in] chIdx
<> 161:2cc1468da177 897 * Identifier of the scan channel. Valid range: 0-15.
<> 161:2cc1468da177 898 *
<> 161:2cc1468da177 899 * @param[in] stepSize
<> 161:2cc1468da177 900 * Step size to be used on all channels.
<> 161:2cc1468da177 901 *
<> 161:2cc1468da177 902 * @param[in] initValue
<> 161:2cc1468da177 903 * The initial sensor value for the channel.
<> 161:2cc1468da177 904 ******************************************************************************/
<> 161:2cc1468da177 905 void LESENSE_ChannelStepDetection(uint8_t chIdx,
<> 161:2cc1468da177 906 uint32_t stepSize,
<> 161:2cc1468da177 907 uint32_t initValue)
<> 161:2cc1468da177 908 {
<> 161:2cc1468da177 909 LESENSE_CH_TypeDef * ch = &LESENSE->CH[chIdx];
<> 161:2cc1468da177 910
<> 161:2cc1468da177 911 LESENSE_StepSizeSet(stepSize);
<> 161:2cc1468da177 912 ch->EVAL = (ch->EVAL & ~(_LESENSE_CH_EVAL_COMPTHRES_MASK | _LESENSE_CH_EVAL_MODE_MASK))
<> 161:2cc1468da177 913 | (initValue << _LESENSE_CH_EVAL_COMPTHRES_SHIFT)
<> 161:2cc1468da177 914 | LESENSE_CH_EVAL_MODE_STEPDET;
<> 161:2cc1468da177 915 }
<> 161:2cc1468da177 916
<> 161:2cc1468da177 917 /***************************************************************************//**
<> 161:2cc1468da177 918 * @brief
<> 161:2cc1468da177 919 * Set the window size for all LESENSE channels.
<> 161:2cc1468da177 920 *
<> 161:2cc1468da177 921 * @details
<> 161:2cc1468da177 922 * The window size is used by all channels that are configured as
<> 161:2cc1468da177 923 * @ref lesenseEvalModeSlidingWindow.
<> 161:2cc1468da177 924 *
<> 161:2cc1468da177 925 * @warning
<> 161:2cc1468da177 926 * The window size configuration is using the same register field as the
<> 161:2cc1468da177 927 * step detection size. So the window size configuration will have an
<> 161:2cc1468da177 928 * effect on channels configured with the @ref lesenseEvalModeStepDetection
<> 161:2cc1468da177 929 * evaluation mode as well.
<> 161:2cc1468da177 930 *
<> 161:2cc1468da177 931 * @param[in] windowSize
<> 161:2cc1468da177 932 * The window size to use for all channels.
<> 161:2cc1468da177 933 ******************************************************************************/
<> 161:2cc1468da177 934 void LESENSE_WindowSizeSet(uint32_t windowSize)
<> 161:2cc1468da177 935 {
<> 161:2cc1468da177 936 LESENSE->EVALCTRL = (LESENSE->EVALCTRL & ~_LESENSE_EVALCTRL_WINSIZE_MASK)
<> 161:2cc1468da177 937 | windowSize;
<> 161:2cc1468da177 938 }
<> 161:2cc1468da177 939
<> 161:2cc1468da177 940 /***************************************************************************//**
<> 161:2cc1468da177 941 * @brief
<> 161:2cc1468da177 942 * Set the step size for all LESENSE channels.
<> 161:2cc1468da177 943 *
<> 161:2cc1468da177 944 * @details
<> 161:2cc1468da177 945 * The step size is configured using the same register field as use to
<> 161:2cc1468da177 946 * configure window size. So calling this function will overwrite any
<> 161:2cc1468da177 947 * previously configured window size as done by the
<> 161:2cc1468da177 948 * @ref LESENSE_WindowSizeSet() function.
<> 161:2cc1468da177 949 *
<> 161:2cc1468da177 950 * @param[in] stepSize
<> 161:2cc1468da177 951 * The step size to use for all channels.
<> 161:2cc1468da177 952 ******************************************************************************/
<> 161:2cc1468da177 953 void LESENSE_StepSizeSet(uint32_t stepSize)
<> 161:2cc1468da177 954 {
<> 161:2cc1468da177 955 LESENSE_WindowSizeSet(stepSize);
<> 161:2cc1468da177 956 }
<> 161:2cc1468da177 957 #endif
<> 144:ef7eb2e8f9f7 958
<> 144:ef7eb2e8f9f7 959 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 960 * @brief
<> 144:ef7eb2e8f9f7 961 * Configure all LESENSE decoder states.
<> 144:ef7eb2e8f9f7 962 *
<> 144:ef7eb2e8f9f7 963 * @details
<> 144:ef7eb2e8f9f7 964 * This function configures all the decoder states of the LESENSE interface.
<> 144:ef7eb2e8f9f7 965 * Please refer to the configuration parameter type definition
<> 144:ef7eb2e8f9f7 966 * (LESENSE_DecStAll_TypeDef) for more details.
<> 144:ef7eb2e8f9f7 967 *
<> 144:ef7eb2e8f9f7 968 * @note
<> 144:ef7eb2e8f9f7 969 * Decoder states can be configured individually using
<> 144:ef7eb2e8f9f7 970 * LESENSE_DecoderStateConfig() function.
<> 144:ef7eb2e8f9f7 971 *
<> 144:ef7eb2e8f9f7 972 * @param[in] confDecStAll
<> 161:2cc1468da177 973 * Configuration structure for all (16 or 32) LESENSE decoder states.
<> 144:ef7eb2e8f9f7 974 ******************************************************************************/
<> 161:2cc1468da177 975 void LESENSE_DecoderStateAllConfig(const LESENSE_DecStAll_TypeDef * confDecStAll)
<> 144:ef7eb2e8f9f7 976 {
<> 144:ef7eb2e8f9f7 977 uint32_t i;
<> 144:ef7eb2e8f9f7 978
<> 161:2cc1468da177 979 /* Iterate through all the 16 or 32 decoder states. */
AnnaBridge 179:b0033dcd6934 980 for (i = 0U; i < LESENSE_NUM_DECODER_STATES; ++i) {
<> 144:ef7eb2e8f9f7 981 /* Configure decoder state i. */
<> 144:ef7eb2e8f9f7 982 LESENSE_DecoderStateConfig(&confDecStAll->St[i], i);
<> 144:ef7eb2e8f9f7 983 }
<> 144:ef7eb2e8f9f7 984 }
<> 144:ef7eb2e8f9f7 985
<> 144:ef7eb2e8f9f7 986 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 987 * @brief
<> 144:ef7eb2e8f9f7 988 * Configure a single LESENSE decoder state.
<> 144:ef7eb2e8f9f7 989 *
<> 144:ef7eb2e8f9f7 990 * @details
<> 144:ef7eb2e8f9f7 991 * This function configures a single decoder state of the LESENSE interface.
<> 144:ef7eb2e8f9f7 992 * Please refer to the configuration parameter type definition
<> 144:ef7eb2e8f9f7 993 * (LESENSE_DecStDesc_TypeDef) for more details.
<> 144:ef7eb2e8f9f7 994 *
<> 144:ef7eb2e8f9f7 995 * @param[in] confDecSt
<> 144:ef7eb2e8f9f7 996 * Configuration structure for a single LESENSE decoder state.
<> 144:ef7eb2e8f9f7 997 *
<> 144:ef7eb2e8f9f7 998 * @param[in] decSt
<> 161:2cc1468da177 999 * Decoder state index to configure (0-15) or (0-31) depending on device.
<> 144:ef7eb2e8f9f7 1000 ******************************************************************************/
<> 161:2cc1468da177 1001 void LESENSE_DecoderStateConfig(const LESENSE_DecStDesc_TypeDef * confDecSt,
<> 161:2cc1468da177 1002 uint32_t decSt)
<> 144:ef7eb2e8f9f7 1003 {
<> 144:ef7eb2e8f9f7 1004 /* Sanity check of configuration parameters */
<> 161:2cc1468da177 1005 EFM_ASSERT(decSt < LESENSE_NUM_DECODER_STATES);
<> 144:ef7eb2e8f9f7 1006 EFM_ASSERT((uint32_t)confDecSt->confA.compMask < 16U);
<> 144:ef7eb2e8f9f7 1007 EFM_ASSERT((uint32_t)confDecSt->confA.compVal < 16U);
<> 161:2cc1468da177 1008 EFM_ASSERT((uint32_t)confDecSt->confA.nextState < LESENSE_NUM_DECODER_STATES);
<> 144:ef7eb2e8f9f7 1009 EFM_ASSERT((uint32_t)confDecSt->confB.compMask < 16U);
<> 144:ef7eb2e8f9f7 1010 EFM_ASSERT((uint32_t)confDecSt->confB.compVal < 16U);
<> 161:2cc1468da177 1011 EFM_ASSERT((uint32_t)confDecSt->confB.nextState < LESENSE_NUM_DECODER_STATES);
<> 144:ef7eb2e8f9f7 1012
<> 144:ef7eb2e8f9f7 1013 /* Configure state descriptor A (LESENSE_STi_TCONFA) for decoder state i.
<> 144:ef7eb2e8f9f7 1014 * Setting sensor compare value, sensor mask, next state index,
<> 144:ef7eb2e8f9f7 1015 * transition action, interrupt flag option and state descriptor chaining
<> 144:ef7eb2e8f9f7 1016 * configurations. */
<> 144:ef7eb2e8f9f7 1017 LESENSE->ST[decSt].TCONFA =
<> 144:ef7eb2e8f9f7 1018 (uint32_t)confDecSt->confA.prsAct
<> 144:ef7eb2e8f9f7 1019 | ((uint32_t)confDecSt->confA.compMask << _LESENSE_ST_TCONFA_MASK_SHIFT)
<> 144:ef7eb2e8f9f7 1020 | ((uint32_t)confDecSt->confA.compVal << _LESENSE_ST_TCONFA_COMP_SHIFT)
<> 144:ef7eb2e8f9f7 1021 | ((uint32_t)confDecSt->confA.nextState << _LESENSE_ST_TCONFA_NEXTSTATE_SHIFT)
<> 144:ef7eb2e8f9f7 1022 | ((uint32_t)confDecSt->confA.setInt << _LESENSE_ST_TCONFA_SETIF_SHIFT)
<> 144:ef7eb2e8f9f7 1023 | ((uint32_t)confDecSt->chainDesc << _LESENSE_ST_TCONFA_CHAIN_SHIFT);
<> 144:ef7eb2e8f9f7 1024
<> 144:ef7eb2e8f9f7 1025 /* Configure state descriptor Bi (LESENSE_STi_TCONFB).
<> 144:ef7eb2e8f9f7 1026 * Setting sensor compare value, sensor mask, next state index, transition
<> 144:ef7eb2e8f9f7 1027 * action and interrupt flag option configurations. */
<> 144:ef7eb2e8f9f7 1028 LESENSE->ST[decSt].TCONFB =
AnnaBridge 179:b0033dcd6934 1029 (uint32_t)confDecSt->confB.prsAct
<> 144:ef7eb2e8f9f7 1030 | ((uint32_t)confDecSt->confB.compMask << _LESENSE_ST_TCONFB_MASK_SHIFT)
<> 144:ef7eb2e8f9f7 1031 | ((uint32_t)confDecSt->confB.compVal << _LESENSE_ST_TCONFB_COMP_SHIFT)
<> 144:ef7eb2e8f9f7 1032 | ((uint32_t)confDecSt->confB.nextState << _LESENSE_ST_TCONFB_NEXTSTATE_SHIFT)
<> 144:ef7eb2e8f9f7 1033 | ((uint32_t)confDecSt->confB.setInt << _LESENSE_ST_TCONFB_SETIF_SHIFT);
<> 144:ef7eb2e8f9f7 1034 }
<> 144:ef7eb2e8f9f7 1035
<> 144:ef7eb2e8f9f7 1036 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1037 * @brief
<> 144:ef7eb2e8f9f7 1038 * Set LESENSE decoder state.
<> 144:ef7eb2e8f9f7 1039 *
<> 144:ef7eb2e8f9f7 1040 * @details
<> 144:ef7eb2e8f9f7 1041 * This function can be used for setting the initial state of the LESENSE
<> 144:ef7eb2e8f9f7 1042 * decoder.
<> 144:ef7eb2e8f9f7 1043 *
<> 144:ef7eb2e8f9f7 1044 * @note
<> 144:ef7eb2e8f9f7 1045 * Make sure the LESENSE decoder state is initialized by this function before
<> 144:ef7eb2e8f9f7 1046 * enabling the decoder!
<> 144:ef7eb2e8f9f7 1047 *
<> 144:ef7eb2e8f9f7 1048 * @param[in] decSt
<> 161:2cc1468da177 1049 * Decoder state to set as current state. Valid range: 0-15 or 0-31
<> 161:2cc1468da177 1050 * depending on device.
<> 144:ef7eb2e8f9f7 1051 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1052 void LESENSE_DecoderStateSet(uint32_t decSt)
<> 144:ef7eb2e8f9f7 1053 {
<> 161:2cc1468da177 1054 EFM_ASSERT(decSt <= _LESENSE_DECSTATE_DECSTATE_MASK);
<> 144:ef7eb2e8f9f7 1055
<> 144:ef7eb2e8f9f7 1056 LESENSE->DECSTATE = decSt & _LESENSE_DECSTATE_DECSTATE_MASK;
<> 144:ef7eb2e8f9f7 1057 }
<> 144:ef7eb2e8f9f7 1058
<> 144:ef7eb2e8f9f7 1059 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1060 * @brief
<> 144:ef7eb2e8f9f7 1061 * Get the current state of the LESENSE decoder.
<> 144:ef7eb2e8f9f7 1062 *
<> 144:ef7eb2e8f9f7 1063 * @return
<> 144:ef7eb2e8f9f7 1064 * This function returns the value of LESENSE_DECSTATE register that
<> 144:ef7eb2e8f9f7 1065 * represents the current state of the LESENSE decoder.
<> 144:ef7eb2e8f9f7 1066 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1067 uint32_t LESENSE_DecoderStateGet(void)
<> 144:ef7eb2e8f9f7 1068 {
<> 144:ef7eb2e8f9f7 1069 return LESENSE->DECSTATE & _LESENSE_DECSTATE_DECSTATE_MASK;
<> 144:ef7eb2e8f9f7 1070 }
<> 144:ef7eb2e8f9f7 1071
<> 161:2cc1468da177 1072 #if defined(_LESENSE_PRSCTRL_MASK)
<> 161:2cc1468da177 1073 /***************************************************************************//**
<> 161:2cc1468da177 1074 * @brief
<> 161:2cc1468da177 1075 * Enable or disable PRS output from the LESENSE decoder.
<> 161:2cc1468da177 1076 *
<> 161:2cc1468da177 1077 * @param[in] enable
<> 161:2cc1468da177 1078 * enable/disable the PRS output from the LESENSE decoder. true to enable and
<> 161:2cc1468da177 1079 * false to disable.
<> 161:2cc1468da177 1080 *
<> 161:2cc1468da177 1081 * @param[in] decMask
<> 161:2cc1468da177 1082 * Decoder state compare value mask
<> 161:2cc1468da177 1083 *
<> 161:2cc1468da177 1084 * @param[in] decVal
<> 161:2cc1468da177 1085 * Decoder state compare value.
<> 161:2cc1468da177 1086 ******************************************************************************/
<> 161:2cc1468da177 1087 void LESENSE_DecoderPrsOut(bool enable, uint32_t decMask, uint32_t decVal)
<> 161:2cc1468da177 1088 {
<> 161:2cc1468da177 1089 LESENSE->PRSCTRL = (enable << _LESENSE_PRSCTRL_DECCMPEN_SHIFT)
<> 161:2cc1468da177 1090 | (decMask << _LESENSE_PRSCTRL_DECCMPMASK_SHIFT)
<> 161:2cc1468da177 1091 | (decVal << _LESENSE_PRSCTRL_DECCMPVAL_SHIFT);
<> 161:2cc1468da177 1092 }
<> 161:2cc1468da177 1093 #endif
<> 144:ef7eb2e8f9f7 1094
<> 144:ef7eb2e8f9f7 1095 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1096 * @brief
<> 144:ef7eb2e8f9f7 1097 * Start scanning of sensors.
<> 144:ef7eb2e8f9f7 1098 *
<> 144:ef7eb2e8f9f7 1099 * @note
<> 144:ef7eb2e8f9f7 1100 * This function will wait for any pending previous write operation to the
<> 144:ef7eb2e8f9f7 1101 * CMD register to complete before accessing the CMD register. It will also
<> 144:ef7eb2e8f9f7 1102 * wait for the write operation to the CMD register to complete before
<> 144:ef7eb2e8f9f7 1103 * returning. Each write operation to the CMD register may take up to 3 LF
<> 144:ef7eb2e8f9f7 1104 * clock cycles, so the user should expect some delay. The user may implement
<> 144:ef7eb2e8f9f7 1105 * a separate function to write multiple command bits in the CMD register
<> 144:ef7eb2e8f9f7 1106 * in one single operation in order to optimize an application.
<> 144:ef7eb2e8f9f7 1107 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1108 void LESENSE_ScanStart(void)
<> 144:ef7eb2e8f9f7 1109 {
<> 144:ef7eb2e8f9f7 1110 /* Wait for any pending previous write operation to the CMD register to
<> 144:ef7eb2e8f9f7 1111 complete before accessing the CMD register. */
<> 144:ef7eb2e8f9f7 1112 while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
<> 144:ef7eb2e8f9f7 1113 ;
<> 144:ef7eb2e8f9f7 1114
<> 144:ef7eb2e8f9f7 1115 /* Start scanning of sensors */
<> 144:ef7eb2e8f9f7 1116 LESENSE->CMD = LESENSE_CMD_START;
<> 144:ef7eb2e8f9f7 1117
<> 144:ef7eb2e8f9f7 1118 /* Wait for the write operation to the CMD register to complete before
<> 144:ef7eb2e8f9f7 1119 returning. */
<> 144:ef7eb2e8f9f7 1120 while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
<> 144:ef7eb2e8f9f7 1121 ;
<> 144:ef7eb2e8f9f7 1122 }
<> 144:ef7eb2e8f9f7 1123
<> 144:ef7eb2e8f9f7 1124 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1125 * @brief
<> 144:ef7eb2e8f9f7 1126 * Stop scanning of sensors.
<> 144:ef7eb2e8f9f7 1127 *
<> 144:ef7eb2e8f9f7 1128 * @note
<> 144:ef7eb2e8f9f7 1129 * This function will wait for any pending previous write operation to the
<> 144:ef7eb2e8f9f7 1130 * CMD register to complete before accessing the CMD register. It will also
<> 144:ef7eb2e8f9f7 1131 * wait for the write operation to the CMD register to complete before
<> 144:ef7eb2e8f9f7 1132 * returning. Each write operation to the CMD register may take up to 3 LF
<> 144:ef7eb2e8f9f7 1133 * clock cycles, so the user should expect some delay. The user may implement
<> 144:ef7eb2e8f9f7 1134 * a separate function to write multiple command bits in the CMD register
<> 144:ef7eb2e8f9f7 1135 * in one single operation in order to optimize an application.
<> 144:ef7eb2e8f9f7 1136 *
<> 144:ef7eb2e8f9f7 1137 * @note
<> 144:ef7eb2e8f9f7 1138 * If issued during a scan, the command takes effect after scan completion.
<> 144:ef7eb2e8f9f7 1139 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1140 void LESENSE_ScanStop(void)
<> 144:ef7eb2e8f9f7 1141 {
<> 144:ef7eb2e8f9f7 1142 /* Wait for any pending previous write operation to the CMD register to
<> 144:ef7eb2e8f9f7 1143 complete before accessing the CMD register. */
<> 144:ef7eb2e8f9f7 1144 while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
<> 144:ef7eb2e8f9f7 1145 ;
<> 144:ef7eb2e8f9f7 1146
<> 144:ef7eb2e8f9f7 1147 /* Stop scanning of sensors */
<> 144:ef7eb2e8f9f7 1148 LESENSE->CMD = LESENSE_CMD_STOP;
<> 144:ef7eb2e8f9f7 1149
<> 144:ef7eb2e8f9f7 1150 /* Wait for the write operation to the CMD register to complete before
<> 144:ef7eb2e8f9f7 1151 returning. */
<> 144:ef7eb2e8f9f7 1152 while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
<> 144:ef7eb2e8f9f7 1153 ;
<> 144:ef7eb2e8f9f7 1154 }
<> 144:ef7eb2e8f9f7 1155
<> 144:ef7eb2e8f9f7 1156 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1157 * @brief
<> 144:ef7eb2e8f9f7 1158 * Start LESENSE decoder.
<> 144:ef7eb2e8f9f7 1159 *
<> 144:ef7eb2e8f9f7 1160 * @note
<> 144:ef7eb2e8f9f7 1161 * This function will wait for any pending previous write operation to the
<> 144:ef7eb2e8f9f7 1162 * CMD register to complete before accessing the CMD register. It will also
<> 144:ef7eb2e8f9f7 1163 * wait for the write operation to the CMD register to complete before
<> 144:ef7eb2e8f9f7 1164 * returning. Each write operation to the CMD register may take up to 3 LF
<> 144:ef7eb2e8f9f7 1165 * clock cycles, so the user should expect some delay. The user may implement
<> 144:ef7eb2e8f9f7 1166 * a separate function to write multiple command bits in the CMD register
<> 144:ef7eb2e8f9f7 1167 * in one single operation in order to optimize an application.
<> 144:ef7eb2e8f9f7 1168 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1169 void LESENSE_DecoderStart(void)
<> 144:ef7eb2e8f9f7 1170 {
<> 144:ef7eb2e8f9f7 1171 /* Wait for any pending previous write operation to the CMD register to
<> 144:ef7eb2e8f9f7 1172 complete before accessing the CMD register. */
<> 144:ef7eb2e8f9f7 1173 while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
<> 144:ef7eb2e8f9f7 1174 ;
<> 144:ef7eb2e8f9f7 1175
<> 144:ef7eb2e8f9f7 1176 /* Start decoder */
<> 144:ef7eb2e8f9f7 1177 LESENSE->CMD = LESENSE_CMD_DECODE;
<> 144:ef7eb2e8f9f7 1178
<> 144:ef7eb2e8f9f7 1179 /* Wait for the write operation to the CMD register to complete before
<> 144:ef7eb2e8f9f7 1180 returning. */
<> 144:ef7eb2e8f9f7 1181 while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
<> 144:ef7eb2e8f9f7 1182 ;
<> 144:ef7eb2e8f9f7 1183 }
<> 144:ef7eb2e8f9f7 1184
<> 144:ef7eb2e8f9f7 1185 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1186 * @brief
<> 144:ef7eb2e8f9f7 1187 * Clear result buffer.
<> 144:ef7eb2e8f9f7 1188 *
<> 144:ef7eb2e8f9f7 1189 * @note
<> 144:ef7eb2e8f9f7 1190 * This function will wait for any pending previous write operation to the
<> 144:ef7eb2e8f9f7 1191 * CMD register to complete before accessing the CMD register. It will also
<> 144:ef7eb2e8f9f7 1192 * wait for the write operation to the CMD register to complete before
<> 144:ef7eb2e8f9f7 1193 * returning. Each write operation to the CMD register may take up to 3 LF
<> 144:ef7eb2e8f9f7 1194 * clock cycles, so the user should expect some delay. The user may implement
<> 144:ef7eb2e8f9f7 1195 * a separate function to write multiple command bits in the CMD register
<> 144:ef7eb2e8f9f7 1196 * in one single operation in order to optimize an application.
<> 144:ef7eb2e8f9f7 1197 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1198 void LESENSE_ResultBufferClear(void)
<> 144:ef7eb2e8f9f7 1199 {
<> 144:ef7eb2e8f9f7 1200 /* Wait for any pending previous write operation to the CMD register to
<> 144:ef7eb2e8f9f7 1201 complete before accessing the CMD register. */
<> 144:ef7eb2e8f9f7 1202 while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
<> 144:ef7eb2e8f9f7 1203 ;
<> 144:ef7eb2e8f9f7 1204
<> 144:ef7eb2e8f9f7 1205 LESENSE->CMD = LESENSE_CMD_CLEARBUF;
<> 144:ef7eb2e8f9f7 1206
<> 144:ef7eb2e8f9f7 1207 /* Wait for the write operation to the CMD register to complete before
<> 144:ef7eb2e8f9f7 1208 returning. */
<> 144:ef7eb2e8f9f7 1209 while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
<> 144:ef7eb2e8f9f7 1210 ;
<> 144:ef7eb2e8f9f7 1211 }
<> 144:ef7eb2e8f9f7 1212
<> 144:ef7eb2e8f9f7 1213 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1214 * @brief
<> 144:ef7eb2e8f9f7 1215 * Reset the LESENSE module.
<> 144:ef7eb2e8f9f7 1216 *
<> 144:ef7eb2e8f9f7 1217 * @details
<> 144:ef7eb2e8f9f7 1218 * Use this function to reset the LESENSE registers.
<> 144:ef7eb2e8f9f7 1219 *
<> 144:ef7eb2e8f9f7 1220 * @note
<> 144:ef7eb2e8f9f7 1221 * Resetting LESENSE registers is required in each reset or power-on cycle in
<> 144:ef7eb2e8f9f7 1222 * order to configure the default values of the RAM mapped LESENSE registers.
<> 144:ef7eb2e8f9f7 1223 * LESENSE_Reset() can be called on initialization by setting the @p reqReset
<> 144:ef7eb2e8f9f7 1224 * parameter to true in LESENSE_Init().
<> 144:ef7eb2e8f9f7 1225 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1226 void LESENSE_Reset(void)
<> 144:ef7eb2e8f9f7 1227 {
<> 144:ef7eb2e8f9f7 1228 uint32_t i;
<> 144:ef7eb2e8f9f7 1229
<> 144:ef7eb2e8f9f7 1230 /* Disable all LESENSE interrupts first */
<> 144:ef7eb2e8f9f7 1231 LESENSE->IEN = _LESENSE_IEN_RESETVALUE;
<> 144:ef7eb2e8f9f7 1232
<> 144:ef7eb2e8f9f7 1233 /* Clear all pending LESENSE interrupts */
<> 144:ef7eb2e8f9f7 1234 LESENSE->IFC = _LESENSE_IFC_MASK;
<> 144:ef7eb2e8f9f7 1235
<> 144:ef7eb2e8f9f7 1236 /* Stop the decoder */
<> 144:ef7eb2e8f9f7 1237 LESENSE->DECCTRL |= LESENSE_DECCTRL_DISABLE;
<> 144:ef7eb2e8f9f7 1238
<> 144:ef7eb2e8f9f7 1239 /* Wait for any pending previous write operation to the CMD register to
<> 144:ef7eb2e8f9f7 1240 complete before accessing the CMD register. */
<> 144:ef7eb2e8f9f7 1241 while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
<> 144:ef7eb2e8f9f7 1242 ;
<> 144:ef7eb2e8f9f7 1243
<> 144:ef7eb2e8f9f7 1244 /* Stop sensor scan and clear result buffer */
<> 144:ef7eb2e8f9f7 1245 LESENSE->CMD = (LESENSE_CMD_STOP | LESENSE_CMD_CLEARBUF);
<> 144:ef7eb2e8f9f7 1246
<> 144:ef7eb2e8f9f7 1247 /* Reset LESENSE configuration registers */
<> 144:ef7eb2e8f9f7 1248 LESENSE->CTRL = _LESENSE_CTRL_RESETVALUE;
<> 144:ef7eb2e8f9f7 1249 LESENSE->PERCTRL = _LESENSE_PERCTRL_RESETVALUE;
<> 144:ef7eb2e8f9f7 1250 LESENSE->DECCTRL = _LESENSE_DECCTRL_RESETVALUE;
<> 144:ef7eb2e8f9f7 1251 LESENSE->BIASCTRL = _LESENSE_BIASCTRL_RESETVALUE;
<> 161:2cc1468da177 1252 #if defined(_LESENSE_EVALCTRL_MASK)
<> 161:2cc1468da177 1253 LESENSE->EVALCTRL = _LESENSE_EVALCTRL_RESETVALUE;
<> 161:2cc1468da177 1254 LESENSE->PRSCTRL = _LESENSE_PRSCTRL_RESETVALUE;
<> 161:2cc1468da177 1255 #endif
<> 144:ef7eb2e8f9f7 1256 LESENSE->CHEN = _LESENSE_CHEN_RESETVALUE;
<> 144:ef7eb2e8f9f7 1257 LESENSE->IDLECONF = _LESENSE_IDLECONF_RESETVALUE;
<> 144:ef7eb2e8f9f7 1258 LESENSE->ALTEXCONF = _LESENSE_ALTEXCONF_RESETVALUE;
<> 144:ef7eb2e8f9f7 1259
<> 144:ef7eb2e8f9f7 1260 /* Disable LESENSE to control GPIO pins */
<> 161:2cc1468da177 1261 #if defined(_LESENSE_ROUTE_MASK)
<> 161:2cc1468da177 1262 LESENSE->ROUTE = _LESENSE_ROUTE_RESETVALUE;
<> 161:2cc1468da177 1263 #else
<> 161:2cc1468da177 1264 LESENSE->ROUTEPEN = _LESENSE_ROUTEPEN_RESETVALUE;
<> 161:2cc1468da177 1265 #endif
<> 144:ef7eb2e8f9f7 1266
<> 144:ef7eb2e8f9f7 1267 /* Reset all channel configuration registers */
AnnaBridge 179:b0033dcd6934 1268 for (i = 0U; i < LESENSE_NUM_CHANNELS; ++i) {
<> 144:ef7eb2e8f9f7 1269 LESENSE->CH[i].TIMING = _LESENSE_CH_TIMING_RESETVALUE;
<> 144:ef7eb2e8f9f7 1270 LESENSE->CH[i].INTERACT = _LESENSE_CH_INTERACT_RESETVALUE;
<> 144:ef7eb2e8f9f7 1271 LESENSE->CH[i].EVAL = _LESENSE_CH_EVAL_RESETVALUE;
<> 144:ef7eb2e8f9f7 1272 }
<> 144:ef7eb2e8f9f7 1273
<> 144:ef7eb2e8f9f7 1274 /* Reset all decoder state configuration registers */
AnnaBridge 179:b0033dcd6934 1275 for (i = 0U; i < LESENSE_NUM_DECODER_STATES; ++i) {
<> 144:ef7eb2e8f9f7 1276 LESENSE->ST[i].TCONFA = _LESENSE_ST_TCONFA_RESETVALUE;
<> 144:ef7eb2e8f9f7 1277 LESENSE->ST[i].TCONFB = _LESENSE_ST_TCONFB_RESETVALUE;
<> 144:ef7eb2e8f9f7 1278 }
<> 144:ef7eb2e8f9f7 1279
<> 144:ef7eb2e8f9f7 1280 /* Wait for the write operation to the CMD register to complete before
<> 144:ef7eb2e8f9f7 1281 returning. */
<> 144:ef7eb2e8f9f7 1282 while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
<> 144:ef7eb2e8f9f7 1283 ;
<> 144:ef7eb2e8f9f7 1284 }
<> 144:ef7eb2e8f9f7 1285
<> 144:ef7eb2e8f9f7 1286 /** @} (end addtogroup LESENSE) */
<> 150:02e0a0aed4ec 1287 /** @} (end addtogroup emlib) */
<> 144:ef7eb2e8f9f7 1288
<> 144:ef7eb2e8f9f7 1289 #endif /* defined(LESENSE_COUNT) && (LESENSE_COUNT > 0) */