// Main Function void main(void) { volatile unsigned int i,j; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1, 8, 12 or 16MHz DCOCTL = CALDCO_1MHZ; BCSCTL1 |= DIVA_0; // ACLK/(0:1,1:2,2:4,3:8) BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO P1OUT = 0x00; // Clear Port 1 bits P1DIR |= BIT0; // Set P1.0 as output pin P2SEL &= ~(BIT6 + BIT7); // Configure XIN (P2.6) and XOUT (P2.7) to GPIO P2OUT = 0x00; // Drive all Port 2 pins low P2DIR = 0xFF; // Configure all Port 2 pins outputs // Initialize Baseline measurement TI_CAPT_Raw(&middle_button,&base_cnt); // Main loop starts here while (1) { // Take raw delta measurement TI_CAPT_Raw(&middle_button,&meas_cnt); if(base_cnt < meas_cnt) // Handle baseline measurment for a base C decrease { // beyond baseline, i.e. cap decreased base_cnt = (base_cnt+meas_cnt) >> 1; // Re-average baseline up quickly delta_cnt = 0; // Zero out delta for position determination } else {
//***************************************************************************** // //! Update baseline capacitance numbers for a single sensor. //! //! \param psSensor Pointer to Sensor structure whose baseline values are to //! be measured. //! //! \param ui8NumberOfAverages Number of measurements to be averaged to form //! the new baseline capacitance. //! //! This function takes a series of TI_CAPT_Raw() measurements and averages //! them in to the baseline capacitance value set by TI_CAPT_Init_Baseline(). //! This function should not be used without first calling //! TI_CAPT_Init_Baseline(). //! //! \return none // //***************************************************************************** void TI_CAPT_Update_Baseline(const tSensor* psSensor, uint8_t ui8NumberOfAverages) { uint8_t ui8Loop2,ui8Loop; // // For every element in the sensor, loop through ui8NumberOfAverages times, // and average the results in to the baseline number stored in the main // baseline tracking array. // for(ui8Loop = 0; ui8Loop < ui8NumberOfAverages; ui8Loop++) { for(ui8Loop2 = 0; ui8Loop2 < psSensor->ui8NumElements; ui8Loop2++) { // // Take a capacitance measurement. // TI_CAPT_Raw(psSensor, g_pui32MeasCount); // // Average into the main baseline array, weighting more recent // samples more heavily than older samples. // g_ui32Baselines[ui8Loop2 + psSensor->ui32BaseOffset] = ((g_pui32MeasCount[ui8Loop2] / 2) + (g_ui32Baselines[ui8Loop2 + psSensor->ui32BaseOffset] / 2)); } } }
/***************************************************************************//** * @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 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; ctsStatusReg &= ~ EVNT; // This section calculates the delta counts************************************* //****************************************************************************** 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)))) { // RO method, interested in an increase in capacitance if(baseCnt[j+groupOfElements->baseOffset] < 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->arrayPtr[j])->threshold) && (baseCnt[j+groupOfElements->baseOffset]+(groupOfElements->arrayPtr[j])->threshold < tempCnt)) { tempCnt = baseCnt[j+groupOfElements->baseOffset]+(groupOfElements->arrayPtr[j])->threshold; } } else { // change occuring in our DOI, save result deltaCnt[j] = baseCnt[j+groupOfElements->baseOffset]-deltaCnt[j]; } } if(((!(ctsStatusReg & DOI_MASK)) && (groupOfElements->halDefinition & RO_MASK)) || ((ctsStatusReg & DOI_MASK) && (!(groupOfElements->halDefinition & RO_MASK)))) { // RO method: interested in a decrease in capactiance // measCnt is greater than baseCnt if(baseCnt[j+groupOfElements->baseOffset] > deltaCnt[j]) { // If capacitance increases, set delta to zero deltaCnt[j] = 0; // Limit the change in the opposite direction to the threshold if(((groupOfElements->arrayPtr[j])->threshold) && (baseCnt[j+groupOfElements->baseOffset] > tempCnt+(groupOfElements->arrayPtr[j])->threshold)) { tempCnt = baseCnt[j+groupOfElements->baseOffset]-(groupOfElements->arrayPtr[j])->threshold; } } else { // change occuring in our DOI 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 // measCnt value for the current index value 'i'. 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 tempCnt = tempCnt/64; baseCnt[j+groupOfElements->baseOffset] = 63*(baseCnt[j+groupOfElements->baseOffset]/64); break; case TRADOI_VSLOW://very slow tempCnt = tempCnt/128; baseCnt[j+groupOfElements->baseOffset] = 127*(baseCnt[j+groupOfElements->baseOffset]/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->baseOffset] = (tempCnt)+(baseCnt[j+groupOfElements->baseOffset]); } // delta counts are 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, switch ((ctsStatusReg & TRIDOI_FAST)) { case TRIDOI_VSLOW://very slow if(deltaCnt[j] > 15) { if(tempCnt < baseCnt[j+groupOfElements->baseOffset]) { baseCnt[j+groupOfElements->baseOffset] = baseCnt[j+groupOfElements->baseOffset] - 1; } else { baseCnt[j+groupOfElements->baseOffset] = baseCnt[j+groupOfElements->baseOffset] + 1; } } tempCnt = 0; break; case TRIDOI_SLOW://slow if(tempCnt < baseCnt[j+groupOfElements->baseOffset]) { baseCnt[j+groupOfElements->baseOffset] = baseCnt[j+groupOfElements->baseOffset] - 1; } else { baseCnt[j+groupOfElements->baseOffset] = baseCnt[j+groupOfElements->baseOffset] + 1; } 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; } // set X, Y & Z, then perform calculation for baseline tracking: // Base_Capacitance = X*(Measured_Capacitance/Z) + Y*(Base_Capacitance/Z) baseCnt[j+groupOfElements->baseOffset] = (tempCnt)+(baseCnt[j+groupOfElements->baseOffset]); } //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 Make a single capacitance measurement 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 Returns estimate of mL for this second. Will * update pad max values and next pad max values when * appropriate. * * \li INPUTS: * \li padCounts[TOTAL_PADS]: Taken from TI_CAPT_Raw. Generated * internally * \li sense_next: Flag to start checking padCounts against * pad_max_next * \li pad_max_current: Updated if necessary * * \li OUTPUTS: * \li numOfSubmergedPads: Raw count of submerged sensors * \li sensor_bits: 1 bit per sensor indicating submerged/not * \li zeroes: count of samples with zero sensors submerged * \li unknowns: count of samples with non-linear submerged * readings * * @return uint16_t Estimate flow in milliLiters */ static uint16_t waterSense_takeReading(void) { volatile uint16_t j; wsData.padStats.submergedPadsBitMask = 0; wsData.padStats.numOfSubmergedPads = 0; // Set the highestPad such that by default the flow rate lookup // value will be zero (in the flow rate table). uint8_t highestPad = TOTAL_PADS; bool waterNotSeenYet = true; // Perform the capacitive measurements TI_CAPT_Raw(&pad_sensors, &wsData.padStats.padCounts[0]); if (wsData.initMaxArrayDelay > 0) { wsData.initMaxArrayDelay--; if (wsData.initMaxArrayDelay == 0) { initMaxArray(); } } // Loop for each pad. // Pad 5 is the lowest and will see water first. // Start with the top pad (0) and move towards bottom pad (5) for (j = 0; j < TOTAL_PADS; j++) { int16_t padMeasDelta = 0; uint16_t padMaxCompare = wsData.pad_max_currentP[j]; uint16_t padCount = wsData.padStats.padCounts[j]; int16_t thresholdVal = thresholdTable[j]; // Rewriting comparison to avoid 'padAverage' and consider maximums instead // Get the difference between now and latest max value. // Higher values represent air. Lower values represent water. // Determined by how many charge counts occur per second. // Takes longer for water to charge the capacitor detection circuitry. padMeasDelta = padMaxCompare - padCount; wsData.padStats.padMeasDelta[j] = padMeasDelta; // If the difference is greater than the calibrated threshold, // then assume pad is covered in water. if ((wsData.padStats.padMeasDelta[j] > 0) && (wsData.padStats.padMeasDelta[j] > thresholdVal)) { // Set binary bit representing pad to true. wsData.padStats.submergedPadsBitMask |= (1 << j); wsData.padStats.numOfSubmergedPads++; // Update statistics for pad, don't roll-over uint16_t padSubmergedCount = wsData.padStats.pad_submerged[j]; if (padSubmergedCount != (uint16_t)0xFFFF) { wsData.padStats.pad_submerged[j]++; } // Mark the first pad from the top that sees water. // This will be used to figure out the current flow rate. if (waterNotSeenYet) { highestPad = j; waterNotSeenYet = false; } } // If this is a new max for the pad, record it if (wsData.padStats.padCounts[j] > wsData.pad_max_currentP[j]) { wsData.pad_max_currentP[j] = wsData.padStats.padCounts[j]; } // If this is a new max and recording for next calibration set, record it if ((wsData.padStats.padCounts[j] > wsData.pad_max_nextP[j]) && (wsData.prefillNextMaxTableFlag)) { wsData.pad_max_nextP[j] = wsData.padStats.padCounts[j]; } // If this is a new min, record it in tracking stats if (wsData.padStats.padCounts[j] < wsData.padStats.pad_min[j]) { wsData.padStats.pad_min[j] = wsData.padStats.padCounts[j]; } // If this is a new max, record it in tracking stats if (wsData.padStats.padCounts[j] > wsData.padStats.pad_max[j]) { wsData.padStats.pad_max[j] = wsData.padStats.padCounts[j]; } } // We are ignoring PAD5 based on the hardware issues with the PAD5 // measurement. Pad-5 is represented by the bit mask 0x20 (bit 6). // Clear bit 6 so that PAD5 will not be considered when checking // if the set of PADs detecting water represent a valid case. wsData.padStats.submergedPadsBitMask &= ~(1 << PAD5); // Based on the submergedPadsBitMask value, determine if it is a valid measurement switch (wsData.padStats.submergedPadsBitMask) { case 0x0: break; // Below are the valid PAD masks that represents readings from Pad4 up // with no gaps. Note that Pad-4 is the 0x10 mask. // Bits must be set in sequential logical bit sequence "down" from Pad4. // For example, it can't have Pad3 on without Pad4 on. Pad2 can't // be set without Pad4 and Pad3, etc. // Note - PAD5 has been removed from the possible detected PAD bit masks case 0x10: // PAD 4 is detecting water case 0x18: // PADS 4,3 are detecting water case 0x1c: // PADS 4,3,2 are detecting water case 0x1e: // PADS 4,3,2,1 are detecting water case 0x1f: // PADS 4,3,2,1,0 are detecting water // A valid PAD sequence has been detected break; default: { // The sensors did not detect in a logical order // We don't want to use the unknown case for flow rate accumulation. // Set the highestPad such that the flow rate lookup // value will be zero (in the flow rate table). highestPad = TOTAL_PADS; // Log the error case. // Don't roll-over the count uint16_t unknowsCount = wsData.padStats.unknowns; if (unknowsCount != (uint16_t)0xFFFF) { wsData.padStats.unknowns++; } } break; } // Return mL flow rate for this second return highMarkFlowRates[highestPad]; }
//***************************************************************************** // //! Make a single capacitance measurement to initialize baseline tracking. //! //! \param psSensor Pointer to Sensor structure whose baseline capacitance is //! to be measured. //! //! This function calls TI_CAPT_Raw(), and saves the resulting measurement to //! the main array of baseline capacitance measurements. This should be called //! towards the beginning of any application that intends to use the more //! complex measurement functions. //! //! \note This function MUST be called on a sensor structure before any other //! function in this file is called on that same sensor structure, with the //! exception of TI_CAPT_Raw(). //! //! \return None. // //***************************************************************************** void TI_CAPT_Init_Baseline(const tSensor *psSensor) { TI_CAPT_Raw(psSensor, &g_ui32Baselines[psSensor->ui32BaseOffset]); }
//***************************************************************************** // //! Measure the changes in capacitance "delta counts" of the elements of the //! chosen sensor in the current direction of interest, and report any detected //! touch events. //! //! \param psSensor Pointer to Sensor structure to be measured //! //! \param pui32DeltaCnt Address to where the measurements are to be written //! //! For every element in the sensor \e psSensor, this function will measure the //! current capacitance, and calculate the difference between the raw //! measurement and the most recent baseline capacitance of that element. If //! this difference is in the current direction of interest (specified by the //! \e g_ui32CtsStatusReg variable), the absolute value of the difference in //! capacitance (referred to as a "delta count") will be placed in the provided //! \e pui32DeltaCnt array. The order of delta counts in \e pui32DeltaCnt will //! match the order of elements in \e psSensor. //! //! If the delta count of any element exceeds the threshold for that element, //! this function will also set the \b EVNT bit in the \e g_ui32CtsStatusReg //! variable. This bit may be used by the caller to determine whether any //! element in \e psSensor is currently being touched. //! //! Finally, if none of the delta counts exceed the threshold for their //! respective elements, this function will use the measured capacitance values //! to adjust the baseline capacitance values for all elements in the sensor. //! The rate at which the baseline value changes is specified by the value of //! \e g_ui32CtsStatusReg. //! //! \return none // //***************************************************************************** void TI_CAPT_Custom(const tSensor* psSensor, uint32_t* pui32DeltaCnt) { uint8_t ui8Loop; uint32_t ui32RawCount, ui32BoundedRawCount, ui32BaseCount; uint32_t ui32Threshold, ui32TrackingFactor; // // Clear any events that might be left in the global status register from // previous iterations of this call. // g_ui32CtsStatusReg &= ~(EVNT); // // First, gather raw measurements of all elements in the sensor. We will // store them in the array called pui32DeltaCnt for no because we can // expect this array to be big enough to hold the data from TI_CAPT_Raw(), // but please note that they are not really "delta counts" at this time. // TI_CAPT_Raw(psSensor, &pui32DeltaCnt[0]); // // Loop over the elements in the sensor // for (ui8Loop = 0; ui8Loop < (psSensor->ui8NumElements); ui8Loop++) { // // Obtain the relevant data for this element, including its baseline // count, threshold, and its most recent raw count. // ui32RawCount = pui32DeltaCnt[ui8Loop]; ui32Threshold = (psSensor->psElement[ui8Loop])->ui32Threshold; ui32BaseCount = g_ui32Baselines[ui8Loop + psSensor->ui32BaseOffset]; // // Use our direction of interest to figure out how to interpret the // relationship between raw count, baseline, and threshold. // if(!(g_ui32CtsStatusReg & DOI_MASK)) { // // If our direction of interest is DECREASING, meaning that // DECREASED count values correspond to touch events, we will use // the following formula to obtain the delta count. // if(ui32BaseCount > ui32RawCount) { pui32DeltaCnt[ui8Loop] = ui32BaseCount - ui32RawCount; } else { pui32DeltaCnt[ui8Loop] = 0; } // // Also, create a bounded version of the raw count for use with the // baseline tracking algorithm. Limiting the raw count to be no // higher than (baseline + threshold) prevents the baseline from // changing too quickly. // if(ui32RawCount > (ui32BaseCount + ui32Threshold)) { ui32BoundedRawCount = ui32BaseCount + ui32Threshold; } else { ui32BoundedRawCount = ui32RawCount; } } else if(g_ui32CtsStatusReg & DOI_MASK) { // // If our direction of interest is INCREASING, meaning that // INCREASED count values correspond to touch events, we will use // the following formula to obtain a delta count. // if(ui32RawCount > ui32BaseCount) { pui32DeltaCnt[ui8Loop] = ui32RawCount - ui32BaseCount; } else { pui32DeltaCnt[ui8Loop] = 0; } // // Again, create a bounded version of the raw count for use with the // baseline tracking algorithm. Limiting the raw count to be no // lower than (baseline - threshold) prevents the baseline from // changing too quickly. // if(ui32RawCount < (ui32BaseCount - ui32Threshold)) { ui32BoundedRawCount = ui32BaseCount - ui32Threshold; } else { ui32BoundedRawCount = ui32RawCount; } } // // At this point, we have determined our delta value for this element, // but we still need to look for touch events and update our baseline // measurements. This all depends on the delta count, the threshold, // and whether an event has been seen recently. // if(pui32DeltaCnt[ui8Loop] > ui32Threshold) { // // Our delta was above the threshold, which means we have a touch // event. Record this in the g_ui32CtsStatusReg so it can be used // by the application. There is no need for further baseline // tracking for a while after an event, so set the PAST_EVNT flag // as well. // g_ui32CtsStatusReg |= EVNT; g_ui32CtsStatusReg |= PAST_EVNT; } else if(!(g_ui32CtsStatusReg & PAST_EVNT)) { // // If we didn't trigger an event above, and we haven't seen an // event recently, we need to do baseline tracking. Calculate the // correct baseline tracking factor here. // if(pui32DeltaCnt[ui8Loop] > 0) { // // If we had a positive delta count, we use the IN // direction-of-interest tracking factor // switch(g_ui32CtsStatusReg & TRIDOI_FAST) { // // Special case for "very slow": only move in increments of // one. // case TRIDOI_VSLOW: // // A tracking factor of zero means that the averaging // equation won't be used. // ui32TrackingFactor = 0; // // Move the base count one value towards the bounded // raw count. // if(ui32BoundedRawCount > ui32BaseCount) { ui32BaseCount++; } else { ui32BaseCount--; } break; case TRIDOI_SLOW: ui32TrackingFactor = 128; break; case TRIDOI_MED: ui32TrackingFactor = 4; break; case TRIDOI_FAST: ui32TrackingFactor = 2; break; default: // // We shouldn't ever get here, but this case should // keep us safe. // ui32TrackingFactor = 0; } } else { // // If we had a zero or negative delta count, set the delta // count to zero, and use the AGAINST direction-of-interest // factor. // pui32DeltaCnt[ui8Loop] = 0; switch ((g_ui32CtsStatusReg & TRADOI_VSLOW)) { case TRADOI_FAST: ui32TrackingFactor = 2; break; case TRADOI_MED: ui32TrackingFactor = 4; break; case TRADOI_SLOW: ui32TrackingFactor = 64; break; case TRADOI_VSLOW: ui32TrackingFactor = 128; break; default: // // We shouldn't ever get here, but this case should // keep us safe. // ui32TrackingFactor = 0; } } // // Update our baseline using our bounded raw count and our tracking // factor, and write our new calculated baseline back to the global // array. // if(ui32TrackingFactor) { ui32BaseCount = ((ui32BaseCount * (ui32TrackingFactor - 1) + ui32BoundedRawCount) / (ui32TrackingFactor)); } g_ui32Baselines[ui8Loop + psSensor->ui32BaseOffset] = ui32BaseCount; } } // // If we got all the way down here without seeing any events, we should // clear the PAST_EVNT flag to avoid interfering with future calls of this // function. // if(!(g_ui32CtsStatusReg & EVNT)) { g_ui32CtsStatusReg &= ~PAST_EVNT; } }
/***************************************************************************//** * @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; } }