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