EFM32 Giant Gecko Software Documentation  efm32gg-doc-5.1.2
em_lesense.c
Go to the documentation of this file.
1 /***************************************************************************/
33 #include "em_lesense.h"
34 
35 #if defined(LESENSE_COUNT) && (LESENSE_COUNT > 0)
36 #include "em_assert.h"
37 #include "em_bus.h"
38 #include "em_cmu.h"
39 
41 #if !defined(UINT32_MAX)
42 #define UINT32_MAX ((uint32_t)(0xFFFFFFFF))
43 #endif
44 
46 /***************************************************************************/
51 /***************************************************************************/
63 #if defined(_LESENSE_ROUTE_MASK)
64 #define GENERIC_LESENSE_ROUTE LESENSE->ROUTE
65 #else
66 #define GENERIC_LESENSE_ROUTE LESENSE->ROUTEPEN
67 #endif
68 
69 #if defined(_SILICON_LABS_32B_SERIES_0)
70 /* DACOUT mode only available on channel 0,1,2,3,12,13,14,15 */
71 #define DACOUT_SUPPORT 0xF00F
72 #else
73 /* DACOUT mode only available on channel 4,5,7,10,12,13 */
74 #define DACOUT_SUPPORT 0x34B0
75 #endif
76 
78 /*******************************************************************************
79  ************************** LOCAL FUNCTIONS ********************************
80  ******************************************************************************/
81 
82 
83 /*******************************************************************************
84  ************************** GLOBAL FUNCTIONS *******************************
85  ******************************************************************************/
86 
87 /***************************************************************************/
118 void LESENSE_Init(const LESENSE_Init_TypeDef * init, bool reqReset)
119 {
120  /* Sanity check of initialization values */
121  EFM_ASSERT((uint32_t)init->timeCtrl.startDelay < 4U);
122 #if defined(_LESENSE_PERCTRL_DACPRESC_MASK)
123  EFM_ASSERT((uint32_t)init->perCtrl.dacPresc < 32U);
124 #endif
125 
126  /* Reset LESENSE registers if requested. */
127  if (reqReset)
128  {
129  LESENSE_Reset();
130  }
131 
132  /* Set sensor start delay for each channel. */
133  LESENSE_StartDelaySet((uint32_t)init->timeCtrl.startDelay);
134 #if defined(_LESENSE_TIMCTRL_AUXSTARTUP_MASK)
135  /* Configure the AUXHRFCO startup delay. */
136  LESENSE->TIMCTRL = (LESENSE->TIMCTRL & (~_LESENSE_TIMCTRL_AUXSTARTUP_MASK))
137  | (init->timeCtrl.delayAuxStartup << _LESENSE_TIMCTRL_AUXSTARTUP_SHIFT);
138 #endif
139 
140  /* LESENSE core control configuration.
141  * Set PRS source, SCANCONF register usage strategy, interrupt and
142  * DMA trigger level condition, DMA wakeup condition, bias mode,
143  * enable/disable to sample both ACMPs simultaneously, enable/disable to store
144  * SCANRES in CNT_RES after each scan, enable/disable to always write to the
145  * result buffer, even if it is full, enable/disable LESENSE running in debug
146  * mode. */
147  LESENSE->CTRL =
148  ((uint32_t)init->coreCtrl.prsSel << _LESENSE_CTRL_PRSSEL_SHIFT)
149  | (uint32_t)init->coreCtrl.scanConfSel
150  | (uint32_t)init->coreCtrl.bufTrigLevel
151  | (uint32_t)init->coreCtrl.wakeupOnDMA
152 #if defined(_LESENSE_CTRL_ACMP0INV_MASK)
153  | ((uint32_t)init->coreCtrl.invACMP0 << _LESENSE_CTRL_ACMP0INV_SHIFT)
154  | ((uint32_t)init->coreCtrl.invACMP1 << _LESENSE_CTRL_ACMP1INV_SHIFT)
155 #endif
156  | ((uint32_t)init->coreCtrl.dualSample << _LESENSE_CTRL_DUALSAMPLE_SHIFT)
158  | ((uint32_t)init->coreCtrl.bufOverWr << _LESENSE_CTRL_BUFOW_SHIFT)
159  | ((uint32_t)init->coreCtrl.debugRun << _LESENSE_CTRL_DEBUGRUN_SHIFT);
160 
161  /* Set scan mode in the CTRL register using the provided function, don't
162  * start scanning immediately. */
164 
165  /* LESENSE peripheral control configuration.
166  * Set DAC0 and DAC1 data source, conversion mode, output mode. Set DAC
167  * prescaler and reference. Set ACMP0 and ACMP1 control mode. Set ACMP and DAC
168  * duty cycle (warm up) mode. */
169  LESENSE->PERCTRL =
172 #if defined(_LESENSE_PERCTRL_DACCH0CONV_MASK)
177  | ((uint32_t)init->perCtrl.dacPresc << _LESENSE_PERCTRL_DACPRESC_SHIFT)
178  | (uint32_t)init->perCtrl.dacRef
179 #endif
180  | ((uint32_t)init->perCtrl.acmp0Mode << _LESENSE_PERCTRL_ACMP0MODE_SHIFT)
181  | ((uint32_t)init->perCtrl.acmp1Mode << _LESENSE_PERCTRL_ACMP1MODE_SHIFT)
182 #if defined(_LESENSE_PERCTRL_ACMP0INV_MASK)
183  | ((uint32_t)init->coreCtrl.invACMP0 << _LESENSE_PERCTRL_ACMP0INV_SHIFT)
184  | ((uint32_t)init->coreCtrl.invACMP1 << _LESENSE_PERCTRL_ACMP1INV_SHIFT)
185 #endif
186 #if defined(_LESENSE_PERCTRL_DACCONVTRIG_MASK)
187  | ((uint32_t)init->perCtrl.dacScan << _LESENSE_PERCTRL_DACCONVTRIG_SHIFT)
188 #endif
189  | (uint32_t)init->perCtrl.warmupMode;
190 
191  /* LESENSE decoder general control configuration.
192  * Set decoder input source, select PRS input for decoder bits.
193  * Enable/disable the decoder to check the present state.
194  * Enable/disable decoder to channel interrupt mapping.
195  * Enable/disable decoder hysteresis on PRS output.
196  * Enable/disable decoder hysteresis on count events.
197  * Enable/disable decoder hysteresis on interrupt requests.
198  * Enable/disable count mode on LESPRS0 and LESPRS1. */
199  LESENSE->DECCTRL =
200  (uint32_t)init->decCtrl.decInput
201  | ((uint32_t)init->decCtrl.prsChSel0 << _LESENSE_DECCTRL_PRSSEL0_SHIFT)
202  | ((uint32_t)init->decCtrl.prsChSel1 << _LESENSE_DECCTRL_PRSSEL1_SHIFT)
203  | ((uint32_t)init->decCtrl.prsChSel2 << _LESENSE_DECCTRL_PRSSEL2_SHIFT)
204  | ((uint32_t)init->decCtrl.prsChSel3 << _LESENSE_DECCTRL_PRSSEL3_SHIFT)
205  | ((uint32_t)init->decCtrl.chkState << _LESENSE_DECCTRL_ERRCHK_SHIFT)
206  | ((uint32_t)init->decCtrl.intMap << _LESENSE_DECCTRL_INTMAP_SHIFT)
207  | ((uint32_t)init->decCtrl.hystPRS0 << _LESENSE_DECCTRL_HYSTPRS0_SHIFT)
208  | ((uint32_t)init->decCtrl.hystPRS1 << _LESENSE_DECCTRL_HYSTPRS1_SHIFT)
209  | ((uint32_t)init->decCtrl.hystPRS2 << _LESENSE_DECCTRL_HYSTPRS2_SHIFT)
210  | ((uint32_t)init->decCtrl.hystIRQ << _LESENSE_DECCTRL_HYSTIRQ_SHIFT)
211  | ((uint32_t)init->decCtrl.prsCount << _LESENSE_DECCTRL_PRSCNT_SHIFT);
212 
213  /* Set initial LESENSE decoder state. */
214  LESENSE_DecoderStateSet((uint32_t)init->decCtrl.initState);
215 
216  /* LESENSE bias control configuration. */
217  LESENSE->BIASCTRL = (uint32_t)init->coreCtrl.biasMode;
218 }
219 
220 
221 /***************************************************************************/
247 uint32_t LESENSE_ScanFreqSet(uint32_t refFreq, uint32_t scanFreq)
248 {
249  uint32_t tmp;
250  uint32_t pcPresc = 0UL; /* Period counter prescaler. */
251  uint32_t clkDiv = 1UL; /* Clock divisor value (2^pcPresc). */
252  uint32_t pcTop = 63UL; /* Period counter top value (max. 63). */
253  uint32_t calcScanFreq; /* Variable for testing the calculation algorithm. */
254 
255 
256  /* If refFreq is set to 0, the currently configured reference clock is
257  * assumed. */
258  if (!refFreq)
259  {
261  }
262 
263  /* Max. value of pcPresc is 128, thus using reference frequency less than
264  * 33554431Hz (33.554431MHz), the frequency calculation in the while loop
265  * below will not overflow. */
266  EFM_ASSERT(refFreq < ((uint32_t)UINT32_MAX / 128UL));
267 
268  /* Sanity check of scan frequency value. */
269  EFM_ASSERT((scanFreq > 0U) && (scanFreq <= refFreq));
270 
271  /* Calculate the minimum necessary prescaler value in order to provide the
272  * biggest possible resolution for setting scan frequency.
273  * Maximum number of calculation cycles is 7 (value of lesenseClkDiv_128). */
274  while ((refFreq / ((uint32_t)scanFreq * clkDiv) > (pcTop + 1UL))
275  && (pcPresc < lesenseClkDiv_128))
276  {
277  ++pcPresc;
278  clkDiv = (uint32_t)1UL << pcPresc;
279  }
280 
281  /* Calculate pcTop value. */
282  pcTop = ((uint32_t)refFreq / ((uint32_t)scanFreq * clkDiv)) - 1UL;
283 
284  /* Clear current PCPRESC and PCTOP settings. Be aware of the effect of
285  * non-atomic Read-Modify-Write on LESENSE->TIMCRTL. */
286  tmp = LESENSE->TIMCTRL & (~_LESENSE_TIMCTRL_PCPRESC_MASK
288 
289  /* Set new values in tmp while reserving other settings. */
290  tmp |= ((uint32_t)pcPresc << _LESENSE_TIMCTRL_PCPRESC_SHIFT)
291  | ((uint32_t)pcTop << _LESENSE_TIMCTRL_PCTOP_SHIFT);
292 
293  /* Set values in LESENSE_TIMCTRL register. */
294  LESENSE->TIMCTRL = tmp;
295 
296  /* For testing the calculation algorithm. */
297  calcScanFreq = ((uint32_t)refFreq / ((uint32_t)(1UL + pcTop) * clkDiv));
298 
299  return calcScanFreq;
300 }
301 
302 
303 /***************************************************************************/
330  bool start)
331 {
332  uint32_t tmp; /* temporary storage of the CTRL register value */
333 
334 
335  /* Save the CTRL register value to tmp.
336  * Please be aware the effects of the non-atomic Read-Modify-Write cycle! */
337  tmp = LESENSE->CTRL & ~(_LESENSE_CTRL_SCANMODE_MASK);
338  /* Setting the requested scanMode to the CTRL register. Casting signed int
339  * (enum) to unsigned long (uint32_t). */
340  tmp |= (uint32_t)scanMode;
341 
342  /* Write the new value to the CTRL register. */
343  LESENSE->CTRL = tmp;
344 
345  /* Start sensor scanning if requested. */
346  if (start)
347  {
349  }
350 }
351 
352 
353 /***************************************************************************/
371 void LESENSE_StartDelaySet(uint8_t startDelay)
372 {
373  uint32_t tmp; /* temporary storage of the TIMCTRL register value */
374 
375 
376  /* Sanity check of startDelay. */
377  EFM_ASSERT(startDelay < 4U);
378 
379  /* Save the TIMCTRL register value to tmp.
380  * Please be aware the effects of the non-atomic Read-Modify-Write cycle! */
381  tmp = LESENSE->TIMCTRL & ~(_LESENSE_TIMCTRL_STARTDLY_MASK);
382  /* Setting the requested startDelay to the TIMCTRL register. */
383  tmp |= (uint32_t)startDelay << _LESENSE_TIMCTRL_STARTDLY_SHIFT;
384 
385  /* Write the new value to the TIMCTRL register. */
386  LESENSE->TIMCTRL = tmp;
387 }
388 
389 
390 /***************************************************************************/
416 {
417  uint32_t tmp;
418 
419 
420  /* Select clock to prescale */
421  switch (clk)
422  {
423  case lesenseClkHF:
424  /* Sanity check of clock divisor for HF clock. */
425  EFM_ASSERT((uint32_t)clkDiv <= lesenseClkDiv_8);
426 
427  /* Clear current AUXPRESC settings. */
428  tmp = LESENSE->TIMCTRL & ~(_LESENSE_TIMCTRL_AUXPRESC_MASK);
429 
430  /* Set new values in tmp while reserving other settings. */
431  tmp |= ((uint32_t)clkDiv << _LESENSE_TIMCTRL_AUXPRESC_SHIFT);
432 
433  /* Set values in LESENSE_TIMCTRL register. */
434  LESENSE->TIMCTRL = tmp;
435  break;
436 
437  case lesenseClkLF:
438  /* Clear current LFPRESC settings. */
439  tmp = LESENSE->TIMCTRL & ~(_LESENSE_TIMCTRL_LFPRESC_MASK);
440 
441  /* Set new values in tmp while reserving other settings. */
442  tmp |= ((uint32_t)clkDiv << _LESENSE_TIMCTRL_LFPRESC_SHIFT);
443 
444  /* Set values in LESENSE_TIMCTRL register. */
445  LESENSE->TIMCTRL = tmp;
446  break;
447 
448  default:
449  EFM_ASSERT(0);
450  break;
451  }
452 }
453 
454 
455 /***************************************************************************/
477 {
478  uint32_t i;
479 
480  /* Iterate through all the 16 channels */
481  for (i = 0U; i < LESENSE_NUM_CHANNELS; ++i)
482  {
483  /* Configure scan channels. */
484  LESENSE_ChannelConfig(&confChAll->Ch[i], i);
485  }
486 }
487 
488 
489 /***************************************************************************/
512  uint32_t chIdx)
513 {
514  uint32_t tmp; /* Service variable. */
515 
516 
517  /* Sanity check of configuration parameters */
518  EFM_ASSERT(chIdx < LESENSE_NUM_CHANNELS);
521 #if defined(_SILICON_LABS_32B_SERIES_0)
522  // Sample delay on other devices are 8 bits which fits perfectly in uint8_t
524 #endif
525 
526  /* Not a complete assert, as the max. value of acmpThres depends on other
527  * configuration parameters, check the parameter description of acmpThres for
528  * for more details! */
529  EFM_ASSERT(confCh->acmpThres < 4096U);
530  if (confCh->chPinExMode == lesenseChPinExDACOut)
531  {
532  EFM_ASSERT((0x1 << chIdx) & DACOUT_SUPPORT);
533  }
534 
535 #if defined(_LESENSE_IDLECONF_CH0_DACCH0)
536  EFM_ASSERT(!(confCh->chPinIdleMode == lesenseChPinIdleDACCh1
537  && ((chIdx != 12U)
538  && (chIdx != 13U)
539  && (chIdx != 14U)
540  && (chIdx != 15U))));
541  EFM_ASSERT(!(confCh->chPinIdleMode == lesenseChPinIdleDACCh0
542  && ((chIdx != 0U)
543  && (chIdx != 1U)
544  && (chIdx != 2U)
545  && (chIdx != 3U))));
546 #endif
547 
548  /* Configure chIdx setup in LESENSE idle phase.
549  * Read-modify-write in order to support reconfiguration during LESENSE
550  * operation. */
551  tmp = (LESENSE->IDLECONF & ~((uint32_t)0x3UL << (chIdx * 2UL)));
552  tmp |= ((uint32_t)confCh->chPinIdleMode << (chIdx * 2UL));
553  LESENSE->IDLECONF = tmp;
554 
555  /* Channel specific timing configuration on scan channel chIdx.
556  * Set excitation time, sampling delay, measurement delay. */
558  confCh->exTime,
559  confCh->sampleDelay,
560  confCh->measDelay);
561 
562  /* Channel specific configuration of clocks, sample mode, excitation pin mode
563  * alternate excitation usage and interrupt mode on scan channel chIdx in
564  * LESENSE_CHchIdx_INTERACT. */
565  LESENSE->CH[chIdx].INTERACT =
566  ((uint32_t)confCh->exClk << _LESENSE_CH_INTERACT_EXCLK_SHIFT)
567  | ((uint32_t)confCh->sampleClk << _LESENSE_CH_INTERACT_SAMPLECLK_SHIFT)
568  | (uint32_t)confCh->sampleMode
569  | (uint32_t)confCh->intMode
570  | (uint32_t)confCh->chPinExMode
571  | ((uint32_t)confCh->useAltEx << _LESENSE_CH_INTERACT_ALTEX_SHIFT);
572 
573  /* Configure channel specific counter comparison mode, optional result
574  * forwarding to decoder, optional counter value storing and optional result
575  * inverting on scan channel chIdx in LESENSE_CHchIdx_EVAL. */
576  LESENSE->CH[chIdx].EVAL =
577  (uint32_t)confCh->compMode
578  | ((uint32_t)confCh->shiftRes << _LESENSE_CH_EVAL_DECODE_SHIFT)
579  | ((uint32_t)confCh->storeCntRes << _LESENSE_CH_EVAL_STRSAMPLE_SHIFT)
580  | ((uint32_t)confCh->invRes << _LESENSE_CH_EVAL_SCANRESINV_SHIFT)
581 #if defined(_LESENSE_CH_EVAL_MODE_MASK)
582  | ((uint32_t)confCh->evalMode << _LESENSE_CH_EVAL_MODE_SHIFT)
583 #endif
584  ;
585 
586  /* Configure analog comparator (ACMP) threshold and decision threshold for
587  * counter separately with the function provided for that. */
589  confCh->acmpThres,
590  confCh->cntThres);
591 
592  /* Enable/disable interrupts on channel */
593  BUS_RegBitWrite(&LESENSE->IEN, chIdx, confCh->enaInt);
594 
595  /* Enable/disable CHchIdx pin. */
596  BUS_RegBitWrite(&GENERIC_LESENSE_ROUTE, chIdx, confCh->enaPin);
597 
598  /* Enable/disable scan channel chIdx. */
599  BUS_RegBitWrite(&LESENSE->CHEN, chIdx, confCh->enaScanCh);
600 }
601 
602 
603 /***************************************************************************/
621 {
622  uint32_t i;
623  uint32_t tmp;
624 
625 
626  /* Configure alternate excitation mapping.
627  * Atomic read-modify-write using BUS_RegBitWrite function in order to
628  * support reconfiguration during LESENSE operation. */
629  BUS_RegBitWrite(&LESENSE->CTRL,
631  confAltEx->altExMap);
632 
633  switch (confAltEx->altExMap)
634  {
636  /* Iterate through the 8 possible alternate excitation pin descriptors. */
637  for (i = 0U; i < 8U; ++i)
638  {
639  /* Enable/disable alternate excitation pin i.
640  * Atomic read-modify-write using BUS_RegBitWrite function in order to
641  * support reconfiguration during LESENSE operation. */
642  BUS_RegBitWrite(&GENERIC_LESENSE_ROUTE,
643  (16UL + i),
644  confAltEx->AltEx[i].enablePin);
645 
646  /* Setup the idle phase state of alternate excitation pin i.
647  * Read-modify-write in order to support reconfiguration during LESENSE
648  * operation. */
649  tmp = (LESENSE->ALTEXCONF & ~((uint32_t)0x3UL << (i * 2UL)));
650  tmp |= ((uint32_t)confAltEx->AltEx[i].idleConf << (i * 2UL));
651  LESENSE->ALTEXCONF = tmp;
652 
653  /* Enable/disable always excite on channel i */
654  BUS_RegBitWrite(&LESENSE->ALTEXCONF,
655  (16UL + i),
656  confAltEx->AltEx[i].alwaysEx);
657  }
658  break;
659 
660 #if defined(_LESENSE_CTRL_ALTEXMAP_ACMP)
661  case lesenseAltExMapACMP:
662 #else
663  case lesenseAltExMapCH:
664 #endif
665  /* Iterate through all the 16 alternate excitation channels */
666  for (i = 0U; i < 16U; ++i)
667  {
668  /* Enable/disable alternate ACMP excitation channel pin i. */
669  /* Atomic read-modify-write using BUS_RegBitWrite function in order to
670  * support reconfiguration during LESENSE operation. */
671  BUS_RegBitWrite(&GENERIC_LESENSE_ROUTE,
672  i,
673  confAltEx->AltEx[i].enablePin);
674  }
675  break;
676  default:
677  /* Illegal value. */
678  EFM_ASSERT(0);
679  break;
680  }
681 }
682 
683 
684 /***************************************************************************/
708 void LESENSE_ChannelEnable(uint8_t chIdx,
709  bool enaScanCh,
710  bool enaPin)
711 {
712  /* Enable/disable the assigned pin of scan channel chIdx.
713  * Note: BUS_RegBitWrite() function is used for setting/clearing single
714  * bit peripheral register bitfields. Read the function description in
715  * em_bus.h for more details. */
716  BUS_RegBitWrite(&GENERIC_LESENSE_ROUTE, chIdx, enaPin);
717 
718  /* Enable/disable scan channel chIdx. */
719  BUS_RegBitWrite(&LESENSE->CHEN, chIdx, enaScanCh);
720 }
721 
722 
723 /***************************************************************************/
745 void LESENSE_ChannelEnableMask(uint16_t chMask, uint16_t pinMask)
746 {
747  /* Enable/disable all channels at once according to the mask. */
748  LESENSE->CHEN = chMask;
749  /* Enable/disable all channel pins at once according to the mask. */
750  GENERIC_LESENSE_ROUTE = pinMask;
751 }
752 
753 
754 /***************************************************************************/
782 void LESENSE_ChannelTimingSet(uint8_t chIdx,
783  uint8_t exTime,
784  uint8_t sampleDelay,
785  uint16_t measDelay)
786 {
787  /* Sanity check of parameters. */
790 #if defined(_SILICON_LABS_32B_SERIES_0)
791  // Sample delay on other devices are 8 bits which fits perfectly in uint8_t
793 #endif
794 
795  /* Channel specific timing configuration on scan channel chIdx.
796  * Setting excitation time, sampling delay, measurement delay. */
797  LESENSE->CH[chIdx].TIMING =
798  ((uint32_t)exTime << _LESENSE_CH_TIMING_EXTIME_SHIFT)
799  | ((uint32_t)sampleDelay << _LESENSE_CH_TIMING_SAMPLEDLY_SHIFT)
800  | ((uint32_t)measDelay << _LESENSE_CH_TIMING_MEASUREDLY_SHIFT);
801 }
802 
803 
804 /***************************************************************************/
837 void LESENSE_ChannelThresSet(uint8_t chIdx,
838  uint16_t acmpThres,
839  uint16_t cntThres)
840 {
841  uint32_t tmp; /* temporary storage */
842 
843 
844  /* Sanity check for acmpThres only, cntThres is 16bit value. */
845  EFM_ASSERT(acmpThres < 4096U);
846  /* Sanity check for LESENSE channel id. */
847  EFM_ASSERT(chIdx < LESENSE_NUM_CHANNELS);
848 
849  /* Save the INTERACT register value of channel chIdx to tmp.
850  * Please be aware the effects of the non-atomic Read-Modify-Write cycle! */
851  tmp = LESENSE->CH[chIdx].INTERACT & ~(0xFFF);
852  /* Set the ACMP threshold value to the INTERACT register of channel chIdx. */
853  tmp |= (uint32_t)acmpThres;
854  /* Write the new value to the INTERACT register. */
855  LESENSE->CH[chIdx].INTERACT = tmp;
856 
857  /* Save the EVAL register value of channel chIdx to tmp.
858  * Please be aware the effects of the non-atomic Read-Modify-Write cycle! */
859  tmp = LESENSE->CH[chIdx].EVAL & ~(_LESENSE_CH_EVAL_COMPTHRES_MASK);
860  /* Set the counter threshold value to the INTERACT register of channel chIdx. */
861  tmp |= (uint32_t)cntThres << _LESENSE_CH_EVAL_COMPTHRES_SHIFT;
862  /* Write the new value to the EVAL register. */
863  LESENSE->CH[chIdx].EVAL = tmp;
864 }
865 
866 #if defined(_LESENSE_CH_EVAL_MODE_MASK)
867 /***************************************************************************/
892 void LESENSE_ChannelSlidingWindow(uint8_t chIdx,
893  uint32_t windowSize,
894  uint32_t initValue)
895 {
896  LESENSE_CH_TypeDef * ch = &LESENSE->CH[chIdx];
897 
898  LESENSE_WindowSizeSet(windowSize);
899  ch->EVAL = (ch->EVAL & ~(_LESENSE_CH_EVAL_COMPTHRES_MASK | _LESENSE_CH_EVAL_MODE_MASK))
900  | (initValue << _LESENSE_CH_EVAL_COMPTHRES_SHIFT)
901  | LESENSE_CH_EVAL_MODE_SLIDINGWIN;
902 }
903 
904 /***************************************************************************/
929 void LESENSE_ChannelStepDetection(uint8_t chIdx,
930  uint32_t stepSize,
931  uint32_t initValue)
932 {
933  LESENSE_CH_TypeDef * ch = &LESENSE->CH[chIdx];
934 
935  LESENSE_StepSizeSet(stepSize);
936  ch->EVAL = (ch->EVAL & ~(_LESENSE_CH_EVAL_COMPTHRES_MASK | _LESENSE_CH_EVAL_MODE_MASK))
937  | (initValue << _LESENSE_CH_EVAL_COMPTHRES_SHIFT)
938  | LESENSE_CH_EVAL_MODE_STEPDET;
939 }
940 
941 /***************************************************************************/
958 void LESENSE_WindowSizeSet(uint32_t windowSize)
959 {
960  LESENSE->EVALCTRL = (LESENSE->EVALCTRL & ~_LESENSE_EVALCTRL_WINSIZE_MASK)
961  | windowSize;
962 }
963 
964 /***************************************************************************/
977 void LESENSE_StepSizeSet(uint32_t stepSize)
978 {
979  LESENSE_WindowSizeSet(stepSize);
980 }
981 #endif
982 
983 /***************************************************************************/
1000 {
1001  uint32_t i;
1002 
1003  /* Iterate through all the 16 or 32 decoder states. */
1004  for (i = 0U; i < LESENSE_NUM_DECODER_STATES; ++i)
1005  {
1006  /* Configure decoder state i. */
1007  LESENSE_DecoderStateConfig(&confDecStAll->St[i], i);
1008  }
1009 }
1010 
1011 
1012 /***************************************************************************/
1028  uint32_t decSt)
1029 {
1030  /* Sanity check of configuration parameters */
1031  EFM_ASSERT(decSt < LESENSE_NUM_DECODER_STATES);
1032  EFM_ASSERT((uint32_t)confDecSt->confA.compMask < 16U);
1033  EFM_ASSERT((uint32_t)confDecSt->confA.compVal < 16U);
1034  EFM_ASSERT((uint32_t)confDecSt->confA.nextState < LESENSE_NUM_DECODER_STATES);
1035  EFM_ASSERT((uint32_t)confDecSt->confB.compMask < 16U);
1036  EFM_ASSERT((uint32_t)confDecSt->confB.compVal < 16U);
1037  EFM_ASSERT((uint32_t)confDecSt->confB.nextState < LESENSE_NUM_DECODER_STATES);
1038 
1039  /* Configure state descriptor A (LESENSE_STi_TCONFA) for decoder state i.
1040  * Setting sensor compare value, sensor mask, next state index,
1041  * transition action, interrupt flag option and state descriptor chaining
1042  * configurations. */
1043  LESENSE->ST[decSt].TCONFA =
1044  (uint32_t)confDecSt->confA.prsAct
1045  | ((uint32_t)confDecSt->confA.compMask << _LESENSE_ST_TCONFA_MASK_SHIFT)
1046  | ((uint32_t)confDecSt->confA.compVal << _LESENSE_ST_TCONFA_COMP_SHIFT)
1047  | ((uint32_t)confDecSt->confA.nextState << _LESENSE_ST_TCONFA_NEXTSTATE_SHIFT)
1048  | ((uint32_t)confDecSt->confA.setInt << _LESENSE_ST_TCONFA_SETIF_SHIFT)
1049  | ((uint32_t)confDecSt->chainDesc << _LESENSE_ST_TCONFA_CHAIN_SHIFT);
1050 
1051  /* Configure state descriptor Bi (LESENSE_STi_TCONFB).
1052  * Setting sensor compare value, sensor mask, next state index, transition
1053  * action and interrupt flag option configurations. */
1054  LESENSE->ST[decSt].TCONFB =
1055  (uint32_t)confDecSt->confB.prsAct
1056  | ((uint32_t)confDecSt->confB.compMask << _LESENSE_ST_TCONFB_MASK_SHIFT)
1057  | ((uint32_t)confDecSt->confB.compVal << _LESENSE_ST_TCONFB_COMP_SHIFT)
1058  | ((uint32_t)confDecSt->confB.nextState << _LESENSE_ST_TCONFB_NEXTSTATE_SHIFT)
1059  | ((uint32_t)confDecSt->confB.setInt << _LESENSE_ST_TCONFB_SETIF_SHIFT);
1060 }
1061 
1062 
1063 /***************************************************************************/
1079 void LESENSE_DecoderStateSet(uint32_t decSt)
1080 {
1081  EFM_ASSERT(decSt <= _LESENSE_DECSTATE_DECSTATE_MASK);
1082 
1083  LESENSE->DECSTATE = decSt & _LESENSE_DECSTATE_DECSTATE_MASK;
1084 }
1085 
1086 
1087 /***************************************************************************/
1096 {
1097  return LESENSE->DECSTATE & _LESENSE_DECSTATE_DECSTATE_MASK;
1098 }
1099 
1100 #if defined(_LESENSE_PRSCTRL_MASK)
1101 /***************************************************************************/
1115 void LESENSE_DecoderPrsOut(bool enable, uint32_t decMask, uint32_t decVal)
1116 {
1117  LESENSE->PRSCTRL = (enable << _LESENSE_PRSCTRL_DECCMPEN_SHIFT)
1118  | (decMask << _LESENSE_PRSCTRL_DECCMPMASK_SHIFT)
1119  | (decVal << _LESENSE_PRSCTRL_DECCMPVAL_SHIFT);
1120 }
1121 #endif
1122 
1123 /***************************************************************************/
1137 {
1138  /* Wait for any pending previous write operation to the CMD register to
1139  complete before accessing the CMD register. */
1140  while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
1141  ;
1142 
1143  /* Start scanning of sensors */
1144  LESENSE->CMD = LESENSE_CMD_START;
1145 
1146  /* Wait for the write operation to the CMD register to complete before
1147  returning. */
1148  while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
1149  ;
1150 }
1151 
1152 
1153 /***************************************************************************/
1170 {
1171  /* Wait for any pending previous write operation to the CMD register to
1172  complete before accessing the CMD register. */
1173  while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
1174  ;
1175 
1176  /* Stop scanning of sensors */
1177  LESENSE->CMD = LESENSE_CMD_STOP;
1178 
1179  /* Wait for the write operation to the CMD register to complete before
1180  returning. */
1181  while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
1182  ;
1183 }
1184 
1185 
1186 /***************************************************************************/
1200 {
1201  /* Wait for any pending previous write operation to the CMD register to
1202  complete before accessing the CMD register. */
1203  while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
1204  ;
1205 
1206  /* Start decoder */
1207  LESENSE->CMD = LESENSE_CMD_DECODE;
1208 
1209  /* Wait for the write operation to the CMD register to complete before
1210  returning. */
1211  while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
1212  ;
1213 }
1214 
1215 
1216 /***************************************************************************/
1230 {
1231  /* Wait for any pending previous write operation to the CMD register to
1232  complete before accessing the CMD register. */
1233  while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
1234  ;
1235 
1237 
1238  /* Wait for the write operation to the CMD register to complete before
1239  returning. */
1240  while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
1241  ;
1242 }
1243 
1244 
1245 /***************************************************************************/
1258 void LESENSE_Reset(void)
1259 {
1260  uint32_t i;
1261 
1262  /* Disable all LESENSE interrupts first */
1264 
1265  /* Clear all pending LESENSE interrupts */
1266  LESENSE->IFC = _LESENSE_IFC_MASK;
1267 
1268  /* Stop the decoder */
1269  LESENSE->DECCTRL |= LESENSE_DECCTRL_DISABLE;
1270 
1271  /* Wait for any pending previous write operation to the CMD register to
1272  complete before accessing the CMD register. */
1273  while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
1274  ;
1275 
1276  /* Stop sensor scan and clear result buffer */
1278 
1279  /* Reset LESENSE configuration registers */
1284 #if defined(_LESENSE_EVALCTRL_MASK)
1285  LESENSE->EVALCTRL = _LESENSE_EVALCTRL_RESETVALUE;
1286  LESENSE->PRSCTRL = _LESENSE_PRSCTRL_RESETVALUE;
1287 #endif
1291 
1292  /* Disable LESENSE to control GPIO pins */
1293 #if defined(_LESENSE_ROUTE_MASK)
1295 #else
1296  LESENSE->ROUTEPEN = _LESENSE_ROUTEPEN_RESETVALUE;
1297 #endif
1298 
1299  /* Reset all channel configuration registers */
1300  for (i = 0U; i < LESENSE_NUM_CHANNELS; ++i)
1301  {
1302  LESENSE->CH[i].TIMING = _LESENSE_CH_TIMING_RESETVALUE;
1303  LESENSE->CH[i].INTERACT = _LESENSE_CH_INTERACT_RESETVALUE;
1304  LESENSE->CH[i].EVAL = _LESENSE_CH_EVAL_RESETVALUE;
1305  }
1306 
1307  /* Reset all decoder state configuration registers */
1308  for (i = 0U; i < LESENSE_NUM_DECODER_STATES; ++i)
1309  {
1310  LESENSE->ST[i].TCONFA = _LESENSE_ST_TCONFA_RESETVALUE;
1311  LESENSE->ST[i].TCONFB = _LESENSE_ST_TCONFB_RESETVALUE;
1312  }
1313 
1314  /* Wait for the write operation to the CMD register to complete before
1315  returning. */
1316  while (LESENSE_SYNCBUSY_CMD & LESENSE->SYNCBUSY)
1317  ;
1318 }
1319 
1320 
1324 #endif /* defined(LESENSE_COUNT) && (LESENSE_COUNT > 0) */
#define _LESENSE_CH_EVAL_STRSAMPLE_SHIFT
Clock management unit (CMU) API.
#define LESENSE_CMD_DECODE
LESENSE_PRSSel_TypeDef prsChSel3
Definition: em_lesense.h:745
LESENSE_TimeCtrlDesc_TypeDef timeCtrl
Definition: em_lesense.h:774
void LESENSE_AltExConfig(const LESENSE_ConfAltEx_TypeDef *confAltEx)
Configure the LESENSE alternate excitation modes.
Definition: em_lesense.c:620
LESENSE_ControlACMP_TypeDef acmp1Mode
Definition: em_lesense.h:658
#define LESENSE_NUM_CHANNELS
Definition: em_lesense.h:61
#define _LESENSE_ST_TCONFA_RESETVALUE
#define _LESENSE_CH_INTERACT_ALTEX_SHIFT
#define _LESENSE_CTRL_BUFOW_SHIFT
void LESENSE_DecoderStart(void)
Start LESENSE decoder.
Definition: em_lesense.c:1199
Emlib peripheral API "assert" implementation.
LESENSE_ControlDACData_TypeDef dacCh0Data
Definition: em_lesense.h:621
#define _LESENSE_ST_TCONFB_NEXTSTATE_SHIFT
LESENSE_DecStCond_TypeDef confA
Definition: em_lesense.h:1108
RAM and peripheral bit-field set and clear API.
LESENSE_DecCtrlDesc_TypeDef decCtrl
Definition: em_lesense.h:780
LESENSE_ControlDACData_TypeDef dacCh1Data
Definition: em_lesense.h:632
LESENSE_ChPinIdleMode_TypeDef chPinIdleMode
Definition: em_lesense.h:811
void LESENSE_Init(const LESENSE_Init_TypeDef *init, bool reqReset)
Initialize the LESENSE module.
Definition: em_lesense.c:118
LESENSE_ChDesc_TypeDef Ch[LESENSE_NUM_CHANNELS]
Definition: em_lesense.h:884
void LESENSE_Reset(void)
Reset the LESENSE module.
Definition: em_lesense.c:1258
#define _LESENSE_CHEN_RESETVALUE
#define LESENSE_CMD_CLEARBUF
void LESENSE_ResultBufferClear(void)
Clear result buffer.
Definition: em_lesense.c:1229
void LESENSE_ChannelThresSet(uint8_t chIdx, uint16_t acmpThres, uint16_t cntThres)
Set LESENSE channel threshold parameters.
Definition: em_lesense.c:837
#define _LESENSE_CTRL_DEBUGRUN_SHIFT
#define _LESENSE_ST_TCONFA_NEXTSTATE_SHIFT
#define _LESENSE_TIMCTRL_LFPRESC_MASK
void LESENSE_ScanModeSet(LESENSE_ScanMode_TypeDef scanMode, bool start)
Set scan mode of the LESENSE channels.
Definition: em_lesense.c:329
LESENSE_AltExDesc_TypeDef AltEx[16]
Definition: em_lesense.h:1002
LESENSE_CH EFM32GG LESENSE CH.
LESENSE_PRSSel_TypeDef prsChSel0
Definition: em_lesense.h:736
#define _LESENSE_ST_TCONFA_SETIF_SHIFT
#define _LESENSE_CH_INTERACT_EXCLK_SHIFT
#define _LESENSE_CH_EVAL_COMPTHRES_MASK
LESENSE_ClkPresc_TypeDef
Definition: em_lesense.h:71
LESENSE_ControlDACOut_TypeDef dacCh0OutMode
Definition: em_lesense.h:628
#define _LESENSE_TIMCTRL_PCPRESC_SHIFT
#define _LESENSE_CTRL_PRSSEL_SHIFT
void LESENSE_DecoderStateSet(uint32_t decSt)
Set LESENSE decoder state.
Definition: em_lesense.c:1079
#define _LESENSE_CTRL_ALTEXMAP_SHIFT
#define _LESENSE_DECCTRL_PRSSEL2_SHIFT
#define LESENSE_SYNCBUSY_CMD
#define _LESENSE_PERCTRL_ACMP1MODE_SHIFT
LESENSE_PRSSel_TypeDef prsSel
Definition: em_lesense.h:543
LESENSE_DecStDesc_TypeDef St[LESENSE_NUM_DECODER_STATES]
Definition: em_lesense.h:1120
#define _LESENSE_ALTEXCONF_RESETVALUE
LESENSE_ChClk_TypeDef exClk
Definition: em_lesense.h:828
#define _LESENSE_CH_TIMING_SAMPLEDLY_SHIFT
#define _LESENSE_CTRL_DUALSAMPLE_SHIFT
#define _LESENSE_ST_TCONFB_COMP_SHIFT
#define _LESENSE_IFC_MASK
#define _LESENSE_IEN_RESETVALUE
void LESENSE_ChannelTimingSet(uint8_t chIdx, uint8_t exTime, uint8_t sampleDelay, uint16_t measDelay)
Set LESENSE channel timing parameters.
Definition: em_lesense.c:782
#define _LESENSE_ST_TCONFA_MASK_SHIFT
#define _LESENSE_DECCTRL_ERRCHK_SHIFT
uint32_t LESENSE_ScanFreqSet(uint32_t refFreq, uint32_t scanFreq)
Set scan frequency for periodic scanning.
Definition: em_lesense.c:247
#define LESENSE_CMD_START
#define _LESENSE_CH_TIMING_EXTIME_MASK
#define _LESENSE_DECCTRL_HYSTPRS1_SHIFT
#define _LESENSE_PERCTRL_DACCH1DATA_SHIFT
LESENSE_DMAWakeUp_TypeDef wakeupOnDMA
Definition: em_lesense.h:569
#define _LESENSE_CTRL_SCANMODE_MASK
LESENSE_ControlDACConv_TypeDef dacCh1ConvMode
Definition: em_lesense.h:636
#define _LESENSE_ST_TCONFA_CHAIN_SHIFT
#define _LESENSE_TIMCTRL_AUXPRESC_MASK
#define _LESENSE_CH_TIMING_SAMPLEDLY_MASK
#define _LESENSE_DECCTRL_INTMAP_SHIFT
#define _LESENSE_TIMCTRL_PCTOP_MASK
#define LESENSE_CMD_STOP
#define _LESENSE_CH_INTERACT_RESETVALUE
LESENSE_ChCompMode_TypeDef compMode
Definition: em_lesense.h:870
void LESENSE_ClkDivSet(LESENSE_ChClk_TypeDef clk, LESENSE_ClkPresc_TypeDef clkDiv)
Set clock division for LESENSE timers.
Definition: em_lesense.c:414
#define _LESENSE_TIMCTRL_PCTOP_SHIFT
#define _LESENSE_IDLECONF_RESETVALUE
LESENSE_PRSSel_TypeDef prsChSel2
Definition: em_lesense.h:742
#define _LESENSE_ST_TCONFB_MASK_SHIFT
#define LESENSE_NUM_DECODER_STATES
Definition: em_lesense.h:58
LESENSE_DACRef_TypeDef dacRef
Definition: em_lesense.h:651
#define _LESENSE_PERCTRL_DACCH1OUT_SHIFT
void LESENSE_ChannelAllConfig(const LESENSE_ChAll_TypeDef *confChAll)
Configure all (16) LESENSE sensor channels.
Definition: em_lesense.c:476
#define _LESENSE_DECCTRL_HYSTIRQ_SHIFT
#define _LESENSE_TIMCTRL_LFPRESC_SHIFT
#define _LESENSE_CH_TIMING_MEASUREDLY_SHIFT
#define _LESENSE_DECCTRL_PRSSEL3_SHIFT
LESENSE_PerCtrlDesc_TypeDef perCtrl
Definition: em_lesense.h:777
#define _LESENSE_CTRL_ACMP0INV_MASK
void LESENSE_ChannelConfig(const LESENSE_ChDesc_TypeDef *confCh, uint32_t chIdx)
Configure a single LESENSE sensor channel.
Definition: em_lesense.c:511
#define _LESENSE_TIMCTRL_STARTDLY_MASK
#define LESENSE
LESENSE_ScanConfSel_TypeDef scanConfSel
Definition: em_lesense.h:546
uint32_t LESENSE_DecoderStateGet(void)
Get the current state of the LESENSE decoder.
Definition: em_lesense.c:1095
#define _LESENSE_CTRL_ACMP0INV_SHIFT
#define _LESENSE_DECCTRL_HYSTPRS0_SHIFT
LESENSE_ControlACMP_TypeDef acmp0Mode
Definition: em_lesense.h:655
void LESENSE_ChannelEnable(uint8_t chIdx, bool enaScanCh, bool enaPin)
Enable/disable LESENSE scan channel and the pin assigned to it.
Definition: em_lesense.c:708
#define _LESENSE_PERCTRL_ACMP0MODE_SHIFT
#define _LESENSE_PERCTRL_DACCH1CONV_SHIFT
#define _LESENSE_DECCTRL_PRSSEL1_SHIFT
LESENSE_ControlDACConv_TypeDef dacCh0ConvMode
Definition: em_lesense.h:625
LESENSE_ControlDACOut_TypeDef dacCh1OutMode
Definition: em_lesense.h:639
#define _LESENSE_CH_EVAL_SCANRESINV_SHIFT
#define _LESENSE_CH_EVAL_DECODE_SHIFT
LESENSE_DecStCond_TypeDef confB
Definition: em_lesense.h:1112
LESENSE_ChClk_TypeDef sampleClk
Definition: em_lesense.h:831
LESENSE_CoreCtrlDesc_TypeDef coreCtrl
Definition: em_lesense.h:771
LESENSE_ScanMode_TypeDef scanStart
Definition: em_lesense.h:540
#define _LESENSE_CH_TIMING_RESETVALUE
#define _LESENSE_TIMCTRL_AUXPRESC_SHIFT
#define _LESENSE_PERCTRL_DACCH0DATA_SHIFT
LESENSE_AltExMap_TypeDef altExMap
Definition: em_lesense.h:988
#define _LESENSE_CTRL_ACMP1INV_SHIFT
#define _LESENSE_DECCTRL_PRSSEL0_SHIFT
LESENSE_ScanMode_TypeDef
Definition: em_lesense.h:85
#define _LESENSE_PERCTRL_DACCH0CONV_SHIFT
#define _LESENSE_CH_EVAL_COMPTHRES_SHIFT
void LESENSE_DecoderStateConfig(const LESENSE_DecStDesc_TypeDef *confDecSt, uint32_t decSt)
Configure a single LESENSE decoder state.
Definition: em_lesense.c:1027
#define _LESENSE_PERCTRL_DACCH0OUT_SHIFT
#define _LESENSE_BIASCTRL_RESETVALUE
#define _LESENSE_CH_EVAL_RESETVALUE
LESENSE_DecInput_TypeDef decInput
Definition: em_lesense.h:702
#define _LESENSE_CTRL_RESETVALUE
#define _LESENSE_CH_INTERACT_SAMPLECLK_SHIFT
#define _LESENSE_TIMCTRL_STARTDLY_SHIFT
Low Energy Sensor (LESENSE) peripheral API.
LESENSE_WarmupMode_TypeDef warmupMode
Definition: em_lesense.h:661
LESENSE_StTransAct_TypeDef prsAct
Definition: em_lesense.h:1082
LESENSE_BiasMode_TypeDef biasMode
Definition: em_lesense.h:572
LESENSE_AltExPinIdle_TypeDef idleConf
Definition: em_lesense.h:971
#define _LESENSE_PERCTRL_DACPRESC_SHIFT
void LESENSE_ChannelEnableMask(uint16_t chMask, uint16_t pinMask)
Enable/disable LESENSE scan channel and the pin assigned to it.
Definition: em_lesense.c:745
__STATIC_INLINE void BUS_RegBitWrite(volatile uint32_t *addr, unsigned int bit, unsigned int val)
Perform a single-bit write operation on a peripheral register.
Definition: em_bus.h:148
void LESENSE_StartDelaySet(uint8_t startDelay)
Set start delay of sensor interaction on each channel.
Definition: em_lesense.c:371
void LESENSE_ScanStart(void)
Start scanning of sensors.
Definition: em_lesense.c:1136
#define _LESENSE_DECCTRL_RESETVALUE
#define _LESENSE_ST_TCONFA_COMP_SHIFT
void LESENSE_ScanStop(void)
Stop scanning of sensors.
Definition: em_lesense.c:1169
#define _LESENSE_TIMCTRL_PCPRESC_MASK
uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
Get clock frequency for a clock point.
Definition: em_cmu.c:1550
#define _LESENSE_ROUTE_RESETVALUE
#define _LESENSE_PERCTRL_RESETVALUE
#define LESENSE_DECCTRL_DISABLE
#define _LESENSE_ST_TCONFB_SETIF_SHIFT
#define _LESENSE_DECCTRL_PRSCNT_SHIFT
#define _LESENSE_CTRL_STRSCANRES_SHIFT
LESENSE_ChClk_TypeDef
Definition: em_lesense.h:423
#define _LESENSE_DECCTRL_HYSTPRS2_SHIFT
#define _LESENSE_CH_TIMING_MEASUREDLY_MASK
LESENSE_ChIntMode_TypeDef intMode
Definition: em_lesense.h:863
LESENSE_ChPinExMode_TypeDef chPinExMode
Definition: em_lesense.h:808
LESENSE_BufTrigLevel_TypeDef bufTrigLevel
Definition: em_lesense.h:566
LESENSE_PRSSel_TypeDef prsChSel1
Definition: em_lesense.h:739
#define _LESENSE_ST_TCONFB_RESETVALUE
LESENSE_ChSampleMode_TypeDef sampleMode
Definition: em_lesense.h:860
#define _LESENSE_CH_TIMING_EXTIME_SHIFT
#define _LESENSE_DECSTATE_DECSTATE_MASK
void LESENSE_DecoderStateAllConfig(const LESENSE_DecStAll_TypeDef *confDecStAll)
Configure all LESENSE decoder states.
Definition: em_lesense.c:999