|
|
- /* --COPYRIGHT--,BSD
- * Copyright (c) 2013, Texas Instruments Incorporated
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of Texas Instruments Incorporated nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * --/COPYRIGHT--*/
- /*!
- * @file CTS_Layer.c
- *
- * @brief This source file contains the API calls and one support function.
- *
- * @par Project:
- * MSP430 Capacitive Touch Library
- *
- * @par Developed using:
- * CCS Version : 5.4.0.00048, w/support for GCC extensions (--gcc)
- * \n IAR Version : 5.51.6 [Kickstart]
- *
- * @author C. Sterzik
- * @author T. Hwang
- *
- * @version 1.2
- * Updated HALs for new devices.
- *
- * @par Supported API Calls:
- * - TI_CAPT_Init_Baseline()
- * - TI_CAPT_Update_Baseline()
- * - TI_CAPT_Reset_Tracking()
- * - TI_CAPT_Update_Tracking_DOI()
- * - TI_CAPT_Update_Tracking_Rate()
- * - TI_CAPT_Raw()
- * - TI_CAPT_Custom()
- * - TI_CAPT_Button()
- * - TI_CAPT_Buttons()
- * - TI_CAPT_Slider()
- * - TI_CAPT_Wheel()
- */
-
- #include "CTS_Layer.h"
-
- /*! @defgroup GLOBAL_VARS Global Variables
- * @{
- */
- #ifdef TOTAL_NUMBER_OF_ELEMENTS
- /*!
- * The baseline tracking variables
- */
- uint16_t baseCnt[TOTAL_NUMBER_OF_ELEMENTS];
- #ifdef RAM_FOR_FLASH
- /*!
- * The current measurement variables
- */
- uint16_t measCnt[MAXIMUM_NUMBER_OF_ELEMENTS_PER_SENSOR];
- #endif
- /*!
- * The Status Register
- */
- uint16_t ctsStatusReg = (DOI_INC+TRADOI_FAST+TRIDOI_SLOW);
- #endif
- /*!
- * @}
- */
-
- /** @defgroup CTS_API API Group
- * @{
- */
-
- /***************************************************************************//**
- * @brief Measure the capacitance of each element within the Sensor
- *
- * This function selects the appropriate HAL to perform the capacitance
- * measurement based upon the halDefinition found in the sensor
- * structure.
- * The order of the elements within the Sensor structure is arbitrary
- * but must be consistent between the application and configuration.
- * The first element in the array (counts) corresponds to the first
- * element within the Sensor structure.
- * @param groupOfElements Pointer to Sensor structure to be measured
- * @param counts Address to where the measurements are to be written
- * @return none
- ******************************************************************************/
- void TI_CAPT_Raw(const struct Sensor* groupOfElements, uint16_t * counts)
- {
- #ifdef RO_CSIO_TA2_WDTA
- if(groupOfElements->halDefinition == RO_CSIO_TA2_WDTA)
- {
- TI_CTS_RO_CSIO_TA2_WDTA_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef RO_CSIO_TA2_TA3
- if(groupOfElements->halDefinition == RO_CSIO_TA2_TA3)
- {
- TI_CTS_RO_CSIO_TA2_TA3_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef fRO_CSIO_TA2_TA3
- if(groupOfElements->halDefinition == fRO_CSIO_TA2_TA3)
- {
- TI_CTS_fRO_CSIO_TA2_TA3_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef RO_COMPB_TB0_WDTA
- if(groupOfElements->halDefinition == RO_COMPB_TB0_WDTA)
- {
- TI_CTS_RO_COMPB_TB0_WDTA_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef RO_PINOSC_TA0_TA1
- if(groupOfElements->halDefinition == RO_PINOSC_TA0_TA1)
- {
- TI_CTS_RO_PINOSC_TA0_TA1_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef fRO_PINOSC_TA0_TA1
- if(groupOfElements->halDefinition == fRO_PINOSC_TA0_TA1)
- {
- TI_CTS_fRO_PINOSC_TA0_TA1_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef RO_COMPAp_TA0_WDTp
- if(groupOfElements->halDefinition == RO_COMPAp_TA0_WDTp)
- {
- TI_CTS_RO_COMPAp_TA0_WDTp_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef fRO_COMPAp_TA0_SW
- if(groupOfElements->halDefinition == fRO_COMPAp_TA0_SW)
- {
- TI_CTS_fRO_COMPAp_TA0_SW_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef fRO_COMPAp_SW_TA0
- if(groupOfElements->halDefinition == fRO_COMPAp_SW_TA0)
- {
- TI_CTS_fRO_COMPAp_SW_TA0_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef RO_COMPAp_TA1_WDTp
- if(groupOfElements->halDefinition == RO_COMPAp_TA1_WDTp)
- {
- TI_CTS_RO_COMPAp_TA1_WDTp_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef fRO_COMPAp_TA1_SW
- if(groupOfElements->halDefinition == fRO_COMPAp_TA1_SW)
- {
- TI_CTS_fRO_COMPAp_TA1_SW_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef RC_PAIR_TA0
- if(groupOfElements->halDefinition == RC_PAIR_TA0)
- {
- TI_CTS_RC_PAIR_TA0_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef RO_PINOSC_TA0_WDTp
- if(groupOfElements->halDefinition == RO_PINOSC_TA0_WDTp)
- {
- TI_CTS_RO_PINOSC_TA0_WDTp_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef RO_PINOSC_TA0
- if(groupOfElements->halDefinition == RO_PINOSC_TA0)
- {
- TI_CTS_RO_PINOSC_TA0_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef fRO_PINOSC_TA0_SW
- if(groupOfElements->halDefinition == fRO_PINOSC_TA0_SW)
- {
- TI_CTS_fRO_PINOSC_TA0_SW_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef RO_COMPB_TA0_WDTA
- if(groupOfElements->halDefinition == RO_COMPB_TA0_WDTA)
- {
- TI_CTS_RO_COMPB_TA0_WDTA_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef fRO_COMPB_TA0_SW
- if(groupOfElements->halDefinition == fRO_COMPB_TA0_SW)
- {
- TI_CTS_fRO_COMPB_TA0_SW_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef RO_COMPB_TA1_WDTA
- if(groupOfElements->halDefinition == RO_COMPB_TA1_WDTA)
- {
- TI_CTS_RO_COMPB_TA1_WDTA_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef fRO_COMPB_TA1_SW
- if(groupOfElements->halDefinition == fRO_COMPB_TA1_SW)
- {
- TI_CTS_fRO_COMPB_TA1_SW_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef RO_COMPB_TA1_TA0
- if(groupOfElements->halDefinition == RO_COMPB_TA1_TA0)
- {
- TI_CTS_RO_COMPB_TA1_TA0_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef fRO_COMPB_TA1_TA0
- if(groupOfElements->halDefinition == fRO_COMPB_TA1_TA0)
- {
- TI_CTS_fRO_COMPB_TA1_TA0_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef RO_PINOSC_TA1_WDTp
- if(groupOfElements->halDefinition == RO_PINOSC_TA1_WDTp)
- {
- TI_CTS_RO_PINOSC_TA1_WDTp_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef RO_PINOSC_TA1_TB0
- if(groupOfElements->halDefinition == RO_PINOSC_TA1_TB0)
- {
- TI_CTS_RO_PINOSC_TA1_TB0_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef fRO_PINOSC_TA1_TA0
- if(groupOfElements->halDefinition == fRO_PINOSC_TA1_TA0)
- {
- TI_CTS_fRO_PINOSC_TA1_TA0_HAL(groupOfElements, counts);
- }
- #endif
-
- #ifdef fRO_PINOSC_TA1_TB0
- if(groupOfElements->halDefinition == fRO_PINOSC_TA1_TB0)
- {
- TI_CTS_fRO_PINOSC_TA1_TB0_HAL(groupOfElements, counts);
- }
- #endif
- }
-
- #ifdef TOTAL_NUMBER_OF_ELEMENTS
- /***************************************************************************//**
- * @brief Make a single capacitance meausrment to initialize baseline tracking
- * @param groupOfElements Pointer to Sensor structure to be measured
- * @return none
- ******************************************************************************/
- void TI_CAPT_Init_Baseline(const struct Sensor* groupOfElements)
- {
- TI_CAPT_Raw(groupOfElements, &baseCnt[groupOfElements->baseOffset]);
- }
-
- /***************************************************************************//**
- * @brief Update baseline tracking by averaging several measurements
- * @param groupOfElements Pointer to Sensor structure to be measured
- * @param numberOfAverages Number of measurements to be averaged
- * @return none
- ******************************************************************************/
- void TI_CAPT_Update_Baseline(const struct Sensor* groupOfElements, uint8_t numberOfAverages)
- {
- uint8_t i,j;
- #ifndef RAM_FOR_FLASH
- uint16_t *measCnt;
- measCnt = (uint16_t *)malloc(groupOfElements->numElements * sizeof(uint16_t));
- if(measCnt ==0)
- {
- while(1);
- }
- #endif
- for(j=0; j < numberOfAverages; j++)
- {
- for(i=0; i < groupOfElements->numElements; i++)
- {
- TI_CAPT_Raw(groupOfElements, measCnt);
- baseCnt[i+groupOfElements->baseOffset]
- = measCnt[i]/2 + baseCnt[i+groupOfElements->baseOffset]/2;
- }
- }
- #ifndef RAM_FOR_FLASH
- free(measCnt);
- #endif
- }
-
- /***************************************************************************//**
- * @brief Reset the Baseline Tracking algorithm to the default state
- * @param none
- * @return none
- ******************************************************************************/
- void TI_CAPT_Reset_Tracking(void)
- {
- ctsStatusReg = (DOI_INC+TRADOI_FAST+TRIDOI_SLOW);
- }
-
- /***************************************************************************//**
- * @brief Update the Baseline Tracking algorithm Direction of Interest
- * @param direction Direction of increasing or decreasing capacitance
- * @return none
- ******************************************************************************/
- void TI_CAPT_Update_Tracking_DOI(uint8_t direction)
- {
- if(direction)
- {
- ctsStatusReg |= DOI_INC;
- }
- else
- {
- ctsStatusReg &= ~DOI_INC;
- }
- }
-
- /***************************************************************************//**
- * @brief Update the baseling tracking algorithm tracking rates
- * @param rate Rate of tracking changes in and against direction of intrest
- * @return none
- ******************************************************************************/
- void TI_CAPT_Update_Tracking_Rate(uint8_t rate)
- {
- ctsStatusReg &= ~(TRIDOI_FAST+TRADOI_VSLOW); // clear fields
- ctsStatusReg |= (rate & 0xF0); // update fields
- }
-
- /***************************************************************************//**
- * @brief Measure the change in capacitance of the Sensor
- *
- * This function measures the change in capacitance of each element
- * within a sensor and updates the baseline tracking in the event that
- * no change exceeds the detection threshold.
- * The order of the elements within the Sensor structure is arbitrary
- * but must be consistent between the application and configuration.
- * The first element in the array (deltaCnt) corresponds to the first
- * element within the Sensor structure.
- * @param groupOfElements Pointer to Sensor structure to be measured
- * @param deltaCnt Address to where the measurements are to be written
- * @return none
- ******************************************************************************/
- void TI_CAPT_Custom(const struct Sensor* groupOfElements, uint16_t * deltaCnt)
- {
- uint8_t j;
- uint16_t tempCnt, remainder;
- ctsStatusReg &= ~ EVNT;
-
- TI_CAPT_Raw(groupOfElements, &deltaCnt[0]); // measure group of sensors
-
- for (j = 0; j < (groupOfElements->numElements); j++)
- {
- tempCnt = deltaCnt[j];
- if(deltaCnt[j])
- {
- if(((ctsStatusReg & DOI_MASK)
- && (groupOfElements->halDefinition & RO_MASK))
- ||
- ((!(ctsStatusReg & DOI_MASK))
- && (!(groupOfElements->halDefinition & RO_MASK))))
- {
- /*
- * Interested in a decrease in counts. Either the decrease
- * represents an increase in capacitance (a touch) with the
- * RO method, or the decrease represents a decrease in capacitance
- * (release) with the fRO or RC methods.
- */
- if(baseCnt[j+groupOfElements->baseOffset] < deltaCnt[j])
- {
- /*
- * The measured value is greater than the baseline therefore
- * no detection logic is needed. The measured value is
- * preserved in tempCnt and is used for baseline updates.
- */
- deltaCnt[j] = 0;
- if(((groupOfElements->arrayPtr[j])->threshold)
- &&
- (baseCnt[j+groupOfElements->baseOffset]
- +((groupOfElements->arrayPtr[j])->threshold/2) < tempCnt))
- {
- /*
- * When the threshold is valid (non-calibration state),
- * limit the measurement to the baseline + threshold/2.
- */
- tempCnt = baseCnt[j+groupOfElements->baseOffset]
- +((groupOfElements->arrayPtr[j])->threshold)/2;
- }
- }
- else
- {
- /*
- * deltaCnt now represents the magnitude of change relative to
- * the baseline.
- */
- deltaCnt[j] = baseCnt[j+groupOfElements->baseOffset]
- - deltaCnt[j];
- }
- }
- if(((!(ctsStatusReg & DOI_MASK))
- && (groupOfElements->halDefinition & RO_MASK))
- ||
- ((ctsStatusReg & DOI_MASK)
- && (!(groupOfElements->halDefinition & RO_MASK))))
- {
- /*
- * Interested in an increase in counts. Either the increase
- * represents a decrease in capacitance (a release) with the
- * RO method, or the increase represents a increase in capacitance
- * (touch) with the fRO or RC methods.
- */
- if(baseCnt[j+groupOfElements->baseOffset] > deltaCnt[j])
- {
- /*
- * The measured value is less than the baseline therefore
- * no detection logic is needed. The measured value is
- * preserved in tempCnt and is used for baseline updates.
- */
- deltaCnt[j] = 0;
- if(((groupOfElements->arrayPtr[j])->threshold)
- &&
- (baseCnt[j+groupOfElements->baseOffset]
- -((groupOfElements->arrayPtr[j])->threshold/2) > tempCnt))
- {
- /*
- * When the threshold is valid (non-calibration state),
- * limit the measurement to the baseline - threshold/2.
- */
- tempCnt = baseCnt[j+groupOfElements->baseOffset]
- -((groupOfElements->arrayPtr[j])->threshold)/2;
- }
- }
- else
- {
- /*
- * deltaCnt now represents the magnitude of change relative to
- * the baseline.
- */
- deltaCnt[j] = deltaCnt[j]
- - baseCnt[j+groupOfElements->baseOffset];
- }
- }
-
- // This section updates the baseline capacitance************************
- if (deltaCnt[j]==0)
- { // if delta counts is 0, then the change in capacitance was opposite
- // the direction of interest. The baseCnt[i] is updated with the
- // saved tempCnt value for the current index value 'i'.
- remainder = 0;
- switch ((ctsStatusReg & TRADOI_VSLOW))
- {
- case TRADOI_FAST://Fast
- tempCnt = tempCnt/2;
- baseCnt[j+groupOfElements->baseOffset]
- = (baseCnt[j+groupOfElements->baseOffset]/2);
- break;
- case TRADOI_MED://Medium
- tempCnt = tempCnt/4;
- baseCnt[j+groupOfElements->baseOffset]
- = 3*(baseCnt[j+groupOfElements->baseOffset]/4);
- break;
- case TRADOI_SLOW://slow
- /* Calculate remainder associated with (x + 63*y)/64 */
- remainder = 0x003F & baseCnt[j+groupOfElements->baseOffset];
- remainder = remainder * 63;
- remainder += 0x003F & tempCnt;
- remainder = remainder >> 6;
- tempCnt = tempCnt/64;
- baseCnt[j+groupOfElements->baseOffset]
- = 63*(baseCnt[j+groupOfElements->baseOffset]/64);
- break;
- case TRADOI_VSLOW://very slow
- /* Calculate remainder associated with (x+127*y)/128 */
- remainder = 0x007F & baseCnt[j+groupOfElements->baseOffset];
- remainder = remainder * 127;
- remainder += 0x007F & tempCnt;
- remainder = remainder >> 7;
- tempCnt = tempCnt/128;
- baseCnt[j+groupOfElements->baseOffset]
- = 127*(baseCnt[j+groupOfElements->baseOffset]/128);
- break;
- }
- /* Base_Capacitance = (Measured_Capacitance/Z)
- + Y*(Base_Capacitance/Z) */
- tempCnt += remainder;
- baseCnt[j+groupOfElements->baseOffset] += tempCnt;
- /* In the case that DOI is set and */
- if(groupOfElements->halDefinition & RO_MASK)
- {
- /* If the RO_MASK is set then the direction of interest is
- * decreasing (counts decrease with capacitance) and therefore
- * movement against the direction of interest would be an
- * increase: increment.
- */
- baseCnt[j+groupOfElements->baseOffset]++;
- }
- else
- {
- /* RO_MASK is not set and therefore a decrease is against
- * the direction of interest: decrement
- */
- baseCnt[j+groupOfElements->baseOffset]--;
- }
- }
- /* deltaCnt is either 0, less than threshold, or greater than
- threshold, never negative. */
- else if(deltaCnt[j]<(groupOfElements->arrayPtr[j])->threshold
- && !(ctsStatusReg & PAST_EVNT))
- { //if delta counts is positive but less than threshold,
- remainder = 1;
- switch ((ctsStatusReg & TRIDOI_FAST))
- {
- case TRIDOI_VSLOW:
- tempCnt = 0;
- break;
- case TRIDOI_SLOW://slow
- remainder = 2;
- tempCnt = 0;
- break;
- case TRIDOI_MED://medium
- tempCnt = tempCnt/4;
- baseCnt[j+groupOfElements->baseOffset] = 3*(baseCnt[j+groupOfElements->baseOffset]/4);
- break;
- case TRIDOI_FAST://fast
- tempCnt = tempCnt/2;
- baseCnt[j+groupOfElements->baseOffset] = (baseCnt[j+groupOfElements->baseOffset]/2);
- break;
- }
- /*
- * Base_Capacitance = (Measured_Capacitance/Z) +
- * Y*(Base_Capacitance/Z)
- */
- baseCnt[j+groupOfElements->baseOffset] += tempCnt;
- if(groupOfElements->halDefinition & RO_MASK)
- {
- /* If the RO_MASK is set then the direction of interest is
- * decreasing (counts decrease with capacitance) and
- * therefore movement in the direction of interest would
- * be a decrease: decrement.
- */
- baseCnt[j+groupOfElements->baseOffset]-= remainder;
- }
- else
- {
- /* RO_MASK is not set and therefore an increase is in the
- * direction of interest: increment
- */
- baseCnt[j+groupOfElements->baseOffset]+= remainder;
- }
- }
- //if delta counts above the threshold, event has occurred
- else if(deltaCnt[j]>=(groupOfElements->arrayPtr[j])->threshold)
- {
- ctsStatusReg |= EVNT;
- ctsStatusReg |= PAST_EVNT;
- }
- }
- }// end of for-loop
- if(!(ctsStatusReg & EVNT))
- {
- ctsStatusReg &= ~PAST_EVNT;
- }
- }
-
- /***************************************************************************//**
- * @brief Determine if a button is being pressed
- * @param groupOfElements Pointer to button to be scanned
- * @return result Indication if button is (1) or is not (0) being pressed
- ******************************************************************************/
- uint8_t TI_CAPT_Button(const struct Sensor * groupOfElements)
- {
- uint8_t result = 0;
-
- #ifndef RAM_FOR_FLASH
- uint16_t *measCnt;
- measCnt = (uint16_t *)malloc(groupOfElements->numElements * sizeof(uint16_t));
- if(measCnt ==0)
- {
- while(1);
- }
- #endif
-
- TI_CAPT_Custom(groupOfElements, measCnt);
- #ifndef RAM_FOR_FLASH
- free(measCnt);
- #endif
- if(ctsStatusReg & EVNT)
- {
- result = 1;
- }
- return result;
- }
-
- /***************************************************************************//**
- * @brief Determine which button if any is being pressed
- * @param groupOfElements Pointer to buttons to be scanned
- * @return result pointer to element (button) being pressed or 0 none
- ******************************************************************************/
- const struct Element *TI_CAPT_Buttons(const struct Sensor *groupOfElements)
- {
- uint8_t index;
- #ifndef RAM_FOR_FLASH
- uint16_t *measCnt;
- measCnt = (uint16_t *)malloc(groupOfElements->numElements * sizeof(uint16_t));
- if(measCnt ==0)
- {
- while(1);
- }
- #endif
- TI_CAPT_Custom(groupOfElements, measCnt);
-
- if(ctsStatusReg & EVNT)
- {
- index = Dominant_Element(groupOfElements, measCnt);
- //ctsStatusReg &= ~EVNT;
- index++;
- }
- else
- {
- index = 0;
- }
- #ifndef RAM_FOR_FLASH
- free(measCnt);
- #endif
- if(index)
- {
- return groupOfElements->arrayPtr[index-1];
- }
- return 0;
- }
-
- #ifdef SLIDER
- /***************************************************************************//**
- * @brief Determine the position on a slider
- * @param groupOfElements Pointer to slider
- * @return result position on slider or illegal value if no touch
- ******************************************************************************/
- uint16_t TI_CAPT_Slider(const struct Sensor* groupOfElements)
- {
- uint8_t index;
- int16_t position;
- // allocate memory for measurement
- #ifndef RAM_FOR_FLASH
- uint16_t *measCnt;
- measCnt = (uint16_t *)malloc(groupOfElements->numElements * sizeof(uint16_t));
- if(measCnt ==0)
- {
- while(1);
- }
- #endif
- position = ILLEGAL_SLIDER_WHEEL_POSITION;
- //make measurement
- TI_CAPT_Custom(groupOfElements, measCnt);
-
- // Use EVNT flag to determine if slider was touched.
- // The EVNT flag is a global variable and managed within the TI_CAPT_Custom
- // function.
- if(ctsStatusReg & EVNT)
- {
- index = Dominant_Element(groupOfElements, &measCnt[0]);
- // The index represents the element within the array with the highest
- // return.
- if(index == 0)
- {
- // Special case of 1st element in slider, add 1st, last, and 2nd
- position = measCnt[0] + measCnt[1];
- }
- else if(index == (groupOfElements->numElements -1))
- {
- // Special case of Last element in slider, add last,
- // 1st, and 2nd to last
- position = measCnt[groupOfElements->numElements -1]
- + measCnt[groupOfElements->numElements -2];
- }
- else
- {
- position = measCnt[index] + measCnt[index+1] + measCnt[index-1];
- }
- // Determine if sensor threshold criteria is met
- if(position >= groupOfElements->sensorThreshold)
- {
- // calculate position
- position = index
- *(groupOfElements->points
- /groupOfElements->numElements);
- position += (groupOfElements->points/groupOfElements->numElements)
- /2;
- if(index == 0)
- {
- // Special case of 1st element in slider, which only has one
- // neighbor, measCnt[1]. measCnt is limited to maxResponse
- // within dominantElement function
- if(measCnt[1])
- {
- position += (measCnt[1]
- *(groupOfElements->points
- /groupOfElements->numElements))/100;
- }
- else
- {
- /* Calculate position based upon measCnt[0] */
- position = (measCnt[0]
- *(groupOfElements->points
- /groupOfElements->numElements)/2)/100;
- }
- }
- else if(index == (groupOfElements->numElements -1))
- {
- // Special case of Last element in slider, which only has one
- // neighbor, measCnt[x-1] or measCnt[numElements-1]
- if(measCnt[index-1])
- {
- position -= (measCnt[index-1]
- *(groupOfElements->points
- /groupOfElements->numElements))/100;
- }
- else
- {
- position = groupOfElements->points;
- position -= (measCnt[index]
- *(groupOfElements->points
- /groupOfElements->numElements)/2)/100;
- }
- }
- else
- {
- position += (measCnt[index+1]*(groupOfElements->points/groupOfElements->numElements))/100;
- position -= (measCnt[index-1]*(groupOfElements->points/groupOfElements->numElements))/100;
- }
- if((position > groupOfElements->points) || (position < 0))
- {
- position = ILLEGAL_SLIDER_WHEEL_POSITION;
- }
- }
- else
- {
- position = ILLEGAL_SLIDER_WHEEL_POSITION;
- }
- }
- #ifndef RAM_FOR_FLASH
- free(measCnt);
- #endif
- return position;
- }
- #endif
-
- #ifdef WHEEL
- /***************************************************************************//**
- * @brief Determine the position on a wheel
- * @param groupOfElements Pointer to wheel
- * @return result position on wheel or illegal value if no touch
- ******************************************************************************/
- uint16_t TI_CAPT_Wheel(const struct Sensor* groupOfElements)
- {
- uint8_t index;
- int16_t position;
- // allocate memory for measurement
- #ifndef RAM_FOR_FLASH
- uint16_t *measCnt;
- measCnt = (uint16_t *)malloc(groupOfElements->numElements * sizeof(uint16_t));
- if(measCnt ==0)
- {
- while(1);
- }
- #endif
- position = ILLEGAL_SLIDER_WHEEL_POSITION;
- //make measurement
- TI_CAPT_Custom(groupOfElements, measCnt);
- // Translate the EVNT flag from an element level EVNT to a sensor level EVNT.
- // The sensor must read at least 75% cumulative response before indicating a
- // touch.
- if(ctsStatusReg & EVNT)
- {
- index = Dominant_Element(groupOfElements, &measCnt[0]);
- // The index represents the element within the array with the highest return.
- //
- if(index == 0)
- {
- // Special case of 1st element in slider, add 1st, last, and 2nd
- position = measCnt[0] + measCnt[groupOfElements->numElements -1] + measCnt[1];
- }
- else if(index == (groupOfElements->numElements -1))
- {
- // Special case of Last element in slider, add last, 1st, and 2nd to last
- position = measCnt[index] + measCnt[0] + measCnt[index-1];
- }
- else
- {
- position = measCnt[index] + measCnt[index+1] + measCnt[index-1];
- }
- if(position > groupOfElements->sensorThreshold)
- {
- //index = Dominant_Element(groupOfElements, &measCnt[0]);
- // The index represents the element within the array with the highest return.
- //
- position = index*(groupOfElements->points/groupOfElements->numElements);
- position += (groupOfElements->points/groupOfElements->numElements)/2;
- if(index == 0)
- {
- // Special case of 1st element in slider, which only has one neighbor, measCnt[1]
- // measCnt is limited to maxResponse within dominantElement function
- position += (measCnt[1]*(groupOfElements->points/groupOfElements->numElements))/100;
- position -= (measCnt[groupOfElements->numElements -1]*(groupOfElements->points/groupOfElements->numElements))/100;
- if(position < 0)
- {
- position = position + (int16_t)groupOfElements->points;
- position++; // -1 goes to points
- }
- }
- else if(index == (groupOfElements->numElements -1))
- {
- // Special case of Last element in slider, which only has one neighbor, measCnt[x-1] or measCnt[numElements-1]
- // measCnt is limited to maxResponse within dominantElement function
- position += (measCnt[0]*(groupOfElements->points/groupOfElements->numElements))/100;
- position -= (measCnt[index-1]*(groupOfElements->points/groupOfElements->numElements))/100;
- if(position > groupOfElements->points)
- {
- position = position - (int16_t)groupOfElements->points;
- position--; // points+1 goes to 0
- }
- }
- else
- {
- position += (measCnt[index+1]*(groupOfElements->points/groupOfElements->numElements))/100;
- position -= (measCnt[index-1]*(groupOfElements->points/groupOfElements->numElements))/100;
- }
- if((position > groupOfElements->points) || position < 0)
- {
- position = ILLEGAL_SLIDER_WHEEL_POSITION;
- }
- }
- else
- {
- position = ILLEGAL_SLIDER_WHEEL_POSITION;
- }
- }
- #ifndef RAM_FOR_FLASH
- free(measCnt);
- #endif
- return position;
- }
- #endif
-
- /** @} */
-
- /***************************************************************************//**
- * @defgroup CTS_support Support Group
- * @ingroup CTS_API
- ******************************************************************************/
-
- /***************************************************************************//**
- * @ingroup CTS_support
- * @brief Determine which element within a sensor has the largest response
- *
- * This function compares and normalizes the change in capacitance to
- * determine which element has the dominant response. The deltaCnt
- * values for each element that exceed the threshold are also
- * converted from a 'raw' measurement to a percentage of the maximum
- * response.
- * @param groupOfElements Pointer to buttons to be scanned
- * @param deltaCnt Address to where the measurements are to be written
- * @return result index to the element which is dominant
- ******************************************************************************/
- uint8_t Dominant_Element(const struct Sensor* groupOfElements, uint16_t* deltaCnt)
- {
- uint8_t i;
- uint16_t percentDelta=0;
- uint8_t dominantElement=0;
- for(i=0;i<groupOfElements->numElements;i++)
- {
- if(deltaCnt[i]>=(groupOfElements->arrayPtr[i])->threshold)
- {
- if(deltaCnt[i] > ((groupOfElements->arrayPtr[i])->maxResponse))
- {
- deltaCnt[i] = (groupOfElements->arrayPtr[i])->maxResponse;
- // limit response to the maximum
- }
- // (maxResponse - threshold) cannot exceed 655
- // 100*(delta - threshold) / (maxResponse - threshold)
- deltaCnt[i] = (100*(deltaCnt[i]
- -(groupOfElements->arrayPtr[i])->threshold))
- /((groupOfElements->arrayPtr[i])->maxResponse
- -(groupOfElements->arrayPtr[i])->threshold);
- if(deltaCnt[i] >= percentDelta)
- {
- //update percentDelta
- percentDelta = deltaCnt[i];
- dominantElement = i;
- }
- }
- else
- {
- deltaCnt[i] = 0;
- }
- } // end for loop
- return dominantElement;
- }
- #endif
|