Part Number:MSP430G2955
Hi all. I have an application on the MSP430G2955 that measures capacitance from 6 elements in a row. Unfortunately, only one of the six pads (Pads 0-5, only pad 1 works consistently) makes TA0R count during the WDT gate timer. When using the debugger to check the value of TA0R after waking up from LPM3, TA0R is only non-zero for Pad 1 and occasionally Pad2 (every 5 readings). My pin mappings have been verified and additionally when probing the pads with an oscilloscope I can see the correct signal on each pad (pulse every 500ms where each pulse's top is made up of the RO-frequency-modulated count signal). The oscillator seems to be operating correctly but the timer is not counting.
Here is my capsense code:
void TI_CTS_RO_PINOSC_TA0_WDTp_HAL(const struct Sensor *group, uint16_t *counts) { uint8_t i = 0; //** Context Save // Status Register: // WDTp: IE1, WDTCTL // TIMERA0: TA0CTL, TA0CCTL1 // Ports: PxSEL, PxSEL2 uint8_t contextSaveSR; uint8_t contextSaveIE1; uint16_t contextSaveWDTCTL; uint16_t contextSaveTA0CTL, contextSaveTA0CCTL1, contextSaveTA0CCR1; uint8_t contextSaveSel, contextSaveSel2; contextSaveSR = __get_SR_register(); contextSaveIE1 = IE1; contextSaveWDTCTL = WDTCTL; contextSaveWDTCTL &= 0x00FF; contextSaveWDTCTL |= WDTPW; contextSaveTA0CTL = TA0CTL; contextSaveTA0CCTL1 = TA0CCTL1; contextSaveTA0CCR1 = TA0CCR1; //** Setup Measurement timer*************************************************** // Choices are TA0,TA1,TB0,TB1,TD0,TD1 these choices are pushed up into the // capacitive touch layer. // Configure and Start Timer TA0CTL = TASSEL_3 + MC_2; // INCLK, cont mode // changed from TASSEL_3 TA0CCTL1 = CM_3 + CCIS_2 + CAP; // Pos&Neg,GND,Cap IE1 |= WDTIE; // enable WDT interrupt
// Loop across all 6 pads for (i = 0; i < (group->numElements); i++) { // Context Save contextSaveSel = *((group->arrayPtr[i])->inputPxselRegister); contextSaveSel2 = *((group->arrayPtr[i])->inputPxsel2Register); // Configure Ports for relaxation oscillator (in English... enable Capacitive sensing) *((group->arrayPtr[i])->inputPxselRegister) &= ~((group->arrayPtr[i])->inputBits); *((group->arrayPtr[i])->inputPxsel2Register) |= ((group->arrayPtr[i])->inputBits); //** Setup Gate Timer ******************************************************** // Set duration of sensor measurment WDTCTL = (WDTPW + WDTTMSEL + (group->measGateSource) + (group->accumulationCycles)); // wdt comes from aclk (gate source), aclk/512 -> use aclk for capsense TA0CTL |= TACLR; // Clear Timer_A TAR if (group->measGateSource == GATE_WDT_ACLK) { __bis_SR_register(LPM3_bits + GIE); // Wait for WDT interrupt } else { __bis_SR_register(LPM0_bits + GIE); // Wait for WDT interrupt } // every other pad the reference signal is alternated between GND and VCC (this causes rising and falling trigger events) // this causes a transition that starts the calculation of capacitance TA0CCTL1 ^= CCIS0; // Create SW capture of CCR1 (setting compare source to VCC) counts[i] = TA0CCR1; // Save result - BREAKPOINT HERE TO CHECK TA0R and TA0CCR1 WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer // Context Restore *((group->arrayPtr[i])->inputPxselRegister) = contextSaveSel; *((group->arrayPtr[i])->inputPxsel2Register) = contextSaveSel2; } // End Sequence // Context Restore __bis_SR_register(contextSaveSR); if (!(contextSaveSR & GIE)) { __bic_SR_register(GIE); // } IE1 = contextSaveIE1; WDTCTL = contextSaveWDTCTL; TA0CTL = contextSaveTA0CTL; TA0CCTL1 = contextSaveTA0CCTL1; TA0CCR1 = contextSaveTA0CCR1; }
Any help or ideas would be greatly appreciated. Feel free to ask questions; I am happy to provide more info.