Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * state.c
- *
- * Created on: 16 mai 2013
- * Author: Valentin
- *
- * RTC is always running.
- * TOUCH SENSOR detection is running in REPOS state.
- * LEDs are off in REPOS state.
- * LEDs indicate hours in AFF_HOUR state.
- * LEDs indicate minutes in AFF_MIN state.
- */
- #include "state.h"
- extern struct Time temps;
- extern uint16_t minutes;
- extern uint8_t count_time;
- extern const uint8_t pinDir[16];
- extern const uint8_t pinOut[16];
- extern uint8_t touch_press;
- State state = REPOS;
- void updateInputs(void) {
- updateTouchSensor();
- }
- void updateStateMachine(void) {
- switch(state) {
- case REPOS: // Sleep most of the time. Wait for a touch press.
- if(touch_press) {
- //state = WAKE; for DEBUG
- count_time = 0;
- }
- break;
- case WAKE: // Wake up. Monitors long or short press.
- if(count_time > T_LONG_PRESS) { // Long press. Go to settings.
- state = SETTINGS;
- // Save time
- temps.min_rough = (minutes % 60) / 5;
- temps.min_precise = minutes % 5;
- temps.hour = (minutes >> 2) / 15; // minutes / 60
- count_time = 0;
- }
- else if(!touch_press) { // Short press. Go to time display.
- state = AFF_HOUR;
- // Save time
- temps.min_rough = (minutes % 60) / 5;
- temps.min_precise = minutes % 5;
- temps.hour = (minutes >> 2) / 15; // minutes / 60
- count_time = 0;
- }
- break;
- case AFF_HOUR: // Display hour
- if(count_time >= T_AFF) {
- state = AFF_MIN;
- count_time = 0;
- }
- break;
- case AFF_MIN: // Display minutes
- if(count_time >= T_AFF) {
- state = REPOS;
- count_time = 0;
- }
- break;
- case SETTINGS: // Display settings screen.
- if(count_time >= T_AFF) {
- state = SET_HOUR;
- count_time = 0;
- }
- break;
- case SET_HOUR: // Modify hour.
- if(touch_press) {
- state = INC_HOUR;
- incHours();
- count_time = 0;
- }
- else if(count_time > T_TIMEOUT) { // No action since T_TIMEOUT. Next setting.
- state = SET_MIN;
- count_time = 0;
- }
- break;
- case INC_HOUR: // Increment hour
- if(!touch_press) { // Short press : Back to SET_HOUR.
- state = SET_HOUR;
- count_time = 0;
- }
- else if(count_time > T_LONG_PRESS) { // Long press : repeat increment.
- state = INC_HOUR_LONG;
- incHours();
- count_time = 0;
- }
- break;
- case INC_HOUR_LONG: // Increment hour while the button is pressed.
- if(!touch_press) { // Stop increment, back to SET_HOUR.
- state = SET_HOUR;
- count_time = 0;
- }
- else if(count_time > T_REPRESS) { // Long press : repeat increment.
- incHours();
- count_time = 0;
- }
- break;
- case SET_MIN: // Modify minutes.
- if(touch_press) {
- state = INC_MIN;
- incMinutes();
- count_time = 0;
- }
- else if(count_time > T_TIMEOUT) { // No action since T_TIMEOUT. go back to sleep.
- // Save time
- minutes = 5*temps.min_rough + temps.min_precise + (temps.hour << 2)*15;
- state = REPOS;
- count_time = 0;
- }
- break;
- case INC_MIN: // Increment minutes
- if(!touch_press) { // Short press : Back to SET_MIN.
- state = SET_MIN;
- count_time = 0;
- }
- else if(count_time > T_LONG_PRESS) { // Long press : repeat increment.
- state = INC_MIN_LONG;
- incMinutes();
- count_time = 0;
- }
- break;
- case INC_MIN_LONG: // Increment minutes while the button is pressed.
- if(!touch_press) { // Stop increment, back to SET_MIN.
- state = SET_MIN;
- count_time = 0;
- }
- else if(count_time > T_REPRESS) { // Long press : repeat increment.
- incMinutes();
- count_time = 0;
- }
- break;
- default:
- state = REPOS;
- break;
- }
- }
- void updateOutputs() {
- static uint8_t toggle = 0;
- switch(state) {
- case REPOS: // Sleep most of the time. Wait for a touch press.
- // LEDs pins as outputs (low)
- P1OUT &= ~LED_MASK;
- P1DIR |= LED_MASK;
- P1OUT &= ~BIT0;
- _BIS_SR(LPM3_bits + GIE); // Put the MSP430 into LPM3
- break;
- case WAKE: // Wake up. Monitors long or short press.
- break;
- case AFF_HOUR: // Display hour
- case SET_HOUR:
- case INC_HOUR:
- case INC_HOUR_LONG:
- P1DIR &= ~LED_MASK;
- P1OUT &= ~LED_MASK;
- P1DIR |= pinDir[temps.hour];
- P1OUT |= pinOut[temps.hour];
- _BIS_SR(LPM3_bits + GIE); // Put the MSP430 into LPM3
- break;
- case AFF_MIN: // Display minutes
- case SET_MIN:
- case INC_MIN:
- case INC_MIN_LONG:
- P1DIR &= ~LED_MASK;
- P1OUT &= ~LED_MASK;
- if(toggle) { // Display rough minutes
- P1DIR |= pinDir[temps.min_rough];
- P1OUT |= pinOut[temps.min_rough];
- toggle = 0;
- }
- else { // Display precise minutes
- if(temps.min_precise != 0) {
- P1DIR |= pinDir[temps.min_precise+11];
- P1OUT |= pinOut[temps.min_precise+11];
- }
- toggle = 1;
- }
- sleep(5); // 5ms of LPM3
- break;
- case SETTINGS: // Display settings screen.
- P1DIR &= ~LED_MASK;
- P1OUT &= ~LED_MASK;
- if((count_time % 2) == 0) {
- if(toggle) { // Display rough minutes
- P1DIR |= pinDir[0];
- P1OUT |= pinOut[0];
- toggle = 0;
- }
- else { // Display precise minutes
- P1DIR |= pinDir[12];
- P1OUT |= pinOut[12];
- toggle = 1;
- }
- }
- else {
- if(toggle) { // Display rough minutes
- P1DIR |= pinDir[6];
- P1OUT |= pinOut[6];
- toggle = 0;
- }
- else { // Display precise minutes
- P1DIR |= pinDir[14];
- P1OUT |= pinOut[14];
- toggle = 1;
- }
- }
- sleep(5); // 5ms of LPM3
- break;
- }
- }
- void sleep(uint16_t ms) {
- TA0CTL |= TASSEL_1 + ID_3 + MC_1 + TAIE; // ACLK + /8 div + up to CCR0 : (4096 Hz : 244ยตs) + interrupt
- TA0CCR0 = ms << 2;
- P1OUT &= ~BIT0;
- _BIS_SR(LPM3_bits+GIE); // Enter LPM3
- }
- void incHours(void) {
- temps.hour = (temps.hour + 1) % 12;
- }
- void incMinutes(void) {
- if(temps.min_precise == 4) {
- temps.min_precise = 0;
- if(temps.min_rough == 11) {
- temps.min_rough = 0;
- }
- else {
- temps.min_rough++;
- }
- }
- else {
- temps.min_precise++;
- }
- }
- /******************************************************************************/
- // Timer0_A1 Overflow Interrupt Service Routine: Exists LPM3
- /******************************************************************************/
- #pragma vector=TIMER0_A1_VECTOR
- __interrupt void sleep_int(void) {
- _BIC_SR_IRQ(LPM3_bits); // Exits LPM3
- P1OUT |= BIT0;
- TA0CTL &= ~(BIT4 + BIT5 + BIT0); // Stop timerA and clear IFG
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement