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.

3142 lines
117 KiB

5 years ago
  1. /* --COPYRIGHT--,BSD
  2. * Copyright (c) 2013, Texas Instruments Incorporated
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. *
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * * Neither the name of Texas Instruments Incorporated nor the names of
  17. * its contributors may be used to endorse or promote products derived
  18. * from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  22. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  24. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  26. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  27. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  28. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  29. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  30. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. * --/COPYRIGHT--*/
  32. /*!
  33. * @file CTS_HAL.c
  34. *
  35. * @brief This file contains the source for the different implementations.
  36. *
  37. * @par Project:
  38. * MSP430 Capacitive Touch Library
  39. *
  40. * @par Developed using:
  41. * CCS Version : 5.4.0.00048, w/support for GCC extensions (--gcc)
  42. * \n IAR Version : 5.51.6 [Kickstart]
  43. *
  44. * @author C. Sterzik
  45. * @author T. Hwang
  46. *
  47. * @version 1.2 Added HALs for new devices.
  48. *
  49. * @par Supported Hardware Implementations:
  50. * - TI_CTS_RO_COMPAp_TA0_WDTp_HAL()
  51. * - TI_CTS_fRO_COMPAp_TA0_SW_HAL()
  52. * - TI_CTS_fRO_COMPAp_SW_TA0_HAL()
  53. * - TI_CTS_RO_COMPAp_TA1_WDTp_HAL()
  54. * - TI_CTS_fRO_COMPAp_TA1_SW_HAL()
  55. * - TI_CTS_RC_PAIR_TA0_HAL()
  56. * - TI_CTS_RO_PINOSC_TA0_WDTp_HAL()
  57. * - TI_CTS_RO_PINOSC_TA0_HAL()
  58. * - TI_CTS_fRO_PINOSC_TA0_SW_HAL()
  59. * - TI_CTS_RO_COMPB_TA0_WDTA_HAL()
  60. * - TI_CTS_RO_COMPB_TA1_WDTA_HAL()
  61. * - TI_CTS_fRO_COMPB_TA0_SW_HAL()
  62. * - TI_CTS_fRO_COMPB_TA1_SW_HAL()
  63. * - Added in version 1.1
  64. * - TI_CTS_fRO_PINOSC_TA0_TA1_HAL()
  65. * - TI_CTS_RO_PINOSC_TA0_TA1_HAL()
  66. * - TI_CTS_RO_CSIO_TA2_WDTA_HAL()
  67. * - TI_CTS_RO_CSIO_TA2_TA3_HAL()
  68. * - TI_CTS_fRO_CSIO_TA2_TA3_HAL()
  69. * - TI_CTS_RO_COMPB_TB0_WDTA_HAL()
  70. * - TI_CTS_RO_COMPB_TA1_TA0_HAL()
  71. * - TI_CTS_fRO_COMPB_TA1_TA0_HAL()
  72. * - Added in version 1.2
  73. * - TI_CTS_RO_PINOSC_TA1_WDTp_HAL()
  74. * - TI_CTS_RO_PINOSC_TA1_TB0_HAL()
  75. * - TI_CTS_fRO_PINOSC_TA1_TA0_HAL()
  76. * - TI_CTS_fRO_PINOSC_TA1_TB0_HAL()
  77. *
  78. */
  79. /*!
  80. * @defgroup CTS_HAL Capacitive Touch Implementations
  81. * @{
  82. */
  83. #include "CTS_HAL.h"
  84. #ifdef RO_COMPB_TB0_WDTA
  85. /*!
  86. * ======== TI_CTS_RO_COMPB_TB0_WDTA_HAL ========
  87. * @brief RO method capactiance measurement using CompB, TimerB0, and WDTA
  88. *
  89. * \n Schematic Description of CompB forming relaxation oscillator and
  90. * coupling (connection) between the relaxation oscillator and TimerA0.
  91. * \n <- Output
  92. * \n -> Input
  93. * \n R Resistor (typically 100Kohms)
  94. *
  95. * \n element---R----<-CBOUT/TB0CLK
  96. *
  97. * \n The WDTA interval represents the measurement window. The number of
  98. * counts within the TB0R that have accumulated during the measurement
  99. * window represents the capacitance of the element.
  100. *
  101. * @param group pointer to the sensor to be measured
  102. * @param counts pointer to where the measurements are to be written
  103. * @return none
  104. */
  105. void TI_CTS_RO_COMPB_TB0_WDTA_HAL(const struct Sensor *group,uint16_t *counts)
  106. {
  107. uint8_t i;
  108. /*
  109. * Allocate Context Save Variables
  110. * Status Register: GIE bit only
  111. * SFR: SFRIE1
  112. * WDTA: WDTCTL
  113. * TIMERB0: TB0CTL, TB0CCTL0, TB0CCR0
  114. * COMPB: CBCTL0,CBCTL1,CBCTL2, CBCTL3
  115. */
  116. uint8_t contextSaveSR;
  117. uint16_t contextSaveSFRIE1;
  118. uint16_t contextSaveWDTCTL;
  119. uint16_t contextSaveTB0CTL,contextSaveTB0CCTL0,contextSaveTB0CCR0;
  120. uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
  121. uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
  122. uint8_t contextSaveCboutDir,contextSaveCboutSel;
  123. /* Perform context save of registers used. */
  124. contextSaveSR = __get_SR_register();
  125. contextSaveSFRIE1 = SFRIE1;
  126. contextSaveWDTCTL = WDTCTL;
  127. contextSaveWDTCTL &= 0x00FF;
  128. contextSaveWDTCTL |= WDTPW;
  129. contextSaveTB0CTL = TB0CTL;
  130. contextSaveTB0CCTL0 = TB0CCTL0;
  131. contextSaveTB0CCR0 = TB0CCR0;
  132. contextSaveCBCTL0 = CBCTL0;
  133. contextSaveCBCTL1 = CBCTL1;
  134. contextSaveCBCTL2 = CBCTL2;
  135. contextSaveCBCTL3 = CBCTL3;
  136. /* TAx naming convention is left to preserve compatibility. */
  137. contextSaveCboutDir = *(group->cboutTAxDirRegister);
  138. contextSaveCboutSel = *(group->cboutTAxSelRegister);
  139. /*
  140. * Connect CBOUT with TB0. This also enables the feedback path for the
  141. * Relaxation oscillator.
  142. */
  143. *(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
  144. *(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
  145. /*
  146. * The COMPB reference is set to Vcc and the reference resistor taps are
  147. * Vcc*(0x18+1)/32 for CBOUT = 1 and Vcc*((0x04+1)/32 for CBOUT = 0.
  148. * If Vcc is 3.0V, then the Vih is 2.34V and the Vil is 0.47V. In the
  149. * event that CBOUT is connected to DVIO which is not equal to Vcc, then
  150. * these voltage levels need to be adjusted.
  151. */
  152. CBCTL2 = CBRS_1 + CBREF14 + CBREF13 + CBREF02;
  153. CBCTL3 |= (group->cbpdBits); // set CPD bits to disable digital IO
  154. /*
  155. * TimerB0 is the measurement timer and counts the number of relaxation
  156. * oscillation cycles of the element which is connected to TBCLK.
  157. * TimerB0 is in continuous mode. TB0CCR0 is configured as a capture
  158. * register and will be triggered as a SW capture event.
  159. */
  160. TB0CTL = TBSSEL_0+MC_2;
  161. TB0CCTL0 = CM_3+CCIS_2+CAP;
  162. /*
  163. * The WDTA is the gate (measurement interval) timer. The number of
  164. * oscillations counted, by TimerB0, within the gate interval represents
  165. * the measured capacitance.
  166. */
  167. SFRIE1 |= WDTIE; // Enable WDTA interrupt
  168. CBCTL1 = CBON; // Turn on COMPB w/out filter
  169. for (i = 0; i<(group->numElements); i++)
  170. {
  171. /* Turn on specific comparator input. */
  172. CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
  173. TB0CTL |= TBCLR; // Clear TimerB0, measurement timer
  174. TB0CTL &= ~TBIFG; // Clear overflow flag
  175. /*
  176. * The measGateSource represents the gate source for the WDTA, which
  177. * can be sourced from ACLK, SMCLK, VLOCLK or X_CLK. The
  178. * accumulationCycles represents the watchdog timer interval select.
  179. */
  180. WDTCTL = WDTPW+WDTTMSEL+WDTCNTCL+ group->measGateSource
  181. + group->accumulationCycles;
  182. /*
  183. * The interrupt handler is defined in WDT_VECTOR, which simply clears
  184. * the low power mode bits in the Status Register before returning
  185. * from the ISR.
  186. */
  187. if(group->measGateSource == GATE_WDT_ACLK)
  188. {
  189. __bis_SR_register(LPM3_bits+GIE); //Enable the GIE and wait for ISR
  190. }
  191. else
  192. {
  193. __bis_SR_register(LPM0_bits+GIE);
  194. }
  195. TB0CCTL0 ^= CCIS0; // Create SW capture of TB0R into TB0CCR0.
  196. WDTCTL = WDTPW + WDTHOLD; // Halt watchdog timer
  197. if(TB0CTL & TBIFG)
  198. {
  199. /*
  200. * If a rollover in the timer has occurred then set counts to
  201. * 0. This will prevent erroneous data from entering the baseline
  202. * tracking algorithm.
  203. */
  204. counts[i] = 0;
  205. }
  206. else
  207. {
  208. counts[i] = TB0CCR0; // Save result
  209. }
  210. } // End For Loop
  211. /* Context restore GIE within Status Register and registers used. */
  212. if(!(contextSaveSR & GIE))
  213. {
  214. __bic_SR_register(GIE);
  215. }
  216. SFRIE1 = contextSaveSFRIE1;
  217. WDTCTL = contextSaveWDTCTL;
  218. TB0CTL = contextSaveTB0CTL;
  219. TB0CCTL0 = contextSaveTB0CCTL0;
  220. TB0CCR0 = contextSaveTB0CCR0;
  221. CBCTL0 = contextSaveCBCTL0;
  222. CBCTL1 = contextSaveCBCTL1;
  223. CBCTL2 = contextSaveCBCTL2;
  224. CBCTL3 = contextSaveCBCTL3;
  225. *(group->cboutTAxDirRegister) = contextSaveCboutDir;
  226. *(group->cboutTAxSelRegister) = contextSaveCboutSel;
  227. }
  228. #endif
  229. #ifdef fRO_CSIO_TA2_TA3
  230. /*!
  231. * ======== TI_CTS_RO_CSIO_TA2_TA3_HAL ========
  232. * @brief fRO using Capacitive Touch IO, TimerA2, and TimerA3
  233. *
  234. * \n Schematic Description:
  235. *
  236. * \n element-----+->Px.y
  237. *
  238. * \n The TimerA2 interval represents the measurement window. The number
  239. * of counts within the TA3R that have accumulated during the
  240. * measurement window represents the capacitance of the element.
  241. *
  242. * @param group pointer to the sensor to be measured
  243. * @param counts pointer to where the measurements are to be written
  244. * @return none
  245. */
  246. void TI_CTS_fRO_CSIO_TA2_TA3_HAL(const struct Sensor *group,uint16_t *counts)
  247. {
  248. uint8_t i;
  249. /*
  250. * Allocate Context Save Variables
  251. * Status Register: GIE bit only
  252. * SFR: SFRIE1
  253. * TIMERA2: TA2CTL, TA2CCTL0, TA2CCR0
  254. * TIMERA3: TA3CTL, TA3CCTL0, TA3CCR0
  255. * CSIO: CSIOxCTL
  256. */
  257. uint8_t contextSaveSR;
  258. uint16_t contextSaveTA2CTL,contextSaveTA2CCTL0,contextSaveTA2CCR0;
  259. uint16_t contextSaveTA3CTL,contextSaveTA3CCTL0,contextSaveTA3CCR0;
  260. uint8_t contextSaveCtl;
  261. /* Perform context save of registers used. */
  262. contextSaveSR = __get_SR_register();
  263. contextSaveTA2CTL = TA2CTL;
  264. contextSaveTA2CCTL0 = TA2CCTL0;
  265. contextSaveTA2CCR0 = TA2CCR0;
  266. contextSaveTA3CTL = TA3CTL;
  267. contextSaveTA3CCTL0 = TA3CCTL0;
  268. contextSaveTA3CCR0 = TA3CCR0;
  269. contextSaveCtl = *(group->inputCapsioctlRegister);
  270. /*
  271. * TimerA3 is the measurement timer and counts the number of clock cycles
  272. * of the source which is connected to measGateSource, typically SMCLK.
  273. * TimerA3 is in continuous mode. TA3CCR0 is configured as a capture
  274. * register and will be triggered as a SW capture event.
  275. */
  276. TA3CTL = group->measGateSource + MC_2;
  277. TA3CCTL0 = CM_3+CCIS_2+CAP;
  278. /*
  279. * TimerA2 is the gate (measurement interval) timer. The number of
  280. * oscillations counted, by TimerA3, within the gate interval represents
  281. * the measured capacitance. The input is TA2CLK.
  282. */
  283. TA2CCR0 = (group->accumulationCycles);
  284. TA2CTL = TASSEL_3+group->sourceScale;
  285. TA2CCTL0 = CCIE;
  286. for (i = 0; i<(group->numElements); i++)
  287. {
  288. /* Enable Capacitive Touch IO oscillation */
  289. *(group->inputCapsioctlRegister)
  290. = ((group->arrayPtr[i])->inputBits)+CAPSIOEN;
  291. TA3CTL |= TACLR; // Clear TimerA3, measurement timer
  292. TA3CTL &= ~TAIFG; // Clear overflow flag
  293. TA2CTL |= (TACLR + MC_1); // Clear and start TimerA3
  294. /*
  295. * The measGateSource represents the measurement source for timer
  296. * TIMERA3, which can be sourced from TACLK, ACLK, SMCLK, or INCLK.
  297. * The interrupt handler is defined in TIMER2_A0_VECTOR, which simply
  298. * clears the low power mode bits in the Status Register before
  299. * returning from the ISR.
  300. */
  301. if(group->measGateSource == TIMER_ACLK)
  302. {
  303. __bis_SR_register(LPM3_bits+GIE); // Enable GIE and wait for ISR
  304. }
  305. else
  306. {
  307. __bis_SR_register(LPM0_bits+GIE);
  308. }
  309. TA3CCTL0 ^= CCIS0; // Create SW capture of TA3R into TA3CCR0
  310. TA2CTL &= ~MC_1; // Halt Timer
  311. if(TA3CTL & TAIFG)
  312. {
  313. /*
  314. * If a rollover in the timer has occurred then set counts to
  315. * 0. This will prevent erroneous data from entering the baseline
  316. * tracking algorithm.
  317. */
  318. counts[i] = 0;
  319. }
  320. else
  321. {
  322. counts[i] = TA3CCR0; // Save result
  323. }
  324. } // End For Loop
  325. /* Context restore GIE within Status Register and registers used. */
  326. *(group->inputCapsioctlRegister) = contextSaveCtl;
  327. if(!(contextSaveSR & GIE))
  328. {
  329. __bic_SR_register(GIE);
  330. }
  331. TA2CTL = contextSaveTA2CTL;
  332. TA2CCTL0 = contextSaveTA2CCTL0;
  333. TA2CCR0 = contextSaveTA2CCR0;
  334. TA3CTL = contextSaveTA3CTL;
  335. TA3CCTL0 = contextSaveTA3CCTL0;
  336. TA3CCR0 = contextSaveTA3CCR0;
  337. }
  338. #endif
  339. #ifdef RO_CSIO_TA2_TA3
  340. /*!
  341. * ======== TI_CTS_RO_CSIO_TA2_TA3_HAL ========
  342. * @brief RO method using Capacitive Touch IO, TimerA2, and TimerA3
  343. *
  344. * \n Schematic Description:
  345. * \n element-----+->Px.y
  346. *
  347. * \n The TimerA3 interval represents the measurement window. The number
  348. * of counts within the TA2R that have accumulated during the
  349. * measurement window represents the capacitance of the element.
  350. *
  351. * @param group pointer to the sensor to be measured
  352. * @param counts pointer to where the measurements are to be written
  353. * @return none
  354. */
  355. void TI_CTS_RO_CSIO_TA2_TA3_HAL(const struct Sensor *group,uint16_t *counts)
  356. {
  357. uint8_t i;
  358. /*
  359. * Allocate Context Save Variables
  360. * Status Register: GIE bit only
  361. * SFR: SFRIE1
  362. * TIMERA2: TA2CTL, TA2CCTL0, TA2CCR0
  363. * TIMERA3: TA3CTL, TA3CCTL0, TA3CCR0
  364. * CSIO: CSIOxCTL
  365. */
  366. uint8_t contextSaveSR;
  367. uint16_t contextSaveTA2CTL,contextSaveTA2CCTL0,contextSaveTA2CCR0;
  368. uint16_t contextSaveTA3CTL,contextSaveTA3CCTL0,contextSaveTA3CCR0;
  369. uint8_t contextSaveCtl;
  370. /* Perform context save of registers used. */
  371. contextSaveSR = __get_SR_register();
  372. contextSaveTA2CTL = TA2CTL;
  373. contextSaveTA2CCTL0 = TA2CCTL0;
  374. contextSaveTA2CCR0 = TA2CCR0;
  375. contextSaveTA3CTL = TA3CTL;
  376. contextSaveTA3CCTL0 = TA3CCTL0;
  377. contextSaveTA3CCR0 = TA3CCR0;
  378. contextSaveCtl = *(group->inputCapsioctlRegister);
  379. /*
  380. * TimerA2 is the measurement timer and counts the number of relaxation
  381. * oscillation cycles of the element which is connected to TA2CLK.
  382. * TimerA2 is in continuous mode. TA2CCR0 is configured as a capture
  383. * register and will be triggered as a SW capture event.
  384. */
  385. TA2CTL = TASSEL_3+MC_2;
  386. TA2CCTL0 = CM_3+CCIS_2+CAP;
  387. /*
  388. * TimerA3 is the gate (measurement interval) timer. The number of
  389. * oscillations counted, by TimerA2, within the gate interval represents
  390. * the measured capacitance.
  391. */
  392. TA3CCR0 = (group->accumulationCycles);
  393. TA3CTL = group->measGateSource + group->sourceScale;
  394. TA3CCTL0 = CCIE;
  395. for (i = 0; i<(group->numElements); i++)
  396. {
  397. /* Enable Capacitive Touch IO oscillation */
  398. *(group->inputCapsioctlRegister)
  399. = ((group->arrayPtr[i])->inputBits)+CAPSIOEN;
  400. TA2CTL |= TACLR; // Clear TimerA2, measurement timer
  401. TA2CTL &= ~TAIFG; // Clear overflow flag
  402. TA3CTL |= (TACLR + MC_1); // Clear and start TimerA3
  403. /*
  404. * The measGateSource represents the gate source for timer TIMERA3,
  405. * which can be sourced from TACLK, ACLK, SMCLK, or INCLK. The
  406. * interrupt handler is defined in TIMER3_A0_VECTOR, which simply
  407. * clears the low power mode bits in the Status Register before
  408. * returning from the ISR.
  409. */
  410. if(group->measGateSource == TIMER_ACLK)
  411. {
  412. __bis_SR_register(LPM3_bits+GIE); // Enable GIE and wait for ISR
  413. }
  414. else
  415. {
  416. __bis_SR_register(LPM0_bits+GIE);
  417. }
  418. TA2CCTL0 ^= CCIS0; // Create SW capture of TA2R into TA2CCR0
  419. TA3CTL &= ~MC_1; // Halt Timer
  420. if(TA2CTL & TAIFG)
  421. {
  422. /*
  423. * If a rollover in the timer has occurred then set counts to
  424. * 0. This will prevent erroneous data from entering the baseline
  425. * tracking algorithm.
  426. */
  427. counts[i] = 0;
  428. }
  429. else
  430. {
  431. counts[i] = TA2CCR0; // Save result
  432. }
  433. } // End For Loop
  434. /* Context restore GIE within Status Register and registers used. */
  435. *(group->inputCapsioctlRegister) = contextSaveCtl;
  436. if(!(contextSaveSR & GIE))
  437. {
  438. __bic_SR_register(GIE);
  439. }
  440. TA2CTL = contextSaveTA2CTL;
  441. TA2CCTL0 = contextSaveTA2CCTL0;
  442. TA2CCR0 = contextSaveTA2CCR0;
  443. TA3CTL = contextSaveTA3CTL;
  444. TA3CCTL0 = contextSaveTA3CCTL0;
  445. TA3CCR0 = contextSaveTA3CCR0;
  446. }
  447. #endif
  448. #ifdef RO_CSIO_TA2_WDTA
  449. /*!
  450. * ======== TI_CTS_RO_CSIO_TA2_WDTA_HAL ========
  451. * @brief RO method measurement using Capacitive Touch IO, TimerA2, and WDTA
  452. *
  453. * \n Schematic Description:
  454. *
  455. * \n element-----+->Px.y
  456. *
  457. * \n The WDTA interval represents the measurement window. The number of
  458. * counts within the TA2R that have accumulated during the measurement
  459. * window represents the capacitance of the element.
  460. *
  461. * @param group pointer to the sensor to be measured
  462. * @param counts pointer to where the measurements are to be written
  463. * @return none
  464. */
  465. void TI_CTS_RO_CSIO_TA2_WDTA_HAL(const struct Sensor *group,uint16_t *counts)
  466. {
  467. uint8_t i;
  468. /*
  469. * Allocate Context Save Variables
  470. * Status Register: GIE bit only
  471. * SFR: SFRIE1
  472. * WDT: WDTCTL
  473. * TIMERA2: TA2CTL, TA2CCTL0, TA2CCR0
  474. * CSIO: CSIOxCTL
  475. */
  476. uint8_t contextSaveSR;
  477. uint8_t contextSaveSFRIE1;
  478. uint16_t contextSaveWDTCTL;
  479. uint16_t contextSaveTA2CTL,contextSaveTA2CCTL0,contextSaveTA2CCR0;
  480. uint8_t contextSaveCtl;
  481. /* Perform context save of registers used. */
  482. contextSaveSR = __get_SR_register();
  483. contextSaveSFRIE1 = SFRIE1;
  484. contextSaveWDTCTL = WDTCTL;
  485. contextSaveWDTCTL &= 0x00FF;
  486. contextSaveWDTCTL |= WDTPW;
  487. contextSaveTA2CTL = TA2CTL;
  488. contextSaveTA2CCTL0 = TA2CCTL0;
  489. contextSaveTA2CCR0 = TA2CCR0;
  490. contextSaveCtl = *(group->inputCapsioctlRegister);
  491. /*
  492. * TimerA2 is the measurement timer and counts the number of relaxation
  493. * oscillation cycles of the element which is connected to TA2CLK.
  494. * TimerA2 is in continuous mode. TA2CCR0 is configured as a capture
  495. * register and will be triggered as a SW capture event.
  496. */
  497. TA2CTL = TASSEL_3+MC_2;
  498. TA2CCTL0 = CM_3+CCIS_2+CAP;
  499. /*
  500. * The WDTA is the gate (measurement interval) timer. The number of
  501. * oscillations counted, by TimerA2, within the gate interval represents
  502. * the measured capacitance.
  503. */
  504. SFRIE1 |= WDTIE; // Enable WDTA interrupt
  505. for (i = 0; i<(group->numElements); i++)
  506. {
  507. /* Enable Capacitive Touch IO oscillation */
  508. *(group->inputCapsioctlRegister)
  509. = ((group->arrayPtr[i])->inputBits)+CAPSIOEN;
  510. TA2CTL |= TACLR; // Clear Timer_A2 measurement timer
  511. TA2CTL &= ~TAIFG; // Clear the overflow flag
  512. /*
  513. * The measGateSource represents the gate source for the WDTA, which
  514. * can be sourced from ACLK, SMCLK, VLOCLK or X_CLK. The
  515. * accumulationCycles represents the watchdog timer interval select.
  516. */
  517. WDTCTL = WDTPW+WDTTMSEL+WDTCNTCL+ group->measGateSource
  518. + group->accumulationCycles;
  519. /*
  520. * The interrupt handler is defined in WDT_VECTOR, which simply clears
  521. * the low power mode bits in the Status Register before returning
  522. * from the ISR.
  523. */
  524. if(group->measGateSource == GATE_WDT_ACLK)
  525. {
  526. __bis_SR_register(LPM3_bits+GIE); //Enable the GIE and wait for ISR
  527. }
  528. else
  529. {
  530. __bis_SR_register(LPM0_bits+GIE);
  531. }
  532. TA2CCTL0 ^= CCIS0; // Create SW capture of TA2R into TA2CCR0
  533. WDTCTL = WDTPW + WDTHOLD; // Halt watchdog timer
  534. if(TA2CTL & TAIFG)
  535. {
  536. /*
  537. * If a rollover in the timer has occurred then set counts to
  538. * 0. This will prevent erroneous data from entering the baseline
  539. * tracking algorithm.
  540. */
  541. counts[i] = 0;
  542. }
  543. else
  544. {
  545. counts[i] = TA2CCR0; // Save result
  546. }
  547. } // End For Loop
  548. /* Context restore GIE within Status Register and registers used. */
  549. *(group->inputCapsioctlRegister) = contextSaveCtl;
  550. if(!(contextSaveSR & GIE))
  551. {
  552. __bic_SR_register(GIE);
  553. }
  554. SFRIE1 = contextSaveSFRIE1;
  555. WDTCTL = contextSaveWDTCTL;
  556. TA2CTL = contextSaveTA2CTL;
  557. TA2CCTL0 = contextSaveTA2CCTL0;
  558. TA2CCR0 = contextSaveTA2CCR0;
  559. }
  560. #endif
  561. #ifdef fRO_PINOSC_TA0_TA1
  562. /*!
  563. * @brief fRO method capacitance measurement using PinOsc IO, TimerA0, and
  564. * TimerA1
  565. *
  566. * \n Schematic Description:
  567. *
  568. * \n element-----+->Px.y
  569. *
  570. * \n The TimerA0 interval represents the measurement window. The number
  571. * of counts within the TA1R that have accumulated during the
  572. * measurement window represents the capacitance of the element.
  573. *
  574. * @param group Pointer to the structure describing the Sensor to be measured
  575. * @param counts Pointer to where the measurements are to be written
  576. * @return none
  577. */
  578. void TI_CTS_fRO_PINOSC_TA0_TA1_HAL(const struct Sensor *group,uint16_t *counts)
  579. {
  580. uint8_t i;
  581. /*
  582. * Context Save
  583. * Status Register: GIE
  584. * TIMERA0: TA0CTL, TA0CCTL0, TA0CCR0
  585. * TIMERA1: TA1CTL, TA1CCTL0, TA1CCR1
  586. * Ports: PxSEL, PxSEL2
  587. */
  588. uint8_t contextSaveSR;
  589. uint16_t contextSaveTA0CTL,contextSaveTA0CCTL0,contextSaveTA0CCR0;
  590. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
  591. uint8_t contextSaveSel,contextSaveSel2;
  592. contextSaveSR = __get_SR_register();
  593. contextSaveTA0CTL = TA0CTL;
  594. contextSaveTA0CCTL0 = TA0CCTL0;
  595. contextSaveTA0CCR0 = TA0CCR0;
  596. contextSaveTA1CTL = TA1CTL;
  597. contextSaveTA1CCTL0 = TA1CCTL0;
  598. contextSaveTA1CCR0 = TA1CCR0;
  599. //** Setup Measurement timer***************************************************
  600. // Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
  601. // capacitive touch layer.
  602. // Configure Measurement interval with TimerA0
  603. TA0CCR0 = (group->accumulationCycles);
  604. /*
  605. * INCLK, IDx settings from sourceScale definition
  606. */
  607. TA0CTL = TASSEL_3 + group->sourceScale;
  608. TA0CCTL0 = CCIE;
  609. // Configure and start measurment timerA1
  610. TA1CTL = group->measGateSource + MC_2 + TACLR; // cont
  611. TA1CCTL0 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  612. for (i = 0; i<(group->numElements); i++)
  613. {
  614. // Context Save
  615. contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
  616. contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
  617. // Configure Ports for relaxation oscillator
  618. *((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
  619. *((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
  620. TA1CTL |= TACLR;
  621. TA1CTL &= ~TAIFG;
  622. TA0CTL |= (TACLR + MC_1); // Clear Timer, Up mode
  623. /*
  624. * In this configuration measGateSource represents the measurement
  625. * source for timer TIMERA1, which can be sourced from TACLK, ACLK,
  626. * SMCLK, or INCLK.
  627. */
  628. if(group->measGateSource == TIMER_ACLK)
  629. {
  630. __bis_SR_register(LPM3_bits+GIE);
  631. }
  632. else
  633. {
  634. __bis_SR_register(LPM0_bits+GIE);
  635. }
  636. TA1CCTL0 ^= CCIS0; // Create SW capture of CCR1
  637. TA0CTL &= ~MC_1; // Halt Timer
  638. if(TA1CTL & TAIFG)
  639. {
  640. /*
  641. * If a rollover in the timer has occurred then set counts to
  642. * 0. This will prevent erroneous data from entering the baseline
  643. * tracking algorithm.
  644. */
  645. counts[i] = 0;
  646. }
  647. else
  648. {
  649. counts[i] = TA1CCR0; // Save result
  650. }
  651. // Context Restore
  652. *((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
  653. *((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
  654. } // End for loop
  655. // Context Restore
  656. if(!(contextSaveSR & GIE))
  657. {
  658. __bic_SR_register(GIE);
  659. }
  660. TA0CTL = contextSaveTA0CTL;
  661. TA0CCTL0 = contextSaveTA0CCTL0;
  662. TA0CCR0 = contextSaveTA0CCR0;
  663. TA1CTL = contextSaveTA1CTL;
  664. TA1CCTL0 = contextSaveTA1CCTL0;
  665. TA1CCR0 = contextSaveTA1CCR0;
  666. }
  667. #endif
  668. #ifdef RO_PINOSC_TA0_TA1
  669. /*!
  670. * ======== TI_CTS_RO_PINOSC_TA0_TA1_HAL ========
  671. * @brief RO method capacitance measurement using PinOsc IO, TimerA0, and
  672. * TimerA1
  673. *
  674. * \n Schematic Description:
  675. *
  676. * \n element-----+->Px.y
  677. *
  678. * \n The TimerA1 interval represents the gate (measurement) time. The
  679. * number of oscillations that have accumulated in TA0R during the
  680. * measurement time represents the capacitance of the element.
  681. *
  682. * @param group pointer to the sensor to be measured
  683. * @param counts pointer to where the measurements are to be written
  684. * @return none
  685. */
  686. void TI_CTS_RO_PINOSC_TA0_TA1_HAL(const struct Sensor *group,uint16_t *counts)
  687. {
  688. uint8_t i;
  689. /*!
  690. * Allocate Context Save Variables
  691. * Status Register: GIE bit only
  692. * TIMERA0: TA0CTL, TA0CCTL0, TA0CCR0
  693. * TIMERA1: TA1CTL, TA1CCTL0, TA1CCR0
  694. * Ports: PxSEL, PxSEL2
  695. */
  696. uint8_t contextSaveSR;
  697. uint16_t contextSaveTA0CTL,contextSaveTA0CCTL0,contextSaveTA0CCR0;
  698. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
  699. uint8_t contextSaveSel,contextSaveSel2;
  700. /*
  701. * Perform context save of registers used except port registers which are
  702. * saved and restored within the for loop as each element within the
  703. * sensor is measured.
  704. */
  705. contextSaveSR = __get_SR_register();
  706. contextSaveTA0CTL = TA0CTL;
  707. contextSaveTA0CCTL0 = TA0CCTL0;
  708. contextSaveTA0CCR0 = TA0CCR0;
  709. contextSaveTA1CTL = TA1CTL;
  710. contextSaveTA1CCTL0 = TA1CCTL0;
  711. contextSaveTA1CCR0 = TA1CCR0;
  712. /*
  713. * TimerA0 is the measurement timer and counts the number of relaxation
  714. * oscillation cycles of the electrode which is routed to INCLK. TA0 is
  715. * in continuous mode and sourced from INCLK.
  716. */
  717. TA0CTL = TASSEL_3+MC_2;
  718. TA0CCTL0 = CM_3+CCIS_2+CAP; // Setup for SW capture
  719. /*
  720. * TimerA1 is the gate (measurement interval) timer. The number of
  721. * oscillations counted within the gate interval represents the measured
  722. * capacitance.
  723. */
  724. TA1CCR0 = (group->accumulationCycles);
  725. // Establish source and scale of timerA1, but halt the timer.
  726. TA1CTL = group->measGateSource + group->sourceScale;
  727. TA1CCTL0 = CCIE; // Enable Interrupt when timer counts to TA1CCR0.
  728. for (i = 0; i<(group->numElements); i++)
  729. {
  730. // Context Save Port Registers
  731. contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
  732. contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
  733. // Configure Ports for relaxation oscillator
  734. *((group->arrayPtr[i])->inputPxselRegister)
  735. &= ~((group->arrayPtr[i])->inputBits);
  736. *((group->arrayPtr[i])->inputPxsel2Register)
  737. |= ((group->arrayPtr[i])->inputBits);
  738. TA0CTL |= TACLR;
  739. TA0CTL &= ~TAIFG;
  740. TA1CTL |= (TACLR + MC_1);
  741. /*!
  742. * The measGateSource represents the gate source for timer TIMERA1,
  743. * which can be sourced from TACLK, ACLK, SMCLK, or INCLK. The
  744. * interrupt handler is defined in TIMER1_A0_VECTOR, which simply
  745. * clears the low power mode bits in the Status Register before
  746. * returning from the ISR.
  747. */
  748. if(group->measGateSource == TIMER_ACLK)
  749. {
  750. __bis_SR_register(LPM3_bits+GIE); // Enable GIE and wait for ISR
  751. }
  752. else
  753. {
  754. __bis_SR_register(LPM0_bits+GIE); // Enable GIE and wait for ISR
  755. }
  756. TA0CCTL0 ^= CCIS0; // Create SW capture of TA0CCR into TA0CCR0.
  757. TA1CTL &= ~MC_1; // Halt Timer
  758. if(TA0CTL & TAIFG)
  759. {
  760. /*
  761. * If a rollover in the timer has occurred then set counts to
  762. * 0. This will prevent erroneous data from entering the baseline
  763. * tracking algorithm.
  764. */
  765. counts[i] = 0;
  766. }
  767. else
  768. {
  769. counts[i] = TA0CCR0; // Save result
  770. }
  771. // Context Restore Port Registers
  772. *((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
  773. *((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
  774. } // End for Loop
  775. /*
  776. * Context restore GIE within Status Register and all timer registers
  777. * used.
  778. */
  779. if(!(contextSaveSR & GIE))
  780. {
  781. __bic_SR_register(GIE);
  782. }
  783. TA0CTL = contextSaveTA0CTL;
  784. TA0CCTL0 = contextSaveTA0CCTL0;
  785. TA0CCR0 = contextSaveTA0CCR0;
  786. TA1CTL = contextSaveTA1CTL;
  787. TA1CCTL0 = contextSaveTA1CCTL0;
  788. TA1CCR0 = contextSaveTA1CCR0;
  789. }
  790. #endif
  791. #ifdef RO_COMPAp_TA0_WDTp
  792. /*!
  793. * @brief RO method capactiance measurement using CompA+, TimerA0, and WDT+
  794. *
  795. * \n Schematic Description of CompA+ forming relaxation oscillator and
  796. * coupling (connection) between the relaxation oscillator and
  797. * TimerA0.
  798. * \n <- Output
  799. * \n -> Input
  800. * \n R Resistor (typically 100Kohms)
  801. *
  802. * +-<-Px.y (reference)
  803. * |
  804. * R
  805. * |
  806. * +---+-->COMPA+
  807. * | |
  808. * R R
  809. * | |
  810. * GND |
  811. * |
  812. * +-->TACLK
  813. * |
  814. * element-+-R--+-<-CAOUT
  815. * |
  816. * +------->COMPA-
  817. *
  818. * \n The WDT+ interval represents the measurement window. The number of
  819. * counts within the TA0R that have accumulated during the measurement
  820. * window represents the capacitance of the element.
  821. *
  822. * @param group Address of the structure describing the Sensor to be measured
  823. * @param counts Address to where the measurements are to be written
  824. * @return none
  825. */
  826. void TI_CTS_RO_COMPAp_TA0_WDTp_HAL(const struct Sensor *group, uint16_t *counts)
  827. {
  828. uint8_t i;
  829. //** Context Save
  830. // Status Register:
  831. // WDTp: IE1, WDTCTL
  832. // TIMERA0: TACTL, TACCTL1
  833. // COMPAp: CACTL1, CACTL2, CAPD
  834. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  835. uint8_t contextSaveSR;
  836. uint8_t contextSaveIE1;
  837. uint16_t contextSaveWDTCTL;
  838. uint16_t contextSaveTACTL,contextSaveTACCTL1,contextSaveTACCR1;
  839. uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
  840. uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
  841. uint8_t contextSavetxclkDir,contextSavetxclkSel;
  842. uint8_t contextSaveRefDir,contextSaveRefOutSel;
  843. #ifdef SEL2REGISTER
  844. uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
  845. contextSaveCaoutSel2 = *(group->caoutSel2Register);
  846. contextSaveTxclkSel2 = *(group->txclkSel2Register);
  847. #endif
  848. contextSaveSR = __get_SR_register();
  849. contextSaveIE1 = IE1;
  850. contextSaveWDTCTL = WDTCTL;
  851. contextSaveWDTCTL &= 0x00FF;
  852. contextSaveWDTCTL |= WDTPW;
  853. contextSaveTACTL = TACTL;
  854. contextSaveTACCTL1 = TACCTL1;
  855. contextSaveTACCR1 = TACCR1;
  856. contextSaveCACTL1 = CACTL1;
  857. contextSaveCACTL2 = CACTL2;
  858. contextSaveCAPD = CAPD;
  859. contextSaveCaoutDir = *(group->caoutDirRegister);
  860. contextSaveCaoutSel = *(group->caoutSelRegister);
  861. contextSavetxclkDir = *(group->txclkDirRegister);
  862. contextSavetxclkSel = *(group->txclkSelRegister);
  863. contextSaveRefDir = *(group->refPxdirRegister);
  864. contextSaveRefOutSel = *(group->refPxoutRegister);
  865. TACTL = TASSEL_0+MC_2; // TACLK, cont mode
  866. TACCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  867. *(group->caoutDirRegister) |= group->caoutBits;
  868. *(group->txclkDirRegister) &= ~group->txclkBits;
  869. *(group->caoutSelRegister) |= group->caoutBits;
  870. *(group->txclkSelRegister) |= group->txclkBits;
  871. #ifdef SEL2REGISTER
  872. *(group->caoutSel2Register) |= group->caoutBits;
  873. *(group->txclkSel2Register) |= group->txclkBits;
  874. #endif
  875. *(group->refPxdirRegister) |= group->refBits;
  876. *(group->refPxoutRegister) |= group->refBits;
  877. CACTL1 |= CAON; // Turn on comparator
  878. CAPD |= (group->capdBits);
  879. IE1 |= WDTIE; // enable WDT interrupt
  880. for (i = 0; i<(group->numElements); i++)
  881. {
  882. CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
  883. //** Setup Gate Timer *****************************************************
  884. // Set duration of sensor measurment
  885. WDTCTL = WDTPW+WDTTMSEL+ group->measGateSource + group->accumulationCycles;
  886. TACTL |= TACLR; // Clear Timer_A TAR
  887. if(group->measGateSource == GATE_WDTp_ACLK)
  888. {
  889. __bis_SR_register(LPM3_bits+GIE); // Wait for WDT interrupt
  890. }
  891. else
  892. {
  893. __bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
  894. }
  895. TACCTL1 ^= CCIS0; // Create SW capture of CCR1
  896. counts[i] = TACCR1; // Save result
  897. WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
  898. }
  899. // End Sequence
  900. //** Context Restore
  901. // WDTp: IE1, WDCTL
  902. // TIMERA0: TACTL, TACCTL1
  903. // COMPAp: CACTL1, CACTL2, CAPD
  904. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  905. #ifdef SEL2REGISTER
  906. *(group->caoutSel2Register) = contextSaveCaoutSel2;
  907. *(group->txclkSel2Register) = contextSaveTxclkSel2;
  908. #endif
  909. __bis_SR_register(contextSaveSR);
  910. if(!(contextSaveSR & GIE))
  911. {
  912. __bic_SR_register(GIE); // Wait for WDT interrupt
  913. }
  914. IE1 = contextSaveIE1;
  915. WDTCTL = contextSaveWDTCTL;
  916. TACTL = contextSaveTACTL;
  917. TACCTL1 = contextSaveTACCTL1;
  918. TACCR1 = contextSaveTACCR1;
  919. CACTL1 = contextSaveCACTL1;
  920. CACTL2 = contextSaveCACTL2;
  921. CAPD = contextSaveCAPD;
  922. *(group->caoutDirRegister) = contextSaveCaoutDir;
  923. *(group->caoutSelRegister) = contextSaveCaoutSel;
  924. *(group->txclkDirRegister) = contextSavetxclkDir;
  925. *(group->txclkSelRegister) = contextSavetxclkSel;
  926. *(group->refPxdirRegister) = contextSaveRefDir;
  927. *(group->refPxoutRegister) = contextSaveRefOutSel;
  928. }
  929. #endif
  930. #ifdef fRO_COMPAp_TA0_SW
  931. /*!
  932. * @brief RO method capactiance measurement using CompA+, TimerA0, and SW loop
  933. *
  934. * \n Schematic Description of CompA+ forming relaxation oscillator.
  935. * \n <- Output
  936. * \n -> Input
  937. * \n R Resistor (typically 100Kohms)
  938. *
  939. * +-<-Px.y (reference)
  940. * |
  941. * R
  942. * |
  943. * +---+-->COMPA+
  944. * | |
  945. * R R
  946. * | |
  947. * GND |
  948. * |
  949. * +-->TACLK
  950. * |
  951. * element-+-R--+-<-CAOUT
  952. * |
  953. * +------->COMPA-
  954. *
  955. * \n The timer counts to TA0CCR0 representing the measurement window. The
  956. * number of counts within the SW loop that have accumulated during the
  957. * measurement window represents the capacitance of the element.
  958. *
  959. * @param group Address of the structure describing the Sensor to be measured
  960. * @param counts Address to where the measurements are to be written
  961. * @return none
  962. */
  963. void TI_CTS_fRO_COMPAp_TA0_SW_HAL(const struct Sensor *group, uint16_t *counts)
  964. {
  965. uint8_t i;
  966. uint16_t j;
  967. //** Context Save
  968. // Status Register:
  969. // TIMERA0: TACTL, TACCTL0
  970. // COMPAp: CACTL1, CACTL2, CAPD
  971. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  972. uint16_t contextSaveTACTL,contextSaveTACCTL0,contextSaveTACCR0;
  973. uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
  974. uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
  975. uint8_t contextSavetxclkDir,contextSavetxclkSel;
  976. uint8_t contextSaveRefDir,contextSaveRefOutSel;
  977. #ifdef SEL2REGISTER
  978. uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
  979. contextSaveCaoutSel2 = *(group->caoutSel2Register);
  980. contextSaveTxclkSel2 = *(group->txclkSel2Register);
  981. #endif
  982. contextSaveTACTL = TACTL;
  983. contextSaveTACCTL0 = TACCTL0;
  984. contextSaveTACCR0 = TACCR0;
  985. contextSaveCACTL1 = CACTL1;
  986. contextSaveCACTL2 = CACTL2;
  987. contextSaveCAPD = CAPD;
  988. contextSaveCaoutDir = *(group->caoutDirRegister);
  989. contextSaveCaoutSel = *(group->caoutSelRegister);
  990. contextSavetxclkDir = *(group->txclkDirRegister);
  991. contextSavetxclkSel = *(group->txclkSelRegister);
  992. contextSaveRefDir = *(group->refPxdirRegister);
  993. contextSaveRefOutSel = *(group->refPxoutRegister);
  994. //** Setup Measurement timer***************************************************
  995. // Configure Timer TA0
  996. TACCR0 =(group->accumulationCycles);
  997. TACCTL0 &= ~CAP;
  998. // setup connections between CAOUT and TA0
  999. *(group->caoutDirRegister) |= group->caoutBits;
  1000. *(group->txclkDirRegister) &= ~group->txclkBits;
  1001. *(group->caoutSelRegister) |= group->caoutBits;
  1002. *(group->txclkSelRegister) |= group->txclkBits;
  1003. #ifdef SEL2REGISTER
  1004. *(group->caoutSel2Register) |= group->caoutBits;
  1005. *(group->txclkSel2Register) |= group->txclkBits;
  1006. #endif
  1007. // setup reference
  1008. *(group->refPxdirRegister) |= group->refBits;
  1009. *(group->refPxoutRegister) |= group->refBits;
  1010. CACTL1 |= CAON; // Turn on comparator
  1011. CAPD |= (group->capdBits);
  1012. for (i = 0; i<(group->numElements); i++)
  1013. {
  1014. j=0;
  1015. CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
  1016. //** Setup Gate Timer **************
  1017. // Set duration of sensor measurment
  1018. TACTL = TASSEL_0+TACLR+MC_1; // TACLK, reset, up mode
  1019. TACTL &= ~TAIFG; // clear IFG
  1020. while(!(TACTL & TAIFG))
  1021. {
  1022. j++;
  1023. } // end accumulation
  1024. counts[i] = j;
  1025. }
  1026. // End Sequence
  1027. //** Context Restore
  1028. // TIMERA0: TACTL, TACCTL1
  1029. // COMPAp: CACTL1, CACTL2, CAPD
  1030. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  1031. #ifdef SEL2REGISTER
  1032. *(group->caoutSel2Register) = contextSaveCaoutSel2;
  1033. *(group->txclkSel2Register) = contextSaveTxclkSel2;
  1034. #endif
  1035. TACTL = contextSaveTACTL;
  1036. TACCTL0 = contextSaveTACCTL0;
  1037. TACCR0 = contextSaveTACCR0;
  1038. CACTL1 = contextSaveCACTL1;
  1039. CACTL2 = contextSaveCACTL2;
  1040. CAPD = contextSaveCAPD;
  1041. *(group->caoutDirRegister) = contextSaveCaoutDir;
  1042. *(group->caoutSelRegister) = contextSaveCaoutSel;
  1043. *(group->txclkDirRegister) = contextSavetxclkDir;
  1044. *(group->txclkSelRegister) = contextSavetxclkSel;
  1045. *(group->refPxdirRegister) = contextSaveRefDir;
  1046. *(group->refPxoutRegister) = contextSaveRefOutSel;
  1047. }
  1048. #endif
  1049. #ifdef fRO_COMPAp_SW_TA0
  1050. /*!
  1051. * @brief RO method capactiance measurement using CompA+, TimerA0, and SW loop
  1052. *
  1053. * \n Schematic Description of CompA+ forming relaxation oscillator.
  1054. * \n <- Output
  1055. * \n -> Input
  1056. * \n R Resistor (typically 100Kohms)
  1057. *
  1058. * +-<-Px.y (reference)
  1059. * |
  1060. * R
  1061. * |
  1062. * +---+-->COMPA+
  1063. * | |
  1064. * R R
  1065. * | |
  1066. * GND |
  1067. * |
  1068. * |
  1069. * element-+-R--+-<-CAOUT
  1070. * |
  1071. * +------->COMPA-
  1072. *
  1073. * \n The SW loop counts to 'n' accumulationCycles, representing the
  1074. * measurement window. The number of timer counts within TA0R register
  1075. * represents the capacitance of the element.
  1076. *
  1077. * @param group Address of the structure describing the Sensor to be measured
  1078. * @param counts Address to where the measurements are to be written
  1079. * @return none
  1080. */
  1081. void TI_CTS_fRO_COMPAp_SW_TA0_HAL(const struct Sensor *group, uint16_t *counts)
  1082. {
  1083. uint8_t i;
  1084. uint16_t j;
  1085. //** Context Save
  1086. // Status Register:
  1087. // TIMERA0: TACTL, TACCTL0, TACCTL1
  1088. // COMPAp: CACTL1, CACTL2, CAPD
  1089. // Ports: caoutDIR, caoutSel, caoutSel2, refout, refdir
  1090. uint16_t contextSaveTACTL,contextSaveTACCTL0,contextSaveTACCTL1;
  1091. uint16_t contextSaveTACCR0,contextSaveTACCR1;
  1092. uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
  1093. uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
  1094. uint8_t contextSaveRefDir,contextSaveRefOutSel;
  1095. #ifdef SEL2REGISTER
  1096. uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
  1097. contextSaveCaoutSel2 = *(group->caoutSel2Register);
  1098. #endif
  1099. contextSaveTACTL = TACTL;
  1100. contextSaveTACCTL0 = TACCTL0;
  1101. contextSaveTACCTL1 = TACCTL1;
  1102. contextSaveTACCR0 = TACCR0;
  1103. contextSaveTACCR1 = TACCR1;
  1104. contextSaveCACTL1 = CACTL1;
  1105. contextSaveCACTL2 = CACTL2;
  1106. contextSaveCAPD = CAPD;
  1107. contextSaveCaoutDir = *(group->caoutDirRegister);
  1108. contextSaveCaoutSel = *(group->caoutSelRegister);
  1109. contextSaveRefDir = *(group->refPxdirRegister);
  1110. contextSaveRefOutSel = *(group->refPxoutRegister);
  1111. //** Setup Measurement timer***************************************************
  1112. // Configure Timer TA0
  1113. TACCTL0 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  1114. TACCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  1115. // setup connections between CAOUT and TA0
  1116. *(group->caoutDirRegister) |= group->caoutBits;
  1117. *(group->caoutSelRegister) |= group->caoutBits;
  1118. #ifdef SEL2REGISTER
  1119. *(group->caoutSel2Register) |= group->caoutBits;
  1120. #endif
  1121. // setup reference
  1122. *(group->refPxdirRegister) |= group->refBits;
  1123. *(group->refPxoutRegister) |= group->refBits;
  1124. CACTL1 |= CAON; // Turn on comparator
  1125. CAPD |= (group->capdBits);
  1126. for (i = 0; i<(group->numElements); i++)
  1127. {
  1128. CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
  1129. //** Setup Gate Timer **************
  1130. // Set duration of sensor measurment
  1131. TACTL = group->measureGateSource+group->sourceScale+TACLR+MC_2;
  1132. TACCTL0 ^= CCIS0; // Create SW capture of CCR0
  1133. for(j = group->accumulationCycles; j > 0; j--)
  1134. {
  1135. CACTL1 &= ~CAIFG;
  1136. while(!(CACTL1 & CAIFG));
  1137. }
  1138. TACCTL1 ^= CCIS0; // Create SW capture of CCR1
  1139. counts[i] = TACCR1; // Save result
  1140. counts[i] -= TACCR0; // Save result
  1141. TACCTL0 &= ~CCIFG;
  1142. TACCTL1 &= ~CCIFG;
  1143. }
  1144. // End Sequence
  1145. //** Context Restore
  1146. // WDTp: IE1, WDCTL
  1147. // TIMERA0: TACTL, TACCTL0, TACCTL1, TACCR0, TACCR1
  1148. // COMPAp: CACTL1, CACTL2, CAPD
  1149. // Ports: caoutDIR, caoutSel, txclkDIR, caoutSel2, refout, refdir
  1150. #ifdef SEL2REGISTER
  1151. *(group->caoutSel2Register) = contextSaveCaoutSel2;
  1152. #endif
  1153. TACTL = contextSaveTACTL;
  1154. TACCTL0 = contextSaveTACCTL0;
  1155. TACCTL1 = contextSaveTACCTL1;
  1156. TACCR0 = contextSaveTACCR0;
  1157. TACCR1 = contextSaveTACCR1;
  1158. CACTL1 = contextSaveCACTL1;
  1159. CACTL2 = contextSaveCACTL2;
  1160. CAPD = contextSaveCAPD;
  1161. *(group->caoutDirRegister) = contextSaveCaoutDir;
  1162. *(group->caoutSelRegister) = contextSaveCaoutSel;
  1163. *(group->refPxdirRegister) = contextSaveRefDir;
  1164. *(group->refPxoutRegister) = contextSaveRefOutSel;
  1165. }
  1166. #endif
  1167. #ifdef RO_COMPAp_TA1_WDTp
  1168. /*!
  1169. * @brief RO method capactiance measurement using CompA+, TimerA1, and WDT+
  1170. *
  1171. * \n Schematic Description of CompA+ forming relaxation oscillator and
  1172. * coupling (connection) between the relaxation oscillator and TimerA0.
  1173. * \n <- Output
  1174. * \n -> Input
  1175. * \n R Resistor (typically 100Kohms)
  1176. *
  1177. * +-<-Px.y (reference)
  1178. * |
  1179. * R
  1180. * |
  1181. * +---+-->COMPA+
  1182. * | |
  1183. * R R
  1184. * | |
  1185. * GND |
  1186. * |
  1187. * +-->TA1CLK
  1188. * |
  1189. * element-+-R--+-<-CAOUT
  1190. * |
  1191. * +------->COMPA-
  1192. *
  1193. * \n The WDT+ interval represents the measurement window. The number of
  1194. * counts within the TA0R that have accumulated during the measurement
  1195. * window represents the capacitance of the element.
  1196. *
  1197. * @param group Address of the structure describing the Sensor to be measured
  1198. * @param counts Address to where the measurements are to be written
  1199. * @return none
  1200. */
  1201. void TI_CTS_RO_COMPAp_TA1_WDTp_HAL(const struct Sensor *group, uint16_t *counts)
  1202. {
  1203. uint8_t i;
  1204. //** Context Save
  1205. // Status Register:
  1206. // WDTp: IE1, WDTCTL
  1207. // TIMERA0: TA1CTL, TA1CCTL1
  1208. // COMPAp: CACTL1, CACTL2, CAPD
  1209. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  1210. uint8_t contextSaveSR;
  1211. uint8_t contextSaveIE1;
  1212. uint16_t contextSaveWDTCTL;
  1213. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL1;
  1214. uint16_t contextSaveTA1CCR1;
  1215. uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
  1216. uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
  1217. uint8_t contextSavetxclkDir,contextSavetxclkSel;
  1218. uint8_t contextSaveRefDir,contextSaveRefOutSel;
  1219. #ifdef SEL2REGISTER
  1220. uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
  1221. contextSaveCaoutSel2 = *(group->caoutSel2Register);
  1222. contextSaveTxclkSel2 = *(group->txclkSel2Register);
  1223. #endif
  1224. contextSaveSR = __get_SR_register();
  1225. contextSaveIE1 = IE1;
  1226. contextSaveWDTCTL = WDTCTL;
  1227. contextSaveWDTCTL &= 0x00FF;
  1228. contextSaveWDTCTL |= WDTPW;
  1229. contextSaveTA1CTL = TA1CTL;
  1230. contextSaveTA1CCTL1 = TA1CCTL1;
  1231. contextSaveTA1CCR1 = TA1CCR1;
  1232. contextSaveCACTL1 = CACTL1;
  1233. contextSaveCACTL2 = CACTL2;
  1234. contextSaveCAPD = CAPD;
  1235. contextSaveCaoutDir = *(group->caoutDirRegister);
  1236. contextSaveCaoutSel = *(group->caoutSelRegister);
  1237. contextSavetxclkDir = *(group->txclkDirRegister);
  1238. contextSavetxclkSel = *(group->txclkSelRegister);
  1239. contextSaveRefDir = *(group->refPxdirRegister);
  1240. contextSaveRefOutSel = *(group->refPxoutRegister);
  1241. //** Setup Measurement timer***************************************************
  1242. // Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
  1243. // capacitive touch layer.
  1244. TA1CTL = TASSEL_0+MC_2; // TA1CLK, cont mode
  1245. TA1CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  1246. *(group->caoutDirRegister) |= group->caoutBits;
  1247. *(group->txclkDirRegister) &= ~group->txclkBits;
  1248. *(group->caoutSelRegister) |= group->caoutBits;
  1249. *(group->txclkSelRegister) |= group->txclkBits;
  1250. #ifdef SEL2REGISTER
  1251. *(group->caoutSel2Register) |= group->caoutBits;
  1252. *(group->txclkSel2Register) |= group->txclkBits;
  1253. #endif
  1254. *(group->refPxdirRegister) |= group->refBits;
  1255. *(group->refPxoutRegister) |= group->refBits;
  1256. CACTL1 |= CAON; // Turn on comparator
  1257. CAPD |= (group->capdBits);
  1258. IE1 |= WDTIE; // enable WDT interrupt
  1259. for (i = 0; i<(group->numElements); i++)
  1260. {
  1261. CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
  1262. //** Setup Gate Timer *****************************************************
  1263. // Set duration of sensor measurment
  1264. WDTCTL = WDTPW+WDTTMSEL+ group->measGateSource + group->accumulationCycles;
  1265. TA1CTL |= TACLR; // Clear Timer_A TAR
  1266. if(group->measGateSource == GATE_WDTp_ACLK)
  1267. {
  1268. __bis_SR_register(LPM3_bits+GIE); // Wait for WDT interrupt
  1269. }
  1270. else
  1271. {
  1272. __bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
  1273. }
  1274. TA1CCTL1 ^= CCIS0; // Create SW capture of CCR1
  1275. counts[i] = TA1CCR1; // Save result
  1276. WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
  1277. }
  1278. // End Sequence
  1279. //** Context Restore
  1280. // WDTp: IE1, WDCTL
  1281. // TIMERA0: TACTL, TACCTL1
  1282. // COMPAp: CACTL1, CACTL2, CAPD
  1283. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  1284. #ifdef SEL2REGISTER
  1285. *(group->caoutSel2Register) = contextSaveCaoutSel2;
  1286. *(group->txclkSel2Register) = contextSaveTxclkSel2;
  1287. #endif
  1288. __bis_SR_register(contextSaveSR);
  1289. if(!(contextSaveSR & GIE))
  1290. {
  1291. __bic_SR_register(GIE); // Wait for WDT interrupt
  1292. }
  1293. IE1 = contextSaveIE1;
  1294. WDTCTL = contextSaveWDTCTL;
  1295. TA1CTL = contextSaveTA1CTL;
  1296. TA1CCTL1 = contextSaveTA1CCTL1;
  1297. TA1CCR1 = contextSaveTA1CCR1;
  1298. CACTL1 = contextSaveCACTL1;
  1299. CACTL2 = contextSaveCACTL2;
  1300. CAPD = contextSaveCAPD;
  1301. *(group->caoutDirRegister) = contextSaveCaoutDir;
  1302. *(group->caoutSelRegister) = contextSaveCaoutSel;
  1303. *(group->txclkDirRegister) = contextSavetxclkDir;
  1304. *(group->txclkSelRegister) = contextSavetxclkSel;
  1305. *(group->refPxdirRegister) = contextSaveRefDir;
  1306. *(group->refPxoutRegister) = contextSaveRefOutSel;
  1307. }
  1308. #endif
  1309. #ifdef fRO_COMPAp_TA1_SW
  1310. /*!
  1311. * @brief RO method capactiance measurement using CompA+, TimerA1, and SW loop
  1312. *
  1313. * Schematic Description of CompA+ forming relaxation oscillator.
  1314. * \n <- Output
  1315. * \n -> Input
  1316. * \n R Resistor (typically 100Kohms)
  1317. *
  1318. * +-<-Px.y (reference)
  1319. * |
  1320. * R
  1321. * |
  1322. * +---+-->COMPA+
  1323. * | |
  1324. * R R
  1325. * | |
  1326. * GND |
  1327. * |
  1328. * +-->TA1CLK
  1329. * |
  1330. * element-+-R--+-<-CAOUT
  1331. * |
  1332. * +------->COMPA-
  1333. *
  1334. * \n The timer counts to TA1CCR0 representing the measurement window. The
  1335. * number of counts within the SW loop that have accumulated during the
  1336. * measurement window represents the capacitance of the element.
  1337. *
  1338. * @param group Address of the structure describing the Sensor to be measured
  1339. * @param counts Address to where the measurements are to be written
  1340. * @return none
  1341. */
  1342. void TI_CTS_fRO_COMPAp_TA1_SW_HAL(const struct Sensor *group, uint16_t *counts)
  1343. {
  1344. uint8_t i;
  1345. uint16_t j;
  1346. //** Context Save
  1347. // Status Register:
  1348. // TIMERA0: TA1CTL, TA1CCTL0
  1349. // COMPAp: CACTL1, CACTL2, CAPD
  1350. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  1351. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
  1352. uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
  1353. uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
  1354. uint8_t contextSavetxclkDir,contextSavetxclkSel;
  1355. uint8_t contextSaveRefDir,contextSaveRefOutSel;
  1356. #ifdef SEL2REGISTER
  1357. uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
  1358. contextSaveCaoutSel2 = *(group->caoutSel2Register);
  1359. contextSaveTxclkSel2 = *(group->txclkSel2Register);
  1360. #endif
  1361. contextSaveTA1CTL = TA1CTL;
  1362. contextSaveTA1CCTL0 = TA1CCTL0;
  1363. contextSaveTA1CCR0 = TA1CCR0;
  1364. contextSaveCACTL1 = CACTL1;
  1365. contextSaveCACTL2 = CACTL2;
  1366. contextSaveCAPD = CAPD;
  1367. contextSaveCaoutDir = *(group->caoutDirRegister);
  1368. contextSaveCaoutSel = *(group->caoutSelRegister);
  1369. contextSavetxclkDir = *(group->txclkDirRegister);
  1370. contextSavetxclkSel = *(group->txclkSelRegister);
  1371. contextSaveRefDir = *(group->refPxdirRegister);
  1372. contextSaveRefOutSel = *(group->refPxoutRegister);
  1373. //** Setup Measurement timer***************************************************
  1374. // Configure Timer TA0
  1375. TA1CCR0 =(group->accumulationCycles);
  1376. // setup connections between CAOUT and TA0
  1377. *(group->caoutDirRegister) |= group->caoutBits;
  1378. *(group->txclkDirRegister) &= ~group->txclkBits;
  1379. *(group->caoutSelRegister) |= group->caoutBits;
  1380. *(group->txclkSelRegister) |= group->txclkBits;
  1381. #ifdef SEL2REGISTER
  1382. *(group->caoutSel2Register) |= group->caoutBits;
  1383. *(group->txclkSel2Register) |= group->txclkBits;
  1384. #endif
  1385. // setup reference
  1386. *(group->refPxdirRegister) |= group->refBits;
  1387. *(group->refPxoutRegister) |= group->refBits;
  1388. CACTL1 |= CAON; // Turn on comparator
  1389. CAPD |= (group->capdBits);
  1390. for (i = 0; i<(group->numElements); i++)
  1391. {
  1392. j=0;
  1393. CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
  1394. //** Setup Gate Timer **************
  1395. // Set duration of sensor measurment
  1396. TA1CTL = TASSEL_0+TACLR+MC_1; // TA1CLK, Reset, up mode
  1397. TA1CTL &= ~TAIFG; // clear IFG
  1398. while(!(TACTL & TAIFG))
  1399. {
  1400. j++;
  1401. } // end accumulation
  1402. counts[i] = j;
  1403. }
  1404. // End Sequence
  1405. //** Context Restore
  1406. // WDTp: IE1, WDCTL
  1407. // TIMERA0: TACTL, TACCTL1
  1408. // COMPAp: CACTL1, CACTL2, CAPD
  1409. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  1410. #ifdef SEL2REGISTER
  1411. *(group->caoutSel2Register) = contextSaveCaoutSel2;
  1412. *(group->txclkSel2Register) = contextSaveTxclkSel2;
  1413. #endif
  1414. TA1CTL = contextSaveTA1CTL;
  1415. TA1CCTL0 = contextSaveTA1CCTL0;
  1416. TA1CCR0 = contextSaveTA1CCR0;
  1417. CACTL1 = contextSaveCACTL1;
  1418. CACTL2 = contextSaveCACTL2;
  1419. CAPD = contextSaveCAPD;
  1420. *(group->caoutDirRegister) = contextSaveCaoutDir;
  1421. *(group->caoutSelRegister) = contextSaveCaoutSel;
  1422. *(group->txclkDirRegister) = contextSavetxclkDir;
  1423. *(group->txclkSelRegister) = contextSavetxclkSel;
  1424. *(group->refPxdirRegister) = contextSaveRefDir;
  1425. *(group->refPxoutRegister) = contextSaveRefOutSel;
  1426. }
  1427. #endif
  1428. #ifdef RC_PAIR_TA0
  1429. /*!
  1430. * @brief RC method capactiance measurement using a Pair of GPIO and TimerA0
  1431. *
  1432. * Schematic Description of two GPIO forming RC measruement.
  1433. * \n <- Output
  1434. * \n -> Input
  1435. * \n R Resistor (typically 1Mohms)
  1436. *
  1437. * +-<-Px.y (reference)
  1438. * |
  1439. * R
  1440. * |
  1441. * Element---+-->Pa.b
  1442. *
  1443. * Charge and Discharge Cycle
  1444. * +
  1445. * + +
  1446. * + +
  1447. * + +
  1448. * + +
  1449. * \n Start Timer After n cycles Stop Timer
  1450. * The TAR reister value is the number of SMCLK periods within n
  1451. * charge and discharge cycles. This value is directly proportional
  1452. * to the capacitance of the element measured. 'n' is defined by the
  1453. * variable accumulation_cycles.
  1454. *
  1455. * @param group Address of the structure describing the Sensor to be measured
  1456. * @param counts Address to where the measurements are to be written
  1457. * @return none
  1458. */
  1459. void TI_CTS_RC_PAIR_TA0_HAL(const struct Sensor *group,uint16_t *counts)
  1460. {
  1461. uint8_t i;
  1462. uint16_t j;
  1463. //** Context Save
  1464. // TIMERA0: TA0CTL
  1465. // Port: inputPxout, inputPxdir, referencePxout, referencePxdir
  1466. uint8_t contextSaveinputPxout,contextSaveinputPxdir,contextSavereferencePxout;
  1467. uint8_t contextSavereferencePxdir;
  1468. #ifdef __MSP430_HAS_SFR__
  1469. uint16_t contextSaveTA0CTL,contextSaveTA0CCR0;
  1470. contextSaveTA0CTL = TA0CTL;
  1471. contextSaveTA0CCR0 = TA0CCR0;
  1472. #else
  1473. uint16_t contextSaveTACTL,contextSaveTACCR0;
  1474. contextSaveTACTL = TACTL;
  1475. contextSaveTACCR0 = TACCR0;
  1476. #endif
  1477. //** Setup Measurement timer****************************************************
  1478. // Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
  1479. // capacitive touch layer.
  1480. #ifdef __MSP430_HAS_SFR__
  1481. TA0CCR0 = 0xFFFF;
  1482. #else
  1483. TACCR0 = 0xFFFF;
  1484. #endif
  1485. for (i = 0; i<(group->numElements); i++)
  1486. {
  1487. // Context Save
  1488. contextSaveinputPxout = *((group->arrayPtr[i])->inputPxoutRegister);
  1489. contextSaveinputPxdir = *((group->arrayPtr[i])->inputPxdirRegister);
  1490. contextSavereferencePxout = *((group->arrayPtr[i])->referencePxoutRegister);
  1491. contextSavereferencePxdir = *((group->arrayPtr[i])->referencePxdirRegister);
  1492. j = (group->accumulationCycles);
  1493. #ifdef __MSP430_HAS_SFR__
  1494. TA0CTL = TASSEL_2+TACLR; // SMCLK, up mode
  1495. #else
  1496. TACTL = TASSEL_2+TACLR; // SMCLK, up mode
  1497. #endif
  1498. while(j--)
  1499. {
  1500. //******************************************************************************
  1501. // Positive cycle
  1502. // SENSOR ---+---- Input (low to high)
  1503. // R
  1504. // +---- Rerefence (high)
  1505. //******************************************************************************
  1506. // Input low
  1507. *((group->arrayPtr[i])->inputPxoutRegister) &= ~((group->arrayPtr[i])->inputBits);
  1508. *((group->arrayPtr[i])->inputPxdirRegister) |= (group->arrayPtr[i])->inputBits;
  1509. // Reference High
  1510. *((group->arrayPtr[i])->referencePxdirRegister) |= (group->arrayPtr[i])->referenceBits;
  1511. *((group->arrayPtr[i])->referencePxoutRegister) |= ((group->arrayPtr[i])->referenceBits);
  1512. // Wait until low
  1513. while((*((group->arrayPtr[i])->inputPxinRegister)) & ((group->arrayPtr[i])->inputBits));
  1514. // Change to an input
  1515. *((group->arrayPtr[i])->inputPxdirRegister) &= ~(group->arrayPtr[i])->inputBits;
  1516. //**************************************************************************
  1517. // This mechanism is traditianally an LPM with the ISR calculating the
  1518. // delta between when the first snapshot and the ISR event. If this is
  1519. // included within the library the entire port ISR would not be available
  1520. // to the calling application. In this example the polling is done with the
  1521. // CPU at expense of power and MIPS but preserves the port ISR for other
  1522. // interruptible functions.
  1523. //**************************************************************************
  1524. #ifdef __MSP430_HAS_SFR__
  1525. TA0CTL |= MC_1; // start timer
  1526. #else
  1527. TACTL |= MC_1; // start timer
  1528. #endif
  1529. //wait until voltage reaches Vih of port
  1530. while(!((*((group->arrayPtr[i])->inputPxinRegister) & (group->arrayPtr[i])->inputBits)));
  1531. #ifdef __MSP430_HAS_SFR__
  1532. TA0CTL &= ~ MC_3; // stop timer
  1533. #else
  1534. TACTL &= ~ MC_3; // stop timer
  1535. #endif
  1536. //******************************************************************************
  1537. // Negative cycle
  1538. // SENSOR ---+---- Input (high to low)
  1539. // R
  1540. // +---- Rerefence (low)
  1541. //******************************************************************************
  1542. // Input High
  1543. *((group->arrayPtr[i])->inputPxoutRegister) |= ((group->arrayPtr[i])->inputBits);
  1544. *((group->arrayPtr[i])->inputPxdirRegister) |= (group->arrayPtr[i])->inputBits;
  1545. // Reference Low
  1546. *((group->arrayPtr[i])->referencePxoutRegister) &= ~((group->arrayPtr[i])->referenceBits);
  1547. // Change to an input
  1548. *((group->arrayPtr[i])->inputPxdirRegister) &= ~((group->arrayPtr[i])->inputBits);
  1549. #ifdef __MSP430_HAS_SFR__
  1550. TA0CTL |= MC_1; // start timer
  1551. #else
  1552. TACTL |= MC_1; // start timer
  1553. #endif
  1554. //wait until voltage reaches Vil of port
  1555. while((*((group->arrayPtr[i])->inputPxinRegister)) & ((group->arrayPtr[i])->inputBits));
  1556. #ifdef __MSP430_HAS_SFR__
  1557. TA0CTL &= ~ MC_3; // stop timer
  1558. #else
  1559. TACTL &= ~ MC_3; // stop timer
  1560. #endif
  1561. } // END accumulation loop for a single element
  1562. #ifdef __MSP430_HAS_SFR__
  1563. counts[i] = TA0R;
  1564. #else
  1565. counts[i] = TAR;
  1566. #endif
  1567. // Context Restore
  1568. *((group->arrayPtr[i])->inputPxoutRegister) = contextSaveinputPxout;
  1569. *((group->arrayPtr[i])->inputPxdirRegister) = contextSaveinputPxdir;
  1570. *((group->arrayPtr[i])->referencePxoutRegister) = contextSavereferencePxout;
  1571. *((group->arrayPtr[i])->referencePxdirRegister) = contextSavereferencePxdir;
  1572. } // END FOR loop which cycles through elements within sensor
  1573. //** Context Restore
  1574. #ifdef __MSP430_HAS_SFR__
  1575. TA0CTL = contextSaveTA0CTL;
  1576. TA0CCR0 = contextSaveTA0CCR0;
  1577. #else
  1578. TACTL = contextSaveTACTL;
  1579. TACCR0 = contextSaveTACCR0;
  1580. #endif
  1581. }
  1582. #endif
  1583. #ifdef fRO_PINOSC_TA0_SW
  1584. /*!
  1585. * @brief fRO method capactiance measurement using the PinOsc and TimerA0
  1586. *
  1587. * Charge and Discharge Cycle
  1588. * +
  1589. * + +
  1590. * + +
  1591. * + +
  1592. * + +
  1593. * Start Timer After n cycles Stop Timer
  1594. * \n The TAR reister value is the number of SW loops (function of MCLK)
  1595. * within n charge and discharge cycles. This value is directly
  1596. * proportional to the capacitance of the element measured. 'n' is
  1597. * defined by the variable accumulation_cycles.
  1598. *
  1599. * @param group Address of the structure describing the Sensor to be measured
  1600. * @param counts Address to where the measurements are to be written
  1601. * @return none
  1602. */
  1603. void TI_CTS_fRO_PINOSC_TA0_SW_HAL(const struct Sensor *group,uint16_t *counts)
  1604. {
  1605. uint8_t i;
  1606. uint16_t j;
  1607. //** Context Save
  1608. // TIMERA0: TA0CTL
  1609. // Ports: PxSEL, PxSEL2
  1610. uint16_t contextSaveTA0CTL, contextSaveTA0CCTL0;
  1611. uint8_t contextSaveSel,contextSaveSel2;
  1612. contextSaveTA0CTL = TA0CTL;
  1613. contextSaveTA0CCTL0 = TA0CCTL0;
  1614. // Setup Measurement timer
  1615. TACCR0 =(group->accumulationCycles);
  1616. for (i =0; i< (group->numElements); i++)
  1617. {
  1618. j = 0;
  1619. // Context Save
  1620. contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
  1621. contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
  1622. // start single oscillation (rise then fall and trigger on fall)
  1623. *((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
  1624. *((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
  1625. TA0CTL = TASSEL_3+TACLR+MC_1; // INCLK, reset, up mode
  1626. TA0CTL &= ~TAIFG; // clear IFG
  1627. // start timer in up mode
  1628. while(!(TA0CTL & TAIFG))
  1629. {
  1630. j++;
  1631. } // end accumulation
  1632. counts[i] = j;
  1633. TA0CTL &= ~MC_1;
  1634. // Context Restore
  1635. *((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
  1636. *((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
  1637. }
  1638. // End Sequence
  1639. // Context Restore
  1640. TA0CTL = contextSaveTA0CTL;
  1641. TA0CCTL0 = contextSaveTA0CCTL0;
  1642. }
  1643. #endif
  1644. #ifdef RO_PINOSC_TA0_WDTp
  1645. /*!
  1646. * @brief RO method capactiance measurement with PinOsc IO, TimerA0, and WDT+
  1647. *
  1648. * \n Schematic Description:
  1649. *
  1650. * \n element-----+->Px.y
  1651. *
  1652. * \n The WDT+ interval represents the measurement window. The number of
  1653. * counts within the TA0R that have accumulated during the measurement
  1654. * window represents the capacitance of the element.
  1655. *
  1656. * @param group Pointer to the structure describing the Sensor to be measured
  1657. * @param counts Pointer to where the measurements are to be written
  1658. * @return none
  1659. */
  1660. void TI_CTS_RO_PINOSC_TA0_WDTp_HAL(const struct Sensor *group,uint16_t *counts)
  1661. {
  1662. uint8_t i;
  1663. //** Context Save
  1664. // Status Register:
  1665. // WDTp: IE1, WDTCTL
  1666. // TIMERA0: TA0CTL, TA0CCTL1
  1667. // Ports: PxSEL, PxSEL2
  1668. uint8_t contextSaveSR;
  1669. uint8_t contextSaveIE1;
  1670. uint16_t contextSaveWDTCTL;
  1671. uint16_t contextSaveTA0CTL,contextSaveTA0CCTL1,contextSaveTA0CCR1;
  1672. uint8_t contextSaveSel,contextSaveSel2;
  1673. contextSaveSR = __get_SR_register();
  1674. contextSaveIE1 = IE1;
  1675. contextSaveWDTCTL = WDTCTL;
  1676. contextSaveWDTCTL &= 0x00FF;
  1677. contextSaveWDTCTL |= WDTPW;
  1678. contextSaveTA0CTL = TA0CTL;
  1679. contextSaveTA0CCTL1 = TA0CCTL1;
  1680. contextSaveTA0CCR1 = TA0CCR1;
  1681. //** Setup Measurement timer***************************************************
  1682. // Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
  1683. // capacitive touch layer.
  1684. // Configure and Start Timer
  1685. TA0CTL = TASSEL_3+MC_2; // INCLK, cont mode
  1686. TA0CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  1687. IE1 |= WDTIE; // enable WDT interrupt
  1688. for (i = 0; i<(group->numElements); i++)
  1689. {
  1690. // Context Save
  1691. contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
  1692. contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
  1693. // Configure Ports for relaxation oscillator
  1694. *((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
  1695. *((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
  1696. //** Setup Gate Timer ********************************************************
  1697. // Set duration of sensor measurment
  1698. //WDTCTL = (WDTPW+WDTTMSEL+group->measGateSource+group->accumulationCycles);
  1699. WDTCTL = (WDTPW+WDTTMSEL+(group->measGateSource)+(group->accumulationCycles));
  1700. TA0CTL |= TACLR; // Clear Timer_A TAR
  1701. if(group->measGateSource == GATE_WDT_ACLK)
  1702. {
  1703. __bis_SR_register(LPM3_bits+GIE); // Wait for WDT interrupt
  1704. }
  1705. else
  1706. {
  1707. __bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
  1708. }
  1709. TA0CCTL1 ^= CCIS0; // Create SW capture of CCR1
  1710. counts[i] = TA0CCR1; // Save result
  1711. WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
  1712. // Context Restore
  1713. *((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
  1714. *((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
  1715. }
  1716. // End Sequence
  1717. // Context Restore
  1718. __bis_SR_register(contextSaveSR);
  1719. if(!(contextSaveSR & GIE))
  1720. {
  1721. __bic_SR_register(GIE); //
  1722. }
  1723. IE1 = contextSaveIE1;
  1724. WDTCTL = contextSaveWDTCTL;
  1725. TA0CTL = contextSaveTA0CTL;
  1726. TA0CCTL1 = contextSaveTA0CCTL1;
  1727. TA0CCR1 = contextSaveTA0CCR1;
  1728. }
  1729. #endif
  1730. #ifdef RO_PINOSC_TA0
  1731. /*!
  1732. * @brief RO method capactiance measurement using PinOsc IO, and TimerA0
  1733. *
  1734. * \n Schematic Description:
  1735. *
  1736. * \n element-----+->Px.y
  1737. *
  1738. * \n The measurement window is accumulation_cycles/ACLK. The ACLK is
  1739. * used to generate a capture event via the internal connection CCIOB.
  1740. * The counts within the TA0R that have accumulated during the
  1741. * measurement window represents the capacitance of the element.
  1742. *
  1743. * @param group Pointer to the structure describing the Sensor to be measured
  1744. * @param counts Pointer to where the measurements are to be written
  1745. * @return none
  1746. */
  1747. void TI_CTS_RO_PINOSC_TA0_HAL(const struct Sensor *group,uint16_t *counts)
  1748. {
  1749. uint8_t i;
  1750. uint16_t j;
  1751. //** Context Save
  1752. // TIMERA0: TA0CTL, TA0CCTL0
  1753. // Ports: PxSEL, PxSEL2
  1754. uint16_t contextSaveTA0CTL,contextSaveTA0CCTL0,contextSaveTA0CCR0;
  1755. uint8_t contextSaveSel,contextSaveSel2;
  1756. contextSaveTA0CTL = TA0CTL;
  1757. contextSaveTA0CCTL0 = TA0CCTL0;
  1758. contextSaveTA0CCR0 = TA0CCR0;
  1759. //** Setup Measurement timer***************************************************
  1760. // Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
  1761. // capacitive touch layer.
  1762. // Configure and Start Timer
  1763. TA0CTL = TASSEL_3+MC_2; // TACLK, cont mode
  1764. for (i =0; i< (group->numElements); i++)
  1765. {
  1766. // Context Save
  1767. contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
  1768. contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
  1769. // Configure Ports for relaxation oscillator
  1770. j = (group->accumulationCycles);
  1771. *((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
  1772. *((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
  1773. TA0CCTL0 = CM_3+CCIS_1+CAP; // Pos&Neg,ACLK (CCI0B),Cap
  1774. while(!(TA0CCTL0 & CCIFG)); // wait for capture event
  1775. TA0CTL |= TACLR; // Clear Timer_A TAR
  1776. while(j--)
  1777. {
  1778. TA0CCTL0 = CM_3+CCIS_1+CAP; // Pos&Neg,ACLK (CCI0B),Cap
  1779. while(!(TA0CCTL0 & CCIFG)); // wait for capture event
  1780. }
  1781. counts[i] = TA0CCR0; // Save result
  1782. TA0CTL = TASSEL_3+MC_2;
  1783. // Context Restore
  1784. *((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
  1785. *((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
  1786. }
  1787. // End Sequence
  1788. // Context Restore
  1789. TA0CTL = contextSaveTA0CTL;
  1790. TA0CCTL0 = contextSaveTA0CCTL0;
  1791. TA0CCR0 = contextSaveTA0CCR0;
  1792. }
  1793. #endif
  1794. #ifdef RO_COMPB_TA0_WDTA
  1795. /*!
  1796. * @brief RO method capactiance measurement using CompB, TimerA0, and WDTA
  1797. *
  1798. * \n Schematic Description of CompB forming relaxation oscillator and
  1799. * coupling (connection) between the relaxation oscillator and
  1800. * TimerA0.
  1801. * \n <- Output
  1802. * \n -> Input
  1803. * \n R Resistor (typically 100Kohms)
  1804. *
  1805. * element---+-R--<-CBOUT/TA1CLK
  1806. * |
  1807. * +---->CBx
  1808. *
  1809. * \n The WDTA interval represents the measurement window. The number of
  1810. * counts within the TA0R that have accumulated during the measurement
  1811. * window represents the capacitance of the element.
  1812. *
  1813. * @param group Address of the structure describing the Sensor to be measured
  1814. * @param counts Address to where the measurements are to be written
  1815. * @return none
  1816. */
  1817. void TI_CTS_RO_COMPB_TA0_WDTA_HAL(const struct Sensor *group,uint16_t *counts)
  1818. {
  1819. uint8_t i;
  1820. //** Context Save
  1821. // Status Register:
  1822. // WDTA: IE1, WDTCTL
  1823. // TIMERA0: TA0CTL, TA0CCTL1
  1824. // COMPAp: CACTL1, CACTL2, CAPD
  1825. // Ports: CboutDIR, CboutSel
  1826. uint8_t contextSaveSR;
  1827. uint16_t contextSaveSFRIE1;
  1828. uint16_t contextSaveWDTCTL;
  1829. uint16_t contextSaveTA0CTL,contextSaveTA0CCTL1,contextSaveTA0CCR1;
  1830. uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
  1831. uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
  1832. uint8_t contextSaveCboutDir,contextSaveCboutSel;
  1833. contextSaveSR = __get_SR_register();
  1834. contextSaveSFRIE1 = SFRIE1;
  1835. contextSaveWDTCTL = WDTCTL;
  1836. contextSaveWDTCTL &= 0x00FF;
  1837. contextSaveWDTCTL |= WDTPW;
  1838. contextSaveTA0CTL = TA0CTL;
  1839. contextSaveTA0CCTL1 = TA0CCTL1;
  1840. contextSaveTA0CCR1 = TA0CCR1;
  1841. contextSaveCBCTL0 = CBCTL0;
  1842. contextSaveCBCTL1 = CBCTL1;
  1843. contextSaveCBCTL2 = CBCTL2;
  1844. contextSaveCBCTL3 = CBCTL3;
  1845. contextSaveCboutDir = *(group->cboutTAxDirRegister);
  1846. contextSaveCboutSel = *(group->cboutTAxSelRegister);
  1847. //** Setup Measurement timer************************************************
  1848. // connect CBOUT with TA0
  1849. *(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
  1850. *(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
  1851. CBCTL2 = CBREF14+CBREF13 + CBREF02;
  1852. // Configure Timer TA0
  1853. TA0CTL = TASSEL_0+MC_2; // TACLK, cont mode
  1854. TA0CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  1855. // Turn on Comparator
  1856. CBCTL1 = CBON; // Comparator on without filter
  1857. // Vcc to resistor ladder
  1858. CBCTL3 |= (group->cbpdBits); // set CPD bits to disable
  1859. // I/O buffer
  1860. SFRIE1 |= WDTIE; // enable WDT interrupt
  1861. CBCTL2 |= CBRS_1; // Turn on reference
  1862. for (i = 0; i<(group->numElements); i++)
  1863. {
  1864. CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
  1865. //** Setup Gate Timer *************************************************
  1866. // Set duration of sensor measurment
  1867. WDTCTL = WDTPW + WDTTMSEL + group->measGateSource
  1868. + group->accumulationCycles;
  1869. TA0CTL |= TACLR; // Clear Timer_A TAR
  1870. if(group->measGateSource == GATE_WDTA_ACLK)
  1871. {
  1872. __bis_SR_register(LPM3_bits+GIE); // Wait for WDT interrupt
  1873. }
  1874. else
  1875. {
  1876. __bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
  1877. }
  1878. TA0CCTL1 ^= CCIS0; // Create SW capture of CCR1
  1879. counts[i] = TA0CCR1; // Save result
  1880. WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
  1881. }
  1882. // End Sequence
  1883. //** Context Restore
  1884. // WDTA: IE1, WDCTL
  1885. // TIMERA0: TACTL, TACCTL1
  1886. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  1887. // Ports: CboutDIR, CboutSel
  1888. __bis_SR_register(contextSaveSR);
  1889. if(!(contextSaveSR & GIE))
  1890. {
  1891. __bic_SR_register(GIE); // Wait for WDT interrupt
  1892. }
  1893. SFRIE1 = contextSaveSFRIE1;
  1894. WDTCTL = contextSaveWDTCTL;
  1895. TA0CTL = contextSaveTA0CTL;
  1896. TA0CCTL1 = contextSaveTA0CCTL1;
  1897. TA0CCR1 = contextSaveTA0CCR1;
  1898. CBCTL0 = contextSaveCBCTL0;
  1899. CBCTL1 = contextSaveCBCTL1;
  1900. CBCTL2 = contextSaveCBCTL2;
  1901. CBCTL3 = contextSaveCBCTL3;
  1902. *(group->cboutTAxDirRegister) = contextSaveCboutDir;
  1903. *(group->cboutTAxSelRegister) = contextSaveCboutSel;
  1904. }
  1905. #endif
  1906. #ifdef RO_COMPB_TA1_WDTA
  1907. /*!
  1908. * @brief RO method capactiance measurement using CompB, TimerA1, and WDTA
  1909. *
  1910. * \n Schematic Description of CompB forming relaxation oscillator and
  1911. * coupling (connection) between the relaxation oscillator and TimerA1.
  1912. * \n <- Output
  1913. * \n -> Input
  1914. * \n R Resistor (typically 100Kohms)
  1915. *
  1916. * element---+-R--<-CBOUT/TA1CLK
  1917. * |
  1918. * +---->CBx
  1919. *
  1920. * \n The WDTA interval represents the measurement window. The number of
  1921. * counts within the TA1R that have accumulated during the measurement
  1922. * window represents the capacitance of the element.
  1923. *
  1924. * @param group Address of the structure describing the Sensor to be measured
  1925. * @param counts Address to where the measurements are to be written
  1926. * @return none
  1927. ******************************************************************************/
  1928. void TI_CTS_RO_COMPB_TA1_WDTA_HAL(const struct Sensor *group, uint16_t *counts)
  1929. {
  1930. uint8_t i=0;
  1931. //** Context Save
  1932. // Status Register:
  1933. // WDTA: IE1, WDTCTL
  1934. // TIMERA1: TA1CTL, TA1CCTL1
  1935. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  1936. // Ports: CboutDIR, CboutSel
  1937. uint8_t contextSaveSR;
  1938. uint16_t contextSaveSFRIE1;
  1939. uint16_t contextSaveWDTCTL;
  1940. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL1,contextSaveTA1CCR1;
  1941. uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
  1942. uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
  1943. uint8_t contextSaveCboutDir,contextSaveCboutSel;
  1944. contextSaveSR = __get_SR_register();
  1945. contextSaveSFRIE1 = SFRIE1;
  1946. contextSaveWDTCTL = WDTCTL;
  1947. contextSaveWDTCTL &= 0x00FF;
  1948. contextSaveWDTCTL |= WDTPW;
  1949. contextSaveTA1CTL = TA1CTL;
  1950. contextSaveTA1CCTL1 = TA1CCTL1;
  1951. contextSaveTA1CCR1 = TA1CCR1;
  1952. contextSaveCBCTL0 = CBCTL0;
  1953. contextSaveCBCTL1 = CBCTL1;
  1954. contextSaveCBCTL2 = CBCTL2;
  1955. contextSaveCBCTL3 = CBCTL3;
  1956. contextSaveCboutDir = *(group->cboutTAxDirRegister);
  1957. contextSaveCboutSel = *(group->cboutTAxSelRegister);
  1958. //** Setup Measurement timer************************************************
  1959. // connect CBOUT with TA1
  1960. *(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
  1961. *(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
  1962. // Setup Comparator
  1963. CBCTL2 = CBREF14+CBREF13 + CBREF02;
  1964. // Configure Timer TA1
  1965. TA1CTL = TASSEL_0+MC_2; // TACLK, cont mode
  1966. TA1CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  1967. // Turn on Comparator
  1968. CBCTL1 = CBON; // Turn on COMPB w/out filter
  1969. CBCTL3 |= (group->cbpdBits); // set CPD bits to disable
  1970. SFRIE1 |= WDTIE; // enable WDT interrupt
  1971. CBCTL2 |= CBRS_1; // Turn on reference
  1972. for (i = 0; i<(group->numElements); i++)
  1973. {
  1974. CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
  1975. //** Setup Gate Timer *************************************************
  1976. // Set duration of sensor measurment
  1977. WDTCTL = WDTPW + WDTTMSEL + WDTCNTCL
  1978. + group->measGateSource + group->accumulationCycles;
  1979. TA1CTL |= TACLR; // Clear Timer_A TAR
  1980. if(group->measGateSource == GATE_WDTA_ACLK)
  1981. {
  1982. __bis_SR_register(LPM3_bits+GIE); // Wait for WDT interrupt
  1983. }
  1984. else
  1985. {
  1986. __bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
  1987. }
  1988. TA1CCTL1 ^= CCIS0; // Create SW capture of CCR1
  1989. counts[i] = TA1CCR1; // Save result
  1990. WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
  1991. CBCTL3 &= ~((group->arrayPtr[i])->inputBits);
  1992. }
  1993. // End Sequence
  1994. //** Context Restore
  1995. // WDTA: IE1, WDCTL
  1996. // TIMERA0: TACTL, TACCTL1
  1997. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  1998. // Ports: CboutDIR, CboutSel
  1999. __bis_SR_register(contextSaveSR);
  2000. if(!(contextSaveSR & GIE))
  2001. {
  2002. __bic_SR_register(GIE); // Wait for WDT interrupt
  2003. }
  2004. SFRIE1 = contextSaveSFRIE1;
  2005. WDTCTL = contextSaveWDTCTL;
  2006. TA1CTL = contextSaveTA1CTL;
  2007. TA1CCTL1 = contextSaveTA1CCTL1;
  2008. TA1CCR1 = contextSaveTA1CCR1;
  2009. CBCTL0 = contextSaveCBCTL0;
  2010. CBCTL1 = contextSaveCBCTL1;
  2011. CBCTL2 = contextSaveCBCTL2;
  2012. CBCTL3 = contextSaveCBCTL3;
  2013. *(group->cboutTAxDirRegister) = contextSaveCboutDir;
  2014. *(group->cboutTAxSelRegister) = contextSaveCboutSel;
  2015. }
  2016. #endif
  2017. #ifdef fRO_COMPB_TA0_SW
  2018. /*!
  2019. * @brief fRO method capactiance measurement using CompB, TimerA0
  2020. *
  2021. * \n Schematic Description of CompB forming relaxation oscillator and
  2022. * coupling (connection) between the relaxation oscillator and
  2023. * TimerA0.
  2024. * \n <- Output
  2025. * \n -> Input
  2026. * \n R Resistor (typically 100Kohms)
  2027. *
  2028. * element---+-R--<-CBOUT/TA1CLK
  2029. * |
  2030. * +---->CBx
  2031. *
  2032. * \n The TAR reister value is the number of SW loops (function of MCLK)
  2033. * within n charge and discharge cycles. This value is directly
  2034. * proportional to the capacitance of the element measured. 'n' is
  2035. * defined by the variable accumulation_cycles.
  2036. *
  2037. * @param group Address of the structure describing the Sensor to be measured
  2038. * @param counts Address to where the measurements are to be written
  2039. * @return none
  2040. */
  2041. void TI_CTS_fRO_COMPB_TA0_SW_HAL(const struct Sensor *group, uint16_t *counts)
  2042. {
  2043. uint8_t i;
  2044. uint16_t j;
  2045. //** Context Save
  2046. // TIMERA0: TA0CTL, TA0CCR1
  2047. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  2048. // Ports: CboutDIR, CboutSel
  2049. uint16_t contextSaveTA0CTL,contextSaveTA0CCR0;
  2050. uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
  2051. uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
  2052. uint8_t contextSaveCboutDir,contextSaveCboutSel;
  2053. contextSaveTA0CTL = TA0CTL;
  2054. contextSaveTA0CCR0 = TA0CCR0;
  2055. contextSaveCBCTL0 = CBCTL0;
  2056. contextSaveCBCTL1 = CBCTL1;
  2057. contextSaveCBCTL2 = CBCTL2;
  2058. contextSaveCBCTL3 = CBCTL3;
  2059. contextSaveCboutDir = *(group->cboutTAxDirRegister);
  2060. contextSaveCboutSel = *(group->cboutTAxSelRegister);
  2061. //** Setup Measurement timer************************************************
  2062. // connect CBOUT with TA0
  2063. *(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
  2064. *(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
  2065. CBCTL2 = CBREF14+CBREF13 + CBREF02;
  2066. // Configure Timer TA0
  2067. TA0CCR0 =(group->accumulationCycles);
  2068. // Turn on Comparator
  2069. CBCTL1 = CBON; // Turn on COMPB w/out filter
  2070. // Vcc to resistor ladder
  2071. CBCTL3 |= (group->cbpdBits); // set CPD bits to disable
  2072. // I/O buffer
  2073. CBCTL2 |= CBRS_1; // Turn on reference
  2074. for (i = 0; i<(group->numElements); i++)
  2075. {
  2076. j=0;
  2077. CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
  2078. //** Setup Gate Timer *************************************************
  2079. // Set duration of sensor measurment
  2080. TA0CTL = TASSEL_0+TACLR+MC_1; // TACLK
  2081. TA0CTL &= ~TAIFG; // TACLK
  2082. while(!(TA0CTL & TAIFG))
  2083. {
  2084. j++;
  2085. } // end accumulation
  2086. counts[i] = j;
  2087. }
  2088. // End Sequence
  2089. //** Context Restore
  2090. // TIMERA0: TACTL, TACCTL1
  2091. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  2092. // Ports: CboutDIR, CboutSel
  2093. TA0CTL = contextSaveTA0CTL;
  2094. TA0CCR0 = contextSaveTA0CCR0;
  2095. CBCTL0 = contextSaveCBCTL0;
  2096. CBCTL1 = contextSaveCBCTL1;
  2097. CBCTL2 = contextSaveCBCTL2;
  2098. CBCTL3 = contextSaveCBCTL3;
  2099. *(group->cboutTAxDirRegister) = contextSaveCboutDir;
  2100. *(group->cboutTAxSelRegister) = contextSaveCboutSel;
  2101. }
  2102. #endif
  2103. #ifdef fRO_COMPB_TA1_SW
  2104. /*!
  2105. * @brief fRO method capactiance measurement using CompB, TimerA1
  2106. *
  2107. * \n Schematic Description of CompB forming relaxation oscillator and
  2108. * coupling (connection) between the relaxation oscillator and
  2109. * TimerA1.
  2110. * \n <- Output
  2111. * \n -> Input
  2112. * \n R Resistor (typically 100Kohms)
  2113. *
  2114. * element---+-R--<-CBOUT/TA1CLK
  2115. * |
  2116. * +---->CBx
  2117. *
  2118. * \n The TAR reister value is the number of SW loops (function of MCLK)
  2119. * within n charge and discharge cycles. This value is directly
  2120. * proportional to the capacitance of the element measured. 'n' is
  2121. * defined by the variable accumulation_cycles.
  2122. *
  2123. * @param group Address of the structure describing the Sensor to be measured
  2124. * @param counts Address to where the measurements are to be written
  2125. * @return none
  2126. */
  2127. void TI_CTS_fRO_COMPB_TA1_SW_HAL(const struct Sensor *group,uint16_t *counts)
  2128. {
  2129. uint8_t i;
  2130. uint16_t j;
  2131. //** Context Save
  2132. // TIMERA0: TA1CTL, TA1CCTL1
  2133. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  2134. // Ports: CboutDIR, CboutSel
  2135. uint16_t contextSaveTA1CTL,contextSaveTA1CCR0;
  2136. uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
  2137. uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
  2138. uint8_t contextSaveCboutDir,contextSaveCboutSel;
  2139. contextSaveTA1CTL = TA1CTL;
  2140. contextSaveTA1CCR0 = TA1CCR0;
  2141. contextSaveCBCTL0 = CBCTL0;
  2142. contextSaveCBCTL1 = CBCTL1;
  2143. contextSaveCBCTL2 = CBCTL2;
  2144. contextSaveCBCTL3 = CBCTL3;
  2145. contextSaveCboutDir = *(group->cboutTAxDirRegister);
  2146. contextSaveCboutSel = *(group->cboutTAxSelRegister);
  2147. //** Setup Measurement timer************************************************
  2148. // connect CBOUT with TA1
  2149. *(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
  2150. *(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
  2151. CBCTL2 = CBREF14+CBREF13 + CBREF02;
  2152. // Configure Timer TA1
  2153. TA1CCR0 =(group->accumulationCycles);
  2154. // Turn on Comparator
  2155. CBCTL1 = CBON; // Turn on COMPB w/out filter
  2156. // Vcc to resistor ladder
  2157. CBCTL3 |= (group->cbpdBits); // set CPD bits to disable
  2158. // I/O buffer
  2159. CBCTL2 |= CBRS_1; // Turn on reference
  2160. for (i = 0; i<(group->numElements); i++)
  2161. {
  2162. j=0;
  2163. CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
  2164. //** Setup Gate Timer *************************************************
  2165. // Set duration of sensor measurment
  2166. TA1CTL = TASSEL_0+TACLR+MC_1; // TA1CLK, reset, up mode
  2167. TA1CTL &= ~TAIFG; // clear ifg
  2168. while(!(TA1CTL & TAIFG))
  2169. {
  2170. j++;
  2171. } // end accumulation
  2172. counts[i] = j;
  2173. //P1SEL &=~BIT4;
  2174. }
  2175. // End Sequence
  2176. //** Context Restore
  2177. // TIMERA0: TACTL, TACCTL1
  2178. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  2179. // Ports: CboutDIR, CboutSel
  2180. TA1CTL = contextSaveTA1CTL;
  2181. TA1CCR0 = contextSaveTA1CCR0;
  2182. CBCTL0 = contextSaveCBCTL0;
  2183. CBCTL1 = contextSaveCBCTL1;
  2184. CBCTL2 = contextSaveCBCTL2;
  2185. CBCTL3 = contextSaveCBCTL3;
  2186. *(group->cboutTAxDirRegister) = contextSaveCboutDir;
  2187. *(group->cboutTAxSelRegister) = contextSaveCboutSel;
  2188. }
  2189. #endif
  2190. #ifdef RO_COMPB_TA1_TA0
  2191. /*!
  2192. * ======== TI_CTS_RO_COMPB_TA1_TA0_HAL =======
  2193. * @brief RO method capacitance measurement using CompB, TimerA1, and TimerA0
  2194. *
  2195. * \n Schematic Description of CompB forming relaxation oscillator and
  2196. * \n coupling (connection) between the relaxation oscillator and TimerA1.
  2197. * \n <- Output
  2198. * \n -> Input
  2199. * \n R Resistor (typically 100Kohms)
  2200. *
  2201. * element--+--R--<-CBOUT/TA1CLK
  2202. * |
  2203. * +----->-CBx
  2204. *
  2205. * \n The TimerA0 interval represents the measurement window. The number
  2206. * of counts within TA1R that have accumulated during the
  2207. * measurement window represents the capacitance of the element.
  2208. *
  2209. * @param group pointer to the sensor to be measured
  2210. * @param counts pointer to where the measurements are to be written
  2211. * @return none
  2212. */
  2213. void TI_CTS_RO_COMPB_TA1_TA0_HAL(const struct Sensor *group, uint16_t *counts)
  2214. {
  2215. uint8_t i=0;
  2216. /*!
  2217. * Allocate Context Save Variables
  2218. * Status Register: GIE bit only
  2219. * TIMERA0: TA0CTL, TA0CCTL0, TA0CCR0
  2220. * TIMERA1: TA1CTL, TA1CCTL0, TA1CCR0
  2221. * COMPB: CBCTL0,CBCTL1,CBCTL2,CBCTL3
  2222. */
  2223. uint8_t contextSaveSR;
  2224. uint16_t contextSaveTA0CTL,contextSaveTA0CCTL0,contextSaveTA0CCR0;
  2225. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
  2226. uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
  2227. uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
  2228. uint8_t contextSaveCboutDir,contextSaveCboutSel;
  2229. /*
  2230. * Perform context save of registers used.
  2231. */
  2232. contextSaveSR = __get_SR_register();
  2233. contextSaveTA0CTL = TA0CTL;
  2234. contextSaveTA0CCTL0 = TA0CCTL0;
  2235. contextSaveTA0CCR0 = TA0CCR0;
  2236. contextSaveTA1CTL = TA1CTL;
  2237. contextSaveTA1CCTL0 = TA1CCTL0;
  2238. contextSaveTA1CCR0 = TA1CCR0;
  2239. contextSaveCBCTL0 = CBCTL0;
  2240. contextSaveCBCTL1 = CBCTL1;
  2241. contextSaveCBCTL2 = CBCTL2;
  2242. contextSaveCBCTL3 = CBCTL3;
  2243. contextSaveCboutDir = *(group->cboutTAxDirRegister);
  2244. contextSaveCboutSel = *(group->cboutTAxSelRegister);
  2245. /*
  2246. * Connect CBOUT with TA1. This also enables the feedback path for the
  2247. * Relaxation oscillator.
  2248. */
  2249. *(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
  2250. *(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
  2251. /*
  2252. * The COMPB reference is set to Vcc and the reference resistor taps are
  2253. * Vcc*(0x18+1)/32 for CBOUT = 1 and Vcc*((0x04+1)/32 for CBOUT = 0.
  2254. * If Vcc is 3.0V, then the Vih is 2.34V and the Vil is 0.47V. In the
  2255. * event that CBOUT is connected to DVIO which is not equal to Vcc, then
  2256. * these voltage levels need to be adjusted.
  2257. */
  2258. CBCTL2 = CBRS_1 + CBREF14 + CBREF13 + CBREF02;
  2259. CBCTL3 |= (group->cbpdBits); // set CPD bits to disable digital IO
  2260. /*
  2261. * TimerA1 is the measurement timer and counts the number of relaxation
  2262. * oscillation cycles of the element which is connected to TACLK.
  2263. * TimerA1 is in continuous mode. TA1CCR0 is configured as a capture
  2264. * register and will be triggered as a SW capture event.
  2265. */
  2266. TA1CTL = TASSEL_0+MC_2;
  2267. TA1CCTL0 = CM_3+CCIS_2+CAP;
  2268. /*
  2269. * TimerA0 is the gate (measurement interval) timer. The number of
  2270. * oscillations counted, by TimerA1, within the gate interval represents
  2271. * the measured capacitance.
  2272. */
  2273. TA0CCR0 = group->accumulationCycles;
  2274. TA0CTL = group->measGateSource + group->sourceScale;
  2275. TA0CCTL0 = CCIE;
  2276. CBCTL1 = CBON; // Turn on COMPB w/out filter
  2277. for (i = 0; i<(group->numElements); i++)
  2278. {
  2279. /* Turn on specific comparator input. */
  2280. CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
  2281. TA1CTL |= TACLR; // Clear TimerA1, measurement timer
  2282. TA1CTL &= ~TAIFG; // Clear overflow flag
  2283. TA0CTL |= (TACLR + MC_1); // Clear and start TimerA0
  2284. /*
  2285. * The measGateSource represents the gate source for timer TIMERA0,
  2286. * which can be sourced from TACLK, ACLK, SMCLK, or INCLK. The
  2287. * interrupt handler is defined in TIMER0_A0_VECTOR, which simply
  2288. * clears the low power mode bits in the Status Register before
  2289. * returning from the ISR.
  2290. */
  2291. if(group->measGateSource == TIMER_ACLK)
  2292. {
  2293. __bis_SR_register(LPM3_bits+GIE); // Enable GIE and wait for ISR
  2294. }
  2295. else
  2296. {
  2297. __bis_SR_register(LPM0_bits+GIE);
  2298. }
  2299. TA1CCTL0 ^= CCIS0; // Create SW capture of TA1R into TA1CCR0.
  2300. TA0CTL &= ~MC_1; // Halt Timer
  2301. if(TA1CTL & TAIFG)
  2302. {
  2303. /*
  2304. * If a rollover in the timer has occurred then set counts to
  2305. * 0. This will prevent erroneous data from entering the baseline
  2306. * tracking algorithm.
  2307. */
  2308. counts[i] = 0;
  2309. }
  2310. else
  2311. {
  2312. counts[i] = TA1CCR0; // Save result
  2313. }
  2314. } // End For Loop
  2315. /*
  2316. * Context restore GIE within Status Register and registers used.
  2317. */
  2318. __bis_SR_register(contextSaveSR);
  2319. if(!(contextSaveSR & GIE))
  2320. {
  2321. __bic_SR_register(GIE);
  2322. }
  2323. TA0CTL = contextSaveTA0CTL;
  2324. TA0CCTL0 = contextSaveTA0CCTL0;
  2325. TA0CCR0 = contextSaveTA0CCR0;
  2326. TA1CTL = contextSaveTA1CTL;
  2327. TA1CCTL0 = contextSaveTA1CCTL0;
  2328. TA1CCR0 = contextSaveTA1CCR0;
  2329. CBCTL0 = contextSaveCBCTL0;
  2330. CBCTL1 = contextSaveCBCTL1;
  2331. CBCTL2 = contextSaveCBCTL2;
  2332. CBCTL3 = contextSaveCBCTL3;
  2333. *(group->cboutTAxDirRegister) = contextSaveCboutDir;
  2334. *(group->cboutTAxSelRegister) = contextSaveCboutSel;
  2335. }
  2336. #endif
  2337. #ifdef fRO_COMPB_TA1_TA0
  2338. /*!
  2339. * ======== TI_CTS_fRO_COMPB_TA1_TA0_HAL() ========
  2340. * @brief fRO method capacitance measurement using CompB, TimerA1, and TimerA0
  2341. *
  2342. * /n Schematic Description of CompB forming relaxation oscillator and
  2343. * coupling (connection) between the relaxation oscillator and TimerA1.
  2344. * /n <- Output
  2345. * /n -> Input
  2346. * /n R Resistor (typically 100Kohms)
  2347. *
  2348. * element--+--R--<-CBOUT/TA1CLK
  2349. * |
  2350. * +----->-CBx
  2351. *
  2352. * /n The TimerA1 interval represents the measurement window. The number
  2353. * of counts within TA0R that have accumulated during the
  2354. * measurement window represents the capacitance of the element.
  2355. *
  2356. * @param (group) pointer to the sensor to be measured
  2357. * @param (counts) pointer to where the measurements are to be written
  2358. * @return none
  2359. */
  2360. void TI_CTS_fRO_COMPB_TA1_TA0_HAL(const struct Sensor *group,uint16_t *counts)
  2361. {
  2362. uint8_t i=0;
  2363. /*!
  2364. * Allocate Context Save Variables
  2365. * Status Register: GIE bit only
  2366. * TIMERA0: TA0CTL, TA0CCTL0, TA0CCR0
  2367. * TIMERA1: TA1CTL, TA1CCTL0, TA1CCR0
  2368. * COMPB: CBCTL0,CBCTL1,CBCTL2,CBCTL3
  2369. */
  2370. uint8_t contextSaveSR;
  2371. uint16_t contextSaveTA0CTL,contextSaveTA0CCTL0,contextSaveTA0CCR0;
  2372. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
  2373. uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
  2374. uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
  2375. uint8_t contextSaveCboutDir,contextSaveCboutSel;
  2376. /*
  2377. * Perform context save of registers used.
  2378. */
  2379. contextSaveSR = __get_SR_register();
  2380. contextSaveTA0CTL = TA0CTL;
  2381. contextSaveTA0CCTL0 = TA0CCTL0;
  2382. contextSaveTA0CCR0 = TA0CCR0;
  2383. contextSaveTA1CTL = TA1CTL;
  2384. contextSaveTA1CCTL0 = TA1CCTL0;
  2385. contextSaveTA1CCR0 = TA1CCR0;
  2386. contextSaveCBCTL0 = CBCTL0;
  2387. contextSaveCBCTL1 = CBCTL1;
  2388. contextSaveCBCTL2 = CBCTL2;
  2389. contextSaveCBCTL3 = CBCTL3;
  2390. contextSaveCboutDir = *(group->cboutTAxDirRegister);
  2391. contextSaveCboutSel = *(group->cboutTAxSelRegister);
  2392. /*
  2393. * Connect CBOUT with TA1. This also enables the feedback path for the
  2394. * Relaxation oscillator.
  2395. */
  2396. *(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
  2397. *(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
  2398. /*
  2399. * The COMPB reference is set to Vcc and the reference resistor taps are
  2400. * Vcc*(0x18+1)/32 for CBOUT = 1 and Vcc*((0x04+1)/32 for CBOUT = 0.
  2401. * If Vcc is 3.0V, then the Vih is 2.34V and the Vil is 0.47V. In the
  2402. * event that CBOUT is connected to DVIO which is not equal to Vcc, then
  2403. * these voltage levels need to be adjusted.
  2404. */
  2405. CBCTL2 = CBRS_1 + CBREF14 + CBREF13 + CBREF02;
  2406. CBCTL3 |= (group->cbpdBits); // set CPD bits to disable digital IO
  2407. /*
  2408. * TimerA0 is the measurement timer and counts the number of clock cycles
  2409. * ;typically SMCLK, but can also be TACLK, INCLK, or ACLK.
  2410. * TimerA0 is in continuous mode. TA0CCR0 is configured as a capture
  2411. * register and will be triggered as a SW capture event.
  2412. */
  2413. TA0CTL = group->measGateSource + MC_2;
  2414. TA0CCTL0 = CM_3+CCIS_2+CAP;
  2415. /*
  2416. * TimerA1 is the gate (measurement interval) timer. With the fRO method
  2417. * the gate time varies with the capacitance of the element. The number of
  2418. * clock cycles counted, by TimerA0, within the gate interval represents
  2419. * the measured capacitance.
  2420. */
  2421. TA1CCR0 = group->accumulationCycles;
  2422. TA1CTL = group->sourceScale;
  2423. TA1CCTL0 = CCIE;
  2424. CBCTL1 = CBON; // Turn on COMPB w/out filter
  2425. for (i = 0; i<(group->numElements); i++)
  2426. {
  2427. /*
  2428. * Turn on specific comparator input.
  2429. */
  2430. CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
  2431. TA0CTL |= TACLR; // Clear TimerA1, measurement timer
  2432. TA0CTL &= ~TAIFG; // Clear overflow flag
  2433. TA1CTL |= (TACLR + MC_1); // Clear and start TimerA0
  2434. /*
  2435. * The measGateSource represents the measurement source for timer
  2436. * TimerA0, which can be sourced from TACLK, ACLK, SMCLK, or INCLK. The
  2437. * interrupt handler is defined in TIMER1_A0_VECTOR, which simply
  2438. * clears the low power mode bits in the Status Register before
  2439. * returning from the ISR.
  2440. */
  2441. if(group->measGateSource == TIMER_ACLK)
  2442. {
  2443. __bis_SR_register(LPM3_bits+GIE); // Enable GIE and wait for ISR
  2444. }
  2445. else
  2446. {
  2447. __bis_SR_register(LPM0_bits+GIE);
  2448. }
  2449. TA0CCTL0 ^= CCIS0; // Create SW capture of TA1R into TA1CCR0.
  2450. TA1CTL &= ~MC_1; // Halt Timer
  2451. if(TA0CTL & TAIFG)
  2452. {
  2453. /*
  2454. * If a rollover in the timer has occurred then set counts to
  2455. * 0. This will prevent erroneous data from entering the baseline
  2456. * tracking algorithm.
  2457. */
  2458. counts[i] = 0;
  2459. }
  2460. else
  2461. {
  2462. counts[i] = TA0CCR0; // Save result
  2463. }
  2464. } // End For Loop
  2465. /*
  2466. * Context restore GIE within Status Register and registers used.
  2467. */
  2468. __bis_SR_register(contextSaveSR);
  2469. if(!(contextSaveSR & GIE))
  2470. {
  2471. __bic_SR_register(GIE);
  2472. }
  2473. TA0CTL = contextSaveTA0CTL;
  2474. TA0CCTL0 = contextSaveTA0CCTL0;
  2475. TA0CCR0 = contextSaveTA0CCR0;
  2476. TA1CTL = contextSaveTA1CTL;
  2477. TA1CCTL0 = contextSaveTA1CCTL0;
  2478. TA1CCR0 = contextSaveTA1CCR0;
  2479. CBCTL0 = contextSaveCBCTL0;
  2480. CBCTL1 = contextSaveCBCTL1;
  2481. CBCTL2 = contextSaveCBCTL2;
  2482. CBCTL3 = contextSaveCBCTL3;
  2483. *(group->cboutTAxDirRegister) = contextSaveCboutDir;
  2484. *(group->cboutTAxSelRegister) = contextSaveCboutSel;
  2485. }
  2486. #endif
  2487. #ifdef RO_PINOSC_TA1_WDTp
  2488. /*!
  2489. * @brief RO method capactiance measurement with PinOsc IO, TimerA1, and WDT+
  2490. *
  2491. * \n Schematic Description:
  2492. *
  2493. * \n element-----+->Px.y
  2494. *
  2495. * \n The WDT+ interval represents the measurement window. The number of
  2496. * counts within the TA0R that have accumulated during the measurement
  2497. * window represents the capacitance of the element.
  2498. *
  2499. * @param group Pointer to the structure describing the Sensor to be measured
  2500. * @param counts Pointer to where the measurements are to be written
  2501. * @return none
  2502. */
  2503. void TI_CTS_RO_PINOSC_TA1_WDTp_HAL(const struct Sensor *group,uint16_t *counts)
  2504. {
  2505. uint8_t i;
  2506. //** Context Save
  2507. // Status Register:
  2508. // WDTp: IE1, WDTCTL
  2509. // TIMERA1: TA1CTL, TA1CCTL1
  2510. // Ports: PxSEL, PxSEL2
  2511. uint8_t contextSaveSR;
  2512. uint8_t contextSaveIE1;
  2513. uint16_t contextSaveWDTCTL;
  2514. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL1,contextSaveTA1CCR1;
  2515. uint8_t contextSaveSel,contextSaveSel2;
  2516. contextSaveSR = __get_SR_register();
  2517. contextSaveIE1 = IE1;
  2518. contextSaveWDTCTL = WDTCTL;
  2519. contextSaveWDTCTL &= 0x00FF;
  2520. contextSaveWDTCTL |= WDTPW;
  2521. contextSaveTA1CTL = TA1CTL;
  2522. contextSaveTA1CCTL1 = TA1CCTL1;
  2523. contextSaveTA1CCR1 = TA1CCR1;
  2524. //** Setup Measurement timer***************************************************
  2525. // Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
  2526. // capacitive touch layer.
  2527. // Configure and Start Timer
  2528. TA1CTL = TASSEL_3+MC_2; // INCLK, cont mode
  2529. TA1CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  2530. IE1 |= WDTIE; // enable WDT interrupt
  2531. for (i = 0; i<(group->numElements); i++)
  2532. {
  2533. // Context Save
  2534. contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
  2535. contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
  2536. // Configure Ports for relaxation oscillator
  2537. *((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
  2538. *((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
  2539. //** Setup Gate Timer ********************************************************
  2540. // Set duration of sensor measurment
  2541. //WDTCTL = (WDTPW+WDTTMSEL+group->measGateSource+group->accumulationCycles);
  2542. WDTCTL = (WDTPW+WDTTMSEL+(group->measGateSource)+(group->accumulationCycles));
  2543. TA1CTL |= TACLR; // Clear Timer_A TAR
  2544. if(group->measGateSource == GATE_WDT_ACLK)
  2545. {
  2546. __bis_SR_register(LPM3_bits+GIE); // Wait for WDT interrupt
  2547. }
  2548. else
  2549. {
  2550. __bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
  2551. }
  2552. TA1CCTL1 ^= CCIS0; // Create SW capture of CCR1
  2553. counts[i] = TA1CCR1; // Save result
  2554. WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
  2555. // Context Restore
  2556. *((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
  2557. *((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
  2558. }
  2559. // End Sequence
  2560. // Context Restore
  2561. __bis_SR_register(contextSaveSR);
  2562. if(!(contextSaveSR & GIE))
  2563. {
  2564. __bic_SR_register(GIE); //
  2565. }
  2566. IE1 = contextSaveIE1;
  2567. WDTCTL = contextSaveWDTCTL;
  2568. TA1CTL = contextSaveTA1CTL;
  2569. TA1CCTL1 = contextSaveTA1CCTL1;
  2570. TA1CCR1 = contextSaveTA1CCR1;
  2571. }
  2572. #endif
  2573. #ifdef RO_PINOSC_TA1_TB0
  2574. /*!
  2575. * ======== TI_CTS_RO_PINOSC_TA1_TB0_HAL ========
  2576. * @brief RO method capacitance measurement using PinOsc IO, TimerA1, and
  2577. * TimerB0
  2578. *
  2579. * \n Schematic Description:
  2580. *
  2581. * \n element-----+->Px.y
  2582. *
  2583. * \n The TimerA1 interval represents the gate (measurement) time. The
  2584. * number of oscillations that have accumulated in TA1R during the
  2585. * measurement time represents the capacitance of the element.
  2586. *
  2587. * @param group pointer to the sensor to be measured
  2588. * @param counts pointer to where the measurements are to be written
  2589. * @return none
  2590. */
  2591. void TI_CTS_RO_PINOSC_TA1_TB0_HAL(const struct Sensor *group,uint16_t *counts)
  2592. {
  2593. uint8_t i;
  2594. /*!
  2595. * Allocate Context Save Variables
  2596. * Status Register: GIE bit only
  2597. * TIMERA0: TA1CTL, TA1CCTL0, TA1CCR0
  2598. * TIMERB1: TB0CTL, TB0CCTL0, TB0CCR0
  2599. * Ports: PxSEL, PxSEL2
  2600. */
  2601. uint8_t contextSaveSR;
  2602. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
  2603. uint16_t contextSaveTB0CTL,contextSaveTB0CCTL0,contextSaveTB0CCR0;
  2604. uint8_t contextSaveSel,contextSaveSel2;
  2605. /*
  2606. * Perform context save of registers used except port registers which are
  2607. * saved and restored within the for loop as each element within the
  2608. * sensor is measured.
  2609. */
  2610. contextSaveSR = __get_SR_register();
  2611. contextSaveTA1CTL = TA1CTL;
  2612. contextSaveTA1CCTL0 = TA1CCTL0;
  2613. contextSaveTA1CCR0 = TA1CCR0;
  2614. contextSaveTB0CTL = TB0CTL;
  2615. contextSaveTB0CCTL0 = TB0CCTL0;
  2616. contextSaveTB0CCR0 = TB0CCR0;
  2617. /*
  2618. * TimerA0 is the measurement timer and counts the number of relaxation
  2619. * oscillation cycles of the electrode which is routed to INCLK. TA1 is
  2620. * in continuous mode and sourced from INCLK.
  2621. */
  2622. TA1CTL = TASSEL_3+MC_2;
  2623. TA1CCTL0 = CM_3+CCIS_2+CAP; // Setup for SW capture
  2624. /*
  2625. * TimerA1 is the gate (measurement interval) timer. The number of
  2626. * oscillations counted within the gate interval represents the measured
  2627. * capacitance.
  2628. */
  2629. TB0CCR0 = (group->accumulationCycles);
  2630. // Establish source and scale of timerA1, but halt the timer.
  2631. TB0CTL = group->measGateSource + group->sourceScale;
  2632. TB0CCTL0 = CCIE; // Enable Interrupt when timer counts to TB0CCR0.
  2633. for (i = 0; i<(group->numElements); i++)
  2634. {
  2635. // Context Save Port Registers
  2636. contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
  2637. contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
  2638. // Configure Ports for relaxation oscillator
  2639. *((group->arrayPtr[i])->inputPxselRegister)
  2640. &= ~((group->arrayPtr[i])->inputBits);
  2641. *((group->arrayPtr[i])->inputPxsel2Register)
  2642. |= ((group->arrayPtr[i])->inputBits);
  2643. TA1CTL |= TACLR;
  2644. TA1CTL &= ~TAIFG;
  2645. TB0CTL |= (TACLR + MC_1);
  2646. /*!
  2647. * The measGateSource represents the gate source for timer TIMERA1,
  2648. * which can be sourced from TACLK, ACLK, SMCLK, or INCLK. The
  2649. * interrupt handler is defined in TIMER1_A0_VECTOR, which simply
  2650. * clears the low power mode bits in the Status Register before
  2651. * returning from the ISR.
  2652. */
  2653. if(group->measGateSource == TIMER_ACLK)
  2654. {
  2655. __bis_SR_register(LPM3_bits+GIE); // Enable GIE and wait for ISR
  2656. }
  2657. else
  2658. {
  2659. __bis_SR_register(LPM0_bits+GIE); // Enable GIE and wait for ISR
  2660. }
  2661. TA1CCTL0 ^= CCIS0; // Create SW capture of TA1CCR into TA1CCR0.
  2662. TB0CTL &= ~MC_1; // Halt Timer
  2663. if(TA1CTL & TAIFG)
  2664. {
  2665. /*
  2666. * If a rollover in the timer has occurred then set counts to
  2667. * 0. This will prevent erroneous data from entering the baseline
  2668. * tracking algorithm.
  2669. */
  2670. counts[i] = 0;
  2671. }
  2672. else
  2673. {
  2674. counts[i] = TA1CCR0; // Save result
  2675. }
  2676. // Context Restore Port Registers
  2677. *((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
  2678. *((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
  2679. } // End for Loop
  2680. /*
  2681. * Context restore GIE within Status Register and all timer registers
  2682. * used.
  2683. */
  2684. if(!(contextSaveSR & GIE))
  2685. {
  2686. __bic_SR_register(GIE);
  2687. }
  2688. TA1CTL = contextSaveTA1CTL;
  2689. TA1CCTL0 = contextSaveTA1CCTL0;
  2690. TA1CCR0 = contextSaveTA1CCR0;
  2691. TB0CTL = contextSaveTB0CTL;
  2692. TB0CCTL0 = contextSaveTB0CCTL0;
  2693. TB0CCR0 = contextSaveTB0CCR0;
  2694. }
  2695. #endif
  2696. #ifdef fRO_PINOSC_TA1_TA0
  2697. /*!
  2698. * @brief fRO method capacitance measurement using PinOsc IO, TimerA1, and
  2699. * TimerA0
  2700. *
  2701. * \n Schematic Description:
  2702. *
  2703. * \n element-----+->Px.y
  2704. *
  2705. *
  2706. * @param group Pointer to the structure describing the Sensor to be measured
  2707. * @param counts Pointer to where the measurements are to be written
  2708. * @return none
  2709. */
  2710. void TI_CTS_fRO_PINOSC_TA1_TA0_HAL(const struct Sensor *group,uint16_t *counts)
  2711. {
  2712. uint8_t i;
  2713. /*
  2714. * Context Save
  2715. * Status Register: GIE
  2716. * TIMERA1: TA1CTL, TA1CCTL0, TA1CCR0
  2717. * TIMERA0: TA0CTL, TA0CCTL0, TA0CCR0
  2718. * Ports: PxSEL, PxSEL2
  2719. */
  2720. uint8_t contextSaveSR;
  2721. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
  2722. uint16_t contextSaveTA0CTL,contextSaveTA0CCTL0,contextSaveTA0CCR0;
  2723. uint8_t contextSaveSel,contextSaveSel2;
  2724. contextSaveSR = __get_SR_register();
  2725. contextSaveTA1CTL = TA1CTL;
  2726. contextSaveTA1CCTL0 = TA1CCTL0;
  2727. contextSaveTA1CCR0 = TA1CCR0;
  2728. contextSaveTA0CTL = TA0CTL;
  2729. contextSaveTA0CCTL0 = TA0CCTL0;
  2730. contextSaveTA0CCR0 = TA0CCR0;
  2731. //** Setup Measurement timer***************************************************
  2732. // Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
  2733. // capacitive touch layer.
  2734. // Configure Measurement interval with TimerA1
  2735. TA1CCR0 = (group->accumulationCycles);
  2736. /*
  2737. * INCLK, IDx settings from sourceScale definition
  2738. */
  2739. TA1CTL = TASSEL_3 + group->sourceScale;
  2740. TA1CCTL0 = CCIE;
  2741. // Configure and start measurment timerA0
  2742. TA0CTL = group->measGateSource + MC_2 + TACLR; // cont
  2743. TA0CCTL0 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  2744. for (i = 0; i<(group->numElements); i++)
  2745. {
  2746. // Context Save
  2747. contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
  2748. contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
  2749. // Configure Ports for relaxation oscillator
  2750. *((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
  2751. *((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
  2752. TA0CTL |= TACLR;
  2753. TA0CTL &= ~TAIFG;
  2754. TA1CTL |= (TACLR + MC_1); // Clear Timer, Up mode
  2755. /*
  2756. * In this configuration measGateSource represents the measurement
  2757. * source for timer TIMERA1, which can be sourced from TACLK, ACLK,
  2758. * SMCLK, or INCLK.
  2759. */
  2760. if(group->measGateSource == TIMER_ACLK)
  2761. {
  2762. __bis_SR_register(LPM3_bits+GIE);
  2763. }
  2764. else
  2765. {
  2766. __bis_SR_register(LPM0_bits+GIE);
  2767. }
  2768. TA0CCTL0 ^= CCIS0; // Create SW capture of CCR1
  2769. TA1CTL &= ~MC_1; // Halt Timer
  2770. if(TA0CTL & TAIFG)
  2771. {
  2772. /*
  2773. * If a rollover in the timer has occurred then set counts to
  2774. * 0. This will prevent erroneous data from entering the baseline
  2775. * tracking algorithm.
  2776. */
  2777. counts[i] = 0;
  2778. }
  2779. else
  2780. {
  2781. counts[i] = TA0CCR0; // Save result
  2782. }
  2783. // Context Restore
  2784. *((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
  2785. *((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
  2786. } // End for loop
  2787. // Context Restore
  2788. if(!(contextSaveSR & GIE))
  2789. {
  2790. __bic_SR_register(GIE);
  2791. }
  2792. TA1CTL = contextSaveTA1CTL;
  2793. TA1CCTL0 = contextSaveTA1CCTL0;
  2794. TA1CCR0 = contextSaveTA1CCR0;
  2795. TA0CTL = contextSaveTA0CTL;
  2796. TA0CCTL0 = contextSaveTA0CCTL0;
  2797. TA0CCR0 = contextSaveTA0CCR0;
  2798. }
  2799. #endif
  2800. #ifdef fRO_PINOSC_TA1_TB0
  2801. /*!
  2802. * @brief fRO method capacitance measurement using PinOsc IO, TimerA1, and
  2803. * TimerB0
  2804. *
  2805. * \n Schematic Description:
  2806. *
  2807. * \n element-----+->Px.y
  2808. *
  2809. *
  2810. * @param group Pointer to the structure describing the Sensor to be measured
  2811. * @param counts Pointer to where the measurements are to be written
  2812. * @return none
  2813. */
  2814. void TI_CTS_fRO_PINOSC_TA1_TB0_HAL(const struct Sensor *group,uint16_t *counts)
  2815. {
  2816. uint8_t i;
  2817. /*
  2818. * Context Save
  2819. * Status Register: GIE
  2820. * TIMERA1: TA1CTL, TA1CCTL0, TA1CCR0
  2821. * TIMERB0: TB0CTL, TB0CCTL0, TB0CCR0
  2822. * Ports: PxSEL, PxSEL2
  2823. */
  2824. uint8_t contextSaveSR;
  2825. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
  2826. uint16_t contextSaveTB0CTL,contextSaveTB0CCTL0,contextSaveTB0CCR0;
  2827. uint8_t contextSaveSel,contextSaveSel2;
  2828. contextSaveSR = __get_SR_register();
  2829. contextSaveTA1CTL = TA1CTL;
  2830. contextSaveTA1CCTL0 = TA1CCTL0;
  2831. contextSaveTA1CCR0 = TA1CCR0;
  2832. contextSaveTB0CTL = TB0CTL;
  2833. contextSaveTB0CCTL0 = TB0CCTL0;
  2834. contextSaveTB0CCR0 = TB0CCR0;
  2835. //** Setup Measurement timer***************************************************
  2836. // Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
  2837. // capacitive touch layer.
  2838. // Configure Measurement interval with TimerA1
  2839. TA1CCR0 = (group->accumulationCycles);
  2840. /*
  2841. * INCLK, IDx settings from sourceScale definition
  2842. */
  2843. TA1CTL = TASSEL_3 + group->sourceScale;
  2844. TA1CCTL0 = CCIE;
  2845. // Configure and start measurment timerA0
  2846. TB0CTL = group->measGateSource + MC_2 + TBCLR; // cont
  2847. TB0CCTL0 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  2848. for (i = 0; i<(group->numElements); i++)
  2849. {
  2850. // Context Save
  2851. contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
  2852. contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
  2853. // Configure Ports for relaxation oscillator
  2854. *((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
  2855. *((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
  2856. TB0CTL |= TBCLR;
  2857. TB0CTL &= ~TBIFG;
  2858. TA1CTL |= (TACLR + MC_1); // Clear Timer, Up mode
  2859. /*
  2860. * In this configuration measGateSource represents the measurement
  2861. * source for timer TIMERA1, which can be sourced from TACLK, ACLK,
  2862. * SMCLK, or INCLK.
  2863. */
  2864. if(group->measGateSource == TIMER_ACLK)
  2865. {
  2866. __bis_SR_register(LPM3_bits+GIE);
  2867. }
  2868. else
  2869. {
  2870. __bis_SR_register(LPM0_bits+GIE);
  2871. }
  2872. TB0CCTL0 ^= CCIS0; // Create SW capture of CCR1
  2873. TA1CTL &= ~MC_1; // Halt Timer
  2874. if(TB0CTL & TBIFG)
  2875. {
  2876. /*
  2877. * If a rollover in the timer has occurred then set counts to
  2878. * 0. This will prevent erroneous data from entering the baseline
  2879. * tracking algorithm.
  2880. */
  2881. counts[i] = 0;
  2882. }
  2883. else
  2884. {
  2885. counts[i] = TB0CCR0; // Save result
  2886. }
  2887. // Context Restore
  2888. *((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
  2889. *((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
  2890. } // End for loop
  2891. // Context Restore
  2892. if(!(contextSaveSR & GIE))
  2893. {
  2894. __bic_SR_register(GIE);
  2895. }
  2896. TA1CTL = contextSaveTA1CTL;
  2897. TA1CCTL0 = contextSaveTA1CCTL0;
  2898. TA1CCR0 = contextSaveTA1CCR0;
  2899. TB0CTL = contextSaveTB0CTL;
  2900. TB0CCTL0 = contextSaveTB0CCTL0;
  2901. TB0CCR0 = contextSaveTB0CCR0;
  2902. }
  2903. #endif
  2904. /*!
  2905. * @}
  2906. */
  2907. /*!
  2908. * @defgroup ISR_GROUP ISR Definitions
  2909. * @ingroup CTS_HAL
  2910. */
  2911. #ifdef WDT_GATE
  2912. /*!
  2913. * ======== watchdog_timer ========
  2914. * @ingroup ISR_GROUP
  2915. * @brief WDT_ISR
  2916. *
  2917. * This ISR clears the LPM bits found in the Status Register (SR/R2).
  2918. *
  2919. * @param none
  2920. * @return none
  2921. */
  2922. #pragma vector=WDT_VECTOR
  2923. __interrupt void watchdog_timer(void)
  2924. {
  2925. __bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
  2926. }
  2927. #endif
  2928. #ifdef TIMER0A0_GATE
  2929. /*!
  2930. * ======== TIMER0_A0_ISR ========
  2931. * @ingroup ISR_GROUP
  2932. * @brief TIMER0_A0_ISR
  2933. *
  2934. * This ISR clears the LPM bits found in the Status Register (SR/R2).
  2935. *
  2936. * @param none
  2937. * @return none
  2938. */
  2939. #pragma vector=TIMER0_A0_VECTOR
  2940. __interrupt void TIMER0_A0_ISR(void)
  2941. {
  2942. __bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
  2943. }
  2944. #endif
  2945. #ifdef TIMER1A0_GATE
  2946. /*!
  2947. * ======== TIMER1_A0_ISR ========
  2948. * @ingroup ISR_GROUP
  2949. * @brief TIMER1_A0_ISR
  2950. *
  2951. * This ISR clears the LPM bits found in the Status Register (SR/R2).
  2952. *
  2953. * @param none
  2954. * @return none
  2955. */
  2956. #pragma vector=TIMER1_A0_VECTOR
  2957. __interrupt void TIMER1_A0_ISR(void)
  2958. {
  2959. __bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
  2960. }
  2961. #endif
  2962. #ifdef TIMER2A0_GATE
  2963. /*!
  2964. * ======== TIMER2_A0_ISR ========
  2965. * @ingroup ISR_GROUP
  2966. * @brief TIMER2_A0_ISR
  2967. *
  2968. * This ISR clears the LPM bits found in the Status Register (SR/R2).
  2969. *
  2970. * @param none
  2971. * @return none
  2972. */
  2973. #pragma vector=TIMER2_A0_VECTOR
  2974. __interrupt void TIMER2_A0_ISR(void)
  2975. {
  2976. __bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
  2977. }
  2978. #endif
  2979. #ifdef TIMER3A0_GATE
  2980. /*!
  2981. * ======== TIMER3_A0_ISR ========
  2982. * @ingroup ISR_GROUP
  2983. * @brief TIMER3_A0_ISR
  2984. *
  2985. * This ISR clears the LPM bits found in the Status Register (SR/R2).
  2986. *
  2987. * @param none
  2988. * @return none
  2989. */
  2990. #pragma vector=TIMER3_A0_VECTOR
  2991. __interrupt void TIMER3_A0_ISR(void)
  2992. {
  2993. __bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
  2994. }
  2995. #endif
  2996. #ifdef TIMERB0_GATE
  2997. /*!
  2998. * ======== TIMER0_B0_ISR ========
  2999. * @ingroup ISR_GROUP
  3000. * @brief TIMER0_B0_ISR
  3001. *
  3002. * This ISR clears the LPM bits found in the Status Register (SR/R2).
  3003. *
  3004. * @param none
  3005. * @return none
  3006. */
  3007. #pragma vector=TIMERB0_VECTOR
  3008. __interrupt void TIMERB0_ISR(void)
  3009. {
  3010. __bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
  3011. }
  3012. #endif