Driver for the capacitive sense slider available on the EFM32 Giant, Wonder and Leopard starter kits.
Dependents: EFM32 RDA5807M RDS Radio EMF32-Segment-Touch-Demo EFM32_Bugs MFALHIMOHAMMED ... more
Information
All examples in this repo are considered EXPERIMENTAL QUALITY, meaning this code has been created as one-off proof-of-concept and is suitable as a demonstration for experimental purposes only. This code will not be regularly maintained by Silicon Labs and there is no guarantee that these projects will work across all environments, SDK versions and hardware.
caplesense.c@0:459a1af84a64, 2015-03-17 (annotated)
- Committer:
- Steven Cooreman
- Date:
- Tue Mar 17 12:44:15 2015 -0500
- Revision:
- 0:459a1af84a64
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Steven Cooreman |
0:459a1af84a64 | 1 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 2 | * @file |
Steven Cooreman |
0:459a1af84a64 | 3 | * @brief Capacitive sense driver |
Steven Cooreman |
0:459a1af84a64 | 4 | * @version 3.20.9 |
Steven Cooreman |
0:459a1af84a64 | 5 | ****************************************************************************** |
Steven Cooreman |
0:459a1af84a64 | 6 | * @section License |
Steven Cooreman |
0:459a1af84a64 | 7 | * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b> |
Steven Cooreman |
0:459a1af84a64 | 8 | ******************************************************************************* |
Steven Cooreman |
0:459a1af84a64 | 9 | * |
Steven Cooreman |
0:459a1af84a64 | 10 | * This file is licensensed under the Silabs License Agreement. See the file |
Steven Cooreman |
0:459a1af84a64 | 11 | * "Silabs_License_Agreement.txt" for details. Before using this software for |
Steven Cooreman |
0:459a1af84a64 | 12 | * any purpose, you must agree to the terms of that agreement. |
Steven Cooreman |
0:459a1af84a64 | 13 | * |
Steven Cooreman |
0:459a1af84a64 | 14 | ******************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 15 | |
Steven Cooreman |
0:459a1af84a64 | 16 | |
Steven Cooreman |
0:459a1af84a64 | 17 | |
Steven Cooreman |
0:459a1af84a64 | 18 | |
Steven Cooreman |
0:459a1af84a64 | 19 | /* EM header files */ |
Steven Cooreman |
0:459a1af84a64 | 20 | #include "em_device.h" |
Steven Cooreman |
0:459a1af84a64 | 21 | |
Steven Cooreman |
0:459a1af84a64 | 22 | /* Drivers */ |
Steven Cooreman |
0:459a1af84a64 | 23 | #include "caplesense.h" |
Steven Cooreman |
0:459a1af84a64 | 24 | #include "em_emu.h" |
Steven Cooreman |
0:459a1af84a64 | 25 | #include "em_acmp.h" |
Steven Cooreman |
0:459a1af84a64 | 26 | #include "em_assert.h" |
Steven Cooreman |
0:459a1af84a64 | 27 | #include "em_cmu.h" |
Steven Cooreman |
0:459a1af84a64 | 28 | #include "em_emu.h" |
Steven Cooreman |
0:459a1af84a64 | 29 | #include "em_gpio.h" |
Steven Cooreman |
0:459a1af84a64 | 30 | #include "em_int.h" |
Steven Cooreman |
0:459a1af84a64 | 31 | #include "em_lesense.h" |
Steven Cooreman |
0:459a1af84a64 | 32 | |
Steven Cooreman |
0:459a1af84a64 | 33 | /* Capacitive sense configuration */ |
Steven Cooreman |
0:459a1af84a64 | 34 | //#include "caplesenseconfig.h" |
Steven Cooreman |
0:459a1af84a64 | 35 | // ^^ Already included through caplesense.h ^^ |
Steven Cooreman |
0:459a1af84a64 | 36 | |
Steven Cooreman |
0:459a1af84a64 | 37 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 38 | * @brief This vector stores the latest read values from LESENSE |
Steven Cooreman |
0:459a1af84a64 | 39 | * @param LESENSE_CHANNELS Vector of channels. |
Steven Cooreman |
0:459a1af84a64 | 40 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 41 | static volatile uint32_t channelValues[LESENSE_CHANNELS] = |
Steven Cooreman |
0:459a1af84a64 | 42 | { |
Steven Cooreman |
0:459a1af84a64 | 43 | /* Ch0, Ch1, Ch2, Ch3, Ch4, Ch5, Ch6, Ch7 */ |
Steven Cooreman |
0:459a1af84a64 | 44 | 0, 0, 0, 0, 0, 0, 0, 0, |
Steven Cooreman |
0:459a1af84a64 | 45 | /* Ch8, Ch9, Ch10, Ch11, Ch12, Ch13, Ch14, Ch15 */ |
Steven Cooreman |
0:459a1af84a64 | 46 | 0, 0, 0, 0, 0, 0, 0, 0 |
Steven Cooreman |
0:459a1af84a64 | 47 | }; |
Steven Cooreman |
0:459a1af84a64 | 48 | |
Steven Cooreman |
0:459a1af84a64 | 49 | |
Steven Cooreman |
0:459a1af84a64 | 50 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 51 | * @brief This stores the maximum values seen by a channel |
Steven Cooreman |
0:459a1af84a64 | 52 | * @param LESENSE_CHANNELS Vector of channels. |
Steven Cooreman |
0:459a1af84a64 | 53 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 54 | static volatile uint32_t channelMaxValues[LESENSE_CHANNELS] = |
Steven Cooreman |
0:459a1af84a64 | 55 | { |
Steven Cooreman |
0:459a1af84a64 | 56 | /* Ch0, Ch1, Ch2, Ch3, Ch4, Ch5, Ch6, Ch7 */ |
Steven Cooreman |
0:459a1af84a64 | 57 | 1, 1, 1, 1, 1, 1, 1, 1, |
Steven Cooreman |
0:459a1af84a64 | 58 | /* Ch8, Ch9, Ch11, Ch11, Ch12, Ch13, Ch14, Ch15 */ |
Steven Cooreman |
0:459a1af84a64 | 59 | 1, 1, 1, 1, 1, 1, 1, 1 |
Steven Cooreman |
0:459a1af84a64 | 60 | }; |
Steven Cooreman |
0:459a1af84a64 | 61 | |
Steven Cooreman |
0:459a1af84a64 | 62 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 63 | * @brief A bit vector which represents the channels to iterate through |
Steven Cooreman |
0:459a1af84a64 | 64 | * @param LESENSE_CHANNELS Vector of channels. |
Steven Cooreman |
0:459a1af84a64 | 65 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 66 | static const bool channelsInUse[LESENSE_CHANNELS] = LESENSE_CAPSENSE_CH_IN_USE; |
Steven Cooreman |
0:459a1af84a64 | 67 | static bool init = true; |
Steven Cooreman |
0:459a1af84a64 | 68 | |
Steven Cooreman |
0:459a1af84a64 | 69 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 70 | * Prototypes |
Steven Cooreman |
0:459a1af84a64 | 71 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 72 | void CAPLESENSE_setupCMU(void); |
Steven Cooreman |
0:459a1af84a64 | 73 | void CAPLESENSE_setupGPIO(void); |
Steven Cooreman |
0:459a1af84a64 | 74 | void CAPLESENSE_setupACMP(void); |
Steven Cooreman |
0:459a1af84a64 | 75 | |
Steven Cooreman |
0:459a1af84a64 | 76 | |
Steven Cooreman |
0:459a1af84a64 | 77 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 78 | * Local variables |
Steven Cooreman |
0:459a1af84a64 | 79 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 80 | /** Callback function for LESENSE interrupts. */ |
Steven Cooreman |
0:459a1af84a64 | 81 | static void (*lesenseScanCb)(void); |
Steven Cooreman |
0:459a1af84a64 | 82 | /** Callback function for LESENSE interrupts. */ |
Steven Cooreman |
0:459a1af84a64 | 83 | static void (*lesenseChCb)(void); |
Steven Cooreman |
0:459a1af84a64 | 84 | |
Steven Cooreman |
0:459a1af84a64 | 85 | /** The current channel we are sensing */ |
Steven Cooreman |
0:459a1af84a64 | 86 | static volatile uint8_t currentChannel; |
Steven Cooreman |
0:459a1af84a64 | 87 | |
Steven Cooreman |
0:459a1af84a64 | 88 | |
Steven Cooreman |
0:459a1af84a64 | 89 | |
Steven Cooreman |
0:459a1af84a64 | 90 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 91 | * @brief Setup the CMU |
Steven Cooreman |
0:459a1af84a64 | 92 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 93 | void CAPLESENSE_setupCMU(void) |
Steven Cooreman |
0:459a1af84a64 | 94 | { |
Steven Cooreman |
0:459a1af84a64 | 95 | /* Ensure core frequency has been updated */ |
Steven Cooreman |
0:459a1af84a64 | 96 | SystemCoreClockUpdate(); |
Steven Cooreman |
0:459a1af84a64 | 97 | |
Steven Cooreman |
0:459a1af84a64 | 98 | /* Enable HF peripheral clock. */ |
Steven Cooreman |
0:459a1af84a64 | 99 | CMU_ClockEnable(cmuClock_HFPER, 1); |
Steven Cooreman |
0:459a1af84a64 | 100 | /* Enable clock for GPIO. */ |
Steven Cooreman |
0:459a1af84a64 | 101 | CMU_ClockEnable(cmuClock_GPIO, 1); |
Steven Cooreman |
0:459a1af84a64 | 102 | /* Enable clock for ACMP0. */ |
Steven Cooreman |
0:459a1af84a64 | 103 | CMU_ClockEnable(cmuClock_ACMP0, 1); |
Steven Cooreman |
0:459a1af84a64 | 104 | /* Enable clock for ACMP1. */ |
Steven Cooreman |
0:459a1af84a64 | 105 | CMU_ClockEnable(cmuClock_ACMP1, 1); |
Steven Cooreman |
0:459a1af84a64 | 106 | /* Enable CORELE clock. */ |
Steven Cooreman |
0:459a1af84a64 | 107 | CMU_ClockEnable(cmuClock_CORELE, 1); |
Steven Cooreman |
0:459a1af84a64 | 108 | /* Enable clock for LESENSE. */ |
Steven Cooreman |
0:459a1af84a64 | 109 | CMU_ClockEnable(cmuClock_LESENSE, 1); |
Steven Cooreman |
0:459a1af84a64 | 110 | |
Steven Cooreman |
0:459a1af84a64 | 111 | /* Enable clock divider for LESENSE. */ |
Steven Cooreman |
0:459a1af84a64 | 112 | CMU_ClockDivSet(cmuClock_LESENSE, cmuClkDiv_1); |
Steven Cooreman |
0:459a1af84a64 | 113 | } |
Steven Cooreman |
0:459a1af84a64 | 114 | |
Steven Cooreman |
0:459a1af84a64 | 115 | |
Steven Cooreman |
0:459a1af84a64 | 116 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 117 | * @brief Setup the GPIO |
Steven Cooreman |
0:459a1af84a64 | 118 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 119 | void CAPLESENSE_setupGPIO(void) |
Steven Cooreman |
0:459a1af84a64 | 120 | { |
Steven Cooreman |
0:459a1af84a64 | 121 | /* Configure the drive strength of the ports for the light sensor. */ |
Steven Cooreman |
0:459a1af84a64 | 122 | GPIO_DriveModeSet(CAPLESENSE_SLIDER_PORT0, gpioDriveModeStandard); |
Steven Cooreman |
0:459a1af84a64 | 123 | |
Steven Cooreman |
0:459a1af84a64 | 124 | /* Initialize the 4 GPIO pins of the touch slider for using them as LESENSE |
Steven Cooreman |
0:459a1af84a64 | 125 | * scan channels for capacitive sensing. */ |
Steven Cooreman |
0:459a1af84a64 | 126 | GPIO_PinModeSet(CAPLESENSE_SLIDER_PORT0, CAPLESENSE_SLIDER0_PIN, gpioModeDisabled, 0); |
Steven Cooreman |
0:459a1af84a64 | 127 | GPIO_PinModeSet(CAPLESENSE_SLIDER_PORT0, CAPLESENSE_SLIDER1_PIN, gpioModeDisabled, 0); |
Steven Cooreman |
0:459a1af84a64 | 128 | GPIO_PinModeSet(CAPLESENSE_SLIDER_PORT0, CAPLESENSE_SLIDER2_PIN, gpioModeDisabled, 0); |
Steven Cooreman |
0:459a1af84a64 | 129 | GPIO_PinModeSet(CAPLESENSE_SLIDER_PORT0, CAPLESENSE_SLIDER3_PIN, gpioModeDisabled, 0); |
Steven Cooreman |
0:459a1af84a64 | 130 | } |
Steven Cooreman |
0:459a1af84a64 | 131 | |
Steven Cooreman |
0:459a1af84a64 | 132 | |
Steven Cooreman |
0:459a1af84a64 | 133 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 134 | * @brief Setup the ACMP |
Steven Cooreman |
0:459a1af84a64 | 135 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 136 | void CAPLESENSE_setupACMP(void) |
Steven Cooreman |
0:459a1af84a64 | 137 | { |
Steven Cooreman |
0:459a1af84a64 | 138 | /* ACMP capsense configuration constant table. */ |
Steven Cooreman |
0:459a1af84a64 | 139 | static const ACMP_CapsenseInit_TypeDef initACMP = |
Steven Cooreman |
0:459a1af84a64 | 140 | { |
Steven Cooreman |
0:459a1af84a64 | 141 | .fullBias = false, |
Steven Cooreman |
0:459a1af84a64 | 142 | .halfBias = false, |
Steven Cooreman |
0:459a1af84a64 | 143 | .biasProg = 0x7, |
Steven Cooreman |
0:459a1af84a64 | 144 | .warmTime = acmpWarmTime512, |
Steven Cooreman |
0:459a1af84a64 | 145 | .hysteresisLevel = acmpHysteresisLevel7, |
Steven Cooreman |
0:459a1af84a64 | 146 | .resistor = acmpResistor0, |
Steven Cooreman |
0:459a1af84a64 | 147 | .lowPowerReferenceEnabled = false, |
Steven Cooreman |
0:459a1af84a64 | 148 | .vddLevel = 0x3D, |
Steven Cooreman |
0:459a1af84a64 | 149 | .enable = false |
Steven Cooreman |
0:459a1af84a64 | 150 | }; |
Steven Cooreman |
0:459a1af84a64 | 151 | |
Steven Cooreman |
0:459a1af84a64 | 152 | |
Steven Cooreman |
0:459a1af84a64 | 153 | /* Configure ACMP locations, ACMP output to pin disabled. */ |
Steven Cooreman |
0:459a1af84a64 | 154 | ACMP_GPIOSetup(ACMP0, 0, false, false); |
Steven Cooreman |
0:459a1af84a64 | 155 | ACMP_GPIOSetup(ACMP1, 0, false, false); |
Steven Cooreman |
0:459a1af84a64 | 156 | |
Steven Cooreman |
0:459a1af84a64 | 157 | /* Initialize ACMPs in capacitive sense mode. */ |
Steven Cooreman |
0:459a1af84a64 | 158 | ACMP_CapsenseInit(ACMP0, &initACMP); |
Steven Cooreman |
0:459a1af84a64 | 159 | ACMP_CapsenseInit(ACMP1, &initACMP); |
Steven Cooreman |
0:459a1af84a64 | 160 | |
Steven Cooreman |
0:459a1af84a64 | 161 | /* Don't enable ACMP, LESENSE controls it! */ |
Steven Cooreman |
0:459a1af84a64 | 162 | } |
Steven Cooreman |
0:459a1af84a64 | 163 | |
Steven Cooreman |
0:459a1af84a64 | 164 | |
Steven Cooreman |
0:459a1af84a64 | 165 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 166 | * @brief Setup the LESENSE for capavitive sensing |
Steven Cooreman |
0:459a1af84a64 | 167 | * @param sleep If true, go into sleep mode. |
Steven Cooreman |
0:459a1af84a64 | 168 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 169 | void CAPLESENSE_setupLESENSE(bool sleep) |
Steven Cooreman |
0:459a1af84a64 | 170 | { |
Steven Cooreman |
0:459a1af84a64 | 171 | uint8_t i; |
Steven Cooreman |
0:459a1af84a64 | 172 | |
Steven Cooreman |
0:459a1af84a64 | 173 | /* Array for storing the calibration values. */ |
Steven Cooreman |
0:459a1af84a64 | 174 | static uint16_t capsenseCalibrateVals[4]; |
Steven Cooreman |
0:459a1af84a64 | 175 | |
Steven Cooreman |
0:459a1af84a64 | 176 | /* LESENSE channel configuration constant table in sense mode. */ |
Steven Cooreman |
0:459a1af84a64 | 177 | static const LESENSE_ChAll_TypeDef initChsSense = LESENSE_CAPSENSE_SCAN_CONF_SENSE; |
Steven Cooreman |
0:459a1af84a64 | 178 | /* LESENSE channel configuration constant table in sleep mode. */ |
Steven Cooreman |
0:459a1af84a64 | 179 | static const LESENSE_ChAll_TypeDef initChsSleep = LESENSE_CAPSENSE_SCAN_CONF_SLEEP; |
Steven Cooreman |
0:459a1af84a64 | 180 | /* LESENSE central configuration constant table. */ |
Steven Cooreman |
0:459a1af84a64 | 181 | static const LESENSE_Init_TypeDef initLESENSE = |
Steven Cooreman |
0:459a1af84a64 | 182 | { |
Steven Cooreman |
0:459a1af84a64 | 183 | .coreCtrl = |
Steven Cooreman |
0:459a1af84a64 | 184 | { |
Steven Cooreman |
0:459a1af84a64 | 185 | .scanStart = lesenseScanStartPeriodic, |
Steven Cooreman |
0:459a1af84a64 | 186 | .prsSel = lesensePRSCh0, |
Steven Cooreman |
0:459a1af84a64 | 187 | .scanConfSel = lesenseScanConfDirMap, |
Steven Cooreman |
0:459a1af84a64 | 188 | .invACMP0 = false, |
Steven Cooreman |
0:459a1af84a64 | 189 | .invACMP1 = false, |
Steven Cooreman |
0:459a1af84a64 | 190 | .dualSample = false, |
Steven Cooreman |
0:459a1af84a64 | 191 | .storeScanRes = false, |
Steven Cooreman |
0:459a1af84a64 | 192 | .bufOverWr = true, |
Steven Cooreman |
0:459a1af84a64 | 193 | .bufTrigLevel = lesenseBufTrigHalf, |
Steven Cooreman |
0:459a1af84a64 | 194 | .wakeupOnDMA = lesenseDMAWakeUpDisable, |
Steven Cooreman |
0:459a1af84a64 | 195 | .biasMode = lesenseBiasModeDutyCycle, |
Steven Cooreman |
0:459a1af84a64 | 196 | .debugRun = false |
Steven Cooreman |
0:459a1af84a64 | 197 | }, |
Steven Cooreman |
0:459a1af84a64 | 198 | |
Steven Cooreman |
0:459a1af84a64 | 199 | .timeCtrl = |
Steven Cooreman |
0:459a1af84a64 | 200 | { |
Steven Cooreman |
0:459a1af84a64 | 201 | .startDelay = 0U |
Steven Cooreman |
0:459a1af84a64 | 202 | }, |
Steven Cooreman |
0:459a1af84a64 | 203 | |
Steven Cooreman |
0:459a1af84a64 | 204 | .perCtrl = |
Steven Cooreman |
0:459a1af84a64 | 205 | { |
Steven Cooreman |
0:459a1af84a64 | 206 | .dacCh0Data = lesenseDACIfData, |
Steven Cooreman |
0:459a1af84a64 | 207 | .dacCh0ConvMode = lesenseDACConvModeDisable, |
Steven Cooreman |
0:459a1af84a64 | 208 | .dacCh0OutMode = lesenseDACOutModeDisable, |
Steven Cooreman |
0:459a1af84a64 | 209 | .dacCh1Data = lesenseDACIfData, |
Steven Cooreman |
0:459a1af84a64 | 210 | .dacCh1ConvMode = lesenseDACConvModeDisable, |
Steven Cooreman |
0:459a1af84a64 | 211 | .dacCh1OutMode = lesenseDACOutModeDisable, |
Steven Cooreman |
0:459a1af84a64 | 212 | .dacPresc = 0U, |
Steven Cooreman |
0:459a1af84a64 | 213 | .dacRef = lesenseDACRefBandGap, |
Steven Cooreman |
0:459a1af84a64 | 214 | .acmp0Mode = lesenseACMPModeMuxThres, |
Steven Cooreman |
0:459a1af84a64 | 215 | .acmp1Mode = lesenseACMPModeMuxThres, |
Steven Cooreman |
0:459a1af84a64 | 216 | .warmupMode = lesenseWarmupModeNormal |
Steven Cooreman |
0:459a1af84a64 | 217 | }, |
Steven Cooreman |
0:459a1af84a64 | 218 | |
Steven Cooreman |
0:459a1af84a64 | 219 | .decCtrl = |
Steven Cooreman |
0:459a1af84a64 | 220 | { |
Steven Cooreman |
0:459a1af84a64 | 221 | .decInput = lesenseDecInputSensorSt, |
Steven Cooreman |
0:459a1af84a64 | 222 | .chkState = false, |
Steven Cooreman |
0:459a1af84a64 | 223 | .intMap = true, |
Steven Cooreman |
0:459a1af84a64 | 224 | .hystPRS0 = false, |
Steven Cooreman |
0:459a1af84a64 | 225 | .hystPRS1 = false, |
Steven Cooreman |
0:459a1af84a64 | 226 | .hystPRS2 = false, |
Steven Cooreman |
0:459a1af84a64 | 227 | .hystIRQ = false, |
Steven Cooreman |
0:459a1af84a64 | 228 | .prsCount = true, |
Steven Cooreman |
0:459a1af84a64 | 229 | .prsChSel0 = lesensePRSCh0, |
Steven Cooreman |
0:459a1af84a64 | 230 | .prsChSel1 = lesensePRSCh1, |
Steven Cooreman |
0:459a1af84a64 | 231 | .prsChSel2 = lesensePRSCh2, |
Steven Cooreman |
0:459a1af84a64 | 232 | .prsChSel3 = lesensePRSCh3 |
Steven Cooreman |
0:459a1af84a64 | 233 | } |
Steven Cooreman |
0:459a1af84a64 | 234 | }; |
Steven Cooreman |
0:459a1af84a64 | 235 | |
Steven Cooreman |
0:459a1af84a64 | 236 | /* Only initialize main LESENSE parameters once. */ |
Steven Cooreman |
0:459a1af84a64 | 237 | if (init) |
Steven Cooreman |
0:459a1af84a64 | 238 | { |
Steven Cooreman |
0:459a1af84a64 | 239 | /* Initialize LESENSE interface with RESET. */ |
Steven Cooreman |
0:459a1af84a64 | 240 | LESENSE_Init(&initLESENSE, true); |
Steven Cooreman |
0:459a1af84a64 | 241 | } |
Steven Cooreman |
0:459a1af84a64 | 242 | |
Steven Cooreman |
0:459a1af84a64 | 243 | /* Different configuration for "sleep" and "sense" modes. */ |
Steven Cooreman |
0:459a1af84a64 | 244 | if (sleep) |
Steven Cooreman |
0:459a1af84a64 | 245 | { |
Steven Cooreman |
0:459a1af84a64 | 246 | /* Stop LESENSE before configuration. */ |
Steven Cooreman |
0:459a1af84a64 | 247 | LESENSE_ScanStop(); |
Steven Cooreman |
0:459a1af84a64 | 248 | |
Steven Cooreman |
0:459a1af84a64 | 249 | /* Wait until the currently active scan is finished. */ |
Steven Cooreman |
0:459a1af84a64 | 250 | while (LESENSE_STATUS_SCANACTIVE & LESENSE_StatusGet()) ; |
Steven Cooreman |
0:459a1af84a64 | 251 | |
Steven Cooreman |
0:459a1af84a64 | 252 | /* Clear result buffer. */ |
Steven Cooreman |
0:459a1af84a64 | 253 | LESENSE_ResultBufferClear(); |
Steven Cooreman |
0:459a1af84a64 | 254 | |
Steven Cooreman |
0:459a1af84a64 | 255 | /* Set scan frequency (in Hz). */ |
Steven Cooreman |
0:459a1af84a64 | 256 | (void) LESENSE_ScanFreqSet(0U, 4U); |
Steven Cooreman |
0:459a1af84a64 | 257 | |
Steven Cooreman |
0:459a1af84a64 | 258 | /* Set clock divisor for LF clock. */ |
Steven Cooreman |
0:459a1af84a64 | 259 | LESENSE_ClkDivSet(lesenseClkLF, lesenseClkDiv_1); |
Steven Cooreman |
0:459a1af84a64 | 260 | |
Steven Cooreman |
0:459a1af84a64 | 261 | /* Configure scan channels. */ |
Steven Cooreman |
0:459a1af84a64 | 262 | LESENSE_ChannelAllConfig(&initChsSleep); |
Steven Cooreman |
0:459a1af84a64 | 263 | |
Steven Cooreman |
0:459a1af84a64 | 264 | /* Restore calibration values. */ |
Steven Cooreman |
0:459a1af84a64 | 265 | LESENSE_ChannelThresSet(CAPLESENSE_SLIDER0_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[0]); |
Steven Cooreman |
0:459a1af84a64 | 266 | LESENSE_ChannelThresSet(CAPLESENSE_SLIDER1_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[1]); |
Steven Cooreman |
0:459a1af84a64 | 267 | LESENSE_ChannelThresSet(CAPLESENSE_SLIDER2_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[2]); |
Steven Cooreman |
0:459a1af84a64 | 268 | LESENSE_ChannelThresSet(CAPLESENSE_SLIDER3_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[3]); |
Steven Cooreman |
0:459a1af84a64 | 269 | |
Steven Cooreman |
0:459a1af84a64 | 270 | /* Disable scan complete interrupt. */ |
Steven Cooreman |
0:459a1af84a64 | 271 | LESENSE_IntDisable(LESENSE_IEN_SCANCOMPLETE); |
Steven Cooreman |
0:459a1af84a64 | 272 | } |
Steven Cooreman |
0:459a1af84a64 | 273 | else |
Steven Cooreman |
0:459a1af84a64 | 274 | { |
Steven Cooreman |
0:459a1af84a64 | 275 | /* Stop LESENSE before configuration. */ |
Steven Cooreman |
0:459a1af84a64 | 276 | LESENSE_ScanStop(); |
Steven Cooreman |
0:459a1af84a64 | 277 | |
Steven Cooreman |
0:459a1af84a64 | 278 | /* Wait until the currently active scan is finished. */ |
Steven Cooreman |
0:459a1af84a64 | 279 | while (LESENSE_STATUS_SCANACTIVE & LESENSE_StatusGet()) ; |
Steven Cooreman |
0:459a1af84a64 | 280 | |
Steven Cooreman |
0:459a1af84a64 | 281 | /* Clean scan complete interrupt flag. */ |
Steven Cooreman |
0:459a1af84a64 | 282 | LESENSE_IntClear(LESENSE_IEN_SCANCOMPLETE); |
Steven Cooreman |
0:459a1af84a64 | 283 | |
Steven Cooreman |
0:459a1af84a64 | 284 | /* Clear result buffer. */ |
Steven Cooreman |
0:459a1af84a64 | 285 | LESENSE_ResultBufferClear(); |
Steven Cooreman |
0:459a1af84a64 | 286 | |
Steven Cooreman |
0:459a1af84a64 | 287 | /* Set scan frequency (in Hz). */ |
Steven Cooreman |
0:459a1af84a64 | 288 | (void) LESENSE_ScanFreqSet(0U, 5U); |
Steven Cooreman |
0:459a1af84a64 | 289 | |
Steven Cooreman |
0:459a1af84a64 | 290 | /* Set clock divisor for LF clock. */ |
Steven Cooreman |
0:459a1af84a64 | 291 | LESENSE_ClkDivSet(lesenseClkLF, lesenseClkDiv_8); |
Steven Cooreman |
0:459a1af84a64 | 292 | |
Steven Cooreman |
0:459a1af84a64 | 293 | /* Configure scan channels. */ |
Steven Cooreman |
0:459a1af84a64 | 294 | LESENSE_ChannelAllConfig(&initChsSense); |
Steven Cooreman |
0:459a1af84a64 | 295 | |
Steven Cooreman |
0:459a1af84a64 | 296 | /* Enable scan complete interrupt. */ |
Steven Cooreman |
0:459a1af84a64 | 297 | LESENSE_IntEnable(LESENSE_IEN_SCANCOMPLETE); |
Steven Cooreman |
0:459a1af84a64 | 298 | } |
Steven Cooreman |
0:459a1af84a64 | 299 | |
Steven Cooreman |
0:459a1af84a64 | 300 | /* Enable LESENSE interrupt in NVIC. */ |
Steven Cooreman |
0:459a1af84a64 | 301 | NVIC_SetPriority(LESENSE_IRQn, 2); |
Steven Cooreman |
0:459a1af84a64 | 302 | NVIC_EnableIRQ(LESENSE_IRQn); |
Steven Cooreman |
0:459a1af84a64 | 303 | |
Steven Cooreman |
0:459a1af84a64 | 304 | /* Start scanning LESENSE channels. */ |
Steven Cooreman |
0:459a1af84a64 | 305 | LESENSE_ScanStart(); |
Steven Cooreman |
0:459a1af84a64 | 306 | |
Steven Cooreman |
0:459a1af84a64 | 307 | /* Run it only once. */ |
Steven Cooreman |
0:459a1af84a64 | 308 | if (init) |
Steven Cooreman |
0:459a1af84a64 | 309 | { |
Steven Cooreman |
0:459a1af84a64 | 310 | /* Assuming that the pads are not touched at first, we can use the result as |
Steven Cooreman |
0:459a1af84a64 | 311 | * the threshold value to calibrate the capacitive sensing in LESENSE. */ |
Steven Cooreman |
0:459a1af84a64 | 312 | init = false; |
Steven Cooreman |
0:459a1af84a64 | 313 | |
Steven Cooreman |
0:459a1af84a64 | 314 | /* Waiting for buffer to be full. */ |
Steven Cooreman |
0:459a1af84a64 | 315 | while (!(LESENSE->STATUS & LESENSE_STATUS_BUFHALFFULL)) ; |
Steven Cooreman |
0:459a1af84a64 | 316 | |
Steven Cooreman |
0:459a1af84a64 | 317 | /* Read out steady state values from LESENSE for calibration. */ |
Steven Cooreman |
0:459a1af84a64 | 318 | for (i = 0U; i < CAPLESENSE_NUMOF_SLIDERS; i++) |
Steven Cooreman |
0:459a1af84a64 | 319 | { |
Steven Cooreman |
0:459a1af84a64 | 320 | capsenseCalibrateVals[i] = LESENSE_ScanResultDataBufferGet(i) - CAPLESENSE_SENSITIVITY_OFFS; |
Steven Cooreman |
0:459a1af84a64 | 321 | } |
Steven Cooreman |
0:459a1af84a64 | 322 | |
Steven Cooreman |
0:459a1af84a64 | 323 | /* Set calibration values. */ |
Steven Cooreman |
0:459a1af84a64 | 324 | LESENSE_ChannelThresSet(CAPLESENSE_SLIDER0_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[0]); |
Steven Cooreman |
0:459a1af84a64 | 325 | LESENSE_ChannelThresSet(CAPLESENSE_SLIDER1_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[1]); |
Steven Cooreman |
0:459a1af84a64 | 326 | LESENSE_ChannelThresSet(CAPLESENSE_SLIDER2_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[2]); |
Steven Cooreman |
0:459a1af84a64 | 327 | LESENSE_ChannelThresSet(CAPLESENSE_SLIDER3_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[3]); |
Steven Cooreman |
0:459a1af84a64 | 328 | } |
Steven Cooreman |
0:459a1af84a64 | 329 | } |
Steven Cooreman |
0:459a1af84a64 | 330 | |
Steven Cooreman |
0:459a1af84a64 | 331 | |
Steven Cooreman |
0:459a1af84a64 | 332 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 333 | * @brief LESENSE callback setup |
Steven Cooreman |
0:459a1af84a64 | 334 | * @param scanCb Scan callback |
Steven Cooreman |
0:459a1af84a64 | 335 | * @param chCb Channel callback |
Steven Cooreman |
0:459a1af84a64 | 336 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 337 | void CAPLESENSE_setupCallbacks(void (*scanCb)(void), void (*chCb)(void)) |
Steven Cooreman |
0:459a1af84a64 | 338 | { |
Steven Cooreman |
0:459a1af84a64 | 339 | lesenseScanCb = scanCb; |
Steven Cooreman |
0:459a1af84a64 | 340 | lesenseChCb = chCb; |
Steven Cooreman |
0:459a1af84a64 | 341 | } |
Steven Cooreman |
0:459a1af84a64 | 342 | |
Steven Cooreman |
0:459a1af84a64 | 343 | |
Steven Cooreman |
0:459a1af84a64 | 344 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 345 | * @brief LESENSE interrupt handler |
Steven Cooreman |
0:459a1af84a64 | 346 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 347 | void LESENSE_IRQHandler(void) |
Steven Cooreman |
0:459a1af84a64 | 348 | { |
Steven Cooreman |
0:459a1af84a64 | 349 | uint32_t count; |
Steven Cooreman |
0:459a1af84a64 | 350 | |
Steven Cooreman |
0:459a1af84a64 | 351 | |
Steven Cooreman |
0:459a1af84a64 | 352 | /* LESENSE scan complete interrupt. */ |
Steven Cooreman |
0:459a1af84a64 | 353 | if (LESENSE_IF_SCANCOMPLETE & LESENSE_IntGetEnabled()) |
Steven Cooreman |
0:459a1af84a64 | 354 | { |
Steven Cooreman |
0:459a1af84a64 | 355 | LESENSE_IntClear(LESENSE_IF_SCANCOMPLETE); |
Steven Cooreman |
0:459a1af84a64 | 356 | |
Steven Cooreman |
0:459a1af84a64 | 357 | /* Iterate trough all channels */ |
Steven Cooreman |
0:459a1af84a64 | 358 | for (currentChannel = 0; currentChannel < LESENSE_CHANNELS; currentChannel++) |
Steven Cooreman |
0:459a1af84a64 | 359 | { |
Steven Cooreman |
0:459a1af84a64 | 360 | /* If this channel is not in use, skip to the next one */ |
Steven Cooreman |
0:459a1af84a64 | 361 | if (!channelsInUse[currentChannel]) |
Steven Cooreman |
0:459a1af84a64 | 362 | { |
Steven Cooreman |
0:459a1af84a64 | 363 | continue; |
Steven Cooreman |
0:459a1af84a64 | 364 | } |
Steven Cooreman |
0:459a1af84a64 | 365 | |
Steven Cooreman |
0:459a1af84a64 | 366 | /* Read out value from LESENSE buffer */ |
Steven Cooreman |
0:459a1af84a64 | 367 | count = LESENSE_ScanResultDataGet(); |
Steven Cooreman |
0:459a1af84a64 | 368 | |
Steven Cooreman |
0:459a1af84a64 | 369 | /* Store value in channelValues */ |
Steven Cooreman |
0:459a1af84a64 | 370 | channelValues[currentChannel] = count; |
Steven Cooreman |
0:459a1af84a64 | 371 | |
Steven Cooreman |
0:459a1af84a64 | 372 | /* Update channelMaxValues */ |
Steven Cooreman |
0:459a1af84a64 | 373 | if (count > channelMaxValues[currentChannel]) |
Steven Cooreman |
0:459a1af84a64 | 374 | { |
Steven Cooreman |
0:459a1af84a64 | 375 | channelMaxValues[currentChannel] = count; |
Steven Cooreman |
0:459a1af84a64 | 376 | } |
Steven Cooreman |
0:459a1af84a64 | 377 | } |
Steven Cooreman |
0:459a1af84a64 | 378 | |
Steven Cooreman |
0:459a1af84a64 | 379 | /* Call callback function. */ |
Steven Cooreman |
0:459a1af84a64 | 380 | if (lesenseScanCb != 0x00000000) |
Steven Cooreman |
0:459a1af84a64 | 381 | { |
Steven Cooreman |
0:459a1af84a64 | 382 | lesenseScanCb(); |
Steven Cooreman |
0:459a1af84a64 | 383 | } |
Steven Cooreman |
0:459a1af84a64 | 384 | } |
Steven Cooreman |
0:459a1af84a64 | 385 | |
Steven Cooreman |
0:459a1af84a64 | 386 | /* LESENSE channel interrupt. */ |
Steven Cooreman |
0:459a1af84a64 | 387 | if (CAPLESENSE_CHANNEL_INT & LESENSE_IntGetEnabled()) |
Steven Cooreman |
0:459a1af84a64 | 388 | { |
Steven Cooreman |
0:459a1af84a64 | 389 | /* Clear flags. */ |
Steven Cooreman |
0:459a1af84a64 | 390 | LESENSE_IntClear(CAPLESENSE_CHANNEL_INT); |
Steven Cooreman |
0:459a1af84a64 | 391 | |
Steven Cooreman |
0:459a1af84a64 | 392 | /* Call callback function. */ |
Steven Cooreman |
0:459a1af84a64 | 393 | if (lesenseChCb != 0x00000000) |
Steven Cooreman |
0:459a1af84a64 | 394 | { |
Steven Cooreman |
0:459a1af84a64 | 395 | lesenseChCb(); |
Steven Cooreman |
0:459a1af84a64 | 396 | } |
Steven Cooreman |
0:459a1af84a64 | 397 | } |
Steven Cooreman |
0:459a1af84a64 | 398 | } |
Steven Cooreman |
0:459a1af84a64 | 399 | |
Steven Cooreman |
0:459a1af84a64 | 400 | |
Steven Cooreman |
0:459a1af84a64 | 401 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 402 | * @brief Get the channelValue for a sensor segment |
Steven Cooreman |
0:459a1af84a64 | 403 | * @param capSegment |
Steven Cooreman |
0:459a1af84a64 | 404 | * @return channel |
Steven Cooreman |
0:459a1af84a64 | 405 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 406 | uint8_t CAPLESENSE_getSegmentChannel(uint8_t capSegment) |
Steven Cooreman |
0:459a1af84a64 | 407 | { |
Steven Cooreman |
0:459a1af84a64 | 408 | uint8_t channel; |
Steven Cooreman |
0:459a1af84a64 | 409 | |
Steven Cooreman |
0:459a1af84a64 | 410 | switch (capSegment) |
Steven Cooreman |
0:459a1af84a64 | 411 | { |
Steven Cooreman |
0:459a1af84a64 | 412 | case(0): |
Steven Cooreman |
0:459a1af84a64 | 413 | channel = SLIDER_PART0_CHANNEL; |
Steven Cooreman |
0:459a1af84a64 | 414 | break; |
Steven Cooreman |
0:459a1af84a64 | 415 | case(1): |
Steven Cooreman |
0:459a1af84a64 | 416 | channel = SLIDER_PART1_CHANNEL; |
Steven Cooreman |
0:459a1af84a64 | 417 | break; |
Steven Cooreman |
0:459a1af84a64 | 418 | case(2): |
Steven Cooreman |
0:459a1af84a64 | 419 | channel = SLIDER_PART2_CHANNEL; |
Steven Cooreman |
0:459a1af84a64 | 420 | break; |
Steven Cooreman |
0:459a1af84a64 | 421 | default: |
Steven Cooreman |
0:459a1af84a64 | 422 | channel = SLIDER_PART3_CHANNEL; |
Steven Cooreman |
0:459a1af84a64 | 423 | break; |
Steven Cooreman |
0:459a1af84a64 | 424 | } |
Steven Cooreman |
0:459a1af84a64 | 425 | return channel; |
Steven Cooreman |
0:459a1af84a64 | 426 | |
Steven Cooreman |
0:459a1af84a64 | 427 | } |
Steven Cooreman |
0:459a1af84a64 | 428 | |
Steven Cooreman |
0:459a1af84a64 | 429 | |
Steven Cooreman |
0:459a1af84a64 | 430 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 431 | * @brief Get the current channelValue for a channel |
Steven Cooreman |
0:459a1af84a64 | 432 | * @param channel The channel. |
Steven Cooreman |
0:459a1af84a64 | 433 | * @return The channelValue. |
Steven Cooreman |
0:459a1af84a64 | 434 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 435 | uint32_t CAPLESENSE_getVal(uint8_t channel) |
Steven Cooreman |
0:459a1af84a64 | 436 | { |
Steven Cooreman |
0:459a1af84a64 | 437 | return channelValues[channel]; |
Steven Cooreman |
0:459a1af84a64 | 438 | } |
Steven Cooreman |
0:459a1af84a64 | 439 | |
Steven Cooreman |
0:459a1af84a64 | 440 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 441 | * @brief Get the current normalized channelValue for a channel |
Steven Cooreman |
0:459a1af84a64 | 442 | * @param channel The channel. |
Steven Cooreman |
0:459a1af84a64 | 443 | * @return The channel value in range (0-256). |
Steven Cooreman |
0:459a1af84a64 | 444 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 445 | uint32_t CAPLESENSE_getNormalizedVal(uint8_t channel) |
Steven Cooreman |
0:459a1af84a64 | 446 | { |
Steven Cooreman |
0:459a1af84a64 | 447 | uint32_t max = channelMaxValues[channel]; |
Steven Cooreman |
0:459a1af84a64 | 448 | return (channelValues[channel] << 8) / max; |
Steven Cooreman |
0:459a1af84a64 | 449 | } |
Steven Cooreman |
0:459a1af84a64 | 450 | |
Steven Cooreman |
0:459a1af84a64 | 451 | |
Steven Cooreman |
0:459a1af84a64 | 452 | |
Steven Cooreman |
0:459a1af84a64 | 453 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 454 | * @brief Get the position of the slider |
Steven Cooreman |
0:459a1af84a64 | 455 | * @return The position of the slider if it can be determined, |
Steven Cooreman |
0:459a1af84a64 | 456 | * -1 otherwise. |
Steven Cooreman |
0:459a1af84a64 | 457 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 458 | int32_t CAPLESENSE_getSliderPosition(void) |
Steven Cooreman |
0:459a1af84a64 | 459 | { |
Steven Cooreman |
0:459a1af84a64 | 460 | int i; |
Steven Cooreman |
0:459a1af84a64 | 461 | int minPos = -1; |
Steven Cooreman |
0:459a1af84a64 | 462 | uint32_t minVal = 236; /* adjust it */ |
Steven Cooreman |
0:459a1af84a64 | 463 | /* Values used for interpolation. There is two more which represents the edges. |
Steven Cooreman |
0:459a1af84a64 | 464 | * This makes the interpolation code a bit cleaner as we do not have to make special |
Steven Cooreman |
0:459a1af84a64 | 465 | * cases for handling them */ |
Steven Cooreman |
0:459a1af84a64 | 466 | uint32_t interpol[6] = { 255, 255, 255, 255, 255, 255 }; |
Steven Cooreman |
0:459a1af84a64 | 467 | uint32_t channelPattern[] = { 0, SLIDER_PART0_CHANNEL + 1, |
Steven Cooreman |
0:459a1af84a64 | 468 | SLIDER_PART1_CHANNEL + 1, |
Steven Cooreman |
0:459a1af84a64 | 469 | SLIDER_PART2_CHANNEL + 1, |
Steven Cooreman |
0:459a1af84a64 | 470 | SLIDER_PART3_CHANNEL + 1 }; |
Steven Cooreman |
0:459a1af84a64 | 471 | |
Steven Cooreman |
0:459a1af84a64 | 472 | /* The calculated slider position. */ |
Steven Cooreman |
0:459a1af84a64 | 473 | int position; |
Steven Cooreman |
0:459a1af84a64 | 474 | |
Steven Cooreman |
0:459a1af84a64 | 475 | /* Iterate through the 4 slider bars and calculate the current value divided by |
Steven Cooreman |
0:459a1af84a64 | 476 | * the maximum value multiplied by 256. |
Steven Cooreman |
0:459a1af84a64 | 477 | * Note that there is an offset of 1 between channelValues and interpol. |
Steven Cooreman |
0:459a1af84a64 | 478 | * This is done to make interpolation easier. |
Steven Cooreman |
0:459a1af84a64 | 479 | */ |
Steven Cooreman |
0:459a1af84a64 | 480 | for (i = 1; i < CAPLESENSE_NUMOF_SLIDERS + 1; i++) |
Steven Cooreman |
0:459a1af84a64 | 481 | { |
Steven Cooreman |
0:459a1af84a64 | 482 | /* interpol[i] will be in the range 0-256 depending on channelMax */ |
Steven Cooreman |
0:459a1af84a64 | 483 | interpol[i] = channelValues[channelPattern[i] - 1] << 8; |
Steven Cooreman |
0:459a1af84a64 | 484 | interpol[i] /= channelMaxValues[channelPattern[i] - 1]; |
Steven Cooreman |
0:459a1af84a64 | 485 | /* Find the minimum value and position */ |
Steven Cooreman |
0:459a1af84a64 | 486 | if (interpol[i] < minVal) |
Steven Cooreman |
0:459a1af84a64 | 487 | { |
Steven Cooreman |
0:459a1af84a64 | 488 | minVal = interpol[i]; |
Steven Cooreman |
0:459a1af84a64 | 489 | minPos = i; |
Steven Cooreman |
0:459a1af84a64 | 490 | } |
Steven Cooreman |
0:459a1af84a64 | 491 | } |
Steven Cooreman |
0:459a1af84a64 | 492 | /* Check if the slider has not been touched */ |
Steven Cooreman |
0:459a1af84a64 | 493 | if (minPos == -1) |
Steven Cooreman |
0:459a1af84a64 | 494 | return -1; |
Steven Cooreman |
0:459a1af84a64 | 495 | |
Steven Cooreman |
0:459a1af84a64 | 496 | /* Start position. Shift by 4 to get additional resolution. */ |
Steven Cooreman |
0:459a1af84a64 | 497 | /* Because of the interpol trick earlier we have to substract one to offset that effect */ |
Steven Cooreman |
0:459a1af84a64 | 498 | position = (minPos - 1) << 4; |
Steven Cooreman |
0:459a1af84a64 | 499 | |
Steven Cooreman |
0:459a1af84a64 | 500 | /* Interpolate with pad to the left */ |
Steven Cooreman |
0:459a1af84a64 | 501 | position -= ((256 - interpol[minPos - 1]) << 3) |
Steven Cooreman |
0:459a1af84a64 | 502 | / (256 - interpol[minPos]); |
Steven Cooreman |
0:459a1af84a64 | 503 | |
Steven Cooreman |
0:459a1af84a64 | 504 | /* Interpolate with pad to the right */ |
Steven Cooreman |
0:459a1af84a64 | 505 | position += ((256 - interpol[minPos + 1]) << 3) |
Steven Cooreman |
0:459a1af84a64 | 506 | / (256 - interpol[minPos]); |
Steven Cooreman |
0:459a1af84a64 | 507 | |
Steven Cooreman |
0:459a1af84a64 | 508 | return position; |
Steven Cooreman |
0:459a1af84a64 | 509 | } |
Steven Cooreman |
0:459a1af84a64 | 510 | |
Steven Cooreman |
0:459a1af84a64 | 511 | |
Steven Cooreman |
0:459a1af84a64 | 512 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 513 | * @brief Send the capacative sense system to sleep mode. |
Steven Cooreman |
0:459a1af84a64 | 514 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 515 | void CAPLESENSE_Sleep(void) |
Steven Cooreman |
0:459a1af84a64 | 516 | { |
Steven Cooreman |
0:459a1af84a64 | 517 | /* Go to EM2 and wait for the measurement to complete. */ |
Steven Cooreman |
0:459a1af84a64 | 518 | EMU_EnterEM2(true); |
Steven Cooreman |
0:459a1af84a64 | 519 | } |
Steven Cooreman |
0:459a1af84a64 | 520 | |
Steven Cooreman |
0:459a1af84a64 | 521 | |
Steven Cooreman |
0:459a1af84a64 | 522 | /**************************************************************************//** |
Steven Cooreman |
0:459a1af84a64 | 523 | * @brief Initializes the capacative sense system without LESENSE. |
Steven Cooreman |
0:459a1af84a64 | 524 | * @param sleep If true, go into sleep mode. |
Steven Cooreman |
0:459a1af84a64 | 525 | *****************************************************************************/ |
Steven Cooreman |
0:459a1af84a64 | 526 | void CAPLESENSE_Init(bool sleep) |
Steven Cooreman |
0:459a1af84a64 | 527 | { |
Steven Cooreman |
0:459a1af84a64 | 528 | /* Disable interrupts */ |
Steven Cooreman |
0:459a1af84a64 | 529 | INT_Disable(); |
Steven Cooreman |
0:459a1af84a64 | 530 | |
Steven Cooreman |
0:459a1af84a64 | 531 | /* Setup CMU. */ |
Steven Cooreman |
0:459a1af84a64 | 532 | CAPLESENSE_setupCMU(); |
Steven Cooreman |
0:459a1af84a64 | 533 | /* Setup GPIO. */ |
Steven Cooreman |
0:459a1af84a64 | 534 | CAPLESENSE_setupGPIO(); |
Steven Cooreman |
0:459a1af84a64 | 535 | /* Setup ACMP. */ |
Steven Cooreman |
0:459a1af84a64 | 536 | CAPLESENSE_setupACMP(); |
Steven Cooreman |
0:459a1af84a64 | 537 | /* Setup LESENSE. */ |
Steven Cooreman |
0:459a1af84a64 | 538 | CAPLESENSE_setupLESENSE(sleep); |
Steven Cooreman |
0:459a1af84a64 | 539 | |
Steven Cooreman |
0:459a1af84a64 | 540 | /* Initialization done, enable interrupts globally. */ |
Steven Cooreman |
0:459a1af84a64 | 541 | INT_Enable(); |
Steven Cooreman |
0:459a1af84a64 | 542 | } |
Steven Cooreman |
0:459a1af84a64 | 543 | |
Steven Cooreman |
0:459a1af84a64 | 544 |