00001
00036
00037 #include "em_device.h"
00038
00039
00040 #include "caplesense.h"
00041 #include "em_emu.h"
00042 #include "em_acmp.h"
00043 #include "em_assert.h"
00044 #include "em_cmu.h"
00045 #include "em_emu.h"
00046 #include "em_gpio.h"
00047 #include "em_int.h"
00048 #include "em_lesense.h"
00049
00050
00051 #include "caplesenseconfig.h"
00052
00053
00057 static volatile uint32_t channelValues[LESENSE_CHANNELS] =
00058 {
00059
00060 0, 0, 0, 0, 0, 0, 0, 0,
00061
00062 0, 0, 0, 0, 0, 0, 0, 0
00063 };
00064
00065
00066
00070 static volatile uint32_t channelMaxValues[LESENSE_CHANNELS] =
00071 {
00072
00073 1, 1, 1, 1, 1, 1, 1, 1,
00074
00075 1, 1, 1, 1, 1, 1, 1, 1
00076 };
00077
00078
00082 static const bool channelsInUse[LESENSE_CHANNELS] = LESENSE_CAPSENSE_CH_IN_USE;
00083
00084
00087 void CAPLESENSE_setupCMU(void);
00088 void CAPLESENSE_setupGPIO(void);
00089 void CAPLESENSE_setupACMP(void);
00090
00091
00092
00096 static void (*lesenseScanCb)(void);
00098 static void (*lesenseChCb)(void);
00099
00101 static volatile uint8_t currentChannel;
00102
00103
00104
00105
00108 void CAPLESENSE_setupCMU(void)
00109 {
00110
00111 SystemCoreClockUpdate();
00112
00113
00114 CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFRCO);
00115
00116 CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO);
00117
00118 CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_Disabled);
00119
00120
00121 CMU_ClockEnable(cmuClock_HFPER, 1);
00122
00123 CMU_ClockEnable(cmuClock_GPIO, 1);
00124
00125 CMU_ClockEnable(cmuClock_ACMP0, 1);
00126
00127 CMU_ClockEnable(cmuClock_ACMP1, 1);
00128
00129 CMU_ClockEnable(cmuClock_CORELE, 1);
00130
00131 CMU_ClockEnable(cmuClock_LESENSE, 1);
00132
00133
00134 CMU_ClockDivSet(cmuClock_LESENSE, cmuClkDiv_1);
00135 }
00136
00137
00138
00141 void CAPLESENSE_setupGPIO(void)
00142 {
00143
00144 GPIO_DriveModeSet(CAPLESENSE_SLIDER_PORT0, gpioDriveModeStandard);
00145
00146
00147
00148 GPIO_PinModeSet(CAPLESENSE_SLIDER_PORT0, CAPLESENSE_SLIDER0_PIN, gpioModeDisabled, 0);
00149 GPIO_PinModeSet(CAPLESENSE_SLIDER_PORT0, CAPLESENSE_SLIDER1_PIN, gpioModeDisabled, 0);
00150 GPIO_PinModeSet(CAPLESENSE_SLIDER_PORT0, CAPLESENSE_SLIDER2_PIN, gpioModeDisabled, 0);
00151 GPIO_PinModeSet(CAPLESENSE_SLIDER_PORT0, CAPLESENSE_SLIDER3_PIN, gpioModeDisabled, 0);
00152 }
00153
00154
00155
00158 void CAPLESENSE_setupACMP(void)
00159 {
00160
00161 static const ACMP_CapsenseInit_TypeDef initACMP =
00162 {
00163 .fullBias = false,
00164 .halfBias = false,
00165 .biasProg = 0x7,
00166 .warmTime = acmpWarmTime512,
00167 .hysteresisLevel = acmpHysteresisLevel7,
00168 .resistor = acmpResistor0,
00169 .lowPowerReferenceEnabled = false,
00170 .vddLevel = 0x3D,
00171 .enable = false
00172 };
00173
00174
00175
00176 ACMP_GPIOSetup(ACMP0, 0, false, false);
00177 ACMP_GPIOSetup(ACMP1, 0, false, false);
00178
00179
00180 ACMP_CapsenseInit(ACMP0, &initACMP);
00181 ACMP_CapsenseInit(ACMP1, &initACMP);
00182
00183
00184 }
00185
00186
00187
00191 void CAPLESENSE_setupLESENSE(bool sleep)
00192 {
00193 uint8_t i;
00194 static bool init = true;
00195
00196
00197 static uint16_t capsenseCalibrateVals[4];
00198
00199
00200 static const LESENSE_ChAll_TypeDef initChsSense = LESENSE_CAPSENSE_SCAN_CONF_SENSE;
00201
00202 static const LESENSE_ChAll_TypeDef initChsSleep = LESENSE_CAPSENSE_SCAN_CONF_SLEEP;
00203
00204 static const LESENSE_Init_TypeDef initLESENSE =
00205 {
00206 .coreCtrl =
00207 {
00208 .scanStart = lesenseScanStartPeriodic,
00209 .prsSel = lesensePRSCh0,
00210 .scanConfSel = lesenseScanConfDirMap,
00211 .invACMP0 = false,
00212 .invACMP1 = false,
00213 .dualSample = false,
00214 .storeScanRes = false,
00215 .bufOverWr = true,
00216 .bufTrigLevel = lesenseBufTrigHalf,
00217 .wakeupOnDMA = lesenseDMAWakeUpDisable,
00218 .biasMode = lesenseBiasModeDutyCycle,
00219 .debugRun = false
00220 },
00221
00222 .timeCtrl =
00223 {
00224 .startDelay = 0U
00225 },
00226
00227 .perCtrl =
00228 {
00229 .dacCh0Data = lesenseDACIfData,
00230 .dacCh0ConvMode = lesenseDACConvModeDisable,
00231 .dacCh0OutMode = lesenseDACOutModeDisable,
00232 .dacCh1Data = lesenseDACIfData,
00233 .dacCh1ConvMode = lesenseDACConvModeDisable,
00234 .dacCh1OutMode = lesenseDACOutModeDisable,
00235 .dacPresc = 0U,
00236 .dacRef = lesenseDACRefBandGap,
00237 .acmp0Mode = lesenseACMPModeMuxThres,
00238 .acmp1Mode = lesenseACMPModeMuxThres,
00239 .warmupMode = lesenseWarmupModeNormal
00240 },
00241
00242 .decCtrl =
00243 {
00244 .decInput = lesenseDecInputSensorSt,
00245 .chkState = false,
00246 .intMap = true,
00247 .hystPRS0 = false,
00248 .hystPRS1 = false,
00249 .hystPRS2 = false,
00250 .hystIRQ = false,
00251 .prsCount = true,
00252 .prsChSel0 = lesensePRSCh0,
00253 .prsChSel1 = lesensePRSCh1,
00254 .prsChSel2 = lesensePRSCh2,
00255 .prsChSel3 = lesensePRSCh3
00256 }
00257 };
00258
00259
00260 if (init)
00261 {
00262
00263 LESENSE_Init(&initLESENSE, true);
00264 }
00265
00266
00267 if (sleep)
00268 {
00269
00270 LESENSE_ScanStop();
00271
00272
00273 while (LESENSE_STATUS_SCANACTIVE & LESENSE_StatusGet()) ;
00274
00275
00276 LESENSE_ResultBufferClear();
00277
00278
00279 (void) LESENSE_ScanFreqSet(0U, 4U);
00280
00281
00282 LESENSE_ClkDivSet(lesenseClkLF, lesenseClkDiv_1);
00283
00284
00285 LESENSE_ChannelAllConfig(&initChsSleep);
00286
00287
00288 LESENSE_ChannelThresSet(CAPLESENSE_SLIDER0_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[0]);
00289 LESENSE_ChannelThresSet(CAPLESENSE_SLIDER1_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[1]);
00290 LESENSE_ChannelThresSet(CAPLESENSE_SLIDER2_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[2]);
00291 LESENSE_ChannelThresSet(CAPLESENSE_SLIDER3_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[3]);
00292
00293
00294 LESENSE_IntDisable(LESENSE_IEN_SCANCOMPLETE);
00295 }
00296 else
00297 {
00298
00299 LESENSE_ScanStop();
00300
00301
00302 while (LESENSE_STATUS_SCANACTIVE & LESENSE_StatusGet()) ;
00303
00304
00305 LESENSE_IntClear(LESENSE_IEN_SCANCOMPLETE);
00306
00307
00308 LESENSE_ResultBufferClear();
00309
00310
00311 (void) LESENSE_ScanFreqSet(0U, 64U);
00312
00313
00314 LESENSE_ClkDivSet(lesenseClkLF, lesenseClkDiv_8);
00315
00316
00317 LESENSE_ChannelAllConfig(&initChsSense);
00318
00319
00320 LESENSE_IntEnable(LESENSE_IEN_SCANCOMPLETE);
00321 }
00322
00323
00324 NVIC_EnableIRQ(LESENSE_IRQn);
00325
00326
00327 LESENSE_ScanStart();
00328
00329
00330 if (init)
00331 {
00332
00333
00334 init = false;
00335
00336
00337 while (!(LESENSE->STATUS & LESENSE_STATUS_BUFHALFFULL)) ;
00338
00339
00340 for (i = 0U; i < CAPLESENSE_NUMOF_SLIDERS; i++)
00341 {
00342 capsenseCalibrateVals[i] = LESENSE_ScanResultDataBufferGet(i) - CAPLESENSE_SENSITIVITY_OFFS;
00343 }
00344
00345
00346 LESENSE_ChannelThresSet(CAPLESENSE_SLIDER0_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[0]);
00347 LESENSE_ChannelThresSet(CAPLESENSE_SLIDER1_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[1]);
00348 LESENSE_ChannelThresSet(CAPLESENSE_SLIDER2_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[2]);
00349 LESENSE_ChannelThresSet(CAPLESENSE_SLIDER3_PIN, CAPLESENSE_ACMP_VDD_SCALE, capsenseCalibrateVals[3]);
00350 }
00351 }
00352
00353
00354
00359 void CAPLESENSE_setupCallbacks(void (*scanCb)(void), void (*chCb)(void))
00360 {
00361 lesenseScanCb = scanCb;
00362 lesenseChCb = chCb;
00363 }
00364
00365
00366
00369 void LESENSE_IRQHandler(void)
00370 {
00371 uint32_t count;
00372
00373
00374
00375 if (LESENSE_IF_SCANCOMPLETE & LESENSE_IntGetEnabled())
00376 {
00377 LESENSE_IntClear(LESENSE_IF_SCANCOMPLETE);
00378
00379
00380 for (currentChannel = 0; currentChannel < LESENSE_CHANNELS; currentChannel++)
00381 {
00382
00383 if (!channelsInUse[currentChannel])
00384 {
00385 continue;
00386 }
00387
00388
00389 count = LESENSE_ScanResultDataGet();
00390
00391
00392 channelValues[currentChannel] = count;
00393
00394
00395 if (count > channelMaxValues[currentChannel])
00396 {
00397 channelMaxValues[currentChannel] = count;
00398 }
00399 }
00400
00401
00402 if (lesenseScanCb != 0x00000000)
00403 {
00404 lesenseScanCb();
00405 }
00406 }
00407
00408
00409 if (CAPLESENSE_CHANNEL_INT & LESENSE_IntGetEnabled())
00410 {
00411
00412 LESENSE_IntClear(CAPLESENSE_CHANNEL_INT);
00413
00414
00415 if (lesenseChCb != 0x00000000)
00416 {
00417 lesenseChCb();
00418 }
00419 }
00420 }
00421
00422
00423
00428 uint8_t CAPLESENSE_getSegmentChannel(uint8_t capSegment)
00429 {
00430 uint8_t channel;
00431
00432 switch (capSegment)
00433 {
00434 case(0):
00435 channel = SLIDER_PART0_CHANNEL;
00436 break;
00437 case(1):
00438 channel = SLIDER_PART1_CHANNEL;
00439 break;
00440 case(2):
00441 channel = SLIDER_PART2_CHANNEL;
00442 break;
00443 default:
00444 channel = SLIDER_PART3_CHANNEL;
00445 break;
00446 }
00447 return channel;
00448
00449 }
00450
00451
00452
00457 uint32_t CAPLESENSE_getVal(uint8_t channel)
00458 {
00459 return channelValues[channel];
00460 }
00461
00462
00467 uint32_t CAPLESENSE_getNormalizedVal(uint8_t channel)
00468 {
00469 uint32_t max = channelMaxValues[channel];
00470 return (channelValues[channel] << 8) / max;
00471 }
00472
00473
00474
00475
00480 int32_t CAPLESENSE_getSliderPosition(void)
00481 {
00482 int i;
00483 int minPos = -1;
00484 uint32_t minVal = 236;
00485
00486
00487
00488 uint32_t interpol[6] = { 255, 255, 255, 255, 255, 255 };
00489 uint32_t channelPattern[] = { 0, SLIDER_PART0_CHANNEL + 1,
00490 SLIDER_PART1_CHANNEL + 1,
00491 SLIDER_PART2_CHANNEL + 1,
00492 SLIDER_PART3_CHANNEL + 1 };
00493
00494
00495 int position;
00496
00497
00498
00499
00500
00501
00502 for (i = 1; i < CAPLESENSE_NUMOF_SLIDERS + 1; i++)
00503 {
00504
00505 interpol[i] = channelValues[channelPattern[i] - 1] << 8;
00506 interpol[i] /= channelMaxValues[channelPattern[i] - 1];
00507
00508 if (interpol[i] < minVal)
00509 {
00510 minVal = interpol[i];
00511 minPos = i;
00512 }
00513 }
00514
00515 if (minPos == -1)
00516 return -1;
00517
00518
00519
00520 position = (minPos - 1) << 4;
00521
00522
00523 position -= ((256 - interpol[minPos - 1]) << 3)
00524 / (256 - interpol[minPos]);
00525
00526
00527 position += ((256 - interpol[minPos + 1]) << 3)
00528 / (256 - interpol[minPos]);
00529
00530 return position;
00531 }
00532
00533
00534
00537 void CAPLESENSE_Sleep(void)
00538 {
00539
00540 EMU_EnterEM2(true);
00541 }
00542
00543
00544
00548 void CAPLESENSE_Init(bool sleep)
00549 {
00550
00551 INT_Disable();
00552
00553
00554 CAPLESENSE_setupCMU();
00555
00556 CAPLESENSE_setupGPIO();
00557
00558 CAPLESENSE_setupACMP();
00559
00560 CAPLESENSE_setupLESENSE(sleep);
00561
00562
00563 INT_Enable();
00564 }
00565
00566