Testing out the PPD42 Air Quality Sensor, with an MSP430 Launchpad and graphing the data with GNUplot.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1512 lines
62 KiB

/*******************************************************************************
* CTS_HAL.c - Hardware abstraction of various combinations of modules to
* perform a capacitance measurement.
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* 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.
*
******************************************************************************/
/***************************************************************************//**
* @file CTS_HAL.c
*
* @brief
*
* @par Project:
* MSP430 Capacitive Touch Library
*
* @par Developed using:
* IAR Version : 5.10.6 [Kickstart] (5.10.6.30180)
* CCS Version : 4.2.1.00004, w/support for GCC extensions (--gcc)
*
*
* @version 1.0.0 Initial Release
*
* @par Supported Hardware Configurations:
* - 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()
******************************************************************************/
/***************************************************************************//**
* @addtogroup CTS_HAL
* @{
******************************************************************************/
#include "CTS_HAL.h"
#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)
* \n
* \n +-<-Px.y (reference)
* \n |
* \n R
* \n |
* \n +---+-->COMPA+
* \n | |
* \n R R
* \n | |
* \n GND |
* \n |
* \n +-->TACLK
* \n |
* \n element-+-R--+-<-CAOUT
* \n |
* \n +------->COMPA-
* \n
* \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
__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)
* \n
* \n +-<-Px.y (reference)
* \n |
* \n R
* \n |
* \n +---+-->COMPA+
* \n | |
* \n R R
* \n | |
* \n GND |
* \n |
* \n +-->TACLK
* \n |
* \n element-+-R--+-<-CAOUT
* \n |
* \n +------->COMPA-
* \n
* \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
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)
* \n
* \n +-<-Px.y (reference)
* \n |
* \n R
* \n |
* \n +---+-->COMPA+
* \n | |
* \n R R
* \n | |
* \n GND |
* \n |
* \n |
* \n element-+-R--+-<-CAOUT
* \n |
* \n +------->COMPA-
* \n
* \n The SW loop counts to 'n' accumulationCycles, representing the
* \n measurement window. The number of timer counts within TA0R register
* \n 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+
*
* 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)
* \n
* \n +-<-Px.y (reference)
* \n |
* \n R
* \n |
* \n +---+-->COMPA+
* \n | |
* \n R R
* \n | |
* \n GND |
* \n |
* \n +-->TA1CLK
* \n |
* \n element-+-R--+-<-CAOUT
* \n |
* \n +------->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
__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)
* \n
* \n +-<-Px.y (reference)
* \n |
* \n R
* \n |
* \n +---+-->COMPA+
* \n | |
* \n R R
* \n | |
* \n GND |
* \n |
* \n +-->TA1CLK
* \n |
* \n element-+-R--+-<-CAOUT
* \n |
* \n +------->COMPA-
* \n
* \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; // TACLK
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
/***************************************************************************//**
* @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)
* \n
* \n +-<-Px.y (reference)
* \n |
* \n R
* \n |
* \n Element---+-->Pa.b
* \n
* \n Charge and Discharge Cycle
* \n +
* \n + +
* \n + +
* \n + +
* \n + +
* \n Start Timer After n cycles Stop Timer
* \n 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
******************************************************************************/
#ifdef RC_PAIR_TA0
void TI_CTS_RC_PAIR_TA0_HAL(const struct Sensor *group, unsigned int *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
/***************************************************************************//**
* @brief fRO method capactiance measurement using the PinOsc and TimerA0
*
* \n Charge and Discharge Cycle
* \n +
* \n + +
* \n + +
* \n + +
* \n + +
* \n 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
******************************************************************************/
#ifdef fRO_PINOSC_TA0_SW
void TI_CTS_fRO_PINOSC_TA0_SW_HAL(const struct Sensor *group, unsigned int *counts)
{
uint8_t i;
uint16_t j;
//** Context Save
// TIMERA0: TA0CTL
// Ports: PxSEL, PxSEL2
uint16_t contextSaveTA0CTL;
uint8_t contextSaveSel,contextSaveSel2;
contextSaveTA0CTL = TA0CTL;
// 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 , up mode
// 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;
}
#endif
#ifdef RO_PINOSC_TA0_WDTp
/***************************************************************************//**
* @brief RO method capactiance measurement using PinOsc IO, TimerA0, and WDT+
*
* 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, unsigned int *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; // TACLK, 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);
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
*
* 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, unsigned int *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
}
TA0CTL &= ~MC_2;
counts[i] = TA0CCR0; // Save result
// 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)
*
* \n element---R----<-CBOUT/TA0CLK
*
* \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, unsigned int *counts)
{
unsigned char 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 + CBF; // Turn on comparator with 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
__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
*
* Schematic Description of CompB forming relaxation oscillator and
* coupling (connection) between the relaxation oscillator and TimerA1.
* <- Output
* -> Input
* R Resistor (typically 100Kohms)
*
* element---R----<-CBOUT/TA1CLK
*
* 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, unsigned int *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 + CBF; // Turn on comparator with 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->sourceScale;
TA1CTL |= TACLR; // Clear Timer_A TAR
__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
*
* Schematic Description of CompB forming relaxation oscillator and
* coupling (connection) between the relaxation oscillator and TimerA0.
* <- Output
* -> Input
* R Resistor (typically 100Kohms)
*
* element---R----<-CBOUT
*
* 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, unsigned int *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 + CBF; // Turn on comparator with 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
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
*
* Schematic Description of CompB forming relaxation oscillator and
* coupling (connection) between the relaxation oscillator and TimerA1.
* <- Output
* -> Input
* R Resistor (typically 100Kohms)
*
* element---R----<-CBOUT
*
* 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, unsigned int *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 + CBF; // Turn on comparator with 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; // TACLK
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 WDT_GATE
// Watchdog Timer interrupt service routine
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
}
#endif
/***************************************************************************//**
* @}
******************************************************************************/