From e018ceebed74b8223482bc9d1ed0b31c938381da Mon Sep 17 00:00:00 2001 From: Yuval Adam Date: Mon, 29 Oct 2012 23:04:19 +0200 Subject: New example files --- .../ek-lm4f120xl-boost-capsense/drivers/CTS_HAL.c | 140 +++++ .../ek-lm4f120xl-boost-capsense/drivers/CTS_HAL.h | 34 ++ .../drivers/CTS_Layer.c | 663 +++++++++++++++++++++ .../drivers/CTS_Layer.h | 64 ++ .../drivers/CTS_structure.c | 131 ++++ .../drivers/CTS_structure.h | 74 +++ 6 files changed, 1106 insertions(+) create mode 100644 boards/ek-lm4f120xl-boost-capsense/drivers/CTS_HAL.c create mode 100644 boards/ek-lm4f120xl-boost-capsense/drivers/CTS_HAL.h create mode 100644 boards/ek-lm4f120xl-boost-capsense/drivers/CTS_Layer.c create mode 100644 boards/ek-lm4f120xl-boost-capsense/drivers/CTS_Layer.h create mode 100644 boards/ek-lm4f120xl-boost-capsense/drivers/CTS_structure.c create mode 100644 boards/ek-lm4f120xl-boost-capsense/drivers/CTS_structure.h (limited to 'boards/ek-lm4f120xl-boost-capsense/drivers') diff --git a/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_HAL.c b/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_HAL.c new file mode 100644 index 0000000..5ad0720 --- /dev/null +++ b/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_HAL.c @@ -0,0 +1,140 @@ +//***************************************************************************** +// +// CTS_HAL.c - Capacative Sense Library Hardware Abstraction Layer. +// +// Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 9453 of the EK-LM4F120XL Firmware Package. +// +//***************************************************************************** + +#include "inc/hw_types.h" +#include "inc/hw_gpio.h" +#include "inc/hw_memmap.h" +#include "inc/hw_nvic.h" +#include "drivers/CTS_structure.h" +#include "drivers/CTS_HAL.h" + +//***************************************************************************** +// +// Function to get a capacitance reading from a single-pin RC-based capacitive +// sensor. This function assumes that the capacitive sensor is charged by a +// GPIO, and then discharged through a resistor to GND. The same GPIO used to +// perform the charging will be used as an input during discharge to sense when +// the capacitor's voltage has decreased to at least VIL. The function will +// execute several cycles of this, and report how long the process took in +// units of SysTick counts. This count should be proportional to the current +// capacitance of the sensor, and the resistance of the discharge resistor. +// +//***************************************************************************** +void +CapSenseSystickRC(const tSensor *group, unsigned long *counts) +{ + unsigned char ucIndex; + + // + // Run an RC based capacitance measurement routine on each element in the + // sensor array. + // + for(ucIndex = 0; ucIndex < (group->ucNumElements); ucIndex++) + { + // + // Reset Systick to zero (probably not necessary for most cases, but we + // want to make sure that Systick doesn't roll over.) + // + HWREG(NVIC_ST_CURRENT) = 0x0; + + // + // Grab a count number from the capacitive sensor element. + // + counts[ucIndex] = + CapSenseElementSystickRC(group->Element[ucIndex]->ulGPIOPort, + group->Element[ucIndex]->ulGPIOPin, + group->ulNumSamples); + + } +} + +//***************************************************************************** +// +// +// +// +//***************************************************************************** +unsigned long +CapSenseElementSystickRC(unsigned long ulGPIOPort, unsigned long ulGPIOPin, + unsigned long ulNumSamples) +{ + volatile unsigned long ulStartTime; + volatile unsigned long ulEndTime; + unsigned long ulIndex; + unsigned long ulGPIODataReg; + unsigned long ulGPIODirReg; + + // + // Save off our GPIO information. + // + ulGPIODataReg = (ulGPIOPort + (GPIO_O_DATA + (ulGPIOPin << 2))); + ulGPIODirReg = ulGPIOPort + GPIO_O_DIR; + + // + // Grab the time + // + ulStartTime = HWREG(NVIC_ST_CURRENT); + + // + // Loop until we have the requisite number of samples. + // + for(ulIndex = 0; ulIndex < ulNumSamples; ulIndex++) + { + // + // Drive up. + // + //GPIOPinWrite(ulGPIOPort, ulGPIOPin, ulGPIOPin); + HWREG(ulGPIODataReg) = 0xFF; + + // + // Configure as input + // + //GPIOPinTypeGPIOInput(ulGPIOPort, ulGPIOPin); + HWREG(ulGPIODirReg) = (HWREG(ulGPIODirReg) & ~(ulGPIOPin)); + + // + // Wait until the capacitor drains away to ground + // + //while(GPIOPinRead(ulGPIOPort, ulGPIOPin)) + while(HWREG(ulGPIODataReg)) + { + } + + // + // Configure as an output. + // + //GPIOPinTypeGPIOOutput(ulGPIOPort, ulGPIOPin); + HWREG(ulGPIODirReg) = (HWREG(ulGPIODirReg) | ulGPIOPin); + } + + // + // Grab the time, and calculate the difference + // + ulEndTime = HWREG(NVIC_ST_CURRENT); + + // + // Return the time difference + // + return(ulStartTime - ulEndTime); +} diff --git a/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_HAL.h b/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_HAL.h new file mode 100644 index 0000000..40ba534 --- /dev/null +++ b/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_HAL.h @@ -0,0 +1,34 @@ +//***************************************************************************** +// +// CTS_HAL.h - Capacative Sense HAL Header file definitions. +// +// Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 9453 of the EK-LM4F120XL Firmware Package. +// +//***************************************************************************** + +#ifndef __CTS_HAL_H__ +#define __CTS_HAL_H__ + +extern void CapSenseSystickRC(const tSensor *group, unsigned long *counts); + +extern unsigned long CapSenseElementSystickRC(unsigned long ulGPIOPort, + unsigned long ulGPIOPin, + unsigned long ulNumSamples); + +#endif // __CTS_HAL_H__ diff --git a/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_Layer.c b/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_Layer.c new file mode 100644 index 0000000..c16a0fd --- /dev/null +++ b/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_Layer.c @@ -0,0 +1,663 @@ +//***************************************************************************** +// +// CTS_HAL.c - Capacative Sense Library Hardware Abstraction Layer. +// +// Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 9453 of the EK-LM4F120XL Firmware Package. +// +//***************************************************************************** + +#include "drivers/CTS_structure.h" +#include "drivers/CTS_Layer.h" +#define RAM_FOR_FLASH + +// Global variables for sensing +#ifdef TOTAL_NUMBER_OF_ELEMENTS +unsigned long baseCnt[TOTAL_NUMBER_OF_ELEMENTS]; +#ifdef RAM_FOR_FLASH +unsigned long measCnt[MAXIMUM_NUMBER_OF_ELEMENTS_PER_SENSOR]; +#endif +unsigned long ctsStatusReg = (DOI_INC+TRADOI_FAST+TRIDOI_SLOW); +#endif + +//***************************************************************************** +// +//! \addtogroup CTS_API +//! @{ +// +//***************************************************************************** + + +//***************************************************************************** +// +//! Measure the capacitance of each element within the Sensor +//! +//! \param groupOfElements Pointer to Sensor structure to be measured +//! +//! \param counts Address to where the measurements are to be written +//! +//! 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. +//! +//! \return None. +// +//***************************************************************************** +void +TI_CAPT_Raw(const tSensor* groupOfElements, unsigned long * counts) +{ + CapSenseSystickRC(groupOfElements, counts); +} + +#ifdef TOTAL_NUMBER_OF_ELEMENTS + + +//***************************************************************************** +// +//! 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 tSensor* groupOfElements) +{ + TI_CAPT_Raw(groupOfElements, &baseCnt[groupOfElements->ulBaseOffset]); +} + +//***************************************************************************** +// +//! 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 tSensor* groupOfElements, unsigned char numberOfAverages) +{ + unsigned char i,j; + #ifndef RAM_FOR_FLASH + unsigned long *measCnt; + measCnt = (unsigned long *)malloc(groupOfElements->ucNumElements * sizeof(unsigned long)); + if(measCnt ==0) + { + while(1); + } + #endif + for(j=0; j < numberOfAverages; j++) + { + for(i=0; i < groupOfElements->ucNumElements; i++) + { + TI_CAPT_Raw(groupOfElements, measCnt); + baseCnt[i+groupOfElements->ulBaseOffset] = measCnt[i]/2 + baseCnt[i+groupOfElements->ulBaseOffset]/2; + } + } + #ifndef RAM_FOR_FLASH + free(measCnt); + #endif +} + +//***************************************************************************** +//! Reset the Baseline Tracking algorithm to the default state +//! +//! \return none +// +//***************************************************************************** +void +TI_CAPT_Reset_Tracking(void) +{ + ctsStatusReg = (DOI_INC+TRADOI_FAST+TRIDOI_SLOW); +} + +//***************************************************************************** +// +//! Update the Baseline Tracking algorithm Direction of Interest +//! +//! \param direction Direction of increasing or decreasing capacitance +//! +//! \return none +// +//***************************************************************************** +void +TI_CAPT_Update_Tracking_DOI(unsigned char direction) +{ + if(direction) + { + ctsStatusReg |= DOI_INC; + } + else + { + ctsStatusReg &= ~DOI_INC; + } +} + +//***************************************************************************** +// +//! 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(unsigned char rate) +{ + ctsStatusReg &= ~(TRIDOI_FAST+TRADOI_VSLOW); // clear fields + ctsStatusReg |= (rate & 0xF0); // update fields +} + +//***************************************************************************** +// +//! Measure the change in capacitance of the Sensor +//! +//! \param groupOfElements Pointer to Sensor structure to be measured +//! +//! \param deltaCnt Address to where the measurements are to be written +//! +//! 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. +//! +//! \return none +// +//***************************************************************************** +void +TI_CAPT_Custom(const tSensor* groupOfElements, unsigned long * deltaCnt) +{ + unsigned char j; + unsigned long tempCnt; + ctsStatusReg &= ~ EVNT; + + // This section calculates the delta counts************************************* + //****************************************************************************** + TI_CAPT_Raw(groupOfElements, &deltaCnt[0]); // measure group of sensors + + for (j = 0; j < (groupOfElements->ucNumElements); j++) + { + tempCnt = deltaCnt[j]; + if((!(ctsStatusReg & DOI_MASK))) + { + // RO method, interested in an increase in capacitance + if(baseCnt[j+groupOfElements->ulBaseOffset] < deltaCnt[j]) + { + // If capacitance decreases, then measCnt is greater than base + // , set delta to zero + deltaCnt[j] = 0; + // Limit the change in the opposite direction to the threshold + if(((groupOfElements->Element[j])->ulThreshold) + && + (baseCnt[j+groupOfElements->ulBaseOffset]+(groupOfElements->Element[j])->ulThreshold < tempCnt)) + { + tempCnt = baseCnt[j+groupOfElements->ulBaseOffset]+(groupOfElements->Element[j])->ulThreshold; + } + } + else + { + // change occuring in our DOI, save result + deltaCnt[j] = baseCnt[j+groupOfElements->ulBaseOffset]-deltaCnt[j]; + } + } + if(((ctsStatusReg & DOI_MASK))) + { + // RO method: interested in a decrease in capactiance + // measCnt is greater than baseCnt + if(baseCnt[j+groupOfElements->ulBaseOffset] > deltaCnt[j]) + { + // If capacitance increases, set delta to zero + deltaCnt[j] = 0; + // Limit the change in the opposite direction to the threshold + if(((groupOfElements->Element[j])->ulThreshold) + && + (baseCnt[j+groupOfElements->ulBaseOffset] > tempCnt+(groupOfElements->Element[j])->ulThreshold)) + { + tempCnt = baseCnt[j+groupOfElements->ulBaseOffset]-(groupOfElements->Element[j])->ulThreshold; + } + } + else + { + // change occuring in our DOI + deltaCnt[j] = deltaCnt[j] - baseCnt[j+groupOfElements->ulBaseOffset]; + } + } + + // 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 + // measCnt value for the current index value 'i'. + switch ((ctsStatusReg & TRADOI_VSLOW)) + { + case TRADOI_FAST://Fast + tempCnt = tempCnt/2; + baseCnt[j+groupOfElements->ulBaseOffset] = (baseCnt[j+groupOfElements->ulBaseOffset]/2); + break; + case TRADOI_MED://Medium + tempCnt = tempCnt/4; + baseCnt[j+groupOfElements->ulBaseOffset] = 3*(baseCnt[j+groupOfElements->ulBaseOffset]/4); + break; + case TRADOI_SLOW://slow + tempCnt = tempCnt/64; + baseCnt[j+groupOfElements->ulBaseOffset] = 63*(baseCnt[j+groupOfElements->ulBaseOffset]/64); + break; + case TRADOI_VSLOW://very slow + tempCnt = tempCnt/128; + baseCnt[j+groupOfElements->ulBaseOffset] = 127*(baseCnt[j+groupOfElements->ulBaseOffset]/128); + break; + } + // set X, Y & Z, then perform calculation for baseline tracking: + // Base_Capacitance = X*(Measured_Capacitance/Z) + Y*(Base_Capacitance/Z) + baseCnt[j+groupOfElements->ulBaseOffset] = (tempCnt)+(baseCnt[j+groupOfElements->ulBaseOffset]); + } + // delta counts are either 0, less than threshold, or greater than threshold + // never negative + else if(deltaCnt[j]<(groupOfElements->Element[j])->ulThreshold && !(ctsStatusReg & PAST_EVNT)) + { //if delta counts is positive but less than threshold, + switch ((ctsStatusReg & TRIDOI_FAST)) + { + case TRIDOI_VSLOW://very slow + if(deltaCnt[j] > 15) + { + if(tempCnt < baseCnt[j+groupOfElements->ulBaseOffset]) + { + baseCnt[j+groupOfElements->ulBaseOffset] = baseCnt[j+groupOfElements->ulBaseOffset] - 1; + } + else + { + baseCnt[j+groupOfElements->ulBaseOffset] = baseCnt[j+groupOfElements->ulBaseOffset] + 1; + } + } + tempCnt = 0; + break; + case TRIDOI_SLOW://slow + if(tempCnt < baseCnt[j+groupOfElements->ulBaseOffset]) + { + baseCnt[j+groupOfElements->ulBaseOffset] = baseCnt[j+groupOfElements->ulBaseOffset] - 1; + } + else + { + baseCnt[j+groupOfElements->ulBaseOffset] = baseCnt[j+groupOfElements->ulBaseOffset] + 1; + } + tempCnt = 0; + break; + case TRIDOI_MED://medium + tempCnt = tempCnt/4; + baseCnt[j+groupOfElements->ulBaseOffset] = 3*(baseCnt[j+groupOfElements->ulBaseOffset]/4); + break; + case TRIDOI_FAST://fast + tempCnt = tempCnt/2; + baseCnt[j+groupOfElements->ulBaseOffset] = (baseCnt[j+groupOfElements->ulBaseOffset]/2); + break; + } + // set X, Y & Z, then perform calculation for baseline tracking: + // Base_Capacitance = X*(Measured_Capacitance/Z) + Y*(Base_Capacitance/Z) + baseCnt[j+groupOfElements->ulBaseOffset] = (tempCnt)+(baseCnt[j+groupOfElements->ulBaseOffset]); + } + //if delta counts above the threshold, event has occurred + else if(deltaCnt[j]>=(groupOfElements->Element[j])->ulThreshold) + { + ctsStatusReg |= EVNT; + ctsStatusReg |= PAST_EVNT; + } + }// end of for-loop + if(!(ctsStatusReg & EVNT)) + { + ctsStatusReg &= ~PAST_EVNT; + } +} + +//***************************************************************************** +// +//! 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 +//! +// +//***************************************************************************** +unsigned char +TI_CAPT_Button(const tSensor * groupOfElements) +{ + unsigned char result = 0; + + #ifndef RAM_FOR_FLASH + unsigned long *measCnt; + measCnt = (unsigned long *)malloc(groupOfElements->ucNumElements * sizeof(unsigned long)); + 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 tCapTouchElement * +TI_CAPT_Buttons(const tSensor *groupOfElements) +{ + unsigned char index; + #ifndef RAM_FOR_FLASH + unsigned long *measCnt; + measCnt = (unsigned long *)malloc(groupOfElements->ucNumElements * sizeof(unsigned long)); + 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->Element[index-1]; + } + return 0; +} + +#ifdef SLIDER +//***************************************************************************** +// +//! Determine the position on a slider +// +//! \param groupOfElements Pointer to slider +// +//! \return result position on slider or illegal value if no touch +// +//***************************************************************************** +unsigned long +TI_CAPT_Slider(const tSensor* groupOfElements) +{ + unsigned char index; + signed long position; + // allocate memory for measurement + #ifndef RAM_FOR_FLASH + unsigned long *measCnt; + measCnt = (unsigned long *)malloc(groupOfElements->ucNumElements * sizeof(unsigned long)); + 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->ucNumElements -1)) + { + // Special case of Last element in slider, add last, 1st, and 2nd to last + position = measCnt[groupOfElements->ucNumElements -1] + measCnt[groupOfElements->ucNumElements -2]; + } + else + { + position = measCnt[index] + measCnt[index+1] + measCnt[index-1]; + } + // Determine if sensor threshold criteria is met + if(position > groupOfElements->ulSensorThreshold) + { + // calculate position + position = index*(groupOfElements->ucPoints/groupOfElements->ucNumElements); + position += (groupOfElements->ucPoints/groupOfElements->ucNumElements)/2; + if(index == 0) + { + // Special case of 1st element in slider, which only has one + // neighbor, measCnt[1]. measCnt is limited to ulMaxResponse + // within dominantElement function + if(measCnt[1]) + { + position += (measCnt[1]*(groupOfElements->ucPoints/groupOfElements->ucNumElements))/100; + } + else + { + position = (measCnt[0]*(groupOfElements->ucPoints/groupOfElements->ucNumElements)/2)/100; + } + } + else if(index == (groupOfElements->ucNumElements -1)) + { + // Special case of Last element in slider, which only has one + // neighbor, measCnt[x-1] or measCnt[ucNumElements-1] + if(measCnt[index-1]) + { + position -= (measCnt[index-1]*(groupOfElements->ucPoints/groupOfElements->ucNumElements))/100; + } + else + { + position = groupOfElements->ucPoints; + position -= (measCnt[index]*(groupOfElements->ucPoints/groupOfElements->ucNumElements)/2)/100; + } + } + else + { + position += (measCnt[index+1]*(groupOfElements->ucPoints/groupOfElements->ucNumElements))/100; + position -= (measCnt[index-1]*(groupOfElements->ucPoints/groupOfElements->ucNumElements))/100; + } + if((position > groupOfElements->ucPoints) || (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 +//***************************************************************************** +// +//! Determine the position on a wheel +// +//! \param groupOfElements Pointer to wheel +// +//! \return result position on wheel or illegal value if no touch +// +//***************************************************************************** +unsigned long +TI_CAPT_Wheel(const tSensor* groupOfElements) +{ + unsigned char index; + signed long position; + // allocate memory for measurement + #ifndef RAM_FOR_FLASH + unsigned long *measCnt; + measCnt = (unsigned long *)malloc(groupOfElements->ucNumElements * sizeof(unsigned long)); + 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->ucNumElements -1] + measCnt[1]; + } + else if(index == (groupOfElements->ucNumElements -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->ulSensorThreshold) + { + //index = Dominant_Element(groupOfElements, &measCnt[0]); + // The index represents the element within the array with the highest return. + // + position = index*(groupOfElements->ucPoints/groupOfElements->ucNumElements); + position += (groupOfElements->ucPoints/groupOfElements->ucNumElements)/2; + if(index == 0) + { + // Special case of 1st element in slider, which only has one neighbor, measCnt[1] + // measCnt is limited to ulMaxResponse within dominantElement function + position += (measCnt[1]*(groupOfElements->ucPoints/groupOfElements->ucNumElements))/100; + position -= (measCnt[groupOfElements->ucNumElements -1]*(groupOfElements->ucPoints/groupOfElements->ucNumElements))/100; + if(position < 0) + { + position = position + (unsigned long)groupOfElements->ucPoints; + } + } + else if(index == (groupOfElements->ucNumElements -1)) + { + // Special case of Last element in slider, which only has one neighbor, measCnt[x-1] or measCnt[ucNumElements-1] + // measCnt is limited to ulMaxResponse within dominantElement function + position += (measCnt[0]*(groupOfElements->ucPoints/groupOfElements->ucNumElements))/100; + position -= (measCnt[index-1]*(groupOfElements->ucPoints/groupOfElements->ucNumElements))/100; + if(position > (groupOfElements->ucPoints -1)) + { + position = position - (unsigned long)groupOfElements->ucPoints; + } + } + else + { + position += (measCnt[index+1]*(groupOfElements->ucPoints/groupOfElements->ucNumElements))/100; + position -= (measCnt[index-1]*(groupOfElements->ucPoints/groupOfElements->ucNumElements))/100; + } + if((position > groupOfElements->ucPoints) || position < 0) + { + position = ILLEGAL_SLIDER_WHEEL_POSITION; + } + } + else + { + position = ILLEGAL_SLIDER_WHEEL_POSITION; + } + } + #ifndef RAM_FOR_FLASH + free(measCnt); + #endif + return position; +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + + +//***************************************************************************** +// +// +//***************************************************************************** +unsigned char +Dominant_Element(const tSensor* groupOfElements, unsigned long* deltaCnt) +{ + unsigned char i; + unsigned long percentDelta=0; + unsigned char dominantElement=0; + for(i=0;iucNumElements;i++) + { + if(deltaCnt[i]>=(groupOfElements->Element[i])->ulThreshold) + { + if(deltaCnt[i] > ((groupOfElements->Element[i])->ulMaxResponse)) + { + deltaCnt[i] = (groupOfElements->Element[i])->ulMaxResponse; + // limit response to the maximum + } + // (ulMaxResponse - threshold) cannot exceed 655 + // 100*(delta - threshold) / (ulMaxResponse - threshold) + deltaCnt[i] = (100*(deltaCnt[i]-(groupOfElements->Element[i])->ulThreshold))/((groupOfElements->Element[i])->ulMaxResponse - (groupOfElements->Element[i])->ulThreshold); + if(deltaCnt[i] > percentDelta) + { + //update percentDelta + percentDelta = deltaCnt[i]; + dominantElement = i; + } + } + else + { + deltaCnt[i] = 0; + } + } // end for loop + return dominantElement; +} +#endif diff --git a/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_Layer.h b/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_Layer.h new file mode 100644 index 0000000..51f54ae --- /dev/null +++ b/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_Layer.h @@ -0,0 +1,64 @@ +//***************************************************************************** +// +// CTS_Layer.h - Capacative Sense API Layer Header file definitions. +// +// Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 9453 of the EK-LM4F120XL Firmware Package. +// +//***************************************************************************** + +#ifndef __CTS_LAYER_H__ +#define __CTS_LAYER_H__ + +#define EVNT 0x01 +#define DOI_MASK 0x02 +#define DOI_INC 0x02 +#define DOI_DEC 0x00 +#define PAST_EVNT 0x04 +#define TRIDOI_VSLOW 0x00 +#define TRIDOI_SLOW 0x10 +#define TRIDOI_MED 0x20 +#define TRIDOI_FAST 0x30 +#define TRADOI_FAST 0x00 +#define TRADOI_MED 0x40 +#define TRADOI_SLOW 0x80 +#define TRADOI_VSLOW 0xC0 + + + +// API Calls +void TI_CAPT_Init_Baseline(const tSensor*); +void TI_CAPT_Update_Baseline(const tSensor*, unsigned char); + +void TI_CAPT_Reset_Tracking(void); +void TI_CAPT_Update_Tracking_DOI(unsigned char); +void TI_CAPT_Update_Tracking_Rate(unsigned char); + +void TI_CAPT_Raw(const tSensor*, unsigned long*); + +void TI_CAPT_Custom(const tSensor *, unsigned long*); + +unsigned char TI_CAPT_Button(const tSensor *); +const tCapTouchElement * TI_CAPT_Buttons(const tSensor *); +unsigned long TI_CAPT_Slider(const tSensor*); +unsigned long TI_CAPT_Wheel(const tSensor*); + +// Internal Calls +unsigned char Dominant_Element (const tSensor*, unsigned long*); + +#endif // __CTS_LAYER_H__ diff --git a/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_structure.c b/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_structure.c new file mode 100644 index 0000000..db1465e --- /dev/null +++ b/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_structure.c @@ -0,0 +1,131 @@ +//***************************************************************************** +// +// CTS_structure.c - Capacative Sense structures. +// +// Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 9453 of the EK-LM4F120XL Firmware Package. +// +//***************************************************************************** + +//***************************************************************************** +// +// 4 elements configured as a wheel. +// 1 element configured as a button. [Center Button] +// 1 element configured as a proximity sensor. +// This file contains the structure names and the variable assingments. +// +// Revision 1.00 Baseline +// Developed with IAR 5.10.4 [Kickstart] (5.10.4.30168) +// +// 09/24/10 Rev1.00 Pre-Alpha Version. Added "max_cnts" slider variable in +// CT_Handler object. +// +// 09/29/10 0.02 Update naming convention for elements and sensors. +// +// 10/11/10 0.03 Update +// +//****************************************************************************** + +#include "inc/hw_types.h" +#include "inc/hw_gpio.h" +#include "inc/hw_memmap.h" +#include "driverlib/gpio.h" +#include "drivers/CTS_structure.h" + +// +// Volume down button on PD3 +// +const tCapTouchElement g_sVolumeDownElement = +{ + GPIO_PORTA_AHB_BASE,//ulGPIOPort + GPIO_PIN_7,//ulGPIOPin + 100,//ulThreshold + 2000//ulMaxResponse +}; + +// +// Left button on PD2 +// +const tCapTouchElement g_sLeftElement = +{ + GPIO_PORTA_AHB_BASE,//ulGPIOPort + GPIO_PIN_6,//ulGPIOPin + 100,//ulThreshold + 2000//ulMaxResponse +}; + +// +// Right button on PE3 +// +const tCapTouchElement g_sRightElement = +{ + GPIO_PORTA_AHB_BASE,//ulGPIOPort + GPIO_PIN_2,//ulGPIOPin + 100,//ulThreshold + 2000//ulMaxResponse +}; + +// +// Volume up button on PE2 +// +const tCapTouchElement g_sVolumeUpElement = +{ + GPIO_PORTA_AHB_BASE,//ulGPIOPort + GPIO_PIN_3,//ulGPIOPin + 100,//ulThreshold + 2000//ulMaxResponse +}; + +// +// Middle button on PE1 +// +const tCapTouchElement g_sMiddleElement = +{ + GPIO_PORTA_AHB_BASE,//ulGPIOPort + GPIO_PIN_4,//ulGPIOPin + 100,//ulThreshold + 1800//ulMaxResponse +}; + +const tSensor g_sSensorWheel = +{ + 4,//unsigned char ucNumElements; + 100,//unsigned long ulNumSamples; + 64,//unsigned char ucPoints; + 75,//unsigned char ucSensorThreshold; + 0,//unsigned long ulBaseOffset; + { + &g_sVolumeUpElement, + &g_sRightElement, + &g_sVolumeDownElement, + &g_sLeftElement + }//const tCapTouchElement *Element[MAXIMUM_NUMBER_OF_ELEMENTS_PER_SENSOR]; +}; + +const tSensor g_sMiddleButton = +{ + 1,//unsigned char ucNumElements; + 100,//unsigned long ulNumSamples; + 0,//unsigned char ucPoints; + 0,//unsigned char ucSensorThreshold; + 4,//unsigned long ulBaseOffset; + { + &g_sMiddleElement + }//const tCapTouchElement *Element[MAXIMUM_NUMBER_OF_ELEMENTS_PER_SENSOR]; +}; + diff --git a/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_structure.h b/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_structure.h new file mode 100644 index 0000000..eb603a4 --- /dev/null +++ b/boards/ek-lm4f120xl-boost-capsense/drivers/CTS_structure.h @@ -0,0 +1,74 @@ +//***************************************************************************** +// +// CTS_structure.c - Capacative Sense structures. +// +// Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 9453 of the EK-LM4F120XL Firmware Package. +// +//***************************************************************************** + +#ifndef __CTS_STRUCTURE_H__ +#define __CTS_STRUCTURE_H__ + + +#define MAXIMUM_NUMBER_OF_ELEMENTS_PER_SENSOR 4 +#define TOTAL_NUMBER_OF_ELEMENTS 6 + + +#define ILLEGAL_SLIDER_WHEEL_POSITION 0xFFFFFFFF +#define WHEEL + +//****************************************************************************** +// The following structure definitons are application independent and are not +// intended to be modified. +// +// The CT_handler 'groups' the sensor based upon function and capacitive +// measurement method. +//****************************************************************************** +typedef struct +{ + unsigned long ulGPIOPort; + unsigned long ulGPIOPin; + unsigned long ulThreshold; + unsigned long ulMaxResponse; +} +tCapTouchElement; + +typedef struct tSensor +{ + unsigned char ucNumElements; + unsigned long ulNumSamples; + unsigned char ucPoints; + unsigned long ulSensorThreshold; + unsigned long ulBaseOffset; + const tCapTouchElement *Element[MAXIMUM_NUMBER_OF_ELEMENTS_PER_SENSOR]; +} +tSensor; + +extern const tCapTouchElement g_sVolumeDownElement; // structure containing elements for +extern const tCapTouchElement g_sVolumeUpElement; // +extern const tCapTouchElement g_sRightElement; // +extern const tCapTouchElement g_sLeftElement; // +extern const tCapTouchElement g_sMiddleElement; // +extern const tCapTouchElement g_sProximityElement; // + +extern const tSensor g_sSensorWheel; + +extern const tSensor g_sMiddleButton; // structure of info for a given + +#endif // __CTS_STRUCTURE_H__ -- cgit v1.3.1