You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1512 lines
62 KiB

5 years ago
  1. /*******************************************************************************
  2. * CTS_HAL.c - Hardware abstraction of various combinations of modules to
  3. * perform a capacitance measurement.
  4. *
  5. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * Neither the name of Texas Instruments Incorporated nor the names of
  20. * its contributors may be used to endorse or promote products derived
  21. * from this software without specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  24. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  25. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  26. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  27. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  28. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  29. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  30. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  32. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  33. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34. *
  35. ******************************************************************************/
  36. /***************************************************************************//**
  37. * @file CTS_HAL.c
  38. *
  39. * @brief
  40. *
  41. * @par Project:
  42. * MSP430 Capacitive Touch Library
  43. *
  44. * @par Developed using:
  45. * IAR Version : 5.10.6 [Kickstart] (5.10.6.30180)
  46. * CCS Version : 4.2.1.00004, w/support for GCC extensions (--gcc)
  47. *
  48. *
  49. * @version 1.0.0 Initial Release
  50. *
  51. * @par Supported Hardware Configurations:
  52. * - TI_CTS_RO_COMPAp_TA0_WDTp_HAL()
  53. * - TI_CTS_fRO_COMPAp_TA0_SW_HAL()
  54. * - TI_CTS_fRO_COMPAp_SW_TA0_HAL()
  55. * - TI_CTS_RO_COMPAp_TA1_WDTp_HAL()
  56. * - TI_CTS_fRO_COMPAp_TA1_SW_HAL()
  57. * - TI_CTS_RC_PAIR_TA0_HAL()
  58. * - TI_CTS_RO_PINOSC_TA0_WDTp_HAL()
  59. * - TI_CTS_RO_PINOSC_TA0_HAL()
  60. * - TI_CTS_fRO_PINOSC_TA0_SW_HAL()
  61. * - TI_CTS_RO_COMPB_TA0_WDTA_HAL()
  62. * - TI_CTS_RO_COMPB_TA1_WDTA_HAL()
  63. * - TI_CTS_fRO_COMPB_TA0_SW_HAL()
  64. * - TI_CTS_fRO_COMPB_TA1_SW_HAL()
  65. ******************************************************************************/
  66. /***************************************************************************//**
  67. * @addtogroup CTS_HAL
  68. * @{
  69. ******************************************************************************/
  70. #include "CTS_HAL.h"
  71. #ifdef RO_COMPAp_TA0_WDTp
  72. /***************************************************************************//**
  73. * @brief RO method capactiance measurement using CompA+, TimerA0, and WDT+
  74. *
  75. * \n Schematic Description of CompA+ forming relaxation oscillator and
  76. * coupling (connection) between the relaxation oscillator and TimerA0.
  77. * \n <- Output
  78. * \n -> Input
  79. * \n R Resistor (typically 100Kohms)
  80. * \n
  81. * \n +-<-Px.y (reference)
  82. * \n |
  83. * \n R
  84. * \n |
  85. * \n +---+-->COMPA+
  86. * \n | |
  87. * \n R R
  88. * \n | |
  89. * \n GND |
  90. * \n |
  91. * \n +-->TACLK
  92. * \n |
  93. * \n element-+-R--+-<-CAOUT
  94. * \n |
  95. * \n +------->COMPA-
  96. * \n
  97. * \n The WDT+ interval represents the measurement window. The number of
  98. * counts within the TA0R that have accumulated during the measurement
  99. * window represents the capacitance of the element.
  100. *
  101. * @param group Address of the structure describing the Sensor to be measured
  102. * @param counts Address to where the measurements are to be written
  103. * @return none
  104. ******************************************************************************/
  105. void TI_CTS_RO_COMPAp_TA0_WDTp_HAL(const struct Sensor *group, uint16_t *counts)
  106. {
  107. uint8_t i;
  108. //** Context Save
  109. // Status Register:
  110. // WDTp: IE1, WDTCTL
  111. // TIMERA0: TACTL, TACCTL1
  112. // COMPAp: CACTL1, CACTL2, CAPD
  113. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  114. uint8_t contextSaveSR;
  115. uint8_t contextSaveIE1;
  116. uint16_t contextSaveWDTCTL;
  117. uint16_t contextSaveTACTL,contextSaveTACCTL1,contextSaveTACCR1;
  118. uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
  119. uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
  120. uint8_t contextSavetxclkDir,contextSavetxclkSel;
  121. uint8_t contextSaveRefDir,contextSaveRefOutSel;
  122. #ifdef SEL2REGISTER
  123. uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
  124. contextSaveCaoutSel2 = *(group->caoutSel2Register);
  125. contextSaveTxclkSel2 = *(group->txclkSel2Register);
  126. #endif
  127. contextSaveSR = __get_SR_register();
  128. contextSaveIE1 = IE1;
  129. contextSaveWDTCTL = WDTCTL;
  130. contextSaveWDTCTL &= 0x00FF;
  131. contextSaveWDTCTL |= WDTPW;
  132. contextSaveTACTL = TACTL;
  133. contextSaveTACCTL1 = TACCTL1;
  134. contextSaveTACCR1 = TACCR1;
  135. contextSaveCACTL1 = CACTL1;
  136. contextSaveCACTL2 = CACTL2;
  137. contextSaveCAPD = CAPD;
  138. contextSaveCaoutDir = *(group->caoutDirRegister);
  139. contextSaveCaoutSel = *(group->caoutSelRegister);
  140. contextSavetxclkDir = *(group->txclkDirRegister);
  141. contextSavetxclkSel = *(group->txclkSelRegister);
  142. contextSaveRefDir = *(group->refPxdirRegister);
  143. contextSaveRefOutSel = *(group->refPxoutRegister);
  144. TACTL = TASSEL_0+MC_2; // TACLK, cont mode
  145. TACCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  146. *(group->caoutDirRegister) |= group->caoutBits;
  147. *(group->txclkDirRegister) &= ~group->txclkBits;
  148. *(group->caoutSelRegister) |= group->caoutBits;
  149. *(group->txclkSelRegister) |= group->txclkBits;
  150. #ifdef SEL2REGISTER
  151. *(group->caoutSel2Register) |= group->caoutBits;
  152. *(group->txclkSel2Register) |= group->txclkBits;
  153. #endif
  154. *(group->refPxdirRegister) |= group->refBits;
  155. *(group->refPxoutRegister) |= group->refBits;
  156. CACTL1 |= CAON; // Turn on comparator
  157. CAPD |= (group->capdBits);
  158. IE1 |= WDTIE; // enable WDT interrupt
  159. for (i = 0; i<(group->numElements); i++)
  160. {
  161. CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
  162. //** Setup Gate Timer *****************************************************
  163. // Set duration of sensor measurment
  164. WDTCTL = WDTPW+WDTTMSEL+ group->measGateSource + group->accumulationCycles;
  165. TACTL |= TACLR; // Clear Timer_A TAR
  166. __bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
  167. TACCTL1 ^= CCIS0; // Create SW capture of CCR1
  168. counts[i] = TACCR1; // Save result
  169. WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
  170. }
  171. // End Sequence
  172. //** Context Restore
  173. // WDTp: IE1, WDCTL
  174. // TIMERA0: TACTL, TACCTL1
  175. // COMPAp: CACTL1, CACTL2, CAPD
  176. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  177. #ifdef SEL2REGISTER
  178. *(group->caoutSel2Register) = contextSaveCaoutSel2;
  179. *(group->txclkSel2Register) = contextSaveTxclkSel2;
  180. #endif
  181. __bis_SR_register(contextSaveSR);
  182. if(!(contextSaveSR & GIE))
  183. {
  184. __bic_SR_register(GIE); // Wait for WDT interrupt
  185. }
  186. IE1 = contextSaveIE1;
  187. WDTCTL = contextSaveWDTCTL;
  188. TACTL = contextSaveTACTL;
  189. TACCTL1 = contextSaveTACCTL1;
  190. TACCR1 = contextSaveTACCR1;
  191. CACTL1 = contextSaveCACTL1;
  192. CACTL2 = contextSaveCACTL2;
  193. CAPD = contextSaveCAPD;
  194. *(group->caoutDirRegister) = contextSaveCaoutDir;
  195. *(group->caoutSelRegister) = contextSaveCaoutSel;
  196. *(group->txclkDirRegister) = contextSavetxclkDir;
  197. *(group->txclkSelRegister) = contextSavetxclkSel;
  198. *(group->refPxdirRegister) = contextSaveRefDir;
  199. *(group->refPxoutRegister) = contextSaveRefOutSel;
  200. }
  201. #endif
  202. #ifdef fRO_COMPAp_TA0_SW
  203. /***************************************************************************//**
  204. * @brief RO method capactiance measurement using CompA+, TimerA0, and SW loop
  205. *
  206. * \n Schematic Description of CompA+ forming relaxation oscillator.
  207. * \n <- Output
  208. * \n -> Input
  209. * \n R Resistor (typically 100Kohms)
  210. * \n
  211. * \n +-<-Px.y (reference)
  212. * \n |
  213. * \n R
  214. * \n |
  215. * \n +---+-->COMPA+
  216. * \n | |
  217. * \n R R
  218. * \n | |
  219. * \n GND |
  220. * \n |
  221. * \n +-->TACLK
  222. * \n |
  223. * \n element-+-R--+-<-CAOUT
  224. * \n |
  225. * \n +------->COMPA-
  226. * \n
  227. * \n The timer counts to TA0CCR0 representing the measurement window. The
  228. * number of counts within the SW loop that have accumulated during the
  229. * measurement window represents the capacitance of the element.
  230. *
  231. * @param group Address of the structure describing the Sensor to be measured
  232. * @param counts Address to where the measurements are to be written
  233. * @return none
  234. ******************************************************************************/
  235. void TI_CTS_fRO_COMPAp_TA0_SW_HAL(const struct Sensor *group, uint16_t *counts)
  236. {
  237. uint8_t i;
  238. uint16_t j;
  239. //** Context Save
  240. // Status Register:
  241. // TIMERA0: TACTL, TACCTL0
  242. // COMPAp: CACTL1, CACTL2, CAPD
  243. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  244. uint16_t contextSaveTACTL,contextSaveTACCTL0,contextSaveTACCR0;
  245. uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
  246. uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
  247. uint8_t contextSavetxclkDir,contextSavetxclkSel;
  248. uint8_t contextSaveRefDir,contextSaveRefOutSel;
  249. #ifdef SEL2REGISTER
  250. uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
  251. contextSaveCaoutSel2 = *(group->caoutSel2Register);
  252. contextSaveTxclkSel2 = *(group->txclkSel2Register);
  253. #endif
  254. contextSaveTACTL = TACTL;
  255. contextSaveTACCTL0 = TACCTL0;
  256. contextSaveTACCR0 = TACCR0;
  257. contextSaveCACTL1 = CACTL1;
  258. contextSaveCACTL2 = CACTL2;
  259. contextSaveCAPD = CAPD;
  260. contextSaveCaoutDir = *(group->caoutDirRegister);
  261. contextSaveCaoutSel = *(group->caoutSelRegister);
  262. contextSavetxclkDir = *(group->txclkDirRegister);
  263. contextSavetxclkSel = *(group->txclkSelRegister);
  264. contextSaveRefDir = *(group->refPxdirRegister);
  265. contextSaveRefOutSel = *(group->refPxoutRegister);
  266. //** Setup Measurement timer***************************************************
  267. // Configure Timer TA0
  268. TACCR0 =(group->accumulationCycles);
  269. TACCTL0 &= ~CAP;
  270. // setup connections between CAOUT and TA0
  271. *(group->caoutDirRegister) |= group->caoutBits;
  272. *(group->txclkDirRegister) &= ~group->txclkBits;
  273. *(group->caoutSelRegister) |= group->caoutBits;
  274. *(group->txclkSelRegister) |= group->txclkBits;
  275. #ifdef SEL2REGISTER
  276. *(group->caoutSel2Register) |= group->caoutBits;
  277. *(group->txclkSel2Register) |= group->txclkBits;
  278. #endif
  279. // setup reference
  280. *(group->refPxdirRegister) |= group->refBits;
  281. *(group->refPxoutRegister) |= group->refBits;
  282. CACTL1 |= CAON; // Turn on comparator
  283. CAPD |= (group->capdBits);
  284. for (i = 0; i<(group->numElements); i++)
  285. {
  286. j=0;
  287. CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
  288. //** Setup Gate Timer **************
  289. // Set duration of sensor measurment
  290. TACTL = TASSEL_0+TACLR+MC_1; // TACLK
  291. while(!(TACTL & TAIFG))
  292. {
  293. j++;
  294. } // end accumulation
  295. counts[i] = j;
  296. }
  297. // End Sequence
  298. //** Context Restore
  299. // TIMERA0: TACTL, TACCTL1
  300. // COMPAp: CACTL1, CACTL2, CAPD
  301. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  302. #ifdef SEL2REGISTER
  303. *(group->caoutSel2Register) = contextSaveCaoutSel2;
  304. *(group->txclkSel2Register) = contextSaveTxclkSel2;
  305. #endif
  306. TACTL = contextSaveTACTL;
  307. TACCTL0 = contextSaveTACCTL0;
  308. TACCR0 = contextSaveTACCR0;
  309. CACTL1 = contextSaveCACTL1;
  310. CACTL2 = contextSaveCACTL2;
  311. CAPD = contextSaveCAPD;
  312. *(group->caoutDirRegister) = contextSaveCaoutDir;
  313. *(group->caoutSelRegister) = contextSaveCaoutSel;
  314. *(group->txclkDirRegister) = contextSavetxclkDir;
  315. *(group->txclkSelRegister) = contextSavetxclkSel;
  316. *(group->refPxdirRegister) = contextSaveRefDir;
  317. *(group->refPxoutRegister) = contextSaveRefOutSel;
  318. }
  319. #endif
  320. #ifdef fRO_COMPAp_SW_TA0
  321. /***************************************************************************//**
  322. * @brief RO method capactiance measurement using CompA+, TimerA0, and SW loop
  323. *
  324. * \n Schematic Description of CompA+ forming relaxation oscillator.
  325. * \n <- Output
  326. * \n -> Input
  327. * \n R Resistor (typically 100Kohms)
  328. * \n
  329. * \n +-<-Px.y (reference)
  330. * \n |
  331. * \n R
  332. * \n |
  333. * \n +---+-->COMPA+
  334. * \n | |
  335. * \n R R
  336. * \n | |
  337. * \n GND |
  338. * \n |
  339. * \n |
  340. * \n element-+-R--+-<-CAOUT
  341. * \n |
  342. * \n +------->COMPA-
  343. * \n
  344. * \n The SW loop counts to 'n' accumulationCycles, representing the
  345. * \n measurement window. The number of timer counts within TA0R register
  346. * \n represents the capacitance of the element.
  347. *
  348. * @param group Address of the structure describing the Sensor to be measured
  349. * @param counts Address to where the measurements are to be written
  350. * @return none
  351. ******************************************************************************/
  352. void TI_CTS_fRO_COMPAp_SW_TA0_HAL(const struct Sensor *group, uint16_t *counts)
  353. {
  354. uint8_t i;
  355. uint16_t j;
  356. //** Context Save
  357. // Status Register:
  358. // TIMERA0: TACTL, TACCTL0, TACCTL1
  359. // COMPAp: CACTL1, CACTL2, CAPD
  360. // Ports: caoutDIR, caoutSel, caoutSel2, refout, refdir
  361. uint16_t contextSaveTACTL,contextSaveTACCTL0,contextSaveTACCTL1;
  362. uint16_t contextSaveTACCR0,contextSaveTACCR1;
  363. uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
  364. uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
  365. uint8_t contextSaveRefDir,contextSaveRefOutSel;
  366. #ifdef SEL2REGISTER
  367. uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
  368. contextSaveCaoutSel2 = *(group->caoutSel2Register);
  369. #endif
  370. contextSaveTACTL = TACTL;
  371. contextSaveTACCTL0 = TACCTL0;
  372. contextSaveTACCTL1 = TACCTL1;
  373. contextSaveTACCR0 = TACCR0;
  374. contextSaveTACCR1 = TACCR1;
  375. contextSaveCACTL1 = CACTL1;
  376. contextSaveCACTL2 = CACTL2;
  377. contextSaveCAPD = CAPD;
  378. contextSaveCaoutDir = *(group->caoutDirRegister);
  379. contextSaveCaoutSel = *(group->caoutSelRegister);
  380. contextSaveRefDir = *(group->refPxdirRegister);
  381. contextSaveRefOutSel = *(group->refPxoutRegister);
  382. //** Setup Measurement timer***************************************************
  383. // Configure Timer TA0
  384. TACCTL0 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  385. TACCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  386. // setup connections between CAOUT and TA0
  387. *(group->caoutDirRegister) |= group->caoutBits;
  388. *(group->caoutSelRegister) |= group->caoutBits;
  389. #ifdef SEL2REGISTER
  390. *(group->caoutSel2Register) |= group->caoutBits;
  391. #endif
  392. // setup reference
  393. *(group->refPxdirRegister) |= group->refBits;
  394. *(group->refPxoutRegister) |= group->refBits;
  395. CACTL1 |= CAON; // Turn on comparator
  396. CAPD |= (group->capdBits);
  397. for (i = 0; i<(group->numElements); i++)
  398. {
  399. CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
  400. //** Setup Gate Timer **************
  401. // Set duration of sensor measurment
  402. TACTL = group->measureGateSource+group->sourceScale+TACLR+MC_2;
  403. TACCTL0 ^= CCIS0; // Create SW capture of CCR0
  404. for(j = group->accumulationCycles; j > 0; j--)
  405. {
  406. CACTL1 &= ~CAIFG;
  407. while(!(CACTL1 & CAIFG));
  408. }
  409. TACCTL1 ^= CCIS0; // Create SW capture of CCR1
  410. counts[i] = TACCR1; // Save result
  411. counts[i] -= TACCR0; // Save result
  412. TACCTL0 &= ~CCIFG;
  413. TACCTL1 &= ~CCIFG;
  414. }
  415. // End Sequence
  416. //** Context Restore
  417. // WDTp: IE1, WDCTL
  418. // TIMERA0: TACTL, TACCTL0, TACCTL1, TACCR0, TACCR1
  419. // COMPAp: CACTL1, CACTL2, CAPD
  420. // Ports: caoutDIR, caoutSel, txclkDIR, caoutSel2, refout, refdir
  421. #ifdef SEL2REGISTER
  422. *(group->caoutSel2Register) = contextSaveCaoutSel2;
  423. #endif
  424. TACTL = contextSaveTACTL;
  425. TACCTL0 = contextSaveTACCTL0;
  426. TACCTL1 = contextSaveTACCTL1;
  427. TACCR0 = contextSaveTACCR0;
  428. TACCR1 = contextSaveTACCR1;
  429. CACTL1 = contextSaveCACTL1;
  430. CACTL2 = contextSaveCACTL2;
  431. CAPD = contextSaveCAPD;
  432. *(group->caoutDirRegister) = contextSaveCaoutDir;
  433. *(group->caoutSelRegister) = contextSaveCaoutSel;
  434. *(group->refPxdirRegister) = contextSaveRefDir;
  435. *(group->refPxoutRegister) = contextSaveRefOutSel;
  436. }
  437. #endif
  438. #ifdef RO_COMPAp_TA1_WDTp
  439. /***************************************************************************//**
  440. * @brief RO method capactiance measurement using CompA+, TimerA1, and WDT+
  441. *
  442. * Schematic Description of CompA+ forming relaxation oscillator and
  443. * coupling (connection) between the relaxation oscillator and TimerA0.
  444. * \n <- Output
  445. * \n -> Input
  446. * \n R Resistor (typically 100Kohms)
  447. * \n
  448. * \n +-<-Px.y (reference)
  449. * \n |
  450. * \n R
  451. * \n |
  452. * \n +---+-->COMPA+
  453. * \n | |
  454. * \n R R
  455. * \n | |
  456. * \n GND |
  457. * \n |
  458. * \n +-->TA1CLK
  459. * \n |
  460. * \n element-+-R--+-<-CAOUT
  461. * \n |
  462. * \n +------->COMPA-
  463. * \n
  464. * The WDT+ interval represents the measurement window. The number of
  465. * counts within the TA0R that have accumulated during the measurement
  466. * window represents the capacitance of the element.
  467. *
  468. * @param group Address of the structure describing the Sensor to be measured
  469. * @param counts Address to where the measurements are to be written
  470. * @return none
  471. ******************************************************************************/
  472. void TI_CTS_RO_COMPAp_TA1_WDTp_HAL(const struct Sensor *group, uint16_t *counts)
  473. {
  474. uint8_t i;
  475. //** Context Save
  476. // Status Register:
  477. // WDTp: IE1, WDTCTL
  478. // TIMERA0: TA1CTL, TA1CCTL1
  479. // COMPAp: CACTL1, CACTL2, CAPD
  480. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  481. uint8_t contextSaveSR;
  482. uint8_t contextSaveIE1;
  483. uint16_t contextSaveWDTCTL;
  484. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL1;
  485. uint16_t contextSaveTA1CCR1;
  486. uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
  487. uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
  488. uint8_t contextSavetxclkDir,contextSavetxclkSel;
  489. uint8_t contextSaveRefDir,contextSaveRefOutSel;
  490. #ifdef SEL2REGISTER
  491. uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
  492. contextSaveCaoutSel2 = *(group->caoutSel2Register);
  493. contextSaveTxclkSel2 = *(group->txclkSel2Register);
  494. #endif
  495. contextSaveSR = __get_SR_register();
  496. contextSaveIE1 = IE1;
  497. contextSaveWDTCTL = WDTCTL;
  498. contextSaveWDTCTL &= 0x00FF;
  499. contextSaveWDTCTL |= WDTPW;
  500. contextSaveTA1CTL = TA1CTL;
  501. contextSaveTA1CCTL1 = TA1CCTL1;
  502. contextSaveTA1CCR1 = TA1CCR1;
  503. contextSaveCACTL1 = CACTL1;
  504. contextSaveCACTL2 = CACTL2;
  505. contextSaveCAPD = CAPD;
  506. contextSaveCaoutDir = *(group->caoutDirRegister);
  507. contextSaveCaoutSel = *(group->caoutSelRegister);
  508. contextSavetxclkDir = *(group->txclkDirRegister);
  509. contextSavetxclkSel = *(group->txclkSelRegister);
  510. contextSaveRefDir = *(group->refPxdirRegister);
  511. contextSaveRefOutSel = *(group->refPxoutRegister);
  512. //** Setup Measurement timer***************************************************
  513. // Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
  514. // capacitive touch layer.
  515. TA1CTL = TASSEL_0+MC_2; // TA1CLK, cont mode
  516. TA1CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  517. *(group->caoutDirRegister) |= group->caoutBits;
  518. *(group->txclkDirRegister) &= ~group->txclkBits;
  519. *(group->caoutSelRegister) |= group->caoutBits;
  520. *(group->txclkSelRegister) |= group->txclkBits;
  521. #ifdef SEL2REGISTER
  522. *(group->caoutSel2Register) |= group->caoutBits;
  523. *(group->txclkSel2Register) |= group->txclkBits;
  524. #endif
  525. *(group->refPxdirRegister) |= group->refBits;
  526. *(group->refPxoutRegister) |= group->refBits;
  527. CACTL1 |= CAON; // Turn on comparator
  528. CAPD |= (group->capdBits);
  529. IE1 |= WDTIE; // enable WDT interrupt
  530. for (i = 0; i<(group->numElements); i++)
  531. {
  532. CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
  533. //** Setup Gate Timer *****************************************************
  534. // Set duration of sensor measurment
  535. WDTCTL = WDTPW+WDTTMSEL+ group->measGateSource + group->accumulationCycles;
  536. TA1CTL |= TACLR; // Clear Timer_A TAR
  537. __bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
  538. TA1CCTL1 ^= CCIS0; // Create SW capture of CCR1
  539. counts[i] = TA1CCR1; // Save result
  540. WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
  541. }
  542. // End Sequence
  543. //** Context Restore
  544. // WDTp: IE1, WDCTL
  545. // TIMERA0: TACTL, TACCTL1
  546. // COMPAp: CACTL1, CACTL2, CAPD
  547. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  548. #ifdef SEL2REGISTER
  549. *(group->caoutSel2Register) = contextSaveCaoutSel2;
  550. *(group->txclkSel2Register) = contextSaveTxclkSel2;
  551. #endif
  552. __bis_SR_register(contextSaveSR);
  553. if(!(contextSaveSR & GIE))
  554. {
  555. __bic_SR_register(GIE); // Wait for WDT interrupt
  556. }
  557. IE1 = contextSaveIE1;
  558. WDTCTL = contextSaveWDTCTL;
  559. TA1CTL = contextSaveTA1CTL;
  560. TA1CCTL1 = contextSaveTA1CCTL1;
  561. TA1CCR1 = contextSaveTA1CCR1;
  562. CACTL1 = contextSaveCACTL1;
  563. CACTL2 = contextSaveCACTL2;
  564. CAPD = contextSaveCAPD;
  565. *(group->caoutDirRegister) = contextSaveCaoutDir;
  566. *(group->caoutSelRegister) = contextSaveCaoutSel;
  567. *(group->txclkDirRegister) = contextSavetxclkDir;
  568. *(group->txclkSelRegister) = contextSavetxclkSel;
  569. *(group->refPxdirRegister) = contextSaveRefDir;
  570. *(group->refPxoutRegister) = contextSaveRefOutSel;
  571. }
  572. #endif
  573. #ifdef fRO_COMPAp_TA1_SW
  574. /***************************************************************************//**
  575. * @brief RO method capactiance measurement using CompA+, TimerA1, and SW loop
  576. *
  577. * Schematic Description of CompA+ forming relaxation oscillator.
  578. * \n <- Output
  579. * \n -> Input
  580. * \n R Resistor (typically 100Kohms)
  581. * \n
  582. * \n +-<-Px.y (reference)
  583. * \n |
  584. * \n R
  585. * \n |
  586. * \n +---+-->COMPA+
  587. * \n | |
  588. * \n R R
  589. * \n | |
  590. * \n GND |
  591. * \n |
  592. * \n +-->TA1CLK
  593. * \n |
  594. * \n element-+-R--+-<-CAOUT
  595. * \n |
  596. * \n +------->COMPA-
  597. * \n
  598. * \n The timer counts to TA1CCR0 representing the measurement window. The
  599. * number of counts within the SW loop that have accumulated during the
  600. * measurement window represents the capacitance of the element.
  601. *
  602. * @param group Address of the structure describing the Sensor to be measured
  603. * @param counts Address to where the measurements are to be written
  604. * @return none
  605. ******************************************************************************/
  606. void TI_CTS_fRO_COMPAp_TA1_SW_HAL(const struct Sensor *group, uint16_t *counts)
  607. {
  608. uint8_t i;
  609. uint16_t j;
  610. //** Context Save
  611. // Status Register:
  612. // TIMERA0: TA1CTL, TA1CCTL0
  613. // COMPAp: CACTL1, CACTL2, CAPD
  614. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  615. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL0,contextSaveTA1CCR0;
  616. uint8_t contextSaveCACTL1,contextSaveCACTL2,contextSaveCAPD;
  617. uint8_t contextSaveCaoutDir,contextSaveCaoutSel;
  618. uint8_t contextSavetxclkDir,contextSavetxclkSel;
  619. uint8_t contextSaveRefDir,contextSaveRefOutSel;
  620. #ifdef SEL2REGISTER
  621. uint8_t contextSaveCaoutSel2,contextSaveTxclkSel2;
  622. contextSaveCaoutSel2 = *(group->caoutSel2Register);
  623. contextSaveTxclkSel2 = *(group->txclkSel2Register);
  624. #endif
  625. contextSaveTA1CTL = TA1CTL;
  626. contextSaveTA1CCTL0 = TA1CCTL0;
  627. contextSaveTA1CCR0 = TA1CCR0;
  628. contextSaveCACTL1 = CACTL1;
  629. contextSaveCACTL2 = CACTL2;
  630. contextSaveCAPD = CAPD;
  631. contextSaveCaoutDir = *(group->caoutDirRegister);
  632. contextSaveCaoutSel = *(group->caoutSelRegister);
  633. contextSavetxclkDir = *(group->txclkDirRegister);
  634. contextSavetxclkSel = *(group->txclkSelRegister);
  635. contextSaveRefDir = *(group->refPxdirRegister);
  636. contextSaveRefOutSel = *(group->refPxoutRegister);
  637. //** Setup Measurement timer***************************************************
  638. // Configure Timer TA0
  639. TA1CCR0 =(group->accumulationCycles);
  640. // setup connections between CAOUT and TA0
  641. *(group->caoutDirRegister) |= group->caoutBits;
  642. *(group->txclkDirRegister) &= ~group->txclkBits;
  643. *(group->caoutSelRegister) |= group->caoutBits;
  644. *(group->txclkSelRegister) |= group->txclkBits;
  645. #ifdef SEL2REGISTER
  646. *(group->caoutSel2Register) |= group->caoutBits;
  647. *(group->txclkSel2Register) |= group->txclkBits;
  648. #endif
  649. // setup reference
  650. *(group->refPxdirRegister) |= group->refBits;
  651. *(group->refPxoutRegister) |= group->refBits;
  652. CACTL1 |= CAON; // Turn on comparator
  653. CAPD |= (group->capdBits);
  654. for (i = 0; i<(group->numElements); i++)
  655. {
  656. j=0;
  657. CACTL2= group->refCactl2Bits + (group->arrayPtr[i])->inputBits;
  658. //** Setup Gate Timer **************
  659. // Set duration of sensor measurment
  660. TA1CTL = TASSEL_0+TACLR+MC_1; // TACLK
  661. while(!(TACTL & TAIFG))
  662. {
  663. j++;
  664. } // end accumulation
  665. counts[i] = j;
  666. }
  667. // End Sequence
  668. //** Context Restore
  669. // WDTp: IE1, WDCTL
  670. // TIMERA0: TACTL, TACCTL1
  671. // COMPAp: CACTL1, CACTL2, CAPD
  672. // Ports: caoutDIR, caoutSel, txclkDIR, txclkSel, caoutSel2, txclkSel2, refout, refdir
  673. #ifdef SEL2REGISTER
  674. *(group->caoutSel2Register) = contextSaveCaoutSel2;
  675. *(group->txclkSel2Register) = contextSaveTxclkSel2;
  676. #endif
  677. TA1CTL = contextSaveTA1CTL;
  678. TA1CCTL0 = contextSaveTA1CCTL0;
  679. TA1CCR0 = contextSaveTA1CCR0;
  680. CACTL1 = contextSaveCACTL1;
  681. CACTL2 = contextSaveCACTL2;
  682. CAPD = contextSaveCAPD;
  683. *(group->caoutDirRegister) = contextSaveCaoutDir;
  684. *(group->caoutSelRegister) = contextSaveCaoutSel;
  685. *(group->txclkDirRegister) = contextSavetxclkDir;
  686. *(group->txclkSelRegister) = contextSavetxclkSel;
  687. *(group->refPxdirRegister) = contextSaveRefDir;
  688. *(group->refPxoutRegister) = contextSaveRefOutSel;
  689. }
  690. #endif
  691. /***************************************************************************//**
  692. * @brief RC method capactiance measurement using a Pair of GPIO and TimerA0
  693. *
  694. * Schematic Description of two GPIO forming RC measruement.
  695. * \n <- Output
  696. * \n -> Input
  697. * \n R Resistor (typically 1Mohms)
  698. * \n
  699. * \n +-<-Px.y (reference)
  700. * \n |
  701. * \n R
  702. * \n |
  703. * \n Element---+-->Pa.b
  704. * \n
  705. * \n Charge and Discharge Cycle
  706. * \n +
  707. * \n + +
  708. * \n + +
  709. * \n + +
  710. * \n + +
  711. * \n Start Timer After n cycles Stop Timer
  712. * \n The TAR reister value is the number of SMCLK periods within n charge
  713. * and discharge cycles. This value is directly proportional to the
  714. * capacitance of the element measured. 'n' is defined by the variable
  715. * accumulation_cycles.
  716. *
  717. * @param group Address of the structure describing the Sensor to be measured
  718. * @param counts Address to where the measurements are to be written
  719. * @return none
  720. ******************************************************************************/
  721. #ifdef RC_PAIR_TA0
  722. void TI_CTS_RC_PAIR_TA0_HAL(const struct Sensor *group, unsigned int *counts)
  723. {
  724. uint8_t i;
  725. uint16_t j;
  726. //** Context Save
  727. // TIMERA0: TA0CTL
  728. // Port: inputPxout, inputPxdir, referencePxout, referencePxdir
  729. uint8_t contextSaveinputPxout,contextSaveinputPxdir,contextSavereferencePxout;
  730. uint8_t contextSavereferencePxdir;
  731. #ifdef __MSP430_HAS_SFR__
  732. uint16_t contextSaveTA0CTL,contextSaveTA0CCR0;
  733. contextSaveTA0CTL = TA0CTL;
  734. contextSaveTA0CCR0 = TA0CCR0;
  735. #else
  736. uint16_t contextSaveTACTL,contextSaveTACCR0;
  737. contextSaveTACTL = TACTL;
  738. contextSaveTACCR0 = TACCR0;
  739. #endif
  740. //** Setup Measurement timer****************************************************
  741. // Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
  742. // capacitive touch layer.
  743. #ifdef __MSP430_HAS_SFR__
  744. TA0CCR0 = 0xFFFF;
  745. #else
  746. TACCR0 = 0xFFFF;
  747. #endif
  748. for (i = 0; i<(group->numElements); i++)
  749. {
  750. // Context Save
  751. contextSaveinputPxout = *((group->arrayPtr[i])->inputPxoutRegister);
  752. contextSaveinputPxdir = *((group->arrayPtr[i])->inputPxdirRegister);
  753. contextSavereferencePxout = *((group->arrayPtr[i])->referencePxoutRegister);
  754. contextSavereferencePxdir = *((group->arrayPtr[i])->referencePxdirRegister);
  755. j = (group->accumulationCycles);
  756. #ifdef __MSP430_HAS_SFR__
  757. TA0CTL = TASSEL_2+TACLR; // SMCLK, up mode
  758. #else
  759. TACTL = TASSEL_2+TACLR; // SMCLK, up mode
  760. #endif
  761. while(j--)
  762. {
  763. //******************************************************************************
  764. // Positive cycle
  765. // SENSOR ---+---- Input (low to high)
  766. // R
  767. // +---- Rerefence (high)
  768. //******************************************************************************
  769. // Input low
  770. *((group->arrayPtr[i])->inputPxoutRegister) &= ~((group->arrayPtr[i])->inputBits);
  771. *((group->arrayPtr[i])->inputPxdirRegister) |= (group->arrayPtr[i])->inputBits;
  772. // Reference High
  773. *((group->arrayPtr[i])->referencePxdirRegister) |= (group->arrayPtr[i])->referenceBits;
  774. *((group->arrayPtr[i])->referencePxoutRegister) |= ((group->arrayPtr[i])->referenceBits);
  775. // Wait until low
  776. while((*((group->arrayPtr[i])->inputPxinRegister)) & ((group->arrayPtr[i])->inputBits));
  777. // Change to an input
  778. *((group->arrayPtr[i])->inputPxdirRegister) &= ~(group->arrayPtr[i])->inputBits;
  779. //**************************************************************************
  780. // This mechanism is traditianally an LPM with the ISR calculating the
  781. // delta between when the first snapshot and the ISR event. If this is
  782. // included within the library the entire port ISR would not be available
  783. // to the calling application. In this example the polling is done with the
  784. // CPU at expense of power and MIPS but preserves the port ISR for other
  785. // interruptible functions.
  786. //**************************************************************************
  787. #ifdef __MSP430_HAS_SFR__
  788. TA0CTL |= MC_1; // start timer
  789. #else
  790. TACTL |= MC_1; // start timer
  791. #endif
  792. //wait until voltage reaches Vih of port
  793. while(!((*((group->arrayPtr[i])->inputPxinRegister) & (group->arrayPtr[i])->inputBits)));
  794. #ifdef __MSP430_HAS_SFR__
  795. TA0CTL &= ~ MC_3; // stop timer
  796. #else
  797. TACTL &= ~ MC_3; // stop timer
  798. #endif
  799. //******************************************************************************
  800. // Negative cycle
  801. // SENSOR ---+---- Input (high to low)
  802. // R
  803. // +---- Rerefence (low)
  804. //******************************************************************************
  805. // Input High
  806. *((group->arrayPtr[i])->inputPxoutRegister) |= ((group->arrayPtr[i])->inputBits);
  807. *((group->arrayPtr[i])->inputPxdirRegister) |= (group->arrayPtr[i])->inputBits;
  808. // Reference Low
  809. *((group->arrayPtr[i])->referencePxoutRegister) &= ~((group->arrayPtr[i])->referenceBits);
  810. // Change to an input
  811. *((group->arrayPtr[i])->inputPxdirRegister) &= ~((group->arrayPtr[i])->inputBits);
  812. #ifdef __MSP430_HAS_SFR__
  813. TA0CTL |= MC_1; // start timer
  814. #else
  815. TACTL |= MC_1; // start timer
  816. #endif
  817. //wait until voltage reaches Vil of port
  818. while((*((group->arrayPtr[i])->inputPxinRegister)) & ((group->arrayPtr[i])->inputBits));
  819. #ifdef __MSP430_HAS_SFR__
  820. TA0CTL &= ~ MC_3; // stop timer
  821. #else
  822. TACTL &= ~ MC_3; // stop timer
  823. #endif
  824. } // END accumulation loop for a single element
  825. #ifdef __MSP430_HAS_SFR__
  826. counts[i] = TA0R;
  827. #else
  828. counts[i] = TAR;
  829. #endif
  830. // Context Restore
  831. *((group->arrayPtr[i])->inputPxoutRegister) = contextSaveinputPxout;
  832. *((group->arrayPtr[i])->inputPxdirRegister) = contextSaveinputPxdir;
  833. *((group->arrayPtr[i])->referencePxoutRegister) = contextSavereferencePxout;
  834. *((group->arrayPtr[i])->referencePxdirRegister) = contextSavereferencePxdir;
  835. } // END FOR loop which cycles through elements within sensor
  836. //** Context Restore
  837. #ifdef __MSP430_HAS_SFR__
  838. TA0CTL = contextSaveTA0CTL;
  839. TA0CCR0 = contextSaveTA0CCR0;
  840. #else
  841. TACTL = contextSaveTACTL;
  842. TACCR0 = contextSaveTACCR0;
  843. #endif
  844. }
  845. #endif
  846. /***************************************************************************//**
  847. * @brief fRO method capactiance measurement using the PinOsc and TimerA0
  848. *
  849. * \n Charge and Discharge Cycle
  850. * \n +
  851. * \n + +
  852. * \n + +
  853. * \n + +
  854. * \n + +
  855. * \n Start Timer After n cycles Stop Timer
  856. * \n The TAR reister value is the number of SW loops (function of MCLK)
  857. * within n charge and discharge cycles. This value is directly
  858. * proportional to the capacitance of the element measured. 'n' is
  859. * defined by the variable accumulation_cycles.
  860. *
  861. * @param group Address of the structure describing the Sensor to be measured
  862. * @param counts Address to where the measurements are to be written
  863. * @return none
  864. ******************************************************************************/
  865. #ifdef fRO_PINOSC_TA0_SW
  866. void TI_CTS_fRO_PINOSC_TA0_SW_HAL(const struct Sensor *group, unsigned int *counts)
  867. {
  868. uint8_t i;
  869. uint16_t j;
  870. //** Context Save
  871. // TIMERA0: TA0CTL
  872. // Ports: PxSEL, PxSEL2
  873. uint16_t contextSaveTA0CTL;
  874. uint8_t contextSaveSel,contextSaveSel2;
  875. contextSaveTA0CTL = TA0CTL;
  876. // Setup Measurement timer
  877. TACCR0 =(group->accumulationCycles);
  878. for (i =0; i< (group->numElements); i++)
  879. {
  880. j = 0;
  881. // Context Save
  882. contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
  883. contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
  884. // start single oscillation (rise then fall and trigger on fall)
  885. *((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
  886. *((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
  887. TA0CTL = TASSEL_3+TACLR+MC_1; // INCLK , up mode
  888. // start timer in up mode
  889. while(!(TA0CTL & TAIFG))
  890. {
  891. j++;
  892. } // end accumulation
  893. counts[i] = j;
  894. TA0CTL &= ~MC_1;
  895. // Context Restore
  896. *((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
  897. *((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
  898. }
  899. // End Sequence
  900. // Context Restore
  901. TA0CTL = contextSaveTA0CTL;
  902. }
  903. #endif
  904. #ifdef RO_PINOSC_TA0_WDTp
  905. /***************************************************************************//**
  906. * @brief RO method capactiance measurement using PinOsc IO, TimerA0, and WDT+
  907. *
  908. * Schematic Description:
  909. *
  910. * \n element-----+->Px.y
  911. *
  912. * \n The WDT+ interval represents the measurement window. The number of
  913. * counts within the TA0R that have accumulated during the measurement
  914. * window represents the capacitance of the element.
  915. *
  916. * @param group Pointer to the structure describing the Sensor to be measured
  917. * @param counts Pointer to where the measurements are to be written
  918. * @return none
  919. ******************************************************************************/
  920. void TI_CTS_RO_PINOSC_TA0_WDTp_HAL(const struct Sensor *group, unsigned int *counts)
  921. {
  922. uint8_t i;
  923. //** Context Save
  924. // Status Register:
  925. // WDTp: IE1, WDTCTL
  926. // TIMERA0: TA0CTL, TA0CCTL1
  927. // Ports: PxSEL, PxSEL2
  928. uint8_t contextSaveSR;
  929. uint8_t contextSaveIE1;
  930. uint16_t contextSaveWDTCTL;
  931. uint16_t contextSaveTA0CTL,contextSaveTA0CCTL1,contextSaveTA0CCR1;
  932. uint8_t contextSaveSel,contextSaveSel2;
  933. contextSaveSR = __get_SR_register();
  934. contextSaveIE1 = IE1;
  935. contextSaveWDTCTL = WDTCTL;
  936. contextSaveWDTCTL &= 0x00FF;
  937. contextSaveWDTCTL |= WDTPW;
  938. contextSaveTA0CTL = TA0CTL;
  939. contextSaveTA0CCTL1 = TA0CCTL1;
  940. contextSaveTA0CCR1 = TA0CCR1;
  941. //** Setup Measurement timer***************************************************
  942. // Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
  943. // capacitive touch layer.
  944. // Configure and Start Timer
  945. TA0CTL = TASSEL_3+MC_2; // TACLK, cont mode
  946. TA0CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  947. IE1 |= WDTIE; // enable WDT interrupt
  948. for (i = 0; i<(group->numElements); i++)
  949. {
  950. // Context Save
  951. contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
  952. contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
  953. // Configure Ports for relaxation oscillator
  954. *((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
  955. *((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
  956. //** Setup Gate Timer ********************************************************
  957. // Set duration of sensor measurment
  958. WDTCTL = (WDTPW+WDTTMSEL+group->measGateSource+group->accumulationCycles);
  959. TA0CTL |= TACLR; // Clear Timer_A TAR
  960. if(group->measGateSource == GATE_WDT_ACLK)
  961. {
  962. __bis_SR_register(LPM3_bits+GIE); // Wait for WDT interrupt
  963. }
  964. else
  965. {
  966. __bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
  967. }
  968. TA0CCTL1 ^= CCIS0; // Create SW capture of CCR1
  969. counts[i] = TA0CCR1; // Save result
  970. WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
  971. // Context Restore
  972. *((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
  973. *((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
  974. }
  975. // End Sequence
  976. // Context Restore
  977. __bis_SR_register(contextSaveSR);
  978. if(!(contextSaveSR & GIE))
  979. {
  980. __bic_SR_register(GIE); //
  981. }
  982. IE1 = contextSaveIE1;
  983. WDTCTL = contextSaveWDTCTL;
  984. TA0CTL = contextSaveTA0CTL;
  985. TA0CCTL1 = contextSaveTA0CCTL1;
  986. TA0CCR1 = contextSaveTA0CCR1;
  987. }
  988. #endif
  989. #ifdef RO_PINOSC_TA0
  990. /***************************************************************************//**
  991. * @brief RO method capactiance measurement using PinOsc IO, and TimerA0
  992. *
  993. * Schematic Description:
  994. *
  995. * \n element-----+->Px.y
  996. *
  997. * \n The measurement window is accumulation_cycles/ACLK. The ACLK is
  998. * used to generate a capture event via the internal connection CCIOB.
  999. * The counts within the TA0R that have accumulated during the
  1000. * measurement window represents the capacitance of the element.
  1001. *
  1002. * @param group Pointer to the structure describing the Sensor to be measured
  1003. * @param counts Pointer to where the measurements are to be written
  1004. * @return none
  1005. ******************************************************************************/
  1006. void TI_CTS_RO_PINOSC_TA0_HAL(const struct Sensor *group, unsigned int *counts)
  1007. {
  1008. uint8_t i;
  1009. uint16_t j;
  1010. //** Context Save
  1011. // TIMERA0: TA0CTL, TA0CCTL0
  1012. // Ports: PxSEL, PxSEL2
  1013. uint16_t contextSaveTA0CTL,contextSaveTA0CCTL0,contextSaveTA0CCR0;
  1014. uint8_t contextSaveSel,contextSaveSel2;
  1015. contextSaveTA0CTL = TA0CTL;
  1016. contextSaveTA0CCTL0 = TA0CCTL0;
  1017. contextSaveTA0CCR0 = TA0CCR0;
  1018. //** Setup Measurement timer***************************************************
  1019. // Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the
  1020. // capacitive touch layer.
  1021. // Configure and Start Timer
  1022. TA0CTL = TASSEL_3+MC_2; // TACLK, cont mode
  1023. for (i =0; i< (group->numElements); i++)
  1024. {
  1025. // Context Save
  1026. contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister);
  1027. contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register);
  1028. // Configure Ports for relaxation oscillator
  1029. j = (group->accumulationCycles);
  1030. *((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits);
  1031. *((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits);
  1032. TA0CCTL0 = CM_3+CCIS_1+CAP; // Pos&Neg,ACLK (CCI0B),Cap
  1033. while(!(TA0CCTL0 & CCIFG)); // wait for capture event
  1034. TA0CTL |= TACLR; // Clear Timer_A TAR
  1035. while(j--)
  1036. {
  1037. TA0CCTL0 = CM_3+CCIS_1+CAP; // Pos&Neg,ACLK (CCI0B),Cap
  1038. while(!(TA0CCTL0 & CCIFG)); // wait for capture event
  1039. }
  1040. TA0CTL &= ~MC_2;
  1041. counts[i] = TA0CCR0; // Save result
  1042. // Context Restore
  1043. *((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel;
  1044. *((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2;
  1045. }
  1046. // End Sequence
  1047. // Context Restore
  1048. TA0CTL = contextSaveTA0CTL;
  1049. TA0CCTL0 = contextSaveTA0CCTL0;
  1050. TA0CCR0 = contextSaveTA0CCR0;
  1051. }
  1052. #endif
  1053. #ifdef RO_COMPB_TA0_WDTA
  1054. /***************************************************************************//**
  1055. * @brief RO method capactiance measurement using CompB, TimerA0, and WDTA
  1056. *
  1057. * \n Schematic Description of CompB forming relaxation oscillator and
  1058. * coupling (connection) between the relaxation oscillator and TimerA0.
  1059. * \n <- Output
  1060. * \n -> Input
  1061. * \n R Resistor (typically 100Kohms)
  1062. *
  1063. * \n element---R----<-CBOUT/TA0CLK
  1064. *
  1065. * \n The WDTA interval represents the measurement window. The number of
  1066. * counts within the TA0R that have accumulated during the measurement
  1067. * window represents the capacitance of the element.
  1068. *
  1069. * @param group Address of the structure describing the Sensor to be measured
  1070. * @param counts Address to where the measurements are to be written
  1071. * @return none
  1072. ******************************************************************************/
  1073. void TI_CTS_RO_COMPB_TA0_WDTA_HAL(const struct Sensor *group, unsigned int *counts)
  1074. {
  1075. unsigned char i;
  1076. //** Context Save
  1077. // Status Register:
  1078. // WDTA: IE1, WDTCTL
  1079. // TIMERA0: TA0CTL, TA0CCTL1
  1080. // COMPAp: CACTL1, CACTL2, CAPD
  1081. // Ports: CboutDIR, CboutSel
  1082. uint8_t contextSaveSR;
  1083. uint16_t contextSaveSFRIE1;
  1084. uint16_t contextSaveWDTCTL;
  1085. uint16_t contextSaveTA0CTL,contextSaveTA0CCTL1,contextSaveTA0CCR1;
  1086. uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
  1087. uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
  1088. uint8_t contextSaveCboutDir,contextSaveCboutSel;
  1089. contextSaveSR = __get_SR_register();
  1090. contextSaveSFRIE1 = SFRIE1;
  1091. contextSaveWDTCTL = WDTCTL;
  1092. contextSaveWDTCTL &= 0x00FF;
  1093. contextSaveWDTCTL |= WDTPW;
  1094. contextSaveTA0CTL = TA0CTL;
  1095. contextSaveTA0CCTL1 = TA0CCTL1;
  1096. contextSaveTA0CCR1 = TA0CCR1;
  1097. contextSaveCBCTL0 = CBCTL0;
  1098. contextSaveCBCTL1 = CBCTL1;
  1099. contextSaveCBCTL2 = CBCTL2;
  1100. contextSaveCBCTL3 = CBCTL3;
  1101. contextSaveCboutDir = *(group->cboutTAxDirRegister);
  1102. contextSaveCboutSel = *(group->cboutTAxSelRegister);
  1103. //** Setup Measurement timer***************************************************
  1104. // connect CBOUT with TA0
  1105. *(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
  1106. *(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
  1107. CBCTL2 = CBREF14+CBREF13 + CBREF02;
  1108. // Configure Timer TA0
  1109. TA0CTL = TASSEL_0+MC_2; // TACLK, cont mode
  1110. TA0CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  1111. // Turn on Comparator
  1112. CBCTL1 = CBON + CBF; // Turn on comparator with filter
  1113. // Vcc to resistor ladder
  1114. CBCTL3 |= (group->cbpdBits); // set CPD bits to disable
  1115. // I/O buffer
  1116. SFRIE1 |= WDTIE; // enable WDT interrupt
  1117. CBCTL2 |= CBRS_1; // Turn on reference
  1118. for (i = 0; i<(group->numElements); i++)
  1119. {
  1120. CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
  1121. //** Setup Gate Timer ********************************************************
  1122. // Set duration of sensor measurment
  1123. WDTCTL = WDTPW+WDTTMSEL+ group->measGateSource + group->accumulationCycles;
  1124. TA0CTL |= TACLR; // Clear Timer_A TAR
  1125. __bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
  1126. TA0CCTL1 ^= CCIS0; // Create SW capture of CCR1
  1127. counts[i] = TA0CCR1; // Save result
  1128. WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
  1129. }
  1130. // End Sequence
  1131. //** Context Restore
  1132. // WDTA: IE1, WDCTL
  1133. // TIMERA0: TACTL, TACCTL1
  1134. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  1135. // Ports: CboutDIR, CboutSel
  1136. __bis_SR_register(contextSaveSR);
  1137. if(!(contextSaveSR & GIE))
  1138. {
  1139. __bic_SR_register(GIE); // Wait for WDT interrupt
  1140. }
  1141. SFRIE1 = contextSaveSFRIE1;
  1142. WDTCTL = contextSaveWDTCTL;
  1143. TA0CTL = contextSaveTA0CTL;
  1144. TA0CCTL1 = contextSaveTA0CCTL1;
  1145. TA0CCR1 = contextSaveTA0CCR1;
  1146. CBCTL0 = contextSaveCBCTL0;
  1147. CBCTL1 = contextSaveCBCTL1;
  1148. CBCTL2 = contextSaveCBCTL2;
  1149. CBCTL3 = contextSaveCBCTL3;
  1150. *(group->cboutTAxDirRegister) = contextSaveCboutDir;
  1151. *(group->cboutTAxSelRegister) = contextSaveCboutSel;
  1152. }
  1153. #endif
  1154. #ifdef RO_COMPB_TA1_WDTA
  1155. /***************************************************************************//**
  1156. * @brief RO method capactiance measurement using CompB, TimerA1, and WDTA
  1157. *
  1158. * Schematic Description of CompB forming relaxation oscillator and
  1159. * coupling (connection) between the relaxation oscillator and TimerA1.
  1160. * <- Output
  1161. * -> Input
  1162. * R Resistor (typically 100Kohms)
  1163. *
  1164. * element---R----<-CBOUT/TA1CLK
  1165. *
  1166. * The WDTA interval represents the measurement window. The number of
  1167. * counts within the TA1R that have accumulated during the measurement
  1168. * window represents the capacitance of the element.
  1169. *
  1170. * @param group Address of the structure describing the Sensor to be measured
  1171. * @param counts Address to where the measurements are to be written
  1172. * @return none
  1173. ******************************************************************************/
  1174. void TI_CTS_RO_COMPB_TA1_WDTA_HAL(const struct Sensor *group, unsigned int *counts)
  1175. {
  1176. uint8_t i=0;
  1177. //** Context Save
  1178. // Status Register:
  1179. // WDTA: IE1, WDTCTL
  1180. // TIMERA1: TA1CTL, TA1CCTL1
  1181. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  1182. // Ports: CboutDIR, CboutSel
  1183. uint8_t contextSaveSR;
  1184. uint16_t contextSaveSFRIE1;
  1185. uint16_t contextSaveWDTCTL;
  1186. uint16_t contextSaveTA1CTL,contextSaveTA1CCTL1,contextSaveTA1CCR1;
  1187. uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
  1188. uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
  1189. uint8_t contextSaveCboutDir,contextSaveCboutSel;
  1190. contextSaveSR = __get_SR_register();
  1191. contextSaveSFRIE1 = SFRIE1;
  1192. contextSaveWDTCTL = WDTCTL;
  1193. contextSaveWDTCTL &= 0x00FF;
  1194. contextSaveWDTCTL |= WDTPW;
  1195. contextSaveTA1CTL = TA1CTL;
  1196. contextSaveTA1CCTL1 = TA1CCTL1;
  1197. contextSaveTA1CCR1 = TA1CCR1;
  1198. contextSaveCBCTL0 = CBCTL0;
  1199. contextSaveCBCTL1 = CBCTL1;
  1200. contextSaveCBCTL2 = CBCTL2;
  1201. contextSaveCBCTL3 = CBCTL3;
  1202. contextSaveCboutDir = *(group->cboutTAxDirRegister);
  1203. contextSaveCboutSel = *(group->cboutTAxSelRegister);
  1204. //** Setup Measurement timer***************************************************
  1205. // connect CBOUT with TA1
  1206. *(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
  1207. *(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
  1208. // Setup Comparator
  1209. CBCTL2 = CBREF14+CBREF13 + CBREF02;
  1210. // Configure Timer TA1
  1211. TA1CTL = TASSEL_0+MC_2; // TACLK, cont mode
  1212. TA1CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
  1213. // Turn on Comparator
  1214. CBCTL1 = CBON + CBF; // Turn on comparator with filter
  1215. CBCTL3 |= (group->cbpdBits); // set CPD bits to disable
  1216. SFRIE1 |= WDTIE; // enable WDT interrupt
  1217. CBCTL2 |= CBRS_1; // Turn on reference
  1218. for (i = 0; i<(group->numElements); i++)
  1219. {
  1220. CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
  1221. //** Setup Gate Timer ********************************************************
  1222. // Set duration of sensor measurment
  1223. WDTCTL = WDTPW+WDTTMSEL+WDTCNTCL+ group->measGateSource + group->sourceScale;
  1224. TA1CTL |= TACLR; // Clear Timer_A TAR
  1225. __bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
  1226. TA1CCTL1 ^= CCIS0; // Create SW capture of CCR1
  1227. counts[i] = TA1CCR1; // Save result
  1228. WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
  1229. CBCTL3 &= ~((group->arrayPtr[i])->inputBits);
  1230. }
  1231. // End Sequence
  1232. //** Context Restore
  1233. // WDTA: IE1, WDCTL
  1234. // TIMERA0: TACTL, TACCTL1
  1235. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  1236. // Ports: CboutDIR, CboutSel
  1237. __bis_SR_register(contextSaveSR);
  1238. if(!(contextSaveSR & GIE))
  1239. {
  1240. __bic_SR_register(GIE); // Wait for WDT interrupt
  1241. }
  1242. SFRIE1 = contextSaveSFRIE1;
  1243. WDTCTL = contextSaveWDTCTL;
  1244. TA1CTL = contextSaveTA1CTL;
  1245. TA1CCTL1 = contextSaveTA1CCTL1;
  1246. TA1CCR1 = contextSaveTA1CCR1;
  1247. CBCTL0 = contextSaveCBCTL0;
  1248. CBCTL1 = contextSaveCBCTL1;
  1249. CBCTL2 = contextSaveCBCTL2;
  1250. CBCTL3 = contextSaveCBCTL3;
  1251. *(group->cboutTAxDirRegister) = contextSaveCboutDir;
  1252. *(group->cboutTAxSelRegister) = contextSaveCboutSel;
  1253. }
  1254. #endif
  1255. #ifdef fRO_COMPB_TA0_SW
  1256. /***************************************************************************//**
  1257. * @brief fRO method capactiance measurement using CompB, TimerA0
  1258. *
  1259. * Schematic Description of CompB forming relaxation oscillator and
  1260. * coupling (connection) between the relaxation oscillator and TimerA0.
  1261. * <- Output
  1262. * -> Input
  1263. * R Resistor (typically 100Kohms)
  1264. *
  1265. * element---R----<-CBOUT
  1266. *
  1267. * The TAR reister value is the number of SW loops (function of MCLK)
  1268. * within n charge and discharge cycles. This value is directly
  1269. * proportional to the capacitance of the element measured. 'n' is
  1270. * defined by the variable accumulation_cycles.
  1271. *
  1272. * @param group Address of the structure describing the Sensor to be measured
  1273. * @param counts Address to where the measurements are to be written
  1274. * @return none
  1275. ******************************************************************************/
  1276. void TI_CTS_fRO_COMPB_TA0_SW_HAL(const struct Sensor *group, unsigned int *counts)
  1277. {
  1278. uint8_t i;
  1279. uint16_t j;
  1280. //** Context Save
  1281. // TIMERA0: TA0CTL, TA0CCR1
  1282. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  1283. // Ports: CboutDIR, CboutSel
  1284. uint16_t contextSaveTA0CTL,contextSaveTA0CCR0;
  1285. uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
  1286. uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
  1287. uint8_t contextSaveCboutDir,contextSaveCboutSel;
  1288. contextSaveTA0CTL = TA0CTL;
  1289. contextSaveTA0CCR0 = TA0CCR0;
  1290. contextSaveCBCTL0 = CBCTL0;
  1291. contextSaveCBCTL1 = CBCTL1;
  1292. contextSaveCBCTL2 = CBCTL2;
  1293. contextSaveCBCTL3 = CBCTL3;
  1294. contextSaveCboutDir = *(group->cboutTAxDirRegister);
  1295. contextSaveCboutSel = *(group->cboutTAxSelRegister);
  1296. //** Setup Measurement timer***************************************************
  1297. // connect CBOUT with TA0
  1298. *(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
  1299. *(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
  1300. CBCTL2 = CBREF14+CBREF13 + CBREF02;
  1301. // Configure Timer TA0
  1302. TA0CCR0 =(group->accumulationCycles);
  1303. // Turn on Comparator
  1304. CBCTL1 = CBON + CBF; // Turn on comparator with filter
  1305. // Vcc to resistor ladder
  1306. CBCTL3 |= (group->cbpdBits); // set CPD bits to disable
  1307. // I/O buffer
  1308. CBCTL2 |= CBRS_1; // Turn on reference
  1309. for (i = 0; i<(group->numElements); i++)
  1310. {
  1311. j=0;
  1312. CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
  1313. //** Setup Gate Timer ********************************************************
  1314. // Set duration of sensor measurment
  1315. TA0CTL = TASSEL_0+TACLR+MC_1; // TACLK
  1316. while(!(TA0CTL & TAIFG))
  1317. {
  1318. j++;
  1319. } // end accumulation
  1320. counts[i] = j;
  1321. }
  1322. // End Sequence
  1323. //** Context Restore
  1324. // TIMERA0: TACTL, TACCTL1
  1325. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  1326. // Ports: CboutDIR, CboutSel
  1327. TA0CTL = contextSaveTA0CTL;
  1328. TA0CCR0 = contextSaveTA0CCR0;
  1329. CBCTL0 = contextSaveCBCTL0;
  1330. CBCTL1 = contextSaveCBCTL1;
  1331. CBCTL2 = contextSaveCBCTL2;
  1332. CBCTL3 = contextSaveCBCTL3;
  1333. *(group->cboutTAxDirRegister) = contextSaveCboutDir;
  1334. *(group->cboutTAxSelRegister) = contextSaveCboutSel;
  1335. }
  1336. #endif
  1337. #ifdef fRO_COMPB_TA1_SW
  1338. /***************************************************************************//**
  1339. * @brief fRO method capactiance measurement using CompB, TimerA1
  1340. *
  1341. * Schematic Description of CompB forming relaxation oscillator and
  1342. * coupling (connection) between the relaxation oscillator and TimerA1.
  1343. * <- Output
  1344. * -> Input
  1345. * R Resistor (typically 100Kohms)
  1346. *
  1347. * element---R----<-CBOUT
  1348. *
  1349. * The TAR reister value is the number of SW loops (function of MCLK)
  1350. * within n charge and discharge cycles. This value is directly
  1351. * proportional to the capacitance of the element measured. 'n' is
  1352. * defined by the variable accumulation_cycles.
  1353. *
  1354. * @param group Address of the structure describing the Sensor to be measured
  1355. * @param counts Address to where the measurements are to be written
  1356. * @return none
  1357. ******************************************************************************/
  1358. void TI_CTS_fRO_COMPB_TA1_SW_HAL(const struct Sensor *group, unsigned int *counts)
  1359. {
  1360. uint8_t i;
  1361. uint16_t j;
  1362. //** Context Save
  1363. // TIMERA0: TA1CTL, TA1CCTL1
  1364. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  1365. // Ports: CboutDIR, CboutSel
  1366. uint16_t contextSaveTA1CTL,contextSaveTA1CCR0;
  1367. uint16_t contextSaveCBCTL0,contextSaveCBCTL1;
  1368. uint16_t contextSaveCBCTL2,contextSaveCBCTL3;
  1369. uint8_t contextSaveCboutDir,contextSaveCboutSel;
  1370. contextSaveTA1CTL = TA1CTL;
  1371. contextSaveTA1CCR0 = TA1CCR0;
  1372. contextSaveCBCTL0 = CBCTL0;
  1373. contextSaveCBCTL1 = CBCTL1;
  1374. contextSaveCBCTL2 = CBCTL2;
  1375. contextSaveCBCTL3 = CBCTL3;
  1376. contextSaveCboutDir = *(group->cboutTAxDirRegister);
  1377. contextSaveCboutSel = *(group->cboutTAxSelRegister);
  1378. //** Setup Measurement timer***************************************************
  1379. // connect CBOUT with TA1
  1380. *(group->cboutTAxDirRegister) |= (group->cboutTAxBits);
  1381. *(group->cboutTAxSelRegister) |= (group->cboutTAxBits);
  1382. CBCTL2 = CBREF14+CBREF13 + CBREF02;
  1383. // Configure Timer TA1
  1384. TA1CCR0 =(group->accumulationCycles);
  1385. // Turn on Comparator
  1386. CBCTL1 = CBON + CBF; // Turn on comparator with filter
  1387. // Vcc to resistor ladder
  1388. CBCTL3 |= (group->cbpdBits); // set CPD bits to disable
  1389. // I/O buffer
  1390. CBCTL2 |= CBRS_1; // Turn on reference
  1391. for (i = 0; i<(group->numElements); i++)
  1392. {
  1393. j=0;
  1394. CBCTL0 = CBIMEN + (group->arrayPtr[i])->inputBits;
  1395. //** Setup Gate Timer ********************************************************
  1396. // Set duration of sensor measurment
  1397. TA1CTL = TASSEL_0+TACLR+MC_1; // TACLK
  1398. while(!(TA1CTL & TAIFG))
  1399. {
  1400. j++;
  1401. } // end accumulation
  1402. counts[i] = j;
  1403. //P1SEL &=~BIT4;
  1404. }
  1405. // End Sequence
  1406. //** Context Restore
  1407. // TIMERA0: TACTL, TACCTL1
  1408. // COMPB: CBCTL0, CBCTL1, CBCTL2, CBCTL3
  1409. // Ports: CboutDIR, CboutSel
  1410. TA1CTL = contextSaveTA1CTL;
  1411. TA1CCR0 = contextSaveTA1CCR0;
  1412. CBCTL0 = contextSaveCBCTL0;
  1413. CBCTL1 = contextSaveCBCTL1;
  1414. CBCTL2 = contextSaveCBCTL2;
  1415. CBCTL3 = contextSaveCBCTL3;
  1416. *(group->cboutTAxDirRegister) = contextSaveCboutDir;
  1417. *(group->cboutTAxSelRegister) = contextSaveCboutSel;
  1418. }
  1419. #endif
  1420. #ifdef WDT_GATE
  1421. // Watchdog Timer interrupt service routine
  1422. #pragma vector=WDT_VECTOR
  1423. __interrupt void watchdog_timer(void)
  1424. {
  1425. __bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
  1426. }
  1427. #endif
  1428. /***************************************************************************//**
  1429. * @}
  1430. ******************************************************************************/