Sunteți pe pagina 1din 8

/****************************************************************************** * MSP430G2-LaunchPad Co-op Design Challenge * Juan C.

Garcia * DLP Systems and Algorithms Co-op * TouchLock: This program creates a touch lock, a locking mechanism bas ed * on user's touch- and utilizes the MSP430G2452 along with t he * Capacitive BoosterPack. The code from the CapTouch User Ex perience * has been used to recognize user's input. Pin 1.2 functioni ng as PWM * through TimerA is used to drive a servo that mechanically closes or * opens the lock. An interrupt is set on pin P1.1 to handle the reset * ability of the system. The minimum touch sequence ("passwo rd") allowed * is 4 and the maximum is 30. The wheel-positions values are divided even * further to facilitate handling. * * As stated, code based off CapTouch User Experience by * D. Dang * Texas Instruments, Inc. * Ver 0.90 Feb 2011 * *----------------- 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 *----------------------------------------------------------------------------*/ #include "CTS_Layer.h" /*General constants definitions*/ #define MIDDLE_BUTTON_CODE 0x80 #define COUNTER_CLOCKWISE 1 #define CLOCKWISE 2 #define WHEEL_POSITION_OFFSET 0x30 #define WHEEL_TOUCH_DELAY ouches*/ #define MAX_IDLE_TIME 12 300 /*Delay between re-sendings of t

#define #define */ #define #define #define

PROXIMITY_THRESHOLD MAX_PW_LENGTH MIN_PW_LENGTH OPEN_LOCK CLOSE_LOCK

60 30 4 2500 1605

/*Maximum touch sequence allowed /*Minimum touch sequence allowed*/ /*CCR1 counter value for opening lock*/ /*CCR1 counter value for closing lock*/

/*Sensor variables and touch recognition variables*/ unsigned int wheel_position=ILLEGAL_SLIDER_WHEEL_POSITION, last_wheel_position=I LLEGAL_SLIDER_WHEEL_POSITION; unsigned int deltaCnts[1]; unsigned int prox_raw_Cnts; /*Masks #define #define #define #define #define #define #define #define for multiplexed LED's*/ MASK7 BIT4 MASK6 BIT5 MASK5 BIT6 MASK4 BIT7 MASK3 MASK2 MASK1 MASK0 (BIT3+BIT4+BIT5+BIT6) (BIT3+BIT4+BIT5+BIT7) (BIT3+BIT4+BIT6+BIT7) (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 }; unsigned int rd input; to unsigned int set at reset unsigned int unsigned int unsigned int usercode[MAX_PW_LENGTH]; be checked*/ passcode[MAX_PW_LENGTH]; time*/ pw_length; user_length; lock_open; /*Contains user's current passwo /*Contains user's original password /*Original password length*/ /*Current password length*/ /*Lock State Flag: 1 open, 0 close*/ /*Button generated Reset flag*/

unsigned int reset;

/*Initialize clocks and LED's in MSP430G2452*/ void InitLaunchPadCore(void) { BCSCTL1 |= DIVA_0; // ACLK/(0:1,1:2,2:4,3:8) BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO

P1OUT P1DIR P2SEL P2DIR P2OUT }

&= ~(BIT3+BIT4+BIT5+BIT6+BIT7+BIT0); |= BIT3+BIT4+BIT5+BIT6+BIT7+BIT0; = 0x00; // No XTAL |= (BIT0+BIT4+BIT2+BIT3+BIT1+BIT5); &= ~(BIT0+BIT4+BIT2+BIT3+BIT1+BIT5);

/* Lock stays in LPM3 'sleep' mode, only Proximity Sensor is used to detect * any movement triggering device wake up */ void LockIdleMode(void) { /*Set DCO to 1MHz*/ /*Set SMCLK to 1MHz / 8 = 125kHz*/ BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; BCSCTL2 |= DIVS_3; deltaCnts[0] = 0; /*Sleeping in LPM3 with ACLK/100 = 12Khz/100 = 120Hz wake up interval*/ /*Measure proximity sensor count upon wake up*/ /*Wake up if proximity deltaCnts > THRESHOLD*/ do { TACCR0 = 100; TACTL = TASSEL_1 + MC_1; TACCTL0 |= CCIE; __bis_SR_register(LPM3_bits+GIE); TACCTL0 &= ~CCIE; TI_CAPT_Custom(&proximity_sensor,deltaCnts); } while (deltaCnts[0] <= PROXIMITY_THRESHOLD); } /* 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); } /* Display an LED lighting sequence to indicate the wake up event*/ void LedStartUpSequence(void) { unsigned char i; TACCTL0 = CCIE; // CCR0 interrupt enabled TACTL |= TACLR; TACCR0 = TAR + 500; // 50ms TACTL = TASSEL_1 + MC_1; // ACLK, upmode /*Slow clockwise sequence*/

for(i=0; i<8; i++) { P1OUT = startSequence[i]; __bis_SR_register(LPM3_bits+GIE); __delay_cycles(1000000); TACCR0 = TAR + 500; // 50ms } /*Fast counter-clockwise sequence*/ while(i) { i--; P1OUT = startSequence[i]; __bis_SR_register(LPM3_bits+GIE); TACCR0 = TAR + 500; // 50ms } TACCTL0 &= ~CCIE; P1OUT = 0; } /*Displays counter and clockwise sequences to imitate movement of lock*/ void LedLockOpenCloseSequence(int open_close) { unsigned char i; TACCTL0 = CCIE; // CCR0 interrupt enabled TACTL |= TACLR; TACCR0 = TAR + 500; // 50ms TACTL = TASSEL_1 + MC_1; // ACLK, upmode if(open_close == CLOSE_LOCK){ i = 8; /* Fast counter-clockwise sequence */ while(i) { i--; P1OUT = startSequence[i]; __bis_SR_register(LPM3_bits+GIE); TACCR0 = TAR + 500; // 50ms } } else{ /*Fast counter-clockwise sequence*/ for(i = 0; i < 8; i++) { P1OUT = startSequence[i]; __bis_SR_register(LPM3_bits+GIE); } } TACCTL0 &= ~CCIE; // CCR0 interrupt disabled P1OUT = 0; // Turn off all LEDs } /*Displays an error sequence consisting of lighting up all right LED's and then * all left ones*/ void LedErrorSequence(void) { P1OUT |= BIT3; __delay_cycles(1000000); P1OUT = ~BIT3; __delay_cycles(1000000); P1OUT = 0x00; } /*Sets up the servo and drives it to either open or close the lock*/ void Open_CloseLock(unsigned int counter) {

// CCR0 interrupt disabled // Turn off all LEDs

TACTL = TASSEL_2 + MC_1 + ID_0; P1DIR |= BIT2; P1SEL |= BIT2; CCR0 = 20000; CCTL1 = OUTMOD_7; CCR1 = counter; ockwise __delay_cycles(10000000); .. P1SEL = (P1SEL ^ BIT2); P1DIR = (P1DIR ^ BIT2); with mormal operations }

// // // // // //

SMCLK, up-down mode P1.2 output P1.2 TA1 otions PWM Period CCR1 toggle/set Move clockwise or countercl

// Give servo time to operate. // Disable PWM on Pin 1.2 to // avoid further interference

/*Checks user's input password versus original one*/ unsigned int CheckPasscode(void) { unsigned char i; if(user_length < pw_length || user_length > pw_length){ user_length = 0; return 0; } for(i = 0; i < pw_length; i++){ if(passcode[i] != usercode[i]){ user_length = 0; return 0; } } user_length = 0; return 1; } /*Sets the interrupt for Pin 1.1 to reset password*/ void SetUp_Reset() { P1IE |= 0x02; // P1.0 interrupt enabled for now P1IES |= 0x00; // P1.0 Hi/lo edge for now P1IFG &= ~0x02; // P1.0 IFG cleared for now } void LockActiveMode() { unsigned char activeCounter, passcodeCounter; unsigned char centerButtonTouched = 0; unsigned int continuous_touch; unsigned int pw_ok; unsigned int idleCounter; idleCounter = 0; activeCounter = 0; passcodeCounter = 0; pw_ok = 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 /* Turn on corresponding LED(s) */ P1OUT = (P1OUT & BIT0) | LedWheelPosition[wheel_position]; if(continuous_touch != 1 || wheel_position != last_wheel_position){ if(reset){ passcode[passcodeCounter++] = wheel_position >> 2; } else{ usercode[passcodeCounter++] = wheel_position >> 2; } } idleCounter = 0; // Reset idle counter activeCounter++; last_wheel_position = wheel_position; continuous_touch = 1; } else { /* no wheel position was detected */ continuous_touch = 0; if(TI_CAPT_Button(&middle_button)) { /* Middle button was touched */ if (centerButtonTouched==0){ centerButtonTouched = 1; P1OUT = (P1OUT & BIT0) ^ BIT0; if(reset){ if(passcodeCounter < MIN_PW_LENGTH || passcodeCounter > MAX_PW_L ENGTH){ LedErrorSequence(); pw_length = 0; } else{ pw_length = passcodeCounter; } reset = 0; passcodeCounter = 0; } else{ if(lock_open){ Open_CloseLock(CLOSE_LOCK);

LedLockOpenCloseSequence(CLOSE_LOCK); lock_open = 0; } else{ pw_ok = CheckPasscode(); if(pw_ok){ Open_CloseLock(OPEN_LOCK); LedLockOpenCloseSequence(OPEN_LOCK); lock_open = 1; } else{ LedErrorSequence(); } passcodeCounter = 0; } } } idleCounter = 0; } else { /* No touch was registered at all [Not wheel or center button * / centerButtonTouched = 0; P1OUT &= BIT0; } // Reset all touch conditions, turn off LEDs, last_wheel_position= ILLEGAL_SLIDER_WHEEL_POSITION; user_length = passcodeCounter; if(user_length == MAX_PW_LENGTH || pw_length == MAX_PW_LENGTH){ LedErrorSequence(); //break loop idleCounter = MAX_IDLE_TIME + 1; } } } } /* Main method: appropriate variables * The system behavior is as follows: * * * ns * void main(void) { WDTCTL = WDTPW + WDTHOLD; InitLaunchPadCore(); /* 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); reset = 0; pw_length = MIN_PW_LENGTH; and clocks are initiliazed (i) starts idle (ii) measures proximity sensor (iii)if awoken, sets up reset capability (iv) becomes active; processing happe (v) repeats */ // Stop watchdog timer

while (1) { LockIdleMode(); MeasureCapBaseLine(); LedStartUpSequence(); SetUp_Reset(); LockActiveMode(); } } /* Toggles center LED, sets reset flag and resets pw_length * Assumes lock is open for reset to happen*/ #pragma vector=PORT1_VECTOR __interrupt void Reset_Lock(void) { P1OUT ^= 0x01; // P1.0 = toggle P1IFG &= ~0x02; // P1.1 IFG cleared reset = 1; pw_length = 0; lock_open = 1; } /* Allows to periodically check proximity sensor and * get out of LPM3 if necessary*/ #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A0_ISR(void) { __bic_SR_register_on_exit(LPM3_bits+GIE); }

S-ar putea să vă placă și