/* --COPYRIGHT--,BSD
|
|
* Copyright (c) 2013, Texas Instruments Incorporated
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* * Neither the name of Texas Instruments Incorporated nor the names of
|
|
* its contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
* --/COPYRIGHT--*/
|
|
/*!
|
|
* @file CTS_HAL.c
|
|
*
|
|
* @brief This file contains the source for the different implementations.
|
|
*
|
|
* @par Project:
|
|
* MSP430 Capacitive Touch Library
|
|
*
|
|
* @par Developed using:
|
|
* CCS Version : 5.4.0.00048, w/support for GCC extensions (--gcc)
|
|
* \n IAR Version : 5.51.6 [Kickstart]
|
|
*
|
|
* @author C. Sterzik
|
|
* @author T. Hwang
|
|
*
|
|
* @version 1.2 Added HALs for new devices.
|
|
*
|
|
* @par Supported Hardware Implementations:
|
|
* - TI_CTS_RO_COMPAp_TA0_WDTp_HAL()
|
|
* - TI_CTS_fRO_COMPAp_TA0_SW_HAL()
|
|
* - TI_CTS_fRO_COMPAp_SW_TA0_HAL()
|
|
* - TI_CTS_RO_COMPAp_TA1_WDTp_HAL()
|
|
* - TI_CTS_fRO_COMPAp_TA1_SW_HAL()
|
|
* - TI_CTS_RC_PAIR_TA0_HAL()
|
|
* - TI_CTS_RO_PINOSC_TA0_WDTp_HAL()
|
|
* - TI_CTS_RO_PINOSC_TA0_HAL()
|
|
* - TI_CTS_fRO_PINOSC_TA0_SW_HAL()
|
|
* - TI_CTS_RO_COMPB_TA0_WDTA_HAL()
|
|
* - TI_CTS_RO_COMPB_TA1_WDTA_HAL()
|
|
* - TI_CTS_fRO_COMPB_TA0_SW_HAL()
|
|
* - TI_CTS_fRO_COMPB_TA1_SW_HAL()
|
|
* - Added in version 1.1
|
|
* - TI_CTS_fRO_PINOSC_TA0_TA1_HAL()
|
|
* - TI_CTS_RO_PINOSC_TA0_TA1_HAL()
|
|
* - TI_CTS_RO_CSIO_TA2_WDTA_HAL()
|
|
* - TI_CTS_RO_CSIO_TA2_TA3_HAL()
|
|
* - TI_CTS_fRO_CSIO_TA2_TA3_HAL()
|
|
* - TI_CTS_RO_COMPB_TB0_WDTA_HAL()
|
|
* - TI_CTS_RO_COMPB_TA1_TA0_HAL()
|
|
* - TI_CTS_fRO_COMPB_TA1_TA0_HAL()
|
|
* - Added in version 1.2
|
|
* - TI_CTS_RO_PINOSC_TA1_WDTp_HAL()
|
|
* - TI_CTS_RO_PINOSC_TA1_TB0_HAL()
|
|
* - TI_CTS_fRO_PINOSC_TA1_TA0_HAL()
|
|
* - TI_CTS_fRO_PINOSC_TA1_TB0_HAL()
|
|
*
|
|
*/
|
|
|
|
/*!
|
|
* @defgroup CTS_HAL Capacitive Touch Implementations
|
|
* @{
|
|
*/
|
|
|
|
#include "CTS_HAL.h"
|
|
|
|
#ifdef RO_COMPB_TB0_WDTA
|
|
/*!
|
|
* ======== TI_CTS_RO_COMPB_TB0_WDTA_HAL ========
|
|
* @brief RO method capactiance measurement using CompB, TimerB0, and WDTA
|
|
*
|
|
* \n Schematic Description of CompB forming relaxation oscillator and
|
|
* coupling (connection) between the relaxation oscillator and TimerA0.
|
|
* \n <- Output
|
|
* \n -> Input
|
|
* \n R Resistor (typically 100Kohms)
|
|
*
|
|
* \n element---R----<-CBOUT/TB0CLK
|
|
*
|
|
* \n The WDTA interval represents the measurement window. The number of
|
|
* counts within the TB0R that have accumulated during the measurement
|
|
* window represents the capacitance of the element.
|
|
*
|
|
* @param group pointer to the sensor to be measured
|
|
* @param counts pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_RO_COMPB_TB0_WDTA_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
/*
|
|
* Allocate Context Save Variables
|
|
* Status Register: GIE bit only
|
|
* SFR: SFRIE1
|
|
* WDTA: WDTCTL
|
|
* TIMERB0: TB0CTL, TB0CCTL0, TB0CCR0
|
|
* COMPB: CBCTL0,CBCTL1,CBCTL2, CBCTL3
|
|
*/
|
|
uint8_t contextSaveSR;
|
|
uint16_t contextSaveSFRIE1;
|
|
uint16_t contextSaveWDTCTL;
|
|
uint16_t contextSaveTB0CTL,contextSaveTB0CCTL0,contextSaveTB0CCR0;
|
|
uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
|
|
uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
|
|
uint8_t contextSaveCboutDir,contextSaveCboutSel;
|
|
/* Perform context save of registers used. */
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveSFRIE1 = SFRIE1;
|
|
contextSaveWDTCTL = WDTCTL;
|
|
contextSaveWDTCTL &= 0x00FF;
|
|
contextSaveWDTCTL |= WDTPW;
|
|
contextSaveTB0CTL = TB0CTL;
|
|
contextSaveTB0CCTL0 = TB0CCTL0;
|
|
contextSaveTB0CCR0 = TB0CCR0;
|
|
contextSaveCBCTL0 = CBCTL0;
|
|
contextSaveCBCTL1 = CBCTL1;
|
|
contextSaveCBCTL2 = CBCTL2;
|
|
contextSaveCBCTL3 = CBCTL3;
|
|
/* TAx naming convention is left to preserve compatibility. */
|
|
contextSaveCboutDir = *(group->cboutTAxDirRegister);
|
|
contextSaveCboutSel = *(group->cboutTAxSelRegister);
|
|
/*
|
|
* Connect CBOUT with TB0. This also enables the feedback path for the
|
|
* Relaxation oscillator.
|
|
*/
|
|
*(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
|
|
*(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
|
|
/*
|
|
* The COMPB reference is set to Vcc and the reference resistor taps are
|
|
* Vcc*(0x18+1)/32 for CBOUT = 1 and Vcc*((0x04+1)/32 for CBOUT = 0.
|
|
* If Vcc is 3.0V, then the Vih is 2.34V and the Vil is 0.47V. In the
|
|
* event that CBOUT is connected to DVIO which is not equal to Vcc, then
|
|
* these voltage levels need to be adjusted.
|
|
*/
|
|
CBCTL2 = CBRS_1 + CBREF14 + CBREF13 + CBREF02;
|
|
CBCTL3 |= (group->cbpdBits); // set CPD bits to disable digital IO
|
|
/*
|
|
* TimerB0 is the measurement timer and counts the number of relaxation
|
|
* oscillation cycles of the element which is connected to TBCLK.
|
|
* TimerB0 is in continuous mode. TB0CCR0 is configured as a capture
|
|
* register and will be triggered as a SW capture event.
|
|
*/
|
|
TB0CTL = TBSSEL_0+MC_2;
|
|
TB0CCTL0 = CM_3+CCIS_2+CAP;
|
|
/*
|
|
* The WDTA is the gate (measurement interval) timer. The number of
|
|
* oscillations counted, by TimerB0, within the gate interval represents
|
|
* the measured capacitance.
|
|
*/
|
|
SFRIE1 |= WDTIE; // Enable WDTA interrupt
|
|
CBCTL1 = CBON; // Turn on COMPB w/out filter
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
/* Turn on specific comparator input. */
|
|
CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
|
|
TB0CTL |= TBCLR; // Clear TimerB0, measurement timer
|
|
TB0CTL &= ~TBIFG; // Clear overflow flag
|
|
/*
|
|
* The measGateSource represents the gate source for the WDTA, which
|
|
* can be sourced from ACLK, SMCLK, VLOCLK or X_CLK. The
|
|
* accumulationCycles represents the watchdog timer interval select.
|
|
*/
|
|
WDTCTL = WDTPW+WDTTMSEL+WDTCNTCL+ group->measGateSource
|
|
+ group->accumulationCycles;
|
|
/*
|
|
* The interrupt handler is defined in WDT_VECTOR, which simply clears
|
|
* the low power mode bits in the Status Register before returning
|
|
* from the ISR.
|
|
*/
|
|
if(group->measGateSource == GATE_WDT_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); //Enable the GIE and wait for ISR
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE);
|
|
}
|
|
TB0CCTL0 ^= CCIS0; // Create SW capture of TB0R into TB0CCR0.
|
|
WDTCTL = WDTPW + WDTHOLD; // Halt watchdog timer
|
|
if(TB0CTL & TBIFG)
|
|
{
|
|
/*
|
|
* If a rollover in the timer has occurred then set counts to
|
|
* 0. This will prevent erroneous data from entering the baseline
|
|
* tracking algorithm.
|
|
*/
|
|
counts[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
counts[i] = TB0CCR0; // Save result
|
|
}
|
|
} // End For Loop
|
|
/* Context restore GIE within Status Register and registers used. */
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE);
|
|
}
|
|
SFRIE1 = contextSaveSFRIE1;
|
|
WDTCTL = contextSaveWDTCTL;
|
|
TB0CTL = contextSaveTB0CTL;
|
|
TB0CCTL0 = contextSaveTB0CCTL0;
|
|
TB0CCR0 = contextSaveTB0CCR0;
|
|
CBCTL0 = contextSaveCBCTL0;
|
|
CBCTL1 = contextSaveCBCTL1;
|
|
CBCTL2 = contextSaveCBCTL2;
|
|
CBCTL3 = contextSaveCBCTL3;
|
|
*(group->cboutTAxDirRegister) = contextSaveCboutDir;
|
|
*(group->cboutTAxSelRegister) = contextSaveCboutSel;
|
|
}
|
|
#endif
|
|
|
|
#ifdef fRO_CSIO_TA2_TA3
|
|
/*!
|
|
* ======== TI_CTS_RO_CSIO_TA2_TA3_HAL ========
|
|
* @brief fRO using Capacitive Touch IO, TimerA2, and TimerA3
|
|
*
|
|
* \n Schematic Description:
|
|
*
|
|
* \n element-----+->Px.y
|
|
*
|
|
* \n The TimerA2 interval represents the measurement window. The number
|
|
* of counts within the TA3R that have accumulated during the
|
|
* measurement window represents the capacitance of the element.
|
|
*
|
|
* @param group pointer to the sensor to be measured
|
|
* @param counts pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_fRO_CSIO_TA2_TA3_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
/*
|
|
* Allocate Context Save Variables
|
|
* Status Register: GIE bit only
|
|
* SFR: SFRIE1
|
|
* TIMERA2: TA2CTL, TA2CCTL0, TA2CCR0
|
|
* TIMERA3: TA3CTL, TA3CCTL0, TA3CCR0
|
|
* CSIO: CSIOxCTL
|
|
*/
|
|
uint8_t contextSaveSR;
|
|
uint16_t contextSaveTA2CTL,contextSaveTA2CCTL0,contextSaveTA2CCR0;
|
|
uint16_t contextSaveTA3CTL,contextSaveTA3CCTL0,contextSaveTA3CCR0;
|
|
uint8_t contextSaveCtl;
|
|
/* Perform context save of registers used. */
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveTA2CTL = TA2CTL;
|
|
contextSaveTA2CCTL0 = TA2CCTL0;
|
|
contextSaveTA2CCR0 = TA2CCR0;
|
|
contextSaveTA3CTL = TA3CTL;
|
|
contextSaveTA3CCTL0 = TA3CCTL0;
|
|
contextSaveTA3CCR0 = TA3CCR0;
|
|
contextSaveCtl = *(group->inputCapsioctlRegister);
|
|
/*
|
|
* TimerA3 is the measurement timer and counts the number of clock cycles
|
|
* of the source which is connected to measGateSource, typically SMCLK.
|
|
* TimerA3 is in continuous mode. TA3CCR0 is configured as a capture
|
|
* register and will be triggered as a SW capture event.
|
|
*/
|
|
TA3CTL = group->measGateSource + MC_2;
|
|
TA3CCTL0 = CM_3+CCIS_2+CAP;
|
|
/*
|
|
* TimerA2 is the gate (measurement interval) timer. The number of
|
|
* oscillations counted, by TimerA3, within the gate interval represents
|
|
* the measured capacitance. The input is TA2CLK.
|
|
*/
|
|
TA2CCR0 = (group->accumulationCycles);
|
|
TA2CTL = TASSEL_3+group->sourceScale;
|
|
TA2CCTL0 = CCIE;
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
/* Enable Capacitive Touch IO oscillation */
|
|
*(group->inputCapsioctlRegister)
|
|
= ((group->arrayPtr[i])->inputBits)+CAPSIOEN;
|
|
TA3CTL |= TACLR; // Clear TimerA3, measurement timer
|
|
TA3CTL &= ~TAIFG; // Clear overflow flag
|
|
TA2CTL |= (TACLR + MC_1); // Clear and start TimerA3
|
|
/*
|
|
* The measGateSource represents the measurement source for timer
|
|
* TIMERA3, which can be sourced from TACLK, ACLK, SMCLK, or INCLK.
|
|
* The interrupt handler is defined in TIMER2_A0_VECTOR, which simply
|
|
* clears the low power mode bits in the Status Register before
|
|
* returning from the ISR.
|
|
*/
|
|
if(group->measGateSource == TIMER_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); // Enable GIE and wait for ISR
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE);
|
|
}
|
|
TA3CCTL0 ^= CCIS0; // Create SW capture of TA3R into TA3CCR0
|
|
TA2CTL &= ~MC_1; // Halt Timer
|
|
if(TA3CTL & TAIFG)
|
|
{
|
|
/*
|
|
* If a rollover in the timer has occurred then set counts to
|
|
* 0. This will prevent erroneous data from entering the baseline
|
|
* tracking algorithm.
|
|
*/
|
|
counts[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
counts[i] = TA3CCR0; // Save result
|
|
}
|
|
} // End For Loop
|
|
/* Context restore GIE within Status Register and registers used. */
|
|
*(group->inputCapsioctlRegister) = contextSaveCtl;
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE);
|
|
}
|
|
TA2CTL = contextSaveTA2CTL;
|
|
TA2CCTL0 = contextSaveTA2CCTL0;
|
|
TA2CCR0 = contextSaveTA2CCR0;
|
|
TA3CTL = contextSaveTA3CTL;
|
|
TA3CCTL0 = contextSaveTA3CCTL0;
|
|
TA3CCR0 = contextSaveTA3CCR0;
|
|
}
|
|
#endif
|
|
|
|
#ifdef RO_CSIO_TA2_TA3
|
|
/*!
|
|
* ======== TI_CTS_RO_CSIO_TA2_TA3_HAL ========
|
|
* @brief RO method using Capacitive Touch IO, TimerA2, and TimerA3
|
|
*
|
|
* \n Schematic Description:
|
|
* \n element-----+->Px.y
|
|
*
|
|
* \n The TimerA3 interval represents the measurement window. The number
|
|
* of counts within the TA2R that have accumulated during the
|
|
* measurement window represents the capacitance of the element.
|
|
*
|
|
* @param group pointer to the sensor to be measured
|
|
* @param counts pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_RO_CSIO_TA2_TA3_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
/*
|
|
* Allocate Context Save Variables
|
|
* Status Register: GIE bit only
|
|
* SFR: SFRIE1
|
|
* TIMERA2: TA2CTL, TA2CCTL0, TA2CCR0
|
|
* TIMERA3: TA3CTL, TA3CCTL0, TA3CCR0
|
|
* CSIO: CSIOxCTL
|
|
*/
|
|
uint8_t contextSaveSR;
|
|
uint16_t contextSaveTA2CTL,contextSaveTA2CCTL0,contextSaveTA2CCR0;
|
|
uint16_t contextSaveTA3CTL,contextSaveTA3CCTL0,contextSaveTA3CCR0;
|
|
uint8_t contextSaveCtl;
|
|
/* Perform context save of registers used. */
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveTA2CTL = TA2CTL;
|
|
contextSaveTA2CCTL0 = TA2CCTL0;
|
|
contextSaveTA2CCR0 = TA2CCR0;
|
|
contextSaveTA3CTL = TA3CTL;
|
|
contextSaveTA3CCTL0 = TA3CCTL0;
|
|
contextSaveTA3CCR0 = TA3CCR0;
|
|
contextSaveCtl = *(group->inputCapsioctlRegister);
|
|
/*
|
|
* TimerA2 is the measurement timer and counts the number of relaxation
|
|
* oscillation cycles of the element which is connected to TA2CLK.
|
|
* TimerA2 is in continuous mode. TA2CCR0 is configured as a capture
|
|
* register and will be triggered as a SW capture event.
|
|
*/
|
|
TA2CTL = TASSEL_3+MC_2;
|
|
TA2CCTL0 = CM_3+CCIS_2+CAP;
|
|
/*
|
|
* TimerA3 is the gate (measurement interval) timer. The number of
|
|
* oscillations counted, by TimerA2, within the gate interval represents
|
|
* the measured capacitance.
|
|
*/
|
|
TA3CCR0 = (group->accumulationCycles);
|
|
TA3CTL = group->measGateSource + group->sourceScale;
|
|
TA3CCTL0 = CCIE;
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
/* Enable Capacitive Touch IO oscillation */
|
|
*(group->inputCapsioctlRegister)
|
|
= ((group->arrayPtr[i])->inputBits)+CAPSIOEN;
|
|
TA2CTL |= TACLR; // Clear TimerA2, measurement timer
|
|
TA2CTL &= ~TAIFG; // Clear overflow flag
|
|
TA3CTL |= (TACLR + MC_1); // Clear and start TimerA3
|
|
/*
|
|
* The measGateSource represents the gate source for timer TIMERA3,
|
|
* which can be sourced from TACLK, ACLK, SMCLK, or INCLK. The
|
|
* interrupt handler is defined in TIMER3_A0_VECTOR, which simply
|
|
* clears the low power mode bits in the Status Register before
|
|
* returning from the ISR.
|
|
*/
|
|
if(group->measGateSource == TIMER_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); // Enable GIE and wait for ISR
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE);
|
|
}
|
|
TA2CCTL0 ^= CCIS0; // Create SW capture of TA2R into TA2CCR0
|
|
TA3CTL &= ~MC_1; // Halt Timer
|
|
if(TA2CTL & TAIFG)
|
|
{
|
|
/*
|
|
* If a rollover in the timer has occurred then set counts to
|
|
* 0. This will prevent erroneous data from entering the baseline
|
|
* tracking algorithm.
|
|
*/
|
|
counts[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
counts[i] = TA2CCR0; // Save result
|
|
}
|
|
} // End For Loop
|
|
/* Context restore GIE within Status Register and registers used. */
|
|
*(group->inputCapsioctlRegister) = contextSaveCtl;
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE);
|
|
}
|
|
TA2CTL = contextSaveTA2CTL;
|
|
TA2CCTL0 = contextSaveTA2CCTL0;
|
|
TA2CCR0 = contextSaveTA2CCR0;
|
|
TA3CTL = contextSaveTA3CTL;
|
|
TA3CCTL0 = contextSaveTA3CCTL0;
|
|
TA3CCR0 = contextSaveTA3CCR0;
|
|
}
|
|
#endif
|
|
|
|
#ifdef RO_CSIO_TA2_WDTA
|
|
/*!
|
|
* ======== TI_CTS_RO_CSIO_TA2_WDTA_HAL ========
|
|
* @brief RO method measurement using Capacitive Touch IO, TimerA2, and WDTA
|
|
*
|
|
* \n Schematic Description:
|
|
*
|
|
* \n element-----+->Px.y
|
|
*
|
|
* \n The WDTA interval represents the measurement window. The number of
|
|
* counts within the TA2R that have accumulated during the measurement
|
|
* window represents the capacitance of the element.
|
|
*
|
|
* @param group pointer to the sensor to be measured
|
|
* @param counts pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_RO_CSIO_TA2_WDTA_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
/*
|
|
* Allocate Context Save Variables
|
|
* Status Register: GIE bit only
|
|
* SFR: SFRIE1
|
|
* WDT: WDTCTL
|
|
* TIMERA2: TA2CTL, TA2CCTL0, TA2CCR0
|
|
* CSIO: CSIOxCTL
|
|
*/
|
|
uint8_t contextSaveSR;
|
|
uint8_t contextSaveSFRIE1;
|
|
uint16_t contextSaveWDTCTL;
|
|
uint16_t contextSaveTA2CTL,contextSaveTA2CCTL0,contextSaveTA2CCR0;
|
|
uint8_t contextSaveCtl;
|
|
/* Perform context save of registers used. */
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveSFRIE1 = SFRIE1;
|
|
contextSaveWDTCTL = WDTCTL;
|
|
contextSaveWDTCTL &= 0x00FF;
|
|
contextSaveWDTCTL |= WDTPW;
|
|
contextSaveTA2CTL = TA2CTL;
|
|
contextSaveTA2CCTL0 = TA2CCTL0;
|
|
contextSaveTA2CCR0 = TA2CCR0;
|
|
contextSaveCtl = *(group->inputCapsioctlRegister);
|
|
/*
|
|
* TimerA2 is the measurement timer and counts the number of relaxation
|
|
* oscillation cycles of the element which is connected to TA2CLK.
|
|
* TimerA2 is in continuous mode. TA2CCR0 is configured as a capture
|
|
* register and will be triggered as a SW capture event.
|
|
*/
|
|
TA2CTL = TASSEL_3+MC_2;
|
|
TA2CCTL0 = CM_3+CCIS_2+CAP;
|
|
/*
|
|
* The WDTA is the gate (measurement interval) timer. The number of
|
|
* oscillations counted, by TimerA2, within the gate interval represents
|
|
* the measured capacitance.
|
|
*/
|
|
SFRIE1 |= WDTIE; // Enable WDTA interrupt
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
/* Enable Capacitive Touch IO oscillation */
|
|
*(group->inputCapsioctlRegister)
|
|
= ((group->arrayPtr[i])->inputBits)+CAPSIOEN;
|
|
TA2CTL |= TACLR; // Clear Timer_A2 measurement timer
|
|
TA2CTL &= ~TAIFG; // Clear the overflow flag
|
|
/*
|
|
* The measGateSource represents the gate source for the WDTA, which
|
|
* can be sourced from ACLK, SMCLK, VLOCLK or X_CLK. The
|
|
* accumulationCycles represents the watchdog timer interval select.
|
|
*/
|
|
WDTCTL = WDTPW+WDTTMSEL+WDTCNTCL+ group->measGateSource
|
|
+ group->accumulationCycles;
|
|
/*
|
|
* The interrupt handler is defined in WDT_VECTOR, which simply clears
|
|
* the low power mode bits in the Status Register before returning
|
|
* from the ISR.
|
|
*/
|
|
if(group->measGateSource == GATE_WDT_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); //Enable the GIE and wait for ISR
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE);
|
|
}
|
|
TA2CCTL0 ^= CCIS0; // Create SW capture of TA2R into TA2CCR0
|
|
WDTCTL = WDTPW + WDTHOLD; // Halt watchdog timer
|
|
if(TA2CTL & TAIFG)
|
|
{
|
|
/*
|
|
* If a rollover in the timer has occurred then set counts to
|
|
* 0. This will prevent erroneous data from entering the baseline
|
|
* tracking algorithm.
|
|
*/
|
|
counts[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
counts[i] = TA2CCR0; // Save result
|
|
}
|
|
} // End For Loop
|
|
/* Context restore GIE within Status Register and registers used. */
|
|
*(group->inputCapsioctlRegister) = contextSaveCtl;
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE);
|
|
}
|
|
SFRIE1 = contextSaveSFRIE1;
|
|
WDTCTL = contextSaveWDTCTL;
|
|
TA2CTL = contextSaveTA2CTL;
|
|
TA2CCTL0 = contextSaveTA2CCTL0;
|
|
TA2CCR0 = contextSaveTA2CCR0;
|
|
}
|
|
#endif
|
|
|
|
#ifdef fRO_PINOSC_TA0_TA1
|
|
/*!
|
|
* @brief fRO method capacitance measurement using PinOsc IO, TimerA0, and
|
|
* TimerA1
|
|
*
|
|
* \n Schematic Description:
|
|
*
|
|
* \n element-----+->Px.y
|
|
*
|
|
* \n The TimerA0 interval represents the measurement window. The number
|
|
* of counts within the TA1R that have accumulated during the
|
|
* measurement window represents the capacitance of the element.
|
|
*
|
|
* @param group Pointer to the structure describing the Sensor to be measured
|
|
* @param counts Pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_fRO_PINOSC_TA0_TA1_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
|
|
/*
|
|
* Context Save
|
|
* Status Register: GIE
|
|
* TIMERA0: TA0CTL, TA0CCTL0, TA0CCR0
|
|
* TIMERA1: TA1CTL, TA1CCTL0, TA1CCR1
|
|
* Ports: PxSEL, PxSEL2
|
|
*/
|
|
uint8_t contextSaveSR;
|
|
uint16_t contextSaveTA0CTL,contextSaveTA0CCTL0,contextSaveTA0CCR0;
|
|
uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
|
|
uint8_t contextSaveSel,contextSaveSel2;
|
|
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveTA0CTL = TA0CTL;
|
|
contextSaveTA0CCTL0 = TA0CCTL0;
|
|
contextSaveTA0CCR0 = TA0CCR0;
|
|
contextSaveTA1CTL = TA1CTL;
|
|
contextSaveTA1CCTL0 = TA1CCTL0;
|
|
contextSaveTA1CCR0 = TA1CCR0;
|
|
|
|
//** Setup Measurement timer***************************************************
|
|
// Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
|
|
// capacitive touch layer.
|
|
|
|
// Configure Measurement interval with TimerA0
|
|
TA0CCR0 = (group->accumulationCycles);
|
|
/*
|
|
* INCLK, IDx settings from sourceScale definition
|
|
*/
|
|
TA0CTL = TASSEL_3 + group->sourceScale;
|
|
TA0CCTL0 = CCIE;
|
|
|
|
// Configure and start measurment timerA1
|
|
TA1CTL = group->measGateSource + MC_2 + TACLR; // cont
|
|
TA1CCTL0 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
|
|
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
// Context Save
|
|
contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
|
|
contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
|
|
// Configure Ports for relaxation oscillator
|
|
*((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
|
|
*((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
|
|
|
|
TA1CTL |= TACLR;
|
|
TA1CTL &= ~TAIFG;
|
|
TA0CTL |= (TACLR + MC_1); // Clear Timer, Up mode
|
|
/*
|
|
* In this configuration measGateSource represents the measurement
|
|
* source for timer TIMERA1, which can be sourced from TACLK, ACLK,
|
|
* SMCLK, or INCLK.
|
|
*/
|
|
if(group->measGateSource == TIMER_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE);
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE);
|
|
}
|
|
TA1CCTL0 ^= CCIS0; // Create SW capture of CCR1
|
|
TA0CTL &= ~MC_1; // Halt Timer
|
|
if(TA1CTL & TAIFG)
|
|
{
|
|
/*
|
|
* If a rollover in the timer has occurred then set counts to
|
|
* 0. This will prevent erroneous data from entering the baseline
|
|
* tracking algorithm.
|
|
*/
|
|
counts[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
counts[i] = TA1CCR0; // Save result
|
|
}
|
|
// Context Restore
|
|
*((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
|
|
*((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
|
|
} // End for loop
|
|
// Context Restore
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE);
|
|
}
|
|
TA0CTL = contextSaveTA0CTL;
|
|
TA0CCTL0 = contextSaveTA0CCTL0;
|
|
TA0CCR0 = contextSaveTA0CCR0;
|
|
TA1CTL = contextSaveTA1CTL;
|
|
TA1CCTL0 = contextSaveTA1CCTL0;
|
|
TA1CCR0 = contextSaveTA1CCR0;
|
|
}
|
|
#endif
|
|
|
|
#ifdef RO_PINOSC_TA0_TA1
|
|
/*!
|
|
* ======== TI_CTS_RO_PINOSC_TA0_TA1_HAL ========
|
|
* @brief RO method capacitance measurement using PinOsc IO, TimerA0, and
|
|
* TimerA1
|
|
*
|
|
* \n Schematic Description:
|
|
*
|
|
* \n element-----+->Px.y
|
|
*
|
|
* \n The TimerA1 interval represents the gate (measurement) time. The
|
|
* number of oscillations that have accumulated in TA0R during the
|
|
* measurement time represents the capacitance of the element.
|
|
*
|
|
* @param group pointer to the sensor to be measured
|
|
* @param counts pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_RO_PINOSC_TA0_TA1_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
/*!
|
|
* Allocate Context Save Variables
|
|
* Status Register: GIE bit only
|
|
* TIMERA0: TA0CTL, TA0CCTL0, TA0CCR0
|
|
* TIMERA1: TA1CTL, TA1CCTL0, TA1CCR0
|
|
* Ports: PxSEL, PxSEL2
|
|
*/
|
|
uint8_t contextSaveSR;
|
|
uint16_t contextSaveTA0CTL,contextSaveTA0CCTL0,contextSaveTA0CCR0;
|
|
uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
|
|
uint8_t contextSaveSel,contextSaveSel2;
|
|
/*
|
|
* Perform context save of registers used except port registers which are
|
|
* saved and restored within the for loop as each element within the
|
|
* sensor is measured.
|
|
*/
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveTA0CTL = TA0CTL;
|
|
contextSaveTA0CCTL0 = TA0CCTL0;
|
|
contextSaveTA0CCR0 = TA0CCR0;
|
|
contextSaveTA1CTL = TA1CTL;
|
|
contextSaveTA1CCTL0 = TA1CCTL0;
|
|
contextSaveTA1CCR0 = TA1CCR0;
|
|
/*
|
|
* TimerA0 is the measurement timer and counts the number of relaxation
|
|
* oscillation cycles of the electrode which is routed to INCLK. TA0 is
|
|
* in continuous mode and sourced from INCLK.
|
|
*/
|
|
TA0CTL = TASSEL_3+MC_2;
|
|
TA0CCTL0 = CM_3+CCIS_2+CAP; // Setup for SW capture
|
|
/*
|
|
* TimerA1 is the gate (measurement interval) timer. The number of
|
|
* oscillations counted within the gate interval represents the measured
|
|
* capacitance.
|
|
*/
|
|
TA1CCR0 = (group->accumulationCycles);
|
|
// Establish source and scale of timerA1, but halt the timer.
|
|
TA1CTL = group->measGateSource + group->sourceScale;
|
|
TA1CCTL0 = CCIE; // Enable Interrupt when timer counts to TA1CCR0.
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
// Context Save Port Registers
|
|
contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
|
|
contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
|
|
// Configure Ports for relaxation oscillator
|
|
*((group->arrayPtr[i])->inputPxselRegister)
|
|
&= ~((group->arrayPtr[i])->inputBits);
|
|
*((group->arrayPtr[i])->inputPxsel2Register)
|
|
|= ((group->arrayPtr[i])->inputBits);
|
|
TA0CTL |= TACLR;
|
|
TA0CTL &= ~TAIFG;
|
|
TA1CTL |= (TACLR + MC_1);
|
|
/*!
|
|
* The measGateSource represents the gate source for timer TIMERA1,
|
|
* which can be sourced from TACLK, ACLK, SMCLK, or INCLK. The
|
|
* interrupt handler is defined in TIMER1_A0_VECTOR, which simply
|
|
* clears the low power mode bits in the Status Register before
|
|
* returning from the ISR.
|
|
*/
|
|
if(group->measGateSource == TIMER_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); // Enable GIE and wait for ISR
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE); // Enable GIE and wait for ISR
|
|
}
|
|
TA0CCTL0 ^= CCIS0; // Create SW capture of TA0CCR into TA0CCR0.
|
|
TA1CTL &= ~MC_1; // Halt Timer
|
|
if(TA0CTL & TAIFG)
|
|
{
|
|
/*
|
|
* If a rollover in the timer has occurred then set counts to
|
|
* 0. This will prevent erroneous data from entering the baseline
|
|
* tracking algorithm.
|
|
*/
|
|
counts[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
counts[i] = TA0CCR0; // Save result
|
|
}
|
|
// Context Restore Port Registers
|
|
*((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
|
|
*((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
|
|
} // End for Loop
|
|
/*
|
|
* Context restore GIE within Status Register and all timer registers
|
|
* used.
|
|
*/
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE);
|
|
}
|
|
TA0CTL = contextSaveTA0CTL;
|
|
TA0CCTL0 = contextSaveTA0CCTL0;
|
|
TA0CCR0 = contextSaveTA0CCR0;
|
|
TA1CTL = contextSaveTA1CTL;
|
|
TA1CCTL0 = contextSaveTA1CCTL0;
|
|
TA1CCR0 = contextSaveTA1CCR0;
|
|
}
|
|
#endif
|
|
|
|
#ifdef RO_COMPAp_TA0_WDTp
|
|
/*!
|
|
* @brief RO method capactiance measurement using CompA+, TimerA0, and WDT+
|
|
*
|
|
* \n Schematic Description of CompA+ forming relaxation oscillator and
|
|
* coupling (connection) between the relaxation oscillator and
|
|
* TimerA0.
|
|
* \n <- Output
|
|
* \n -> Input
|
|
* \n R Resistor (typically 100Kohms)
|
|
*
|
|
* +-<-Px.y (reference)
|
|
* |
|
|
* R
|
|
* |
|
|
* +---+-->COMPA+
|
|
* | |
|
|
* R R
|
|
* | |
|
|
* GND |
|
|
* |
|
|
* +-->TACLK
|
|
* |
|
|
* element-+-R--+-<-CAOUT
|
|
* |
|
|
* +------->COMPA-
|
|
*
|
|
* \n The WDT+ interval represents the measurement window. The number of
|
|
* counts within the TA0R that have accumulated during the measurement
|
|
* window represents the capacitance of the element.
|
|
*
|
|
* @param group Address of the structure describing the Sensor to be measured
|
|
* @param counts Address to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_RO_COMPAp_TA0_WDTp_HAL(const struct Sensor *group, uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
//** Context Save
|
|
// Status Register:
|
|
// WDTp: IE1, WDTCTL
|
|
// TIMERA0: TACTL, TACCTL1
|
|
// COMPAp: CACTL1, CACTL2, CAPD
|
|
// Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
|
|
uint8_t contextSaveSR;
|
|
uint8_t contextSaveIE1;
|
|
uint16_t contextSaveWDTCTL;
|
|
uint16_t contextSaveTACTL,contextSaveTACCTL1,contextSaveTACCR1;
|
|
uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
|
|
uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
|
|
uint8_t contextSavetxclkDir,contextSavetxclkSel;
|
|
uint8_t contextSaveRefDir,contextSaveRefOutSel;
|
|
#ifdef SEL2REGISTER
|
|
uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
|
|
|
|
contextSaveCaoutSel2 = *(group->caoutSel2Register);
|
|
contextSaveTxclkSel2 = *(group->txclkSel2Register);
|
|
#endif
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveIE1 = IE1;
|
|
contextSaveWDTCTL = WDTCTL;
|
|
contextSaveWDTCTL &= 0x00FF;
|
|
contextSaveWDTCTL |= WDTPW;
|
|
contextSaveTACTL = TACTL;
|
|
contextSaveTACCTL1 = TACCTL1;
|
|
contextSaveTACCR1 = TACCR1;
|
|
contextSaveCACTL1 = CACTL1;
|
|
contextSaveCACTL2 = CACTL2;
|
|
contextSaveCAPD = CAPD;
|
|
contextSaveCaoutDir = *(group->caoutDirRegister);
|
|
contextSaveCaoutSel = *(group->caoutSelRegister);
|
|
contextSavetxclkDir = *(group->txclkDirRegister);
|
|
contextSavetxclkSel = *(group->txclkSelRegister);
|
|
contextSaveRefDir = *(group->refPxdirRegister);
|
|
contextSaveRefOutSel = *(group->refPxoutRegister);
|
|
|
|
TACTL = TASSEL_0+MC_2; // TACLK, cont mode
|
|
TACCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
|
|
|
|
*(group->caoutDirRegister) |= group->caoutBits;
|
|
*(group->txclkDirRegister) &= ~group->txclkBits;
|
|
*(group->caoutSelRegister) |= group->caoutBits;
|
|
*(group->txclkSelRegister) |= group->txclkBits;
|
|
|
|
#ifdef SEL2REGISTER
|
|
*(group->caoutSel2Register) |= group->caoutBits;
|
|
*(group->txclkSel2Register) |= group->txclkBits;
|
|
#endif
|
|
|
|
*(group->refPxdirRegister) |= group->refBits;
|
|
*(group->refPxoutRegister) |= group->refBits;
|
|
CACTL1 |= CAON; // Turn on comparator
|
|
CAPD |= (group->capdBits);
|
|
IE1 |= WDTIE; // enable WDT interrupt
|
|
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
|
|
//** Setup Gate Timer *****************************************************
|
|
// Set duration of sensor measurment
|
|
WDTCTL = WDTPW+WDTTMSEL+ group->measGateSource + group->accumulationCycles;
|
|
TACTL |= TACLR; // Clear Timer_A TAR
|
|
if(group->measGateSource == GATE_WDTp_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); // Wait for WDT interrupt
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
|
|
}
|
|
TACCTL1 ^= CCIS0; // Create SW capture of CCR1
|
|
counts[i] = TACCR1; // Save result
|
|
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
|
|
}
|
|
// End Sequence
|
|
|
|
//** Context Restore
|
|
// WDTp: IE1, WDCTL
|
|
// TIMERA0: TACTL, TACCTL1
|
|
// COMPAp: CACTL1, CACTL2, CAPD
|
|
// Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
|
|
#ifdef SEL2REGISTER
|
|
*(group->caoutSel2Register) = contextSaveCaoutSel2;
|
|
*(group->txclkSel2Register) = contextSaveTxclkSel2;
|
|
#endif
|
|
__bis_SR_register(contextSaveSR);
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE); // Wait for WDT interrupt
|
|
}
|
|
IE1 = contextSaveIE1;
|
|
WDTCTL = contextSaveWDTCTL;
|
|
TACTL = contextSaveTACTL;
|
|
TACCTL1 = contextSaveTACCTL1;
|
|
TACCR1 = contextSaveTACCR1;
|
|
CACTL1 = contextSaveCACTL1;
|
|
CACTL2 = contextSaveCACTL2;
|
|
CAPD = contextSaveCAPD;
|
|
*(group->caoutDirRegister) = contextSaveCaoutDir;
|
|
*(group->caoutSelRegister) = contextSaveCaoutSel;
|
|
*(group->txclkDirRegister) = contextSavetxclkDir;
|
|
*(group->txclkSelRegister) = contextSavetxclkSel;
|
|
*(group->refPxdirRegister) = contextSaveRefDir;
|
|
*(group->refPxoutRegister) = contextSaveRefOutSel;
|
|
}
|
|
#endif
|
|
|
|
#ifdef fRO_COMPAp_TA0_SW
|
|
/*!
|
|
* @brief RO method capactiance measurement using CompA+, TimerA0, and SW loop
|
|
*
|
|
* \n Schematic Description of CompA+ forming relaxation oscillator.
|
|
* \n <- Output
|
|
* \n -> Input
|
|
* \n R Resistor (typically 100Kohms)
|
|
*
|
|
* +-<-Px.y (reference)
|
|
* |
|
|
* R
|
|
* |
|
|
* +---+-->COMPA+
|
|
* | |
|
|
* R R
|
|
* | |
|
|
* GND |
|
|
* |
|
|
* +-->TACLK
|
|
* |
|
|
* element-+-R--+-<-CAOUT
|
|
* |
|
|
* +------->COMPA-
|
|
*
|
|
* \n The timer counts to TA0CCR0 representing the measurement window. The
|
|
* number of counts within the SW loop that have accumulated during the
|
|
* measurement window represents the capacitance of the element.
|
|
*
|
|
* @param group Address of the structure describing the Sensor to be measured
|
|
* @param counts Address to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_fRO_COMPAp_TA0_SW_HAL(const struct Sensor *group, uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
uint16_t j;
|
|
//** Context Save
|
|
// Status Register:
|
|
// TIMERA0: TACTL, TACCTL0
|
|
// COMPAp: CACTL1, CACTL2, CAPD
|
|
// Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
|
|
uint16_t contextSaveTACTL,contextSaveTACCTL0,contextSaveTACCR0;
|
|
uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
|
|
uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
|
|
uint8_t contextSavetxclkDir,contextSavetxclkSel;
|
|
uint8_t contextSaveRefDir,contextSaveRefOutSel;
|
|
#ifdef SEL2REGISTER
|
|
uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
|
|
|
|
contextSaveCaoutSel2 = *(group->caoutSel2Register);
|
|
contextSaveTxclkSel2 = *(group->txclkSel2Register);
|
|
#endif
|
|
contextSaveTACTL = TACTL;
|
|
contextSaveTACCTL0 = TACCTL0;
|
|
contextSaveTACCR0 = TACCR0;
|
|
contextSaveCACTL1 = CACTL1;
|
|
contextSaveCACTL2 = CACTL2;
|
|
contextSaveCAPD = CAPD;
|
|
contextSaveCaoutDir = *(group->caoutDirRegister);
|
|
contextSaveCaoutSel = *(group->caoutSelRegister);
|
|
contextSavetxclkDir = *(group->txclkDirRegister);
|
|
contextSavetxclkSel = *(group->txclkSelRegister);
|
|
contextSaveRefDir = *(group->refPxdirRegister);
|
|
contextSaveRefOutSel = *(group->refPxoutRegister);
|
|
|
|
//** Setup Measurement timer***************************************************
|
|
|
|
// Configure Timer TA0
|
|
TACCR0 =(group->accumulationCycles);
|
|
TACCTL0 &= ~CAP;
|
|
// setup connections between CAOUT and TA0
|
|
*(group->caoutDirRegister) |= group->caoutBits;
|
|
*(group->txclkDirRegister) &= ~group->txclkBits;
|
|
*(group->caoutSelRegister) |= group->caoutBits;
|
|
*(group->txclkSelRegister) |= group->txclkBits;
|
|
|
|
#ifdef SEL2REGISTER
|
|
*(group->caoutSel2Register) |= group->caoutBits;
|
|
*(group->txclkSel2Register) |= group->txclkBits;
|
|
#endif
|
|
// setup reference
|
|
*(group->refPxdirRegister) |= group->refBits;
|
|
*(group->refPxoutRegister) |= group->refBits;
|
|
CACTL1 |= CAON; // Turn on comparator
|
|
CAPD |= (group->capdBits);
|
|
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
j=0;
|
|
CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
|
|
//** Setup Gate Timer **************
|
|
// Set duration of sensor measurment
|
|
TACTL = TASSEL_0+TACLR+MC_1; // TACLK, reset, up mode
|
|
TACTL &= ~TAIFG; // clear IFG
|
|
while(!(TACTL & TAIFG))
|
|
{
|
|
j++;
|
|
} // end accumulation
|
|
counts[i] = j;
|
|
}
|
|
// End Sequence
|
|
//** Context Restore
|
|
// TIMERA0: TACTL, TACCTL1
|
|
// COMPAp: CACTL1, CACTL2, CAPD
|
|
// Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
|
|
#ifdef SEL2REGISTER
|
|
*(group->caoutSel2Register) = contextSaveCaoutSel2;
|
|
*(group->txclkSel2Register) = contextSaveTxclkSel2;
|
|
#endif
|
|
TACTL = contextSaveTACTL;
|
|
TACCTL0 = contextSaveTACCTL0;
|
|
TACCR0 = contextSaveTACCR0;
|
|
CACTL1 = contextSaveCACTL1;
|
|
CACTL2 = contextSaveCACTL2;
|
|
CAPD = contextSaveCAPD;
|
|
*(group->caoutDirRegister) = contextSaveCaoutDir;
|
|
*(group->caoutSelRegister) = contextSaveCaoutSel;
|
|
*(group->txclkDirRegister) = contextSavetxclkDir;
|
|
*(group->txclkSelRegister) = contextSavetxclkSel;
|
|
*(group->refPxdirRegister) = contextSaveRefDir;
|
|
*(group->refPxoutRegister) = contextSaveRefOutSel;
|
|
}
|
|
#endif
|
|
|
|
#ifdef fRO_COMPAp_SW_TA0
|
|
/*!
|
|
* @brief RO method capactiance measurement using CompA+, TimerA0, and SW loop
|
|
*
|
|
* \n Schematic Description of CompA+ forming relaxation oscillator.
|
|
* \n <- Output
|
|
* \n -> Input
|
|
* \n R Resistor (typically 100Kohms)
|
|
*
|
|
* +-<-Px.y (reference)
|
|
* |
|
|
* R
|
|
* |
|
|
* +---+-->COMPA+
|
|
* | |
|
|
* R R
|
|
* | |
|
|
* GND |
|
|
* |
|
|
* |
|
|
* element-+-R--+-<-CAOUT
|
|
* |
|
|
* +------->COMPA-
|
|
*
|
|
* \n The SW loop counts to 'n' accumulationCycles, representing the
|
|
* measurement window. The number of timer counts within TA0R register
|
|
* represents the capacitance of the element.
|
|
*
|
|
* @param group Address of the structure describing the Sensor to be measured
|
|
* @param counts Address to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_fRO_COMPAp_SW_TA0_HAL(const struct Sensor *group, uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
uint16_t j;
|
|
//** Context Save
|
|
// Status Register:
|
|
// TIMERA0: TACTL, TACCTL0, TACCTL1
|
|
// COMPAp: CACTL1, CACTL2, CAPD
|
|
// Ports: caoutDIR, caoutSel, caoutSel2, refout, refdir
|
|
uint16_t contextSaveTACTL,contextSaveTACCTL0,contextSaveTACCTL1;
|
|
uint16_t contextSaveTACCR0,contextSaveTACCR1;
|
|
uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
|
|
uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
|
|
uint8_t contextSaveRefDir,contextSaveRefOutSel;
|
|
#ifdef SEL2REGISTER
|
|
uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
|
|
|
|
contextSaveCaoutSel2 = *(group->caoutSel2Register);
|
|
#endif
|
|
contextSaveTACTL = TACTL;
|
|
contextSaveTACCTL0 = TACCTL0;
|
|
contextSaveTACCTL1 = TACCTL1;
|
|
contextSaveTACCR0 = TACCR0;
|
|
contextSaveTACCR1 = TACCR1;
|
|
contextSaveCACTL1 = CACTL1;
|
|
contextSaveCACTL2 = CACTL2;
|
|
contextSaveCAPD = CAPD;
|
|
contextSaveCaoutDir = *(group->caoutDirRegister);
|
|
contextSaveCaoutSel = *(group->caoutSelRegister);
|
|
contextSaveRefDir = *(group->refPxdirRegister);
|
|
contextSaveRefOutSel = *(group->refPxoutRegister);
|
|
//** Setup Measurement timer***************************************************
|
|
|
|
// Configure Timer TA0
|
|
TACCTL0 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
|
|
TACCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
|
|
|
|
// setup connections between CAOUT and TA0
|
|
*(group->caoutDirRegister) |= group->caoutBits;
|
|
*(group->caoutSelRegister) |= group->caoutBits;
|
|
|
|
#ifdef SEL2REGISTER
|
|
*(group->caoutSel2Register) |= group->caoutBits;
|
|
#endif
|
|
// setup reference
|
|
*(group->refPxdirRegister) |= group->refBits;
|
|
*(group->refPxoutRegister) |= group->refBits;
|
|
CACTL1 |= CAON; // Turn on comparator
|
|
CAPD |= (group->capdBits);
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
|
|
//** Setup Gate Timer **************
|
|
// Set duration of sensor measurment
|
|
TACTL = group->measureGateSource+group->sourceScale+TACLR+MC_2;
|
|
TACCTL0 ^= CCIS0; // Create SW capture of CCR0
|
|
for(j = group->accumulationCycles; j > 0; j--)
|
|
{
|
|
CACTL1 &= ~CAIFG;
|
|
while(!(CACTL1 & CAIFG));
|
|
}
|
|
TACCTL1 ^= CCIS0; // Create SW capture of CCR1
|
|
counts[i] = TACCR1; // Save result
|
|
counts[i] -= TACCR0; // Save result
|
|
TACCTL0 &= ~CCIFG;
|
|
TACCTL1 &= ~CCIFG;
|
|
}
|
|
// End Sequence
|
|
//** Context Restore
|
|
// WDTp: IE1, WDCTL
|
|
// TIMERA0: TACTL, TACCTL0, TACCTL1, TACCR0, TACCR1
|
|
// COMPAp: CACTL1, CACTL2, CAPD
|
|
// Ports: caoutDIR, caoutSel, txclkDIR, caoutSel2, refout, refdir
|
|
#ifdef SEL2REGISTER
|
|
*(group->caoutSel2Register) = contextSaveCaoutSel2;
|
|
#endif
|
|
TACTL = contextSaveTACTL;
|
|
TACCTL0 = contextSaveTACCTL0;
|
|
TACCTL1 = contextSaveTACCTL1;
|
|
TACCR0 = contextSaveTACCR0;
|
|
TACCR1 = contextSaveTACCR1;
|
|
CACTL1 = contextSaveCACTL1;
|
|
CACTL2 = contextSaveCACTL2;
|
|
CAPD = contextSaveCAPD;
|
|
*(group->caoutDirRegister) = contextSaveCaoutDir;
|
|
*(group->caoutSelRegister) = contextSaveCaoutSel;
|
|
*(group->refPxdirRegister) = contextSaveRefDir;
|
|
*(group->refPxoutRegister) = contextSaveRefOutSel;
|
|
}
|
|
#endif
|
|
|
|
#ifdef RO_COMPAp_TA1_WDTp
|
|
/*!
|
|
* @brief RO method capactiance measurement using CompA+, TimerA1, and WDT+
|
|
*
|
|
* \n Schematic Description of CompA+ forming relaxation oscillator and
|
|
* coupling (connection) between the relaxation oscillator and TimerA0.
|
|
* \n <- Output
|
|
* \n -> Input
|
|
* \n R Resistor (typically 100Kohms)
|
|
*
|
|
* +-<-Px.y (reference)
|
|
* |
|
|
* R
|
|
* |
|
|
* +---+-->COMPA+
|
|
* | |
|
|
* R R
|
|
* | |
|
|
* GND |
|
|
* |
|
|
* +-->TA1CLK
|
|
* |
|
|
* element-+-R--+-<-CAOUT
|
|
* |
|
|
* +------->COMPA-
|
|
*
|
|
* \n The WDT+ interval represents the measurement window. The number of
|
|
* counts within the TA0R that have accumulated during the measurement
|
|
* window represents the capacitance of the element.
|
|
*
|
|
* @param group Address of the structure describing the Sensor to be measured
|
|
* @param counts Address to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_RO_COMPAp_TA1_WDTp_HAL(const struct Sensor *group, uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
//** Context Save
|
|
// Status Register:
|
|
// WDTp: IE1, WDTCTL
|
|
// TIMERA0: TA1CTL, TA1CCTL1
|
|
// COMPAp: CACTL1, CACTL2, CAPD
|
|
// Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
|
|
uint8_t contextSaveSR;
|
|
uint8_t contextSaveIE1;
|
|
uint16_t contextSaveWDTCTL;
|
|
uint16_t contextSaveTA1CTL,contextSaveTA1CCTL1;
|
|
uint16_t contextSaveTA1CCR1;
|
|
uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
|
|
uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
|
|
uint8_t contextSavetxclkDir,contextSavetxclkSel;
|
|
uint8_t contextSaveRefDir,contextSaveRefOutSel;
|
|
#ifdef SEL2REGISTER
|
|
uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
|
|
|
|
contextSaveCaoutSel2 = *(group->caoutSel2Register);
|
|
contextSaveTxclkSel2 = *(group->txclkSel2Register);
|
|
#endif
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveIE1 = IE1;
|
|
contextSaveWDTCTL = WDTCTL;
|
|
contextSaveWDTCTL &= 0x00FF;
|
|
contextSaveWDTCTL |= WDTPW;
|
|
contextSaveTA1CTL = TA1CTL;
|
|
contextSaveTA1CCTL1 = TA1CCTL1;
|
|
contextSaveTA1CCR1 = TA1CCR1;
|
|
contextSaveCACTL1 = CACTL1;
|
|
contextSaveCACTL2 = CACTL2;
|
|
contextSaveCAPD = CAPD;
|
|
contextSaveCaoutDir = *(group->caoutDirRegister);
|
|
contextSaveCaoutSel = *(group->caoutSelRegister);
|
|
contextSavetxclkDir = *(group->txclkDirRegister);
|
|
contextSavetxclkSel = *(group->txclkSelRegister);
|
|
contextSaveRefDir = *(group->refPxdirRegister);
|
|
contextSaveRefOutSel = *(group->refPxoutRegister);
|
|
//** Setup Measurement timer***************************************************
|
|
// Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
|
|
// capacitive touch layer.
|
|
|
|
TA1CTL = TASSEL_0+MC_2; // TA1CLK, cont mode
|
|
TA1CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
|
|
|
|
*(group->caoutDirRegister) |= group->caoutBits;
|
|
*(group->txclkDirRegister) &= ~group->txclkBits;
|
|
*(group->caoutSelRegister) |= group->caoutBits;
|
|
*(group->txclkSelRegister) |= group->txclkBits;
|
|
|
|
#ifdef SEL2REGISTER
|
|
*(group->caoutSel2Register) |= group->caoutBits;
|
|
*(group->txclkSel2Register) |= group->txclkBits;
|
|
#endif
|
|
|
|
*(group->refPxdirRegister) |= group->refBits;
|
|
*(group->refPxoutRegister) |= group->refBits;
|
|
CACTL1 |= CAON; // Turn on comparator
|
|
CAPD |= (group->capdBits);
|
|
IE1 |= WDTIE; // enable WDT interrupt
|
|
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
|
|
//** Setup Gate Timer *****************************************************
|
|
// Set duration of sensor measurment
|
|
WDTCTL = WDTPW+WDTTMSEL+ group->measGateSource + group->accumulationCycles;
|
|
TA1CTL |= TACLR; // Clear Timer_A TAR
|
|
if(group->measGateSource == GATE_WDTp_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); // Wait for WDT interrupt
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
|
|
}
|
|
TA1CCTL1 ^= CCIS0; // Create SW capture of CCR1
|
|
counts[i] = TA1CCR1; // Save result
|
|
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
|
|
}
|
|
// End Sequence
|
|
//** Context Restore
|
|
// WDTp: IE1, WDCTL
|
|
// TIMERA0: TACTL, TACCTL1
|
|
// COMPAp: CACTL1, CACTL2, CAPD
|
|
// Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
|
|
#ifdef SEL2REGISTER
|
|
*(group->caoutSel2Register) = contextSaveCaoutSel2;
|
|
*(group->txclkSel2Register) = contextSaveTxclkSel2;
|
|
#endif
|
|
__bis_SR_register(contextSaveSR);
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE); // Wait for WDT interrupt
|
|
}
|
|
IE1 = contextSaveIE1;
|
|
WDTCTL = contextSaveWDTCTL;
|
|
TA1CTL = contextSaveTA1CTL;
|
|
TA1CCTL1 = contextSaveTA1CCTL1;
|
|
TA1CCR1 = contextSaveTA1CCR1;
|
|
CACTL1 = contextSaveCACTL1;
|
|
CACTL2 = contextSaveCACTL2;
|
|
CAPD = contextSaveCAPD;
|
|
*(group->caoutDirRegister) = contextSaveCaoutDir;
|
|
*(group->caoutSelRegister) = contextSaveCaoutSel;
|
|
*(group->txclkDirRegister) = contextSavetxclkDir;
|
|
*(group->txclkSelRegister) = contextSavetxclkSel;
|
|
*(group->refPxdirRegister) = contextSaveRefDir;
|
|
*(group->refPxoutRegister) = contextSaveRefOutSel;
|
|
}
|
|
#endif
|
|
|
|
#ifdef fRO_COMPAp_TA1_SW
|
|
/*!
|
|
* @brief RO method capactiance measurement using CompA+, TimerA1, and SW loop
|
|
*
|
|
* Schematic Description of CompA+ forming relaxation oscillator.
|
|
* \n <- Output
|
|
* \n -> Input
|
|
* \n R Resistor (typically 100Kohms)
|
|
*
|
|
* +-<-Px.y (reference)
|
|
* |
|
|
* R
|
|
* |
|
|
* +---+-->COMPA+
|
|
* | |
|
|
* R R
|
|
* | |
|
|
* GND |
|
|
* |
|
|
* +-->TA1CLK
|
|
* |
|
|
* element-+-R--+-<-CAOUT
|
|
* |
|
|
* +------->COMPA-
|
|
*
|
|
* \n The timer counts to TA1CCR0 representing the measurement window. The
|
|
* number of counts within the SW loop that have accumulated during the
|
|
* measurement window represents the capacitance of the element.
|
|
*
|
|
* @param group Address of the structure describing the Sensor to be measured
|
|
* @param counts Address to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_fRO_COMPAp_TA1_SW_HAL(const struct Sensor *group, uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
uint16_t j;
|
|
//** Context Save
|
|
// Status Register:
|
|
// TIMERA0: TA1CTL, TA1CCTL0
|
|
// COMPAp: CACTL1, CACTL2, CAPD
|
|
// Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
|
|
uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
|
|
uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
|
|
uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
|
|
uint8_t contextSavetxclkDir,contextSavetxclkSel;
|
|
uint8_t contextSaveRefDir,contextSaveRefOutSel;
|
|
#ifdef SEL2REGISTER
|
|
uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
|
|
|
|
contextSaveCaoutSel2 = *(group->caoutSel2Register);
|
|
contextSaveTxclkSel2 = *(group->txclkSel2Register);
|
|
#endif
|
|
contextSaveTA1CTL = TA1CTL;
|
|
contextSaveTA1CCTL0 = TA1CCTL0;
|
|
contextSaveTA1CCR0 = TA1CCR0;
|
|
contextSaveCACTL1 = CACTL1;
|
|
contextSaveCACTL2 = CACTL2;
|
|
contextSaveCAPD = CAPD;
|
|
contextSaveCaoutDir = *(group->caoutDirRegister);
|
|
contextSaveCaoutSel = *(group->caoutSelRegister);
|
|
contextSavetxclkDir = *(group->txclkDirRegister);
|
|
contextSavetxclkSel = *(group->txclkSelRegister);
|
|
contextSaveRefDir = *(group->refPxdirRegister);
|
|
contextSaveRefOutSel = *(group->refPxoutRegister);
|
|
//** Setup Measurement timer***************************************************
|
|
|
|
// Configure Timer TA0
|
|
TA1CCR0 =(group->accumulationCycles);
|
|
// setup connections between CAOUT and TA0
|
|
*(group->caoutDirRegister) |= group->caoutBits;
|
|
*(group->txclkDirRegister) &= ~group->txclkBits;
|
|
*(group->caoutSelRegister) |= group->caoutBits;
|
|
*(group->txclkSelRegister) |= group->txclkBits;
|
|
|
|
#ifdef SEL2REGISTER
|
|
*(group->caoutSel2Register) |= group->caoutBits;
|
|
*(group->txclkSel2Register) |= group->txclkBits;
|
|
#endif
|
|
// setup reference
|
|
*(group->refPxdirRegister) |= group->refBits;
|
|
*(group->refPxoutRegister) |= group->refBits;
|
|
CACTL1 |= CAON; // Turn on comparator
|
|
CAPD |= (group->capdBits);
|
|
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
j=0;
|
|
CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
|
|
//** Setup Gate Timer **************
|
|
// Set duration of sensor measurment
|
|
TA1CTL = TASSEL_0+TACLR+MC_1; // TA1CLK, Reset, up mode
|
|
TA1CTL &= ~TAIFG; // clear IFG
|
|
while(!(TACTL & TAIFG))
|
|
{
|
|
j++;
|
|
} // end accumulation
|
|
counts[i] = j;
|
|
}
|
|
// End Sequence
|
|
//** Context Restore
|
|
// WDTp: IE1, WDCTL
|
|
// TIMERA0: TACTL, TACCTL1
|
|
// COMPAp: CACTL1, CACTL2, CAPD
|
|
// Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
|
|
#ifdef SEL2REGISTER
|
|
*(group->caoutSel2Register) = contextSaveCaoutSel2;
|
|
*(group->txclkSel2Register) = contextSaveTxclkSel2;
|
|
#endif
|
|
TA1CTL = contextSaveTA1CTL;
|
|
TA1CCTL0 = contextSaveTA1CCTL0;
|
|
TA1CCR0 = contextSaveTA1CCR0;
|
|
CACTL1 = contextSaveCACTL1;
|
|
CACTL2 = contextSaveCACTL2;
|
|
CAPD = contextSaveCAPD;
|
|
*(group->caoutDirRegister) = contextSaveCaoutDir;
|
|
*(group->caoutSelRegister) = contextSaveCaoutSel;
|
|
*(group->txclkDirRegister) = contextSavetxclkDir;
|
|
*(group->txclkSelRegister) = contextSavetxclkSel;
|
|
*(group->refPxdirRegister) = contextSaveRefDir;
|
|
*(group->refPxoutRegister) = contextSaveRefOutSel;
|
|
}
|
|
#endif
|
|
#ifdef RC_PAIR_TA0
|
|
/*!
|
|
* @brief RC method capactiance measurement using a Pair of GPIO and TimerA0
|
|
*
|
|
* Schematic Description of two GPIO forming RC measruement.
|
|
* \n <- Output
|
|
* \n -> Input
|
|
* \n R Resistor (typically 1Mohms)
|
|
*
|
|
* +-<-Px.y (reference)
|
|
* |
|
|
* R
|
|
* |
|
|
* Element---+-->Pa.b
|
|
*
|
|
* Charge and Discharge Cycle
|
|
* +
|
|
* + +
|
|
* + +
|
|
* + +
|
|
* + +
|
|
* \n Start Timer After n cycles Stop Timer
|
|
* The TAR reister value is the number of SMCLK periods within n
|
|
* charge and discharge cycles. This value is directly proportional
|
|
* to the capacitance of the element measured. 'n' is defined by the
|
|
* variable accumulation_cycles.
|
|
*
|
|
* @param group Address of the structure describing the Sensor to be measured
|
|
* @param counts Address to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_RC_PAIR_TA0_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
uint16_t j;
|
|
|
|
//** Context Save
|
|
// TIMERA0: TA0CTL
|
|
// Port: inputPxout, inputPxdir, referencePxout, referencePxdir
|
|
|
|
uint8_t contextSaveinputPxout,contextSaveinputPxdir,contextSavereferencePxout;
|
|
uint8_t contextSavereferencePxdir;
|
|
|
|
#ifdef __MSP430_HAS_SFR__
|
|
uint16_t contextSaveTA0CTL,contextSaveTA0CCR0;
|
|
|
|
contextSaveTA0CTL = TA0CTL;
|
|
contextSaveTA0CCR0 = TA0CCR0;
|
|
#else
|
|
uint16_t contextSaveTACTL,contextSaveTACCR0;
|
|
|
|
contextSaveTACTL = TACTL;
|
|
contextSaveTACCR0 = TACCR0;
|
|
#endif
|
|
|
|
//** Setup Measurement timer****************************************************
|
|
// Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
|
|
// capacitive touch layer.
|
|
#ifdef __MSP430_HAS_SFR__
|
|
TA0CCR0 = 0xFFFF;
|
|
#else
|
|
TACCR0 = 0xFFFF;
|
|
#endif
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
// Context Save
|
|
contextSaveinputPxout = *((group->arrayPtr[i])->inputPxoutRegister);
|
|
contextSaveinputPxdir = *((group->arrayPtr[i])->inputPxdirRegister);
|
|
contextSavereferencePxout = *((group->arrayPtr[i])->referencePxoutRegister);
|
|
contextSavereferencePxdir = *((group->arrayPtr[i])->referencePxdirRegister);
|
|
j = (group->accumulationCycles);
|
|
#ifdef __MSP430_HAS_SFR__
|
|
TA0CTL = TASSEL_2+TACLR; // SMCLK, up mode
|
|
#else
|
|
TACTL = TASSEL_2+TACLR; // SMCLK, up mode
|
|
#endif
|
|
while(j--)
|
|
{
|
|
//******************************************************************************
|
|
// Positive cycle
|
|
// SENSOR ---+---- Input (low to high)
|
|
// R
|
|
// +---- Rerefence (high)
|
|
//******************************************************************************
|
|
// Input low
|
|
*((group->arrayPtr[i])->inputPxoutRegister) &= ~((group->arrayPtr[i])->inputBits);
|
|
*((group->arrayPtr[i])->inputPxdirRegister) |= (group->arrayPtr[i])->inputBits;
|
|
// Reference High
|
|
*((group->arrayPtr[i])->referencePxdirRegister) |= (group->arrayPtr[i])->referenceBits;
|
|
*((group->arrayPtr[i])->referencePxoutRegister) |= ((group->arrayPtr[i])->referenceBits);
|
|
// Wait until low
|
|
while((*((group->arrayPtr[i])->inputPxinRegister)) & ((group->arrayPtr[i])->inputBits));
|
|
// Change to an input
|
|
*((group->arrayPtr[i])->inputPxdirRegister) &= ~(group->arrayPtr[i])->inputBits;
|
|
//**************************************************************************
|
|
// This mechanism is traditianally an LPM with the ISR calculating the
|
|
// delta between when the first snapshot and the ISR event. If this is
|
|
// included within the library the entire port ISR would not be available
|
|
// to the calling application. In this example the polling is done with the
|
|
// CPU at expense of power and MIPS but preserves the port ISR for other
|
|
// interruptible functions.
|
|
//**************************************************************************
|
|
#ifdef __MSP430_HAS_SFR__
|
|
TA0CTL |= MC_1; // start timer
|
|
#else
|
|
TACTL |= MC_1; // start timer
|
|
#endif
|
|
//wait until voltage reaches Vih of port
|
|
while(!((*((group->arrayPtr[i])->inputPxinRegister) & (group->arrayPtr[i])->inputBits)));
|
|
#ifdef __MSP430_HAS_SFR__
|
|
TA0CTL &= ~ MC_3; // stop timer
|
|
#else
|
|
TACTL &= ~ MC_3; // stop timer
|
|
#endif
|
|
//******************************************************************************
|
|
// Negative cycle
|
|
// SENSOR ---+---- Input (high to low)
|
|
// R
|
|
// +---- Rerefence (low)
|
|
//******************************************************************************
|
|
// Input High
|
|
*((group->arrayPtr[i])->inputPxoutRegister) |= ((group->arrayPtr[i])->inputBits);
|
|
*((group->arrayPtr[i])->inputPxdirRegister) |= (group->arrayPtr[i])->inputBits;
|
|
// Reference Low
|
|
*((group->arrayPtr[i])->referencePxoutRegister) &= ~((group->arrayPtr[i])->referenceBits);
|
|
// Change to an input
|
|
*((group->arrayPtr[i])->inputPxdirRegister) &= ~((group->arrayPtr[i])->inputBits);
|
|
#ifdef __MSP430_HAS_SFR__
|
|
TA0CTL |= MC_1; // start timer
|
|
#else
|
|
TACTL |= MC_1; // start timer
|
|
#endif
|
|
//wait until voltage reaches Vil of port
|
|
while((*((group->arrayPtr[i])->inputPxinRegister)) & ((group->arrayPtr[i])->inputBits));
|
|
#ifdef __MSP430_HAS_SFR__
|
|
TA0CTL &= ~ MC_3; // stop timer
|
|
#else
|
|
TACTL &= ~ MC_3; // stop timer
|
|
#endif
|
|
} // END accumulation loop for a single element
|
|
#ifdef __MSP430_HAS_SFR__
|
|
counts[i] = TA0R;
|
|
#else
|
|
counts[i] = TAR;
|
|
#endif
|
|
// Context Restore
|
|
*((group->arrayPtr[i])->inputPxoutRegister) = contextSaveinputPxout;
|
|
*((group->arrayPtr[i])->inputPxdirRegister) = contextSaveinputPxdir;
|
|
*((group->arrayPtr[i])->referencePxoutRegister) = contextSavereferencePxout;
|
|
*((group->arrayPtr[i])->referencePxdirRegister) = contextSavereferencePxdir;
|
|
} // END FOR loop which cycles through elements within sensor
|
|
|
|
//** Context Restore
|
|
#ifdef __MSP430_HAS_SFR__
|
|
TA0CTL = contextSaveTA0CTL;
|
|
TA0CCR0 = contextSaveTA0CCR0;
|
|
#else
|
|
TACTL = contextSaveTACTL;
|
|
TACCR0 = contextSaveTACCR0;
|
|
#endif
|
|
|
|
}
|
|
#endif
|
|
#ifdef fRO_PINOSC_TA0_SW
|
|
/*!
|
|
* @brief fRO method capactiance measurement using the PinOsc and TimerA0
|
|
*
|
|
* Charge and Discharge Cycle
|
|
* +
|
|
* + +
|
|
* + +
|
|
* + +
|
|
* + +
|
|
* Start Timer After n cycles Stop Timer
|
|
* \n The TAR reister value is the number of SW loops (function of MCLK)
|
|
* within n charge and discharge cycles. This value is directly
|
|
* proportional to the capacitance of the element measured. 'n' is
|
|
* defined by the variable accumulation_cycles.
|
|
*
|
|
* @param group Address of the structure describing the Sensor to be measured
|
|
* @param counts Address to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_fRO_PINOSC_TA0_SW_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
uint16_t j;
|
|
//** Context Save
|
|
// TIMERA0: TA0CTL
|
|
// Ports: PxSEL, PxSEL2
|
|
uint16_t contextSaveTA0CTL, contextSaveTA0CCTL0;
|
|
uint8_t contextSaveSel,contextSaveSel2;
|
|
|
|
contextSaveTA0CTL = TA0CTL;
|
|
contextSaveTA0CCTL0 = TA0CCTL0;
|
|
// Setup Measurement timer
|
|
TACCR0 =(group->accumulationCycles);
|
|
for (i =0; i< (group->numElements); i++)
|
|
{
|
|
j = 0;
|
|
// Context Save
|
|
contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
|
|
contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
|
|
// start single oscillation (rise then fall and trigger on fall)
|
|
*((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
|
|
*((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
|
|
TA0CTL = TASSEL_3+TACLR+MC_1; // INCLK, reset, up mode
|
|
TA0CTL &= ~TAIFG; // clear IFG
|
|
// start timer in up mode
|
|
while(!(TA0CTL & TAIFG))
|
|
{
|
|
j++;
|
|
} // end accumulation
|
|
counts[i] = j;
|
|
TA0CTL &= ~MC_1;
|
|
// Context Restore
|
|
*((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
|
|
*((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
|
|
}
|
|
// End Sequence
|
|
// Context Restore
|
|
TA0CTL = contextSaveTA0CTL;
|
|
TA0CCTL0 = contextSaveTA0CCTL0;
|
|
}
|
|
#endif
|
|
|
|
#ifdef RO_PINOSC_TA0_WDTp
|
|
/*!
|
|
* @brief RO method capactiance measurement with PinOsc IO, TimerA0, and WDT+
|
|
*
|
|
* \n Schematic Description:
|
|
*
|
|
* \n element-----+->Px.y
|
|
*
|
|
* \n The WDT+ interval represents the measurement window. The number of
|
|
* counts within the TA0R that have accumulated during the measurement
|
|
* window represents the capacitance of the element.
|
|
*
|
|
* @param group Pointer to the structure describing the Sensor to be measured
|
|
* @param counts Pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_RO_PINOSC_TA0_WDTp_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
|
|
//** Context Save
|
|
// Status Register:
|
|
// WDTp: IE1, WDTCTL
|
|
// TIMERA0: TA0CTL, TA0CCTL1
|
|
// Ports: PxSEL, PxSEL2
|
|
uint8_t contextSaveSR;
|
|
uint8_t contextSaveIE1;
|
|
uint16_t contextSaveWDTCTL;
|
|
uint16_t contextSaveTA0CTL,contextSaveTA0CCTL1,contextSaveTA0CCR1;
|
|
uint8_t contextSaveSel,contextSaveSel2;
|
|
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveIE1 = IE1;
|
|
contextSaveWDTCTL = WDTCTL;
|
|
contextSaveWDTCTL &= 0x00FF;
|
|
contextSaveWDTCTL |= WDTPW;
|
|
contextSaveTA0CTL = TA0CTL;
|
|
contextSaveTA0CCTL1 = TA0CCTL1;
|
|
contextSaveTA0CCR1 = TA0CCR1;
|
|
|
|
//** Setup Measurement timer***************************************************
|
|
// Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
|
|
// capacitive touch layer.
|
|
|
|
// Configure and Start Timer
|
|
TA0CTL = TASSEL_3+MC_2; // INCLK, cont mode
|
|
TA0CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
|
|
IE1 |= WDTIE; // enable WDT interrupt
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
// Context Save
|
|
contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
|
|
contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
|
|
// Configure Ports for relaxation oscillator
|
|
*((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
|
|
*((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
|
|
//** Setup Gate Timer ********************************************************
|
|
// Set duration of sensor measurment
|
|
//WDTCTL = (WDTPW+WDTTMSEL+group->measGateSource+group->accumulationCycles);
|
|
WDTCTL = (WDTPW+WDTTMSEL+(group->measGateSource)+(group->accumulationCycles));
|
|
TA0CTL |= TACLR; // Clear Timer_A TAR
|
|
if(group->measGateSource == GATE_WDT_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); // Wait for WDT interrupt
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
|
|
}
|
|
TA0CCTL1 ^= CCIS0; // Create SW capture of CCR1
|
|
counts[i] = TA0CCR1; // Save result
|
|
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
|
|
// Context Restore
|
|
*((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
|
|
*((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
|
|
}
|
|
// End Sequence
|
|
// Context Restore
|
|
__bis_SR_register(contextSaveSR);
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE); //
|
|
}
|
|
IE1 = contextSaveIE1;
|
|
WDTCTL = contextSaveWDTCTL;
|
|
TA0CTL = contextSaveTA0CTL;
|
|
TA0CCTL1 = contextSaveTA0CCTL1;
|
|
TA0CCR1 = contextSaveTA0CCR1;
|
|
}
|
|
#endif
|
|
|
|
#ifdef RO_PINOSC_TA0
|
|
/*!
|
|
* @brief RO method capactiance measurement using PinOsc IO, and TimerA0
|
|
*
|
|
* \n Schematic Description:
|
|
*
|
|
* \n element-----+->Px.y
|
|
*
|
|
* \n The measurement window is accumulation_cycles/ACLK. The ACLK is
|
|
* used to generate a capture event via the internal connection CCIOB.
|
|
* The counts within the TA0R that have accumulated during the
|
|
* measurement window represents the capacitance of the element.
|
|
*
|
|
* @param group Pointer to the structure describing the Sensor to be measured
|
|
* @param counts Pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_RO_PINOSC_TA0_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
uint16_t j;
|
|
//** Context Save
|
|
// TIMERA0: TA0CTL, TA0CCTL0
|
|
// Ports: PxSEL, PxSEL2
|
|
uint16_t contextSaveTA0CTL,contextSaveTA0CCTL0,contextSaveTA0CCR0;
|
|
uint8_t contextSaveSel,contextSaveSel2;
|
|
|
|
contextSaveTA0CTL = TA0CTL;
|
|
contextSaveTA0CCTL0 = TA0CCTL0;
|
|
contextSaveTA0CCR0 = TA0CCR0;
|
|
|
|
//** Setup Measurement timer***************************************************
|
|
// Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
|
|
// capacitive touch layer.
|
|
|
|
// Configure and Start Timer
|
|
TA0CTL = TASSEL_3+MC_2; // TACLK, cont mode
|
|
for (i =0; i< (group->numElements); i++)
|
|
{
|
|
// Context Save
|
|
contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
|
|
contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
|
|
// Configure Ports for relaxation oscillator
|
|
j = (group->accumulationCycles);
|
|
*((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
|
|
*((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
|
|
TA0CCTL0 = CM_3+CCIS_1+CAP; // Pos&Neg,ACLK (CCI0B),Cap
|
|
while(!(TA0CCTL0 & CCIFG)); // wait for capture event
|
|
TA0CTL |= TACLR; // Clear Timer_A TAR
|
|
while(j--)
|
|
{
|
|
TA0CCTL0 = CM_3+CCIS_1+CAP; // Pos&Neg,ACLK (CCI0B),Cap
|
|
while(!(TA0CCTL0 & CCIFG)); // wait for capture event
|
|
}
|
|
counts[i] = TA0CCR0; // Save result
|
|
TA0CTL = TASSEL_3+MC_2;
|
|
// Context Restore
|
|
*((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
|
|
*((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
|
|
}
|
|
// End Sequence
|
|
// Context Restore
|
|
TA0CTL = contextSaveTA0CTL;
|
|
TA0CCTL0 = contextSaveTA0CCTL0;
|
|
TA0CCR0 = contextSaveTA0CCR0;
|
|
}
|
|
#endif
|
|
|
|
#ifdef RO_COMPB_TA0_WDTA
|
|
/*!
|
|
* @brief RO method capactiance measurement using CompB, TimerA0, and WDTA
|
|
*
|
|
* \n Schematic Description of CompB forming relaxation oscillator and
|
|
* coupling (connection) between the relaxation oscillator and
|
|
* TimerA0.
|
|
* \n <- Output
|
|
* \n -> Input
|
|
* \n R Resistor (typically 100Kohms)
|
|
*
|
|
* element---+-R--<-CBOUT/TA1CLK
|
|
* |
|
|
* +---->CBx
|
|
*
|
|
* \n The WDTA interval represents the measurement window. The number of
|
|
* counts within the TA0R that have accumulated during the measurement
|
|
* window represents the capacitance of the element.
|
|
*
|
|
* @param group Address of the structure describing the Sensor to be measured
|
|
* @param counts Address to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_RO_COMPB_TA0_WDTA_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
|
|
//** Context Save
|
|
// Status Register:
|
|
// WDTA: IE1, WDTCTL
|
|
// TIMERA0: TA0CTL, TA0CCTL1
|
|
// COMPAp: CACTL1, CACTL2, CAPD
|
|
// Ports: CboutDIR, CboutSel
|
|
uint8_t contextSaveSR;
|
|
uint16_t contextSaveSFRIE1;
|
|
uint16_t contextSaveWDTCTL;
|
|
uint16_t contextSaveTA0CTL,contextSaveTA0CCTL1,contextSaveTA0CCR1;
|
|
uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
|
|
uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
|
|
uint8_t contextSaveCboutDir,contextSaveCboutSel;
|
|
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveSFRIE1 = SFRIE1;
|
|
contextSaveWDTCTL = WDTCTL;
|
|
contextSaveWDTCTL &= 0x00FF;
|
|
contextSaveWDTCTL |= WDTPW;
|
|
contextSaveTA0CTL = TA0CTL;
|
|
contextSaveTA0CCTL1 = TA0CCTL1;
|
|
contextSaveTA0CCR1 = TA0CCR1;
|
|
|
|
contextSaveCBCTL0 = CBCTL0;
|
|
contextSaveCBCTL1 = CBCTL1;
|
|
contextSaveCBCTL2 = CBCTL2;
|
|
contextSaveCBCTL3 = CBCTL3;
|
|
contextSaveCboutDir = *(group->cboutTAxDirRegister);
|
|
contextSaveCboutSel = *(group->cboutTAxSelRegister);
|
|
|
|
//** Setup Measurement timer************************************************
|
|
// connect CBOUT with TA0
|
|
*(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
|
|
*(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
|
|
|
|
CBCTL2 = CBREF14+CBREF13 + CBREF02;
|
|
|
|
// Configure Timer TA0
|
|
TA0CTL = TASSEL_0+MC_2; // TACLK, cont mode
|
|
TA0CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
|
|
|
|
// Turn on Comparator
|
|
CBCTL1 = CBON; // Comparator on without filter
|
|
// Vcc to resistor ladder
|
|
|
|
CBCTL3 |= (group->cbpdBits); // set CPD bits to disable
|
|
// I/O buffer
|
|
SFRIE1 |= WDTIE; // enable WDT interrupt
|
|
CBCTL2 |= CBRS_1; // Turn on reference
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
|
|
|
|
//** Setup Gate Timer *************************************************
|
|
// Set duration of sensor measurment
|
|
WDTCTL = WDTPW + WDTTMSEL + group->measGateSource
|
|
+ group->accumulationCycles;
|
|
TA0CTL |= TACLR; // Clear Timer_A TAR
|
|
if(group->measGateSource == GATE_WDTA_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); // Wait for WDT interrupt
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
|
|
}
|
|
TA0CCTL1 ^= CCIS0; // Create SW capture of CCR1
|
|
counts[i] = TA0CCR1; // Save result
|
|
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
|
|
}
|
|
// End Sequence
|
|
//** Context Restore
|
|
// WDTA: IE1, WDCTL
|
|
// TIMERA0: TACTL, TACCTL1
|
|
// COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
|
|
// Ports: CboutDIR, CboutSel
|
|
__bis_SR_register(contextSaveSR);
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE); // Wait for WDT interrupt
|
|
}
|
|
SFRIE1 = contextSaveSFRIE1;
|
|
WDTCTL = contextSaveWDTCTL;
|
|
TA0CTL = contextSaveTA0CTL;
|
|
TA0CCTL1 = contextSaveTA0CCTL1;
|
|
TA0CCR1 = contextSaveTA0CCR1;
|
|
CBCTL0 = contextSaveCBCTL0;
|
|
CBCTL1 = contextSaveCBCTL1;
|
|
CBCTL2 = contextSaveCBCTL2;
|
|
CBCTL3 = contextSaveCBCTL3;
|
|
*(group->cboutTAxDirRegister) = contextSaveCboutDir;
|
|
*(group->cboutTAxSelRegister) = contextSaveCboutSel;
|
|
}
|
|
#endif
|
|
|
|
#ifdef RO_COMPB_TA1_WDTA
|
|
/*!
|
|
* @brief RO method capactiance measurement using CompB, TimerA1, and WDTA
|
|
*
|
|
* \n Schematic Description of CompB forming relaxation oscillator and
|
|
* coupling (connection) between the relaxation oscillator and TimerA1.
|
|
* \n <- Output
|
|
* \n -> Input
|
|
* \n R Resistor (typically 100Kohms)
|
|
*
|
|
* element---+-R--<-CBOUT/TA1CLK
|
|
* |
|
|
* +---->CBx
|
|
*
|
|
* \n The WDTA interval represents the measurement window. The number of
|
|
* counts within the TA1R that have accumulated during the measurement
|
|
* window represents the capacitance of the element.
|
|
*
|
|
* @param group Address of the structure describing the Sensor to be measured
|
|
* @param counts Address to where the measurements are to be written
|
|
* @return none
|
|
******************************************************************************/
|
|
void TI_CTS_RO_COMPB_TA1_WDTA_HAL(const struct Sensor *group, uint16_t *counts)
|
|
{
|
|
uint8_t i=0;
|
|
|
|
//** Context Save
|
|
// Status Register:
|
|
// WDTA: IE1, WDTCTL
|
|
// TIMERA1: TA1CTL, TA1CCTL1
|
|
// COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
|
|
// Ports: CboutDIR, CboutSel
|
|
uint8_t contextSaveSR;
|
|
uint16_t contextSaveSFRIE1;
|
|
uint16_t contextSaveWDTCTL;
|
|
uint16_t contextSaveTA1CTL,contextSaveTA1CCTL1,contextSaveTA1CCR1;
|
|
uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
|
|
uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
|
|
uint8_t contextSaveCboutDir,contextSaveCboutSel;
|
|
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveSFRIE1 = SFRIE1;
|
|
contextSaveWDTCTL = WDTCTL;
|
|
contextSaveWDTCTL &= 0x00FF;
|
|
contextSaveWDTCTL |= WDTPW;
|
|
contextSaveTA1CTL = TA1CTL;
|
|
contextSaveTA1CCTL1 = TA1CCTL1;
|
|
contextSaveTA1CCR1 = TA1CCR1;
|
|
|
|
contextSaveCBCTL0 = CBCTL0;
|
|
contextSaveCBCTL1 = CBCTL1;
|
|
contextSaveCBCTL2 = CBCTL2;
|
|
contextSaveCBCTL3 = CBCTL3;
|
|
contextSaveCboutDir = *(group->cboutTAxDirRegister);
|
|
contextSaveCboutSel = *(group->cboutTAxSelRegister);
|
|
|
|
//** Setup Measurement timer************************************************
|
|
// connect CBOUT with TA1
|
|
*(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
|
|
*(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
|
|
// Setup Comparator
|
|
CBCTL2 = CBREF14+CBREF13 + CBREF02;
|
|
// Configure Timer TA1
|
|
TA1CTL = TASSEL_0+MC_2; // TACLK, cont mode
|
|
TA1CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
|
|
// Turn on Comparator
|
|
CBCTL1 = CBON; // Turn on COMPB w/out filter
|
|
CBCTL3 |= (group->cbpdBits); // set CPD bits to disable
|
|
SFRIE1 |= WDTIE; // enable WDT interrupt
|
|
CBCTL2 |= CBRS_1; // Turn on reference
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
|
|
//** Setup Gate Timer *************************************************
|
|
// Set duration of sensor measurment
|
|
WDTCTL = WDTPW + WDTTMSEL + WDTCNTCL
|
|
+ group->measGateSource + group->accumulationCycles;
|
|
TA1CTL |= TACLR; // Clear Timer_A TAR
|
|
if(group->measGateSource == GATE_WDTA_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); // Wait for WDT interrupt
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
|
|
}
|
|
TA1CCTL1 ^= CCIS0; // Create SW capture of CCR1
|
|
counts[i] = TA1CCR1; // Save result
|
|
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
|
|
CBCTL3 &= ~((group->arrayPtr[i])->inputBits);
|
|
}
|
|
// End Sequence
|
|
//** Context Restore
|
|
// WDTA: IE1, WDCTL
|
|
// TIMERA0: TACTL, TACCTL1
|
|
// COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
|
|
// Ports: CboutDIR, CboutSel
|
|
__bis_SR_register(contextSaveSR);
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE); // Wait for WDT interrupt
|
|
}
|
|
SFRIE1 = contextSaveSFRIE1;
|
|
WDTCTL = contextSaveWDTCTL;
|
|
TA1CTL = contextSaveTA1CTL;
|
|
TA1CCTL1 = contextSaveTA1CCTL1;
|
|
TA1CCR1 = contextSaveTA1CCR1;
|
|
CBCTL0 = contextSaveCBCTL0;
|
|
CBCTL1 = contextSaveCBCTL1;
|
|
CBCTL2 = contextSaveCBCTL2;
|
|
CBCTL3 = contextSaveCBCTL3;
|
|
*(group->cboutTAxDirRegister) = contextSaveCboutDir;
|
|
*(group->cboutTAxSelRegister) = contextSaveCboutSel;
|
|
}
|
|
#endif
|
|
|
|
#ifdef fRO_COMPB_TA0_SW
|
|
/*!
|
|
* @brief fRO method capactiance measurement using CompB, TimerA0
|
|
*
|
|
* \n Schematic Description of CompB forming relaxation oscillator and
|
|
* coupling (connection) between the relaxation oscillator and
|
|
* TimerA0.
|
|
* \n <- Output
|
|
* \n -> Input
|
|
* \n R Resistor (typically 100Kohms)
|
|
*
|
|
* element---+-R--<-CBOUT/TA1CLK
|
|
* |
|
|
* +---->CBx
|
|
*
|
|
* \n The TAR reister value is the number of SW loops (function of MCLK)
|
|
* within n charge and discharge cycles. This value is directly
|
|
* proportional to the capacitance of the element measured. 'n' is
|
|
* defined by the variable accumulation_cycles.
|
|
*
|
|
* @param group Address of the structure describing the Sensor to be measured
|
|
* @param counts Address to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_fRO_COMPB_TA0_SW_HAL(const struct Sensor *group, uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
uint16_t j;
|
|
|
|
//** Context Save
|
|
// TIMERA0: TA0CTL, TA0CCR1
|
|
// COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
|
|
// Ports: CboutDIR, CboutSel
|
|
|
|
uint16_t contextSaveTA0CTL,contextSaveTA0CCR0;
|
|
uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
|
|
uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
|
|
uint8_t contextSaveCboutDir,contextSaveCboutSel;
|
|
|
|
contextSaveTA0CTL = TA0CTL;
|
|
contextSaveTA0CCR0 = TA0CCR0;
|
|
|
|
contextSaveCBCTL0 = CBCTL0;
|
|
contextSaveCBCTL1 = CBCTL1;
|
|
contextSaveCBCTL2 = CBCTL2;
|
|
contextSaveCBCTL3 = CBCTL3;
|
|
contextSaveCboutDir = *(group->cboutTAxDirRegister);
|
|
contextSaveCboutSel = *(group->cboutTAxSelRegister);
|
|
//** Setup Measurement timer************************************************
|
|
// connect CBOUT with TA0
|
|
*(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
|
|
*(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
|
|
CBCTL2 = CBREF14+CBREF13 + CBREF02;
|
|
// Configure Timer TA0
|
|
TA0CCR0 =(group->accumulationCycles);
|
|
|
|
// Turn on Comparator
|
|
CBCTL1 = CBON; // Turn on COMPB w/out filter
|
|
// Vcc to resistor ladder
|
|
CBCTL3 |= (group->cbpdBits); // set CPD bits to disable
|
|
// I/O buffer
|
|
CBCTL2 |= CBRS_1; // Turn on reference
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
j=0;
|
|
CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
|
|
//** Setup Gate Timer *************************************************
|
|
// Set duration of sensor measurment
|
|
TA0CTL = TASSEL_0+TACLR+MC_1; // TACLK
|
|
TA0CTL &= ~TAIFG; // TACLK
|
|
while(!(TA0CTL & TAIFG))
|
|
{
|
|
j++;
|
|
} // end accumulation
|
|
counts[i] = j;
|
|
}
|
|
// End Sequence
|
|
//** Context Restore
|
|
// TIMERA0: TACTL, TACCTL1
|
|
// COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
|
|
// Ports: CboutDIR, CboutSel
|
|
TA0CTL = contextSaveTA0CTL;
|
|
TA0CCR0 = contextSaveTA0CCR0;
|
|
CBCTL0 = contextSaveCBCTL0;
|
|
CBCTL1 = contextSaveCBCTL1;
|
|
CBCTL2 = contextSaveCBCTL2;
|
|
CBCTL3 = contextSaveCBCTL3;
|
|
*(group->cboutTAxDirRegister) = contextSaveCboutDir;
|
|
*(group->cboutTAxSelRegister) = contextSaveCboutSel;
|
|
}
|
|
#endif
|
|
|
|
#ifdef fRO_COMPB_TA1_SW
|
|
/*!
|
|
* @brief fRO method capactiance measurement using CompB, TimerA1
|
|
*
|
|
* \n Schematic Description of CompB forming relaxation oscillator and
|
|
* coupling (connection) between the relaxation oscillator and
|
|
* TimerA1.
|
|
* \n <- Output
|
|
* \n -> Input
|
|
* \n R Resistor (typically 100Kohms)
|
|
*
|
|
* element---+-R--<-CBOUT/TA1CLK
|
|
* |
|
|
* +---->CBx
|
|
*
|
|
* \n The TAR reister value is the number of SW loops (function of MCLK)
|
|
* within n charge and discharge cycles. This value is directly
|
|
* proportional to the capacitance of the element measured. 'n' is
|
|
* defined by the variable accumulation_cycles.
|
|
*
|
|
* @param group Address of the structure describing the Sensor to be measured
|
|
* @param counts Address to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_fRO_COMPB_TA1_SW_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
uint16_t j;
|
|
//** Context Save
|
|
// TIMERA0: TA1CTL, TA1CCTL1
|
|
// COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
|
|
// Ports: CboutDIR, CboutSel
|
|
|
|
uint16_t contextSaveTA1CTL,contextSaveTA1CCR0;
|
|
uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
|
|
uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
|
|
uint8_t contextSaveCboutDir,contextSaveCboutSel;
|
|
|
|
contextSaveTA1CTL = TA1CTL;
|
|
contextSaveTA1CCR0 = TA1CCR0;
|
|
|
|
contextSaveCBCTL0 = CBCTL0;
|
|
contextSaveCBCTL1 = CBCTL1;
|
|
contextSaveCBCTL2 = CBCTL2;
|
|
contextSaveCBCTL3 = CBCTL3;
|
|
contextSaveCboutDir = *(group->cboutTAxDirRegister);
|
|
contextSaveCboutSel = *(group->cboutTAxSelRegister);
|
|
//** Setup Measurement timer************************************************
|
|
// connect CBOUT with TA1
|
|
*(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
|
|
*(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
|
|
CBCTL2 = CBREF14+CBREF13 + CBREF02;
|
|
// Configure Timer TA1
|
|
TA1CCR0 =(group->accumulationCycles);
|
|
|
|
// Turn on Comparator
|
|
CBCTL1 = CBON; // Turn on COMPB w/out filter
|
|
// Vcc to resistor ladder
|
|
CBCTL3 |= (group->cbpdBits); // set CPD bits to disable
|
|
// I/O buffer
|
|
CBCTL2 |= CBRS_1; // Turn on reference
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
j=0;
|
|
CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
|
|
//** Setup Gate Timer *************************************************
|
|
// Set duration of sensor measurment
|
|
TA1CTL = TASSEL_0+TACLR+MC_1; // TA1CLK, reset, up mode
|
|
TA1CTL &= ~TAIFG; // clear ifg
|
|
while(!(TA1CTL & TAIFG))
|
|
{
|
|
j++;
|
|
} // end accumulation
|
|
counts[i] = j;
|
|
//P1SEL &=~BIT4;
|
|
}
|
|
// End Sequence
|
|
//** Context Restore
|
|
// TIMERA0: TACTL, TACCTL1
|
|
// COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
|
|
// Ports: CboutDIR, CboutSel
|
|
TA1CTL = contextSaveTA1CTL;
|
|
TA1CCR0 = contextSaveTA1CCR0;
|
|
CBCTL0 = contextSaveCBCTL0;
|
|
CBCTL1 = contextSaveCBCTL1;
|
|
CBCTL2 = contextSaveCBCTL2;
|
|
CBCTL3 = contextSaveCBCTL3;
|
|
*(group->cboutTAxDirRegister) = contextSaveCboutDir;
|
|
*(group->cboutTAxSelRegister) = contextSaveCboutSel;
|
|
}
|
|
#endif
|
|
|
|
#ifdef RO_COMPB_TA1_TA0
|
|
/*!
|
|
* ======== TI_CTS_RO_COMPB_TA1_TA0_HAL =======
|
|
* @brief RO method capacitance measurement using CompB, TimerA1, and TimerA0
|
|
*
|
|
* \n Schematic Description of CompB forming relaxation oscillator and
|
|
* \n coupling (connection) between the relaxation oscillator and TimerA1.
|
|
* \n <- Output
|
|
* \n -> Input
|
|
* \n R Resistor (typically 100Kohms)
|
|
*
|
|
* element--+--R--<-CBOUT/TA1CLK
|
|
* |
|
|
* +----->-CBx
|
|
*
|
|
* \n The TimerA0 interval represents the measurement window. The number
|
|
* of counts within TA1R that have accumulated during the
|
|
* measurement window represents the capacitance of the element.
|
|
*
|
|
* @param group pointer to the sensor to be measured
|
|
* @param counts pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_RO_COMPB_TA1_TA0_HAL(const struct Sensor *group, uint16_t *counts)
|
|
{
|
|
uint8_t i=0;
|
|
|
|
/*!
|
|
* Allocate Context Save Variables
|
|
* Status Register: GIE bit only
|
|
* TIMERA0: TA0CTL, TA0CCTL0, TA0CCR0
|
|
* TIMERA1: TA1CTL, TA1CCTL0, TA1CCR0
|
|
* COMPB: CBCTL0,CBCTL1,CBCTL2,CBCTL3
|
|
*/
|
|
uint8_t contextSaveSR;
|
|
uint16_t contextSaveTA0CTL,contextSaveTA0CCTL0,contextSaveTA0CCR0;
|
|
uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
|
|
uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
|
|
uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
|
|
uint8_t contextSaveCboutDir,contextSaveCboutSel;
|
|
/*
|
|
* Perform context save of registers used.
|
|
*/
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveTA0CTL = TA0CTL;
|
|
contextSaveTA0CCTL0 = TA0CCTL0;
|
|
contextSaveTA0CCR0 = TA0CCR0;
|
|
contextSaveTA1CTL = TA1CTL;
|
|
contextSaveTA1CCTL0 = TA1CCTL0;
|
|
contextSaveTA1CCR0 = TA1CCR0;
|
|
contextSaveCBCTL0 = CBCTL0;
|
|
contextSaveCBCTL1 = CBCTL1;
|
|
contextSaveCBCTL2 = CBCTL2;
|
|
contextSaveCBCTL3 = CBCTL3;
|
|
contextSaveCboutDir = *(group->cboutTAxDirRegister);
|
|
contextSaveCboutSel = *(group->cboutTAxSelRegister);
|
|
/*
|
|
* Connect CBOUT with TA1. This also enables the feedback path for the
|
|
* Relaxation oscillator.
|
|
*/
|
|
*(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
|
|
*(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
|
|
/*
|
|
* The COMPB reference is set to Vcc and the reference resistor taps are
|
|
* Vcc*(0x18+1)/32 for CBOUT = 1 and Vcc*((0x04+1)/32 for CBOUT = 0.
|
|
* If Vcc is 3.0V, then the Vih is 2.34V and the Vil is 0.47V. In the
|
|
* event that CBOUT is connected to DVIO which is not equal to Vcc, then
|
|
* these voltage levels need to be adjusted.
|
|
*/
|
|
CBCTL2 = CBRS_1 + CBREF14 + CBREF13 + CBREF02;
|
|
CBCTL3 |= (group->cbpdBits); // set CPD bits to disable digital IO
|
|
/*
|
|
* TimerA1 is the measurement timer and counts the number of relaxation
|
|
* oscillation cycles of the element which is connected to TACLK.
|
|
* TimerA1 is in continuous mode. TA1CCR0 is configured as a capture
|
|
* register and will be triggered as a SW capture event.
|
|
*/
|
|
TA1CTL = TASSEL_0+MC_2;
|
|
TA1CCTL0 = CM_3+CCIS_2+CAP;
|
|
/*
|
|
* TimerA0 is the gate (measurement interval) timer. The number of
|
|
* oscillations counted, by TimerA1, within the gate interval represents
|
|
* the measured capacitance.
|
|
*/
|
|
TA0CCR0 = group->accumulationCycles;
|
|
TA0CTL = group->measGateSource + group->sourceScale;
|
|
TA0CCTL0 = CCIE;
|
|
CBCTL1 = CBON; // Turn on COMPB w/out filter
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
/* Turn on specific comparator input. */
|
|
CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
|
|
TA1CTL |= TACLR; // Clear TimerA1, measurement timer
|
|
TA1CTL &= ~TAIFG; // Clear overflow flag
|
|
TA0CTL |= (TACLR + MC_1); // Clear and start TimerA0
|
|
/*
|
|
* The measGateSource represents the gate source for timer TIMERA0,
|
|
* which can be sourced from TACLK, ACLK, SMCLK, or INCLK. The
|
|
* interrupt handler is defined in TIMER0_A0_VECTOR, which simply
|
|
* clears the low power mode bits in the Status Register before
|
|
* returning from the ISR.
|
|
*/
|
|
if(group->measGateSource == TIMER_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); // Enable GIE and wait for ISR
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE);
|
|
}
|
|
TA1CCTL0 ^= CCIS0; // Create SW capture of TA1R into TA1CCR0.
|
|
TA0CTL &= ~MC_1; // Halt Timer
|
|
if(TA1CTL & TAIFG)
|
|
{
|
|
/*
|
|
* If a rollover in the timer has occurred then set counts to
|
|
* 0. This will prevent erroneous data from entering the baseline
|
|
* tracking algorithm.
|
|
*/
|
|
counts[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
counts[i] = TA1CCR0; // Save result
|
|
}
|
|
} // End For Loop
|
|
/*
|
|
* Context restore GIE within Status Register and registers used.
|
|
*/
|
|
__bis_SR_register(contextSaveSR);
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE);
|
|
}
|
|
TA0CTL = contextSaveTA0CTL;
|
|
TA0CCTL0 = contextSaveTA0CCTL0;
|
|
TA0CCR0 = contextSaveTA0CCR0;
|
|
TA1CTL = contextSaveTA1CTL;
|
|
TA1CCTL0 = contextSaveTA1CCTL0;
|
|
TA1CCR0 = contextSaveTA1CCR0;
|
|
CBCTL0 = contextSaveCBCTL0;
|
|
CBCTL1 = contextSaveCBCTL1;
|
|
CBCTL2 = contextSaveCBCTL2;
|
|
CBCTL3 = contextSaveCBCTL3;
|
|
*(group->cboutTAxDirRegister) = contextSaveCboutDir;
|
|
*(group->cboutTAxSelRegister) = contextSaveCboutSel;
|
|
}
|
|
#endif
|
|
|
|
#ifdef fRO_COMPB_TA1_TA0
|
|
/*!
|
|
* ======== TI_CTS_fRO_COMPB_TA1_TA0_HAL() ========
|
|
* @brief fRO method capacitance measurement using CompB, TimerA1, and TimerA0
|
|
*
|
|
* /n Schematic Description of CompB forming relaxation oscillator and
|
|
* coupling (connection) between the relaxation oscillator and TimerA1.
|
|
* /n <- Output
|
|
* /n -> Input
|
|
* /n R Resistor (typically 100Kohms)
|
|
*
|
|
* element--+--R--<-CBOUT/TA1CLK
|
|
* |
|
|
* +----->-CBx
|
|
*
|
|
* /n The TimerA1 interval represents the measurement window. The number
|
|
* of counts within TA0R that have accumulated during the
|
|
* measurement window represents the capacitance of the element.
|
|
*
|
|
* @param (group) pointer to the sensor to be measured
|
|
* @param (counts) pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_fRO_COMPB_TA1_TA0_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i=0;
|
|
|
|
/*!
|
|
* Allocate Context Save Variables
|
|
* Status Register: GIE bit only
|
|
* TIMERA0: TA0CTL, TA0CCTL0, TA0CCR0
|
|
* TIMERA1: TA1CTL, TA1CCTL0, TA1CCR0
|
|
* COMPB: CBCTL0,CBCTL1,CBCTL2,CBCTL3
|
|
*/
|
|
uint8_t contextSaveSR;
|
|
uint16_t contextSaveTA0CTL,contextSaveTA0CCTL0,contextSaveTA0CCR0;
|
|
uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
|
|
uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
|
|
uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
|
|
uint8_t contextSaveCboutDir,contextSaveCboutSel;
|
|
/*
|
|
* Perform context save of registers used.
|
|
*/
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveTA0CTL = TA0CTL;
|
|
contextSaveTA0CCTL0 = TA0CCTL0;
|
|
contextSaveTA0CCR0 = TA0CCR0;
|
|
contextSaveTA1CTL = TA1CTL;
|
|
contextSaveTA1CCTL0 = TA1CCTL0;
|
|
contextSaveTA1CCR0 = TA1CCR0;
|
|
contextSaveCBCTL0 = CBCTL0;
|
|
contextSaveCBCTL1 = CBCTL1;
|
|
contextSaveCBCTL2 = CBCTL2;
|
|
contextSaveCBCTL3 = CBCTL3;
|
|
contextSaveCboutDir = *(group->cboutTAxDirRegister);
|
|
contextSaveCboutSel = *(group->cboutTAxSelRegister);
|
|
/*
|
|
* Connect CBOUT with TA1. This also enables the feedback path for the
|
|
* Relaxation oscillator.
|
|
*/
|
|
*(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
|
|
*(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
|
|
/*
|
|
* The COMPB reference is set to Vcc and the reference resistor taps are
|
|
* Vcc*(0x18+1)/32 for CBOUT = 1 and Vcc*((0x04+1)/32 for CBOUT = 0.
|
|
* If Vcc is 3.0V, then the Vih is 2.34V and the Vil is 0.47V. In the
|
|
* event that CBOUT is connected to DVIO which is not equal to Vcc, then
|
|
* these voltage levels need to be adjusted.
|
|
*/
|
|
CBCTL2 = CBRS_1 + CBREF14 + CBREF13 + CBREF02;
|
|
CBCTL3 |= (group->cbpdBits); // set CPD bits to disable digital IO
|
|
/*
|
|
* TimerA0 is the measurement timer and counts the number of clock cycles
|
|
* ;typically SMCLK, but can also be TACLK, INCLK, or ACLK.
|
|
* TimerA0 is in continuous mode. TA0CCR0 is configured as a capture
|
|
* register and will be triggered as a SW capture event.
|
|
*/
|
|
TA0CTL = group->measGateSource + MC_2;
|
|
TA0CCTL0 = CM_3+CCIS_2+CAP;
|
|
/*
|
|
* TimerA1 is the gate (measurement interval) timer. With the fRO method
|
|
* the gate time varies with the capacitance of the element. The number of
|
|
* clock cycles counted, by TimerA0, within the gate interval represents
|
|
* the measured capacitance.
|
|
*/
|
|
TA1CCR0 = group->accumulationCycles;
|
|
TA1CTL = group->sourceScale;
|
|
TA1CCTL0 = CCIE;
|
|
CBCTL1 = CBON; // Turn on COMPB w/out filter
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
/*
|
|
* Turn on specific comparator input.
|
|
*/
|
|
CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
|
|
TA0CTL |= TACLR; // Clear TimerA1, measurement timer
|
|
TA0CTL &= ~TAIFG; // Clear overflow flag
|
|
TA1CTL |= (TACLR + MC_1); // Clear and start TimerA0
|
|
/*
|
|
* The measGateSource represents the measurement source for timer
|
|
* TimerA0, which can be sourced from TACLK, ACLK, SMCLK, or INCLK. The
|
|
* interrupt handler is defined in TIMER1_A0_VECTOR, which simply
|
|
* clears the low power mode bits in the Status Register before
|
|
* returning from the ISR.
|
|
*/
|
|
if(group->measGateSource == TIMER_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); // Enable GIE and wait for ISR
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE);
|
|
}
|
|
TA0CCTL0 ^= CCIS0; // Create SW capture of TA1R into TA1CCR0.
|
|
TA1CTL &= ~MC_1; // Halt Timer
|
|
if(TA0CTL & TAIFG)
|
|
{
|
|
/*
|
|
* If a rollover in the timer has occurred then set counts to
|
|
* 0. This will prevent erroneous data from entering the baseline
|
|
* tracking algorithm.
|
|
*/
|
|
counts[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
counts[i] = TA0CCR0; // Save result
|
|
}
|
|
} // End For Loop
|
|
/*
|
|
* Context restore GIE within Status Register and registers used.
|
|
*/
|
|
__bis_SR_register(contextSaveSR);
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE);
|
|
}
|
|
TA0CTL = contextSaveTA0CTL;
|
|
TA0CCTL0 = contextSaveTA0CCTL0;
|
|
TA0CCR0 = contextSaveTA0CCR0;
|
|
TA1CTL = contextSaveTA1CTL;
|
|
TA1CCTL0 = contextSaveTA1CCTL0;
|
|
TA1CCR0 = contextSaveTA1CCR0;
|
|
CBCTL0 = contextSaveCBCTL0;
|
|
CBCTL1 = contextSaveCBCTL1;
|
|
CBCTL2 = contextSaveCBCTL2;
|
|
CBCTL3 = contextSaveCBCTL3;
|
|
*(group->cboutTAxDirRegister) = contextSaveCboutDir;
|
|
*(group->cboutTAxSelRegister) = contextSaveCboutSel;
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef RO_PINOSC_TA1_WDTp
|
|
/*!
|
|
* @brief RO method capactiance measurement with PinOsc IO, TimerA1, and WDT+
|
|
*
|
|
* \n Schematic Description:
|
|
*
|
|
* \n element-----+->Px.y
|
|
*
|
|
* \n The WDT+ interval represents the measurement window. The number of
|
|
* counts within the TA0R that have accumulated during the measurement
|
|
* window represents the capacitance of the element.
|
|
*
|
|
* @param group Pointer to the structure describing the Sensor to be measured
|
|
* @param counts Pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
|
|
void TI_CTS_RO_PINOSC_TA1_WDTp_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
|
|
//** Context Save
|
|
// Status Register:
|
|
// WDTp: IE1, WDTCTL
|
|
// TIMERA1: TA1CTL, TA1CCTL1
|
|
// Ports: PxSEL, PxSEL2
|
|
uint8_t contextSaveSR;
|
|
uint8_t contextSaveIE1;
|
|
uint16_t contextSaveWDTCTL;
|
|
uint16_t contextSaveTA1CTL,contextSaveTA1CCTL1,contextSaveTA1CCR1;
|
|
uint8_t contextSaveSel,contextSaveSel2;
|
|
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveIE1 = IE1;
|
|
contextSaveWDTCTL = WDTCTL;
|
|
contextSaveWDTCTL &= 0x00FF;
|
|
contextSaveWDTCTL |= WDTPW;
|
|
contextSaveTA1CTL = TA1CTL;
|
|
contextSaveTA1CCTL1 = TA1CCTL1;
|
|
contextSaveTA1CCR1 = TA1CCR1;
|
|
|
|
//** Setup Measurement timer***************************************************
|
|
// Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
|
|
// capacitive touch layer.
|
|
|
|
// Configure and Start Timer
|
|
TA1CTL = TASSEL_3+MC_2; // INCLK, cont mode
|
|
TA1CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
|
|
IE1 |= WDTIE; // enable WDT interrupt
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
// Context Save
|
|
contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
|
|
contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
|
|
// Configure Ports for relaxation oscillator
|
|
*((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
|
|
*((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
|
|
//** Setup Gate Timer ********************************************************
|
|
// Set duration of sensor measurment
|
|
//WDTCTL = (WDTPW+WDTTMSEL+group->measGateSource+group->accumulationCycles);
|
|
WDTCTL = (WDTPW+WDTTMSEL+(group->measGateSource)+(group->accumulationCycles));
|
|
TA1CTL |= TACLR; // Clear Timer_A TAR
|
|
if(group->measGateSource == GATE_WDT_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); // Wait for WDT interrupt
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
|
|
}
|
|
TA1CCTL1 ^= CCIS0; // Create SW capture of CCR1
|
|
counts[i] = TA1CCR1; // Save result
|
|
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
|
|
// Context Restore
|
|
*((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
|
|
*((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
|
|
}
|
|
// End Sequence
|
|
// Context Restore
|
|
__bis_SR_register(contextSaveSR);
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE); //
|
|
}
|
|
IE1 = contextSaveIE1;
|
|
WDTCTL = contextSaveWDTCTL;
|
|
TA1CTL = contextSaveTA1CTL;
|
|
TA1CCTL1 = contextSaveTA1CCTL1;
|
|
TA1CCR1 = contextSaveTA1CCR1;
|
|
}
|
|
#endif
|
|
|
|
#ifdef RO_PINOSC_TA1_TB0
|
|
/*!
|
|
* ======== TI_CTS_RO_PINOSC_TA1_TB0_HAL ========
|
|
* @brief RO method capacitance measurement using PinOsc IO, TimerA1, and
|
|
* TimerB0
|
|
*
|
|
* \n Schematic Description:
|
|
*
|
|
* \n element-----+->Px.y
|
|
*
|
|
* \n The TimerA1 interval represents the gate (measurement) time. The
|
|
* number of oscillations that have accumulated in TA1R during the
|
|
* measurement time represents the capacitance of the element.
|
|
*
|
|
* @param group pointer to the sensor to be measured
|
|
* @param counts pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_RO_PINOSC_TA1_TB0_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
/*!
|
|
* Allocate Context Save Variables
|
|
* Status Register: GIE bit only
|
|
* TIMERA0: TA1CTL, TA1CCTL0, TA1CCR0
|
|
* TIMERB1: TB0CTL, TB0CCTL0, TB0CCR0
|
|
* Ports: PxSEL, PxSEL2
|
|
*/
|
|
uint8_t contextSaveSR;
|
|
uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
|
|
uint16_t contextSaveTB0CTL,contextSaveTB0CCTL0,contextSaveTB0CCR0;
|
|
uint8_t contextSaveSel,contextSaveSel2;
|
|
/*
|
|
* Perform context save of registers used except port registers which are
|
|
* saved and restored within the for loop as each element within the
|
|
* sensor is measured.
|
|
*/
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveTA1CTL = TA1CTL;
|
|
contextSaveTA1CCTL0 = TA1CCTL0;
|
|
contextSaveTA1CCR0 = TA1CCR0;
|
|
contextSaveTB0CTL = TB0CTL;
|
|
contextSaveTB0CCTL0 = TB0CCTL0;
|
|
contextSaveTB0CCR0 = TB0CCR0;
|
|
/*
|
|
* TimerA0 is the measurement timer and counts the number of relaxation
|
|
* oscillation cycles of the electrode which is routed to INCLK. TA1 is
|
|
* in continuous mode and sourced from INCLK.
|
|
*/
|
|
TA1CTL = TASSEL_3+MC_2;
|
|
TA1CCTL0 = CM_3+CCIS_2+CAP; // Setup for SW capture
|
|
/*
|
|
* TimerA1 is the gate (measurement interval) timer. The number of
|
|
* oscillations counted within the gate interval represents the measured
|
|
* capacitance.
|
|
*/
|
|
TB0CCR0 = (group->accumulationCycles);
|
|
// Establish source and scale of timerA1, but halt the timer.
|
|
TB0CTL = group->measGateSource + group->sourceScale;
|
|
TB0CCTL0 = CCIE; // Enable Interrupt when timer counts to TB0CCR0.
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
// Context Save Port Registers
|
|
contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
|
|
contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
|
|
// Configure Ports for relaxation oscillator
|
|
*((group->arrayPtr[i])->inputPxselRegister)
|
|
&= ~((group->arrayPtr[i])->inputBits);
|
|
*((group->arrayPtr[i])->inputPxsel2Register)
|
|
|= ((group->arrayPtr[i])->inputBits);
|
|
TA1CTL |= TACLR;
|
|
TA1CTL &= ~TAIFG;
|
|
TB0CTL |= (TACLR + MC_1);
|
|
/*!
|
|
* The measGateSource represents the gate source for timer TIMERA1,
|
|
* which can be sourced from TACLK, ACLK, SMCLK, or INCLK. The
|
|
* interrupt handler is defined in TIMER1_A0_VECTOR, which simply
|
|
* clears the low power mode bits in the Status Register before
|
|
* returning from the ISR.
|
|
*/
|
|
if(group->measGateSource == TIMER_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE); // Enable GIE and wait for ISR
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE); // Enable GIE and wait for ISR
|
|
}
|
|
TA1CCTL0 ^= CCIS0; // Create SW capture of TA1CCR into TA1CCR0.
|
|
TB0CTL &= ~MC_1; // Halt Timer
|
|
if(TA1CTL & TAIFG)
|
|
{
|
|
/*
|
|
* If a rollover in the timer has occurred then set counts to
|
|
* 0. This will prevent erroneous data from entering the baseline
|
|
* tracking algorithm.
|
|
*/
|
|
counts[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
counts[i] = TA1CCR0; // Save result
|
|
}
|
|
// Context Restore Port Registers
|
|
*((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
|
|
*((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
|
|
} // End for Loop
|
|
/*
|
|
* Context restore GIE within Status Register and all timer registers
|
|
* used.
|
|
*/
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE);
|
|
}
|
|
TA1CTL = contextSaveTA1CTL;
|
|
TA1CCTL0 = contextSaveTA1CCTL0;
|
|
TA1CCR0 = contextSaveTA1CCR0;
|
|
TB0CTL = contextSaveTB0CTL;
|
|
TB0CCTL0 = contextSaveTB0CCTL0;
|
|
TB0CCR0 = contextSaveTB0CCR0;
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef fRO_PINOSC_TA1_TA0
|
|
/*!
|
|
* @brief fRO method capacitance measurement using PinOsc IO, TimerA1, and
|
|
* TimerA0
|
|
*
|
|
* \n Schematic Description:
|
|
*
|
|
* \n element-----+->Px.y
|
|
*
|
|
*
|
|
* @param group Pointer to the structure describing the Sensor to be measured
|
|
* @param counts Pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_fRO_PINOSC_TA1_TA0_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
|
|
/*
|
|
* Context Save
|
|
* Status Register: GIE
|
|
* TIMERA1: TA1CTL, TA1CCTL0, TA1CCR0
|
|
* TIMERA0: TA0CTL, TA0CCTL0, TA0CCR0
|
|
* Ports: PxSEL, PxSEL2
|
|
*/
|
|
uint8_t contextSaveSR;
|
|
uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
|
|
uint16_t contextSaveTA0CTL,contextSaveTA0CCTL0,contextSaveTA0CCR0;
|
|
uint8_t contextSaveSel,contextSaveSel2;
|
|
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveTA1CTL = TA1CTL;
|
|
contextSaveTA1CCTL0 = TA1CCTL0;
|
|
contextSaveTA1CCR0 = TA1CCR0;
|
|
contextSaveTA0CTL = TA0CTL;
|
|
contextSaveTA0CCTL0 = TA0CCTL0;
|
|
contextSaveTA0CCR0 = TA0CCR0;
|
|
|
|
//** Setup Measurement timer***************************************************
|
|
// Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
|
|
// capacitive touch layer.
|
|
|
|
// Configure Measurement interval with TimerA1
|
|
TA1CCR0 = (group->accumulationCycles);
|
|
/*
|
|
* INCLK, IDx settings from sourceScale definition
|
|
*/
|
|
TA1CTL = TASSEL_3 + group->sourceScale;
|
|
TA1CCTL0 = CCIE;
|
|
|
|
// Configure and start measurment timerA0
|
|
TA0CTL = group->measGateSource + MC_2 + TACLR; // cont
|
|
TA0CCTL0 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
|
|
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
// Context Save
|
|
contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
|
|
contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
|
|
// Configure Ports for relaxation oscillator
|
|
*((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
|
|
*((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
|
|
|
|
TA0CTL |= TACLR;
|
|
TA0CTL &= ~TAIFG;
|
|
TA1CTL |= (TACLR + MC_1); // Clear Timer, Up mode
|
|
/*
|
|
* In this configuration measGateSource represents the measurement
|
|
* source for timer TIMERA1, which can be sourced from TACLK, ACLK,
|
|
* SMCLK, or INCLK.
|
|
*/
|
|
if(group->measGateSource == TIMER_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE);
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE);
|
|
}
|
|
TA0CCTL0 ^= CCIS0; // Create SW capture of CCR1
|
|
TA1CTL &= ~MC_1; // Halt Timer
|
|
if(TA0CTL & TAIFG)
|
|
{
|
|
/*
|
|
* If a rollover in the timer has occurred then set counts to
|
|
* 0. This will prevent erroneous data from entering the baseline
|
|
* tracking algorithm.
|
|
*/
|
|
counts[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
counts[i] = TA0CCR0; // Save result
|
|
}
|
|
// Context Restore
|
|
*((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
|
|
*((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
|
|
} // End for loop
|
|
// Context Restore
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE);
|
|
}
|
|
TA1CTL = contextSaveTA1CTL;
|
|
TA1CCTL0 = contextSaveTA1CCTL0;
|
|
TA1CCR0 = contextSaveTA1CCR0;
|
|
TA0CTL = contextSaveTA0CTL;
|
|
TA0CCTL0 = contextSaveTA0CCTL0;
|
|
TA0CCR0 = contextSaveTA0CCR0;
|
|
}
|
|
#endif
|
|
|
|
#ifdef fRO_PINOSC_TA1_TB0
|
|
/*!
|
|
* @brief fRO method capacitance measurement using PinOsc IO, TimerA1, and
|
|
* TimerB0
|
|
*
|
|
* \n Schematic Description:
|
|
*
|
|
* \n element-----+->Px.y
|
|
*
|
|
*
|
|
* @param group Pointer to the structure describing the Sensor to be measured
|
|
* @param counts Pointer to where the measurements are to be written
|
|
* @return none
|
|
*/
|
|
void TI_CTS_fRO_PINOSC_TA1_TB0_HAL(const struct Sensor *group,uint16_t *counts)
|
|
{
|
|
uint8_t i;
|
|
|
|
/*
|
|
* Context Save
|
|
* Status Register: GIE
|
|
* TIMERA1: TA1CTL, TA1CCTL0, TA1CCR0
|
|
* TIMERB0: TB0CTL, TB0CCTL0, TB0CCR0
|
|
* Ports: PxSEL, PxSEL2
|
|
*/
|
|
uint8_t contextSaveSR;
|
|
uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
|
|
uint16_t contextSaveTB0CTL,contextSaveTB0CCTL0,contextSaveTB0CCR0;
|
|
uint8_t contextSaveSel,contextSaveSel2;
|
|
|
|
contextSaveSR = __get_SR_register();
|
|
contextSaveTA1CTL = TA1CTL;
|
|
contextSaveTA1CCTL0 = TA1CCTL0;
|
|
contextSaveTA1CCR0 = TA1CCR0;
|
|
contextSaveTB0CTL = TB0CTL;
|
|
contextSaveTB0CCTL0 = TB0CCTL0;
|
|
contextSaveTB0CCR0 = TB0CCR0;
|
|
|
|
//** Setup Measurement timer***************************************************
|
|
// Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
|
|
// capacitive touch layer.
|
|
|
|
// Configure Measurement interval with TimerA1
|
|
TA1CCR0 = (group->accumulationCycles);
|
|
/*
|
|
* INCLK, IDx settings from sourceScale definition
|
|
*/
|
|
TA1CTL = TASSEL_3 + group->sourceScale;
|
|
TA1CCTL0 = CCIE;
|
|
|
|
// Configure and start measurment timerA0
|
|
TB0CTL = group->measGateSource + MC_2 + TBCLR; // cont
|
|
TB0CCTL0 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
|
|
|
|
for (i = 0; i<(group->numElements); i++)
|
|
{
|
|
// Context Save
|
|
contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
|
|
contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
|
|
// Configure Ports for relaxation oscillator
|
|
*((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
|
|
*((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
|
|
|
|
TB0CTL |= TBCLR;
|
|
TB0CTL &= ~TBIFG;
|
|
TA1CTL |= (TACLR + MC_1); // Clear Timer, Up mode
|
|
/*
|
|
* In this configuration measGateSource represents the measurement
|
|
* source for timer TIMERA1, which can be sourced from TACLK, ACLK,
|
|
* SMCLK, or INCLK.
|
|
*/
|
|
if(group->measGateSource == TIMER_ACLK)
|
|
{
|
|
__bis_SR_register(LPM3_bits+GIE);
|
|
}
|
|
else
|
|
{
|
|
__bis_SR_register(LPM0_bits+GIE);
|
|
}
|
|
TB0CCTL0 ^= CCIS0; // Create SW capture of CCR1
|
|
TA1CTL &= ~MC_1; // Halt Timer
|
|
if(TB0CTL & TBIFG)
|
|
{
|
|
/*
|
|
* If a rollover in the timer has occurred then set counts to
|
|
* 0. This will prevent erroneous data from entering the baseline
|
|
* tracking algorithm.
|
|
*/
|
|
counts[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
counts[i] = TB0CCR0; // Save result
|
|
}
|
|
// Context Restore
|
|
*((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
|
|
*((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
|
|
} // End for loop
|
|
// Context Restore
|
|
if(!(contextSaveSR & GIE))
|
|
{
|
|
__bic_SR_register(GIE);
|
|
}
|
|
TA1CTL = contextSaveTA1CTL;
|
|
TA1CCTL0 = contextSaveTA1CCTL0;
|
|
TA1CCR0 = contextSaveTA1CCR0;
|
|
TB0CTL = contextSaveTB0CTL;
|
|
TB0CCTL0 = contextSaveTB0CCTL0;
|
|
TB0CCR0 = contextSaveTB0CCR0;
|
|
}
|
|
#endif
|
|
|
|
/*!
|
|
* @}
|
|
*/
|
|
|
|
/*!
|
|
* @defgroup ISR_GROUP ISR Definitions
|
|
* @ingroup CTS_HAL
|
|
*/
|
|
|
|
#ifdef WDT_GATE
|
|
/*!
|
|
* ======== watchdog_timer ========
|
|
* @ingroup ISR_GROUP
|
|
* @brief WDT_ISR
|
|
*
|
|
* This ISR clears the LPM bits found in the Status Register (SR/R2).
|
|
*
|
|
* @param none
|
|
* @return none
|
|
*/
|
|
#pragma vector=WDT_VECTOR
|
|
__interrupt void watchdog_timer(void)
|
|
{
|
|
__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
|
|
}
|
|
#endif
|
|
|
|
#ifdef TIMER0A0_GATE
|
|
/*!
|
|
* ======== TIMER0_A0_ISR ========
|
|
* @ingroup ISR_GROUP
|
|
* @brief TIMER0_A0_ISR
|
|
*
|
|
* This ISR clears the LPM bits found in the Status Register (SR/R2).
|
|
*
|
|
* @param none
|
|
* @return none
|
|
*/
|
|
#pragma vector=TIMER0_A0_VECTOR
|
|
__interrupt void TIMER0_A0_ISR(void)
|
|
{
|
|
__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
|
|
}
|
|
#endif
|
|
|
|
#ifdef TIMER1A0_GATE
|
|
/*!
|
|
* ======== TIMER1_A0_ISR ========
|
|
* @ingroup ISR_GROUP
|
|
* @brief TIMER1_A0_ISR
|
|
*
|
|
* This ISR clears the LPM bits found in the Status Register (SR/R2).
|
|
*
|
|
* @param none
|
|
* @return none
|
|
*/
|
|
#pragma vector=TIMER1_A0_VECTOR
|
|
__interrupt void TIMER1_A0_ISR(void)
|
|
|
|
{
|
|
__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
|
|
}
|
|
#endif
|
|
|
|
#ifdef TIMER2A0_GATE
|
|
/*!
|
|
* ======== TIMER2_A0_ISR ========
|
|
* @ingroup ISR_GROUP
|
|
* @brief TIMER2_A0_ISR
|
|
*
|
|
* This ISR clears the LPM bits found in the Status Register (SR/R2).
|
|
*
|
|
* @param none
|
|
* @return none
|
|
*/
|
|
#pragma vector=TIMER2_A0_VECTOR
|
|
__interrupt void TIMER2_A0_ISR(void)
|
|
{
|
|
__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
|
|
}
|
|
#endif
|
|
|
|
#ifdef TIMER3A0_GATE
|
|
/*!
|
|
* ======== TIMER3_A0_ISR ========
|
|
* @ingroup ISR_GROUP
|
|
* @brief TIMER3_A0_ISR
|
|
*
|
|
* This ISR clears the LPM bits found in the Status Register (SR/R2).
|
|
*
|
|
* @param none
|
|
* @return none
|
|
*/
|
|
#pragma vector=TIMER3_A0_VECTOR
|
|
__interrupt void TIMER3_A0_ISR(void)
|
|
|
|
{
|
|
__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
|
|
}
|
|
#endif
|
|
|
|
#ifdef TIMERB0_GATE
|
|
/*!
|
|
* ======== TIMER0_B0_ISR ========
|
|
* @ingroup ISR_GROUP
|
|
* @brief TIMER0_B0_ISR
|
|
*
|
|
* This ISR clears the LPM bits found in the Status Register (SR/R2).
|
|
*
|
|
* @param none
|
|
* @return none
|
|
*/
|
|
#pragma vector=TIMERB0_VECTOR
|
|
__interrupt void TIMERB0_ISR(void)
|
|
|
|
{
|
|
__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
|
|
}
|
|
#endif
|