Advertisement
Guest User

state.c

a guest
May 18th, 2014
27
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.37 KB | None | 0 0
  1. /*
  2.  * state.c
  3.  *
  4.  *  Created on: 16 mai 2013
  5.  *      Author: Valentin
  6.  *
  7.  *      RTC is always running.
  8.  *      TOUCH SENSOR detection is running in REPOS state.
  9.  *      LEDs are off in REPOS state.
  10.  *      LEDs indicate hours in AFF_HOUR state.
  11.  *      LEDs indicate minutes in AFF_MIN state.
  12.  */
  13.  
  14. #include "state.h"
  15.  
  16. extern struct Time temps;
  17. extern uint16_t minutes;
  18. extern uint8_t count_time;
  19. extern const uint8_t pinDir[16];
  20. extern const uint8_t pinOut[16];
  21. extern uint8_t touch_press;
  22.  
  23. State state = REPOS;
  24.  
  25. void updateInputs(void) {
  26.     updateTouchSensor();
  27. }
  28.  
  29. void updateStateMachine(void) {
  30.     switch(state) {
  31.         case REPOS: // Sleep most of the time. Wait for a touch press.
  32.             if(touch_press) {
  33.                 //state = WAKE; for DEBUG
  34.                 count_time = 0;
  35.             }
  36.             break;
  37.  
  38.         case WAKE:  // Wake up. Monitors long or short press.
  39.             if(count_time > T_LONG_PRESS) { // Long press. Go to settings.
  40.                 state = SETTINGS;
  41.  
  42.                     // Save time
  43.                 temps.min_rough   = (minutes % 60) / 5;
  44.                 temps.min_precise = minutes % 5;
  45.                 temps.hour        = (minutes >> 2) / 15;    // minutes / 60
  46.  
  47.                 count_time = 0;
  48.             }
  49.             else if(!touch_press) { // Short press. Go to time display.
  50.                 state = AFF_HOUR;
  51.  
  52.                     // Save time
  53.                 temps.min_rough   = (minutes % 60) / 5;
  54.                 temps.min_precise = minutes % 5;
  55.                 temps.hour        = (minutes >> 2) / 15;    // minutes / 60
  56.  
  57.                 count_time = 0;
  58.             }
  59.             break;
  60.  
  61.         case AFF_HOUR:  // Display hour
  62.             if(count_time >= T_AFF) {
  63.                 state = AFF_MIN;
  64.                 count_time = 0;
  65.             }
  66.             break;
  67.  
  68.         case AFF_MIN:   // Display minutes
  69.             if(count_time >= T_AFF) {
  70.                 state = REPOS;
  71.                 count_time = 0;
  72.             }
  73.             break;
  74.  
  75.         case SETTINGS:  // Display settings screen.
  76.             if(count_time >= T_AFF) {
  77.                 state = SET_HOUR;
  78.                 count_time = 0;
  79.             }
  80.             break;
  81.  
  82.         case SET_HOUR:  // Modify hour.
  83.             if(touch_press) {
  84.                 state = INC_HOUR;
  85.                 incHours();
  86.                 count_time = 0;
  87.             }
  88.             else if(count_time > T_TIMEOUT) {   // No action since T_TIMEOUT. Next setting.
  89.                 state = SET_MIN;
  90.                 count_time = 0;
  91.             }
  92.             break;
  93.  
  94.         case INC_HOUR:  // Increment hour
  95.             if(!touch_press) {  // Short press : Back to SET_HOUR.
  96.                 state = SET_HOUR;
  97.                 count_time = 0;
  98.             }
  99.             else if(count_time > T_LONG_PRESS) {    // Long press : repeat increment.
  100.                 state = INC_HOUR_LONG;
  101.                 incHours();
  102.                 count_time = 0;
  103.             }
  104.             break;
  105.  
  106.         case INC_HOUR_LONG: // Increment hour while the button is pressed.
  107.             if(!touch_press) {  // Stop increment, back to SET_HOUR.
  108.                 state = SET_HOUR;
  109.                 count_time = 0;
  110.             }
  111.             else if(count_time > T_REPRESS) {   // Long press : repeat increment.
  112.                 incHours();
  113.                 count_time = 0;
  114.             }
  115.             break;
  116.  
  117.         case SET_MIN:   // Modify minutes.
  118.             if(touch_press) {
  119.                 state = INC_MIN;
  120.                 incMinutes();
  121.                 count_time = 0;
  122.             }
  123.             else if(count_time > T_TIMEOUT) {   // No action since T_TIMEOUT. go back to sleep.
  124.                     // Save time
  125.                 minutes = 5*temps.min_rough + temps.min_precise + (temps.hour << 2)*15;
  126.  
  127.                 state = REPOS;
  128.                 count_time = 0;
  129.             }
  130.             break;
  131.  
  132.         case INC_MIN:   // Increment minutes
  133.             if(!touch_press) {  // Short press : Back to SET_MIN.
  134.                 state = SET_MIN;
  135.                 count_time = 0;
  136.             }
  137.             else if(count_time > T_LONG_PRESS) {    // Long press : repeat increment.
  138.                 state = INC_MIN_LONG;
  139.                 incMinutes();
  140.                 count_time = 0;
  141.             }
  142.             break;
  143.  
  144.         case INC_MIN_LONG:  // Increment minutes while the button is pressed.
  145.             if(!touch_press) {  // Stop increment, back to SET_MIN.
  146.                 state = SET_MIN;
  147.                 count_time = 0;
  148.             }
  149.             else if(count_time > T_REPRESS) {   // Long press : repeat increment.
  150.                 incMinutes();
  151.  
  152.                 count_time = 0;
  153.             }
  154.             break;
  155.  
  156.         default:
  157.             state = REPOS;
  158.             break;
  159.     }
  160. }
  161.  
  162. void updateOutputs() {
  163.     static uint8_t toggle = 0;
  164.  
  165.     switch(state) {
  166.     case REPOS: // Sleep most of the time. Wait for a touch press.
  167.             // LEDs pins as outputs (low)
  168.         P1OUT &= ~LED_MASK;
  169.         P1DIR |= LED_MASK;
  170.  
  171.         P1OUT &= ~BIT0;
  172.         _BIS_SR(LPM3_bits + GIE);   // Put the MSP430 into LPM3
  173.         break;
  174.  
  175.     case WAKE:  // Wake up. Monitors long or short press.
  176.         break;
  177.  
  178.     case AFF_HOUR:  // Display hour
  179.     case SET_HOUR:
  180.     case INC_HOUR:
  181.     case INC_HOUR_LONG:
  182.         P1DIR &= ~LED_MASK;
  183.         P1OUT &= ~LED_MASK;
  184.  
  185.         P1DIR |= pinDir[temps.hour];
  186.         P1OUT |= pinOut[temps.hour];
  187.  
  188.         _BIS_SR(LPM3_bits + GIE);   // Put the MSP430 into LPM3
  189.         break;
  190.  
  191.     case AFF_MIN:   // Display minutes
  192.     case SET_MIN:
  193.     case INC_MIN:
  194.     case INC_MIN_LONG:
  195.         P1DIR &= ~LED_MASK;
  196.         P1OUT &= ~LED_MASK;
  197.  
  198.         if(toggle) {    // Display rough minutes
  199.             P1DIR |= pinDir[temps.min_rough];
  200.             P1OUT |= pinOut[temps.min_rough];
  201.  
  202.             toggle = 0;
  203.         }
  204.         else {  // Display precise minutes
  205.             if(temps.min_precise != 0) {
  206.                 P1DIR |= pinDir[temps.min_precise+11];
  207.                 P1OUT |= pinOut[temps.min_precise+11];
  208.             }
  209.  
  210.             toggle = 1;
  211.         }
  212.         sleep(5);       // 5ms of LPM3
  213.         break;
  214.  
  215.     case SETTINGS:  // Display settings screen.
  216.         P1DIR &= ~LED_MASK;
  217.         P1OUT &= ~LED_MASK;
  218.  
  219.         if((count_time % 2) == 0) {
  220.             if(toggle) {    // Display rough minutes
  221.                 P1DIR |= pinDir[0];
  222.                 P1OUT |= pinOut[0];
  223.  
  224.                 toggle = 0;
  225.             }
  226.             else {  // Display precise minutes
  227.                 P1DIR |= pinDir[12];
  228.                 P1OUT |= pinOut[12];
  229.  
  230.                 toggle = 1;
  231.             }
  232.         }
  233.         else {
  234.             if(toggle) {    // Display rough minutes
  235.                 P1DIR |= pinDir[6];
  236.                 P1OUT |= pinOut[6];
  237.  
  238.                 toggle = 0;
  239.             }
  240.             else {  // Display precise minutes
  241.                 P1DIR |= pinDir[14];
  242.                 P1OUT |= pinOut[14];
  243.  
  244.                 toggle = 1;
  245.             }
  246.         }
  247.         sleep(5);       // 5ms of LPM3
  248.         break;
  249.     }
  250. }
  251.  
  252. void sleep(uint16_t ms) {
  253.     TA0CTL |= TASSEL_1 + ID_3 + MC_1 + TAIE;    // ACLK + /8 div + up to CCR0 : (4096 Hz : 244ยตs) + interrupt
  254.     TA0CCR0 = ms << 2;
  255.  
  256.     P1OUT &= ~BIT0;
  257.     _BIS_SR(LPM3_bits+GIE);                     // Enter LPM3
  258. }
  259.  
  260. void incHours(void) {
  261.     temps.hour = (temps.hour + 1) % 12;
  262. }
  263.  
  264. void incMinutes(void) {
  265.     if(temps.min_precise == 4) {
  266.         temps.min_precise = 0;
  267.         if(temps.min_rough == 11) {
  268.             temps.min_rough = 0;
  269.         }
  270.         else {
  271.             temps.min_rough++;
  272.         }
  273.     }
  274.     else {
  275.         temps.min_precise++;
  276.     }
  277. }
  278.  
  279. /******************************************************************************/
  280. // Timer0_A1 Overflow Interrupt Service Routine: Exists LPM3
  281. /******************************************************************************/
  282. #pragma vector=TIMER0_A1_VECTOR
  283. __interrupt void sleep_int(void) {
  284.     _BIC_SR_IRQ(LPM3_bits);                 // Exits LPM3
  285.     P1OUT |= BIT0;
  286.  
  287.     TA0CTL &= ~(BIT4 + BIT5 + BIT0);        // Stop timerA and clear IFG
  288. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement