Beispiel #1
0
// 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 
      {
Beispiel #2
0
//*****************************************************************************
//
//! 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));
        }
    }
}
Beispiel #3
0
/***************************************************************************//**
 * @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
}
Beispiel #4
0
/***************************************************************************//**
 * @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;
    }
}
Beispiel #5
0
/***************************************************************************//**
 * @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]);
}
Beispiel #6
0
/**
* 
* \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];
}
Beispiel #7
0
//*****************************************************************************
//
//! 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]);
}
Beispiel #8
0
//*****************************************************************************
//
//! 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;
    }
}
Beispiel #9
0
/***************************************************************************//**
 * @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;
        }
        }