This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Serial RX with cap sense booster

Other Parts Discussed in Thread: MSP430G2452

Hello

I am having trouble getting my code to receive an RX byte when I use the cap sense library.
It either freezes the code or does not echo.

Here is my (hacked up) code:

[code]
/*******************************************************************************
*
* CapTouchBoosterPack_UserExperience.c
* - MSP430 firmware application to demonstrate the capacitive touch
* capability of the MSP430G2452 interfacing with the LaunchPad CapTouch
* BoosterPack.
*
* Copyright (C) 2011 Texas Instruments Incorporated -
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
******************************************************************************/

/******************************************************************************
* MSP430G2-LaunchPad CapTouch BoosterPack User Experience
*
* This application operates on the LaunchPad platform using the MSP430G2452
* device and the CapTouch BoosterPack plugin board. The capacitive touch and
* proximity sensing are enabled by the pin oscillator feature new to the
* MSP430G2xx2 family devices. The User Experience application also utilizes
* the cap touch library to realize & measure the capacitive touch and proximity
* sensors. The cap touch library also provides layers of abstractions to
* generate higher logical outputs such as logical touches, geometry (in this
* hardware, a four-button wheel), and even gestures.
*
* The User Experience application starts up and remains in 'sleep' mode,
* sampling the proximity sensor every ~8.3ms [VLO/100=12kHz/100=120Hz]. Upon
* registering a valid proximity event [hand/finger/object hovering ~3-5cm from
* the BoosterPack], the application wakes up to operate in the 'active' mode.
*
* In active mode, the application samples and registers individual finger touches
* on the 16-position wheel or the center button as well as simple gestures
* [Clockwise & Counter-clockwise] while the finger moves along and remains on
* the wheel.
*
* a 9600 baud UART link is also implemented using SW TimerA to provide
* application and cap touch data back to the PC via the UART-USB back channel.
* The application sends UART data upon events such as wake up, sleep, touch,
* or gesture.
*
* D. Dang
* Texas Instruments, Inc.
* Ver 0.90 Feb 2011
******************************************************************************/

#include "CTS_Layer.h"
#include "uart.h"


#define WAKE_UP_UART_CODE 0xBE
#define WAKE_UP_UART_CODE2 0xEF
#define SLEEP_MODE_UART_CODE 0xDE
#define SLEEP_MODE_UART_CODE2 0xAD
#define MIDDLE_BUTTON_CODE 0x80
#define INVALID_GESTURE 0xFD
#define GESTURE_START 0xFC
#define GESTURE_STOP 0xFB
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE 2
#define GESTURE_POSITION_OFFSET 0x20
#define WHEEL_POSITION_OFFSET 0x30

#define WHEEL_TOUCH_DELAY 12 //Delay between re-sendings of touches
#define MAX_IDLE_TIME 200
#define PROXIMITY_THRESHOLD 60

unsigned int wheel_position=ILLEGAL_SLIDER_WHEEL_POSITION, last_wheel_position=ILLEGAL_SLIDER_WHEEL_POSITION;
unsigned int deltaCnts[1];
unsigned int prox_raw_Cnts;


/*----------------- LED definition---------------------------------------------
* There are 8 LEDs to represent different positions around the wheel. They are
* controlled by 5 pins of Port 1 using a muxing scheme. The LEDs are divided
* vertically into two groups of 4, in which each LED is paired up [muxed] with
* the LED mirrored on the other side of the imaginary center vertical line via
* the use of pin P1.3 and one specific port pin.
* Specifically, the pairs are LEDs [0,7], [1,6], [2,5], [3,4], as shown in the
* diagram below.
* LED Position (degrees, clockwise)
* --RIGHT SIDE--
* 0 BIT4,!BIT3 45
* 1 BIT5,!BIT3 80
* 2 BIT6,!BIT3 100
* 3 BIT7,!BIT3 135 *
*
* --LEFT SIDE--
* 4 BIT3,(BIT4,5,6) 225
* 5 BIT3,(BIT4,5,7) 260
* 6 BIT3,(BIT4,6,7) 280
* 7 BIT3,(BIT5,6,7) 315
*----------------------------------------------------------------------------*/
#define MASK7 BIT4
#define MASK6 BIT5
#define MASK5 BIT6
#define MASK4 BIT7

#define MASK3 (BIT3+BIT4+BIT5+BIT6)
#define MASK2 (BIT3+BIT4+BIT5+BIT7)
#define MASK1 (BIT3+BIT4+BIT6+BIT7)
#define MASK0 (BIT3+BIT5+BIT6+BIT7)

const unsigned char LedWheelPosition[16] =
{
MASK0, MASK0, MASK0 & MASK1, MASK1,
MASK1 & MASK2, MASK2, MASK2 & MASK3, MASK3,
MASK4, MASK4, MASK4 | MASK5, MASK5,
MASK5 | MASK6, MASK6, MASK6 | MASK7, MASK7
};
const unsigned char startSequence[8] =
{
MASK0,
MASK1,
MASK2,
MASK3,
MASK4,
MASK5,
MASK6,
MASK7
};
/*----------------- LED definition------------------------------*/

void echo();


void InitLaunchPadCore(void)

{
BCSCTL1 |= DIVA_0; // ACLK/(0:1,1:2,2:4,3:8)
BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO

// Port init
P1OUT &= ~(BIT3+BIT4+BIT5+BIT6+BIT7+BIT0);
P1DIR |= BIT3+BIT4+BIT5+BIT6+BIT7+BIT0;
P2SEL = 0x00; // No XTAL
P2DIR |= (BIT0+BIT4+BIT2+BIT3+BIT1+BIT5);
P2OUT &= ~(BIT0+BIT4+BIT2+BIT3+BIT1+BIT5);
}

void SendByte(unsigned char touch)
{
// TimerA_UART_init();
TimerA_UART_tx(touch);
// TimerA_UART_shutdown();
}


/* ----------------MeasureCapBaseLine--------------------------------------
* Re-measure the baseline capacitance of the wheel elements & the center
* button. To be called after each wake up event.
* ------------------------------------------------------------------------*/
void MeasureCapBaseLine(void)
{
//P1OUT = BIT0;
/* Set DCO to 8MHz */
/* SMCLK = 8MHz/8 = 1MHz */
BCSCTL1 = CALBC1_8MHZ;
DCOCTL = CALDCO_8MHZ;
BCSCTL2 |= DIVS_3;

TI_CAPT_Init_Baseline(&wheel);
TI_CAPT_Update_Baseline(&wheel,2);
TI_CAPT_Init_Baseline(&middle_button);
TI_CAPT_Update_Baseline(&middle_button,2);
}

/* ----------------GetGesture----------------------------------------------
* Determine immediate gesture based on current & previous wheel position
* ------------------------------------------------------------------------*/
unsigned char GetGesture(unsigned char wheel_position)
{
unsigned char gesture = INVALID_GESTURE, direction, ccw_check, cw_check;
// ******************************************************************************
// gesturing
// determine if a direction/swipe is occuring
// the difference between the initial position and
// the current wheel position should not exceed 8
// 0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F-0...
//
// E-F-0-1-2: cw, 4
// 2-1-0-F-E: ccw, 4
// A-B-C-D-E-F

//if(initial_wheel_position == INVALID_WHEEL_POSITION)
//{
//gesture = 0;
//initial_wheel_position = wheel_position;
//}
//else

if(last_wheel_position != ILLEGAL_SLIDER_WHEEL_POSITION)
{
if(last_wheel_position > wheel_position)
{
// E-D-C-B-A: ccw, 4
// counter clockwise: 0 < (init_wheel_position - wheel_position) < 8
// gesture = init_wheel_position - wheel_position
//
// E-F-0-1-2: cw, 4
// clockwise: 0 < (init_wheel_position+wheel_position)-16 <8
//
ccw_check = last_wheel_position - wheel_position;
if(ccw_check < 8)
{
gesture = ccw_check;
direction = COUNTER_CLOCKWISE;
}
else
{
// E-F-0-1-2: cw, 4
// 16 - 14 + 2 = 4
cw_check = 16 - last_wheel_position + wheel_position ;
if(cw_check < 8)
{
gesture = cw_check;
direction = CLOCKWISE;
}
}
}
else
{
// initial_wheel_position <= wheel_position
//
// 2-1-0-F-E: ccw, 4
// counter clockwise:
// 0 < (init_wheel_position+wheel_position)-16 <8
// gesture = init_wheel_position - wheel_position
//
// 0-1-2-3-4: cw, 4
// clockwise: 0 < (wheel_position - init_wheel_position) < 8
//
cw_check = wheel_position - last_wheel_position ;
if(cw_check < 8)
{
gesture = cw_check;
direction = CLOCKWISE;
}
else
{
// 2-1-0-F-E: ccw, 4
// 16 + 2 - 14 = 4
ccw_check = 16 + last_wheel_position - wheel_position ;
if(ccw_check < 8)
{
gesture = ccw_check;
direction = COUNTER_CLOCKWISE;
}
}
}
}
if (gesture == INVALID_GESTURE)
return gesture;
if (direction == COUNTER_CLOCKWISE)
return (gesture + 16);
else
return gesture;
}

/* ----------------CapTouchActiveMode----------------------------------------------
* Determine immediate gesture based on current & previous wheel position
*
*
*
*
*
*
*
* -------------------------------------------------------------------------------*/
void CapTouchActiveMode()
{
unsigned char idleCounter, activeCounter;
unsigned char gesture, gestureDetected;
unsigned char centerButtonTouched = 0;
unsigned int wheelTouchCounter = WHEEL_TOUCH_DELAY - 1;


gesture = INVALID_GESTURE; // Wipes out gesture history

/* Send status via UART: 'wake up' = [0xBE, 0xEF] */
// SendByte(WAKE_UP_UART_CODE);
//SendByte(WAKE_UP_UART_CODE2);

idleCounter = 0;
activeCounter = 0;
gestureDetected = 0;

while (idleCounter++ < MAX_IDLE_TIME)
{
/* Set DCO to 8MHz */
/* SMCLK = 8MHz/8 = 1MHz */
BCSCTL1 = CALBC1_8MHZ;
DCOCTL = CALDCO_8MHZ;
BCSCTL2 |= DIVS_3;
TACCTL0 &= ~CCIE;


wheel_position = ILLEGAL_SLIDER_WHEEL_POSITION;
wheel_position = TI_CAPT_Wheel(&wheel);

/* Process wheel touch/position/gesture if a wheel touch is registered*/
/* Wheel processing has higher priority than center button*/

if(wheel_position != ILLEGAL_SLIDER_WHEEL_POSITION)
{
centerButtonTouched = 0;

/* Adjust wheel position based: rotate CCW by 2 positions */
if (wheel_position < 0x08)
{
wheel_position += 0x40 - 0x08;
}
else
{
wheel_position -= 0x08;
/* Adjust wheel position based: rotate CCW by 2 positions */
}

wheel_position = wheel_position >>2; // divide by four

gesture = GetGesture(wheel_position);

/* Add hysteresis to reduce toggling between wheel positions if no gesture
* has been TRULY detected. */

if ( (gestureDetected==0) && ((gesture<=1) || (gesture==0x11) || (gesture==0x10)))
{
if (last_wheel_position != ILLEGAL_SLIDER_WHEEL_POSITION)
wheel_position = last_wheel_position;
gesture = 0;
}

/* Turn on corresponding LED(s) */
P1OUT = (P1OUT & BIT0) | LedWheelPosition[wheel_position];


if ((gesture != 0) && (gesture != 16) && (gesture != INVALID_GESTURE))
{ /* A gesture has been detected */

if (gestureDetected ==0)
{ /* Starting of a new gesture sequence */
gestureDetected = 1;

/* Transmit gesture start status update & position via UART to PC */
SendByte(GESTURE_START);
SendByte(last_wheel_position + GESTURE_POSITION_OFFSET);
}

/* Transmit gesture & position via UART to PC */
SendByte(gesture);
SendByte(wheel_position + GESTURE_POSITION_OFFSET);
}
else
if (gestureDetected==0)
{ /* If no gesture was detected, this is constituted as a touch/tap */
if (++wheelTouchCounter >= WHEEL_TOUCH_DELAY)
{
/* Transmit wheel position [twice] via UART to PC */
wheelTouchCounter = 0;
SendByte(wheel_position + WHEEL_POSITION_OFFSET );
SendByte(wheel_position + WHEEL_POSITION_OFFSET );
}
}
else
wheelTouchCounter = WHEEL_TOUCH_DELAY - 1;

idleCounter = 0; // Reset idle counter
activeCounter++;
last_wheel_position = wheel_position;
}
else
{ /* no wheel position was detected */

if(TI_CAPT_Button(&middle_button))
{ /* Middle button was touched */
if (centerButtonTouched==0)
{
/* Transmit center button code [twice] via UART to PC */
SendByte(MIDDLE_BUTTON_CODE);
SendByte(MIDDLE_BUTTON_CODE);

centerButtonTouched = 1;

P1OUT = (P1OUT&BIT0) ^ BIT0; // Toggle Center LED
}
idleCounter = 0;
}
else
{ /* No touch was registered at all [Not wheel or center button */
centerButtonTouched = 0;
P1OUT &= BIT0;
if ( (gesture == INVALID_GESTURE) || (gestureDetected ==0))
{ /* No gesture was registered previously */
if (last_wheel_position != ILLEGAL_SLIDER_WHEEL_POSITION)
{
/* Transmit last wheel position [twice] via UART to PC */
SendByte(last_wheel_position + WHEEL_POSITION_OFFSET );
SendByte(last_wheel_position + WHEEL_POSITION_OFFSET );
wheelTouchCounter = WHEEL_TOUCH_DELAY - 1;
}
}

if (gestureDetected == 1)
{ /* A gesture was registered previously */

/* Transmit status update: stop gesture tracking [twice] via UART to PC */
SendByte(GESTURE_STOP);
SendByte(GESTURE_STOP);
}

}

// Reset all touch conditions, turn off LEDs,
last_wheel_position= ILLEGAL_SLIDER_WHEEL_POSITION;
gesture = INVALID_GESTURE;
gestureDetected = 0;

}

/* ------------------------------------------------------------------------
* Option:
* Add delay/sleep cycle here to reduce active duty cycle. This lowers power
* consumption but sacrifices wheel responsiveness. Additional timing
* refinement must be taken into consideration when interfacing with PC
* applications GUI to retain proper communication protocol.
* -----------------------------------------------------------------------*/
}
}

void echo(){
char in = getRx();
SendByte(in);
}

void main(void)
{

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

InitLaunchPadCore();
TimerA_UART_init();

/* Set DCO to 1MHz */
/* Set SMCLK to 1MHz / 8 = 125kHz */
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
BCSCTL2 |= DIVS_3;
/* Establish baseline for the proximity sensor */
TI_CAPT_Init_Baseline(&proximity_sensor);
TI_CAPT_Update_Baseline(&proximity_sensor,5);
MeasureCapBaseLine();
__enable_interrupt();
while (1)
{
echo();
CapTouchActiveMode();
}

}
[/code]


and the UART code:

[code]
/*******************************************************************************
*
* uart.c - c file for UART communication using MSP430 TimerA
* - peripheral
*
* Copyright (C) 2011 Texas Instruments Incorporated -
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
******************************************************************************/
#include "uart.h"
unsigned int txData;
unsigned int rxBuffer;

//------------------------------------------------------------------------------
// Function configures Timer_A for full-duplex UART operation
//------------------------------------------------------------------------------
void TimerA_UART_init(void)
{
DCOCTL = 0x00; // Set DCOCLK to 1MHz
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
BCSCTL2 &= ~DIVS_3; // SMCLK = 1MHz

P1SEL |= UART_TXD + UART_RXD; // Timer function for TXD/RXD pins
// P1SEL |= UART_TXD ;
P1DIR |= UART_TXD; // TXD
P1DIR &= ~UART_RXD;

TACCTL0 = OUT; // Set TXD Idle as Mark = '1'
TACCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int
TACTL |= TACLR; // SMCLK, start in continuous mode
TACTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode


}

//------------------------------------------------------------------------------
// Outputs one byte using the Timer_A UART
//------------------------------------------------------------------------------
void TimerA_UART_tx(unsigned char byte)
{
while (TACCTL0 & CCIE); // Ensure last char got TX'd
TACCR0 = TAR; // Current state of TA counter
TACCR0 += UART_TBIT; // One bit time till first bit
txData = byte; // Load global variable
txData |= 0x100; // Add mark stop bit to TXData
txData <<= 1; // Add space start bit
TACCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU2 (idle), Int
__bis_SR_register(GIE);
}
//------------------------------------------------------------------------------
// Prints a string over using the Timer_A UART
//------------------------------------------------------------------------------
void TimerA_UART_print(char *string)
{
while (*string) {
TimerA_UART_tx(*string++);
}
}
//------------------------------------------------------------------------------
// Timer_A UART - Transmit Interrupt Handler
//------------------------------------------------------------------------------
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A0_ISR(void)
{
static unsigned char txBitCnt = 10;
TACCR0 += UART_TBIT; // Add Offset to CCRx
if (--txBitCnt == 0) // All bits TXed?
{
TACCTL0 &= ~CCIE; // All bits TXed, disable interrupt
txBitCnt = 10;
__bic_SR_register_on_exit(GIE);
}
else {
if (txData & 0x01) {
TACCTL0 &= ~OUTMOD2; // TX Mark '1'
}
else {
TACCTL0 |= OUTMOD2; // TX Space '0'
}
txData >>= 1;

}
}


//------------------------------------------------------------------------------
// Timer_A UART - Receive Interrupt Handler
//------------------------------------------------------------------------------
#pragma vector = TIMER0_A1_VECTOR
__interrupt void Timer_A1_ISR(void)
{
static unsigned char rxBitCnt = 8;
static unsigned char rxData = 0;

switch (__even_in_range(TA0IV, TA0IV_TAIFG)) { // Use calculated branching
case TA0IV_TACCR1: // TACCR1 CCIFG - UART RX
TACCR1 += UART_TBIT; // Add Offset to CCRx
if (TACCTL1 & CAP) { // Capture mode = start bit edge
TACCTL1 &= ~CAP; // Switch capture to compare mode
TACCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0
}
else {
rxData >>= 1;
if (TACCTL1 & SCCI) { // Get bit waiting in receive latch
rxData |= 0x80;
}
rxBitCnt--;
if (rxBitCnt == 0) { // All bits RXed?
rxBuffer = rxData; // Store in global variable
rxBitCnt = 8; // Re-load bit counter
TACCTL1 |= CAP; // Switch compare to capture mode
__bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR)
}
}
break;
}
}
//------------------------------------------------------------------------------

int getRx()
{
return rxBuffer;
}

[/code]

**Attention** This is a public forum