/**************************************************************************//** * @brief Sets up the ACMP *****************************************************************************/ static void LETOUCH_setupACMP( void ) { /* Configuration structure for ACMP */ /* See application note document for description of the different settings. */ static const ACMP_CapsenseInit_TypeDef acmpInit = { .fullBias = true, //Configured according to application note .halfBias = true, //Configured according to application note .biasProg = 0x5, //Configured according to application note .warmTime = acmpWarmTime512, //LESENSE uses a fixed warmup time .hysteresisLevel = acmpHysteresisLevel5, //Configured according to application note .resistor = acmpResistor0, //Configured according to application note .lowPowerReferenceEnabled = false, //LP-reference can introduce glitches with captouch .vddLevel = 0x30, //Configured according to application note .enable = false //LESENSE enables the ACMP }; /* Initialize ACMP in capsense mode*/ ACMP_CapsenseInit(ACMP0, &acmpInit); ACMP_CapsenseInit(ACMP1, &acmpInit); } /**************************************************************************//** * @brief Sets up the LESENSE *****************************************************************************/ static void LETOUCH_setupLESENSE( void ) { uint8_t i; /* LESENSE configuration structure */ static const LESENSE_Init_TypeDef initLesense = { .coreCtrl = { .scanStart = lesenseScanStartPeriodic, .prsSel = lesensePRSCh0, .scanConfSel = lesenseScanConfDirMap, .invACMP0 = false, .invACMP1 = false, .dualSample = false, .storeScanRes = false, .bufOverWr = true, .bufTrigLevel = lesenseBufTrigHalf, .wakeupOnDMA = lesenseDMAWakeUpDisable, .biasMode = lesenseBiasModeDutyCycle, .debugRun = false }, .timeCtrl = { .startDelay = 0x0 }, .perCtrl =
/**************************************************************************//** * @brief Initializes the capacative sense system. * Capacative sensing uses two timers: TIMER0 and TIMER1 as well as ACMP. * ACMP is set up in cap-sense (oscialltor mode). * TIMER1 counts the number of pulses generated by ACMP_CAPSENSE. * When TIMER0 expires it generates an interrupt. * The number of pulses counted by TIMER1 is then stored in channelValues *****************************************************************************/ void CAPSENSE_Init(void) { /* Use the default STK capacative sensing setup */ ACMP_CapsenseInit_TypeDef capsenseInit = ACMP_CAPSENSE_INIT_DEFAULT; /* Enable TIMER0, TIMER1, ACMP_CAPSENSE and PRS clock */ CMU->HFPERCLKDIV |= CMU_HFPERCLKDIV_HFPERCLKEN; CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_TIMER0 | CMU_HFPERCLKEN0_TIMER1 | ACMP_CAPSENSE_CLKEN | CMU_HFPERCLKEN0_PRS; /* Initialize TIMER0 - Prescaler 2^9, top value 10, interrupt on overflow */ TIMER0->CTRL = TIMER_CTRL_PRESC_DIV512; TIMER0->TOP = 10; TIMER0->IEN = TIMER_IEN_OF; TIMER0->CNT = 0; /* Initialize TIMER1 - Prescaler 2^10, clock source CC1, top value 0xFFFF */ TIMER1->CTRL = TIMER_CTRL_PRESC_DIV1024 | TIMER_CTRL_CLKSEL_CC1; TIMER1->TOP = 0xFFFF; /*Set up TIMER1 CC1 to trigger on PRS channel 0 */ TIMER1->CC[1].CTRL = TIMER_CC_CTRL_MODE_INPUTCAPTURE /* Input capture */ | TIMER_CC_CTRL_PRSSEL_PRSCH0 /* PRS channel 0 */ | TIMER_CC_CTRL_INSEL_PRS /* PRS input selected */ | TIMER_CC_CTRL_ICEVCTRL_RISING /* PRS on rising edge */ | TIMER_CC_CTRL_ICEDGE_BOTH; /* PRS on rising edge */ /*Set up PRS channel 0 to trigger on ACMP1 output*/ PRS->CH[0].CTRL = PRS_CH_CTRL_EDSEL_POSEDGE /* Posedge triggers action */ | PRS_CH_CTRL_SOURCESEL_ACMP_CAPSENSE /* PRS source */ | PRS_CH_CTRL_SIGSEL_ACMPOUT_CAMPSENSE; /* PRS source */ /* Set up ACMP1 in capsense mode */ ACMP_CapsenseInit(ACMP_CAPSENSE, &capsenseInit); /* Enable TIMER0 interrupt */ NVIC_EnableIRQ(TIMER0_IRQn); }
/**************************************************************************//** * @brief Setup the ACMP *****************************************************************************/ void CAPLESENSE_setupACMP(void) { /* ACMP capsense configuration constant table. */ static const ACMP_CapsenseInit_TypeDef initACMP = { .fullBias = false, .halfBias = false, .biasProg = 0x7, .warmTime = acmpWarmTime512, .hysteresisLevel = acmpHysteresisLevel7, .resistor = acmpResistor0, .lowPowerReferenceEnabled = false, .vddLevel = 0x3D, .enable = false }; /* Configure ACMP locations, ACMP output to pin disabled. */ ACMP_GPIOSetup(ACMP0, 0, false, false); ACMP_GPIOSetup(ACMP1, 0, false, false); /* Initialize ACMPs in capacitive sense mode. */ ACMP_CapsenseInit(ACMP0, &initACMP); ACMP_CapsenseInit(ACMP1, &initACMP); /* Don't enable ACMP, LESENSE controls it! */ } /**************************************************************************//** * @brief Setup the LESENSE for capavitive sensing * @param sleep * If true, go into sleep mode. *****************************************************************************/ void CAPLESENSE_setupLESENSE(bool sleep) { uint8_t i; static bool init = true; /* Array for storing the calibration values. */ static uint16_t capsenseCalibrateVals[4]; /* LESENSE channel configuration constant table in sense mode. */ static const LESENSE_ChAll_TypeDef initChsSense = LESENSE_CAPSENSE_SCAN_CONF_SENSE; /* LESENSE channel configuration constant table in sleep mode. */ static const LESENSE_ChAll_TypeDef initChsSleep = LESENSE_CAPSENSE_SCAN_CONF_SLEEP; /* LESENSE central configuration constant table. */ static const LESENSE_Init_TypeDef initLESENSE = { .coreCtrl = { .scanStart = lesenseScanStartPeriodic, .prsSel = lesensePRSCh0, .scanConfSel = lesenseScanConfDirMap, .invACMP0 = false, .invACMP1 = false, .dualSample = false, .storeScanRes = false, .bufOverWr = true, .bufTrigLevel = lesenseBufTrigHalf, .wakeupOnDMA = lesenseDMAWakeUpDisable, .biasMode = lesenseBiasModeDutyCycle, .debugRun = false }, .timeCtrl = { .startDelay = 0U }, .perCtrl =