/***************************************************************************//** * @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; }
//***************************************************************************** // //! Determine which element in a multi-element sensor is being pressed, if any. //! //! \param psSensor Pointer to sensor containing elements to be scanned. //! //! This function takes a capacitive measurement of all elements in \e //! psSensor, and checks to see if any element has exceeded the threshold for a //! touch event. If so, it will will return a pointer to the most active //! element, normalized by the \e ui32MaxResponse for each element. This //! function can be used with multi-element sensors to create an array of //! mutually exclusive buttons. //! //! Please note that this function will also update the baseline capacitance //! for all elements in the sensor psSensor. //! //! \return Returns a pointer to the element (button) being pressed or 0 if no //! element was pressed. // //***************************************************************************** const tCapTouchElement * TI_CAPT_Buttons(const tSensor *psSensor) { uint8_t ui8Index; // // Find the delta counts of all elements in the given sensor. // TI_CAPT_Custom(psSensor, g_pui32MeasCount); // // If at least one element was pressed, find the dominant element // (normalized by maximum response), and return a pointer to that element // back to the caller. // if(g_ui32CtsStatusReg & EVNT) { ui8Index = Dominant_Element(psSensor, g_pui32MeasCount); return(psSensor->psElement[ui8Index]); } else { // // If there were no touch events at all, return a zero. // return(0); } }
/***************************************************************************//** * @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; } } 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 -1)) { position = position - (int16_t)groupOfElements->points; } } 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; }
/***************************************************************************//** * @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 { 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; }
//***************************************************************************** // //! Detect touch events on a wheel element, and return the position of any //! touch event found in units of points. //! //! \param psSensor Pointer to the wheel element to be measured. //! //! This function performs a capacitive measurement on the given sensor \e //! psSensor, and interprets the results assuming that this sensor represents a //! physical wheel. Its return value is a numerical position along the surface //! of the wheel. A position of zero represents a touch on the wheel centered //! at the point where the element of index zero and the last element in the //! array physically touch. Position values increase around the circumference //! of the wheel in the same direction as increasing element indices in the \e //! psSensor structure. //! //! Please note that this function will also update the baseline capacitance //! for all elements in the sensor \e psSensor. //! //! \return Returns the calculate position of the touch event on the wheel or //! an illegal value \b ILLEGAL_SLIDER_WHEEL_POSITION if no touch was detected. // //***************************************************************************** uint32_t TI_CAPT_Wheel(const tSensor* psSensor) { uint8_t ui8NumElements, ui8Points, ui8PointsPerElement; uint8_t ui8Index; uint32_t ui32SensorThreshold, ui32WheelPosition; uint32_t ui32ThresholdCheck; // // Gather important sensor-level information // ui32SensorThreshold = psSensor->ui32SensorThreshold; ui8NumElements = psSensor->ui8NumElements; ui8Points = psSensor->ui8Points; ui8PointsPerElement = ui8Points / ui8NumElements; // // Take a measurement of delta counts, and store it in our global // measurement array. // TI_CAPT_Custom(psSensor, g_pui32MeasCount); // // Check the global EVNT flag to see if any elements in this sensor are // active. If not, we can skip the calculations and simply return an // illegal position. // if(g_ui32CtsStatusReg & EVNT) { // // If we did have a touch event, normalize the responses and find the // index of the dominant element. // ui8Index = Dominant_Element(psSensor, &g_pui32MeasCount[0]); // // Check to see if the normalized responses of the dominant element and // the adjacent elements are collectively high enough to cross the // overall sensor threshold. If so, we can conclude that the touch // event is somewhere within the intended track of the physical wheel, // and we can go ahead and calculate the position. Make sure to handle // the first and last elements carefully, as their neighbors wrap // around the array boundary. // if(ui8Index == 0) { ui32ThresholdCheck = (g_pui32MeasCount[ui8Index] + g_pui32MeasCount[ui8Index + 1] + g_pui32MeasCount[ui8NumElements - 1]); } else if(ui8Index == (ui8NumElements - 1)) { ui32ThresholdCheck = (g_pui32MeasCount[ui8Index] + g_pui32MeasCount[ui8Index - 1] + g_pui32MeasCount[0]); } else { ui32ThresholdCheck = (g_pui32MeasCount[ui8Index] + g_pui32MeasCount[ui8Index + 1] + g_pui32MeasCount[ui8Index - 1]); } // // If we didn't pass our threshold check, we probably have a touch // event close to the sensor, but not actually in the desired region of // the physical wheel. This means we should stop our calculation here // and return an illegal position value. // if(ui32ThresholdCheck < ui32SensorThreshold) { return ILLEGAL_SLIDER_WHEEL_POSITION; } // // If we passed the check, it's time to calculate the position (in // points) of the touch. We will start with the assumption that the // touch is in the exact center of the dominant element // ui32WheelPosition = ((ui8Index * ui8PointsPerElement) + (ui8PointsPerElement / 2)); // // Then we will improve our calculation of the touch position by // factoring in the measurements from the two adjacent elements. The // first and last sensors in the wheel are special cases, as each of // them only has one adjacent element. // if(ui8Index == 0) { // // Special case for the first element in the array, which requires // wrapping of the index. // ui32WheelPosition += ((g_pui32MeasCount[ui8Index + 1] * ui8PointsPerElement) / 100); ui32WheelPosition -= ((g_pui32MeasCount[ui8NumElements - 1] * ui8PointsPerElement) / 100); } else if(ui8Index == (ui8NumElements - 1)) { // // Special case for the last element in the array, which requires // wrapping of the index. // ui32WheelPosition += ((g_pui32MeasCount[0] * ui8PointsPerElement) / 100); ui32WheelPosition -= ((g_pui32MeasCount[ui8Index - 1] * ui8PointsPerElement) / 100); } else { // // No wrapping necessary, so just push the position based on the // measurements of the adjacent elements // ui32WheelPosition += ((g_pui32MeasCount[ui8Index + 1] * ui8PointsPerElement) / 100); ui32WheelPosition -= ((g_pui32MeasCount[ui8Index - 1] * ui8PointsPerElement) / 100); } // // Return the adjusted position back to the caller. // return ui32WheelPosition; } else { // // We didn't register any touch events at all, so return an illegal // wheel position // return ILLEGAL_SLIDER_WHEEL_POSITION; } }