__interrupt void TIMER0_A0_ISR(void)
{
    static u8 button_lock_counter = 0;

    // Disable IE
    TA0CCTL0 &= ~CCIE;
    // Reset IRQ flag
    TA0CCTL0 &= ~CCIFG;
    // Add 1 sec to TACCR0 register (IRQ will be asserted at 0x7FFF and 0xFFFF = 1 sec intervals)
    TA0CCR0 += 32768;
    // Enable IE
    TA0CCTL0 |= CCIE;

    // Add 1 second to global time
    clock_tick();

    // Set clock update flag
    display.flag.update_time = 1;

    // While SimpliciTI stack operates or BlueRobin searches, freeze system state
    if (is_rf() || is_bluerobin_searching())
    {
        // SimpliciTI automatic timeout
        if (sRFsmpl.timeout == 0)
        {
            simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
        }
        else
        {
            sRFsmpl.timeout--;
        }

        // switch message after received packet
        if (sRFsmpl.mode == SIMPLICITI_SYNC)
        {
            if (sRFsmpl.display_sync_done == 0)
            {
                display_chars(LCD_SEG_L2_5_0, (u8 *) "  SYNC", SEG_ON);
            }
            else
            {
                sRFsmpl.display_sync_done--;
            }
        }
        // Exit from LPM3 on RETI
        _BIC_SR_IRQ(LPM3_bits);
        return;
    }

    // -------------------------------------------------------------------
    // Service modules that require 1/min processing
    if (sTime.drawFlag >= 2)
    {
        // Measure battery voltage to keep track of remaining battery life
        request.flag.voltage_measurement = 1;

        // Check if alarm needs to be turned on
        check_alarm();
    }

    // -------------------------------------------------------------------
    // Service active modules that require 1/s processing

    // Generate alarm signal
    if (sAlarm.state == ALARM_ON)
    {
        // Decrement alarm duration counter
        if (sAlarm.duration-- > 0)
        {
            request.flag.buzzer = 1;
        }
        else
        {
            sAlarm.duration = ALARM_ON_DURATION;
            stop_alarm();
        }
    }

    // Do a temperature measurement each second while menu item is active
    if (is_temp_measurement())
        request.flag.temperature_measurement = 1;

    // Do a pressure measurement each second while menu item is active
    if (is_altitude_measurement())
    {
        // Countdown altitude measurement timeout while menu item is active
        sAlt.timeout--;

        // Stop measurement when timeout has elapsed
        if (sAlt.timeout == 0)
        {
            stop_altitude_measurement();
            // Show ---- m/ft
            display_chars(LCD_SEG_L1_3_0, (u8 *) "----", SEG_ON);
            // Clear up/down arrow
            display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
            display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
        }

        // In case we missed the IRQ due to debouncing, get data now
        if ((PS_INT_IN & PS_INT_PIN) == PS_INT_PIN)
            request.flag.altitude_measurement = 1;
    }

    // Count down timeout
    if (is_acceleration_measurement())
    {
        // Countdown acceleration measurement timeout
        sAccel.timeout--;

        // Stop measurement when timeout has elapsed
        if (sAccel.timeout == 0)
        {
            as_stop();
            // Show ----
            display_chars(LCD_SEG_L1_3_0, (u8 *) "----", SEG_ON);
            // Clear up/down arrow
            display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
            display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
            display_symbol(LCD_SEG_L1_DP1, SEG_OFF);
        }

        // If DRDY is (still) high, request data again
        if ((AS_INT_IN & AS_INT_PIN) == AS_INT_PIN)
            request.flag.acceleration_measurement = 1;
    }

    // If BlueRobin transmitter is connected, get data from API
    if (is_bluerobin())
        get_bluerobin_data();

    // If battery is low, decrement display counter
    if (sys.flag.low_battery)
    {
        if (sBatt.lobatt_display-- == 0)
        {
            message.flag.prepare = 1;
            message.flag.type_lobatt = 1;
            sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE;
        }
    }

    // If a message has to be displayed, set display flag
    if (message.all_flags)
    {
        if (message.flag.prepare)
        {
            message.flag.prepare = 0;
            message.flag.show = 1;
        }
        else if (message.flag.erase)    // message cycle is over, so erase it
        {
            message.flag.erase = 0;
            display.flag.full_update = 1;
        }
    }

    // -------------------------------------------------------------------
    // Check idle timeout, set timeout flag
    if (sys.flag.idle_timeout_enabled)
    {
        if (sTime.system_time - sTime.last_activity > INACTIVITY_TIME)
            sys.flag.idle_timeout = 1;  //setFlag(sysFlag_g, SYS_TIMEOUT_IDLE);
    }

    // -------------------------------------------------------------------
    // Turn the Backlight off after timeout
    if (sButton.backlight_status == 1)
    {
        if (sButton.backlight_timeout > BACKLIGHT_TIME_ON)
        {
            //turn off Backlight
            P2OUT &= ~BUTTON_BACKLIGHT_PIN;
            P2DIR &= ~BUTTON_BACKLIGHT_PIN;
            sButton.backlight_timeout = 0;
            sButton.backlight_status = 0;
        }
        else
        {
            sButton.backlight_timeout++;
        }
    }

    // -------------------------------------------------------------------
    // Detect continuous button high states

    // Trying to lock/unlock buttons?
    if (BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED)
    {
        if (button_lock_counter++ > LEFT_BUTTON_LONG_TIME)
        {
            // Toggle lock / unlock buttons flag
            sys.flag.lock_buttons = ~sys.flag.lock_buttons;

            // Show "buttons are locked/unlocked" message synchronously with next second tick
            message.flag.prepare = 1;
            if (sys.flag.lock_buttons)
                message.flag.type_locked = 1;
            else
                message.flag.type_unlocked = 1;

            // Reset button lock counter
            button_lock_counter = 0;
        }
    }
    else                        // Trying to create a long button press?
    {
        // Reset button lock counter
        button_lock_counter = 0;

        if (BUTTON_STAR_IS_PRESSED)
        {
            sButton.star_timeout++;

            // Check if button was held low for some seconds
            if (sButton.star_timeout > LEFT_BUTTON_LONG_TIME)
            {
                button.flag.star_long = 1;
                button.flag.star_not_long = 0;
                sButton.star_timeout = 0;
                // Return interrupt edge to normal value
                BUTTONS_IES &= ~BUTTON_STAR_PIN;
            }
        }
        else                    // there was a button press not long enough
        {
            sButton.star_timeout = 0;
        }

        if (BUTTON_NUM_IS_PRESSED)
        {
            sButton.num_timeout++;

            // Check if button was held low for some seconds
            if (sButton.num_timeout > LEFT_BUTTON_LONG_TIME)
            {
                button.flag.num_long = 1;
                button.flag.num_not_long = 0;
                sButton.num_timeout = 0;
                // Return interrupt edge to normal value
                BUTTONS_IES &= ~BUTTON_NUM_PIN;
            }
        }
        else                    // there was a button press not long enough
        {
            sButton.num_timeout = 0;
        }
    }

    // Exit from LPM3 on RETI
    _BIC_SR_IRQ(LPM3_bits);
}
Exemple #2
0
__interrupt void TIMER0_A0_ISR(void)
#endif
{
	static u8 button_lock_counter = 0;
	static u8 button_beep_counter = 0;
	
	// Disable IE 
	TA0CCTL0 &= ~CCIE;
	// Reset IRQ flag  
	TA0CCTL0 &= ~CCIFG;  
	// Add 1 sec to TACCR0 register (IRQ will be asserted at 0x7FFF and 0xFFFF = 1 sec intervals)
	TA0CCR0 += 32768;
	// Enable IE 
	TA0CCTL0 |= CCIE;
	
	// Add 1 second to global time
	clock_tick();
	
	// Set clock update flag
	display.flag.update_time = 1;
	
	// While SimpliciTI stack operates or BlueRobin searches, freeze system state
	//pfs
	#ifdef ELIMINATE_BLUEROBIN
	if (is_rf())
	#else
	if (is_rf() || is_bluerobin_searching()) 
	#endif
	{
		// SimpliciTI automatic timeout
		if (sRFsmpl.timeout == 0) 
		{
			simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
		}
		else
		{
			sRFsmpl.timeout--;
		}
		
		// Exit from LPM3 on RETI
		_BIC_SR_IRQ(LPM3_bits);     
		return;
	}
	
	// -------------------------------------------------------------------
	// Service modules that require 1/min processing
	if (sTime.drawFlag >= 2) 
	{
		#ifdef CONFIG_BATTERY
		// Measure battery voltage to keep track of remaining battery life
		request.flag.voltage_measurement = 1;
		#endif
		
		#ifdef CONFIG_ALARM
		// If the chime is enabled, we beep here
		if (sTime.minute == 0) {
			if (sAlarm.hourly == ALARM_ENABLED) {
				request.flag.alarm_buzzer = 1;
			}
            #if (CONFIG_DST > 0)
            if ((sTime.hour == 1) &&
                (dst_state == 0) &&
                dst_isDateInDST(sDate.month, sDate.day))
            {
                // spring forward
                sTime.hour++;
                dst_state = 1;
            }
            if ((sTime.hour == 2) &&
                (dst_state != 0) &&
                (!dst_isDateInDST(sDate.month, sDate.day)))
            {
                // fall back
                sTime.hour--;
                dst_state = 0;
            }
            #endif
		}
		// Check if alarm needs to be turned on
		check_alarm();
		#endif
		#ifdef CONFIG_ALTI_ACCUMULATOR
		// Check if we need to do an altitude accumulation
		if (alt_accum_enable)
			request.flag.altitude_accumulator = 1;
		#endif
	}

	// -------------------------------------------------------------------
	// Service active modules that require 1/s processing
#ifdef CONFIG_EGGTIMER
	if (sEggtimer.state == EGGTIMER_RUN) {
		eggtimer_tick(); // Subtract 1 second from eggtimer's count
	}

	if (sEggtimer.state == EGGTIMER_ALARM) { // no "else if" intentional
		// Decrement alarm duration counter
		if (sEggtimer.duration-- > 0)
		{
			request.flag.eggtimer_buzzer = 1;
		}
		else
		{
			stop_eggtimer_alarm(); // Set state to Stop and reset duration
		}
	}
#endif
	#ifdef CONFIG_ALARM
	// Generate alarm signal
	if (sAlarm.state == ALARM_ON) 
	{
		// Decrement alarm duration counter
		if (sAlarm.duration-- > 0)
		{
			request.flag.alarm_buzzer = 1;
		}
		else
		{
			sAlarm.duration = ALARM_ON_DURATION;
			stop_alarm();
		}
	}
	#endif
	
#ifdef CONFIG_PROUT
        if (is_prout()) prout_tick();
#endif
		
#ifdef CONFIG_STRENGTH
        // One more second gone by.
        if(is_strength())
	{
		strength_tick();
	}            
#endif

	// Do a temperature measurement each second while menu item is active
	if (is_temp_measurement()) request.flag.temperature_measurement = 1;
	
	// Do a pressure measurement each second while menu item is active
#ifdef CONFIG_ALTITUDE
	if (is_altitude_measurement()) 
	{
		// Countdown altitude measurement timeout while menu item is active
		sAlt.timeout--;

		// Stop measurement when timeout has elapsed
		if (sAlt.timeout == 0)	
		{
			stop_altitude_measurement();
			// Show ---- m/ft
			display_chars(LCD_SEG_L1_3_0, (u8*)"----", SEG_ON);
			// Clear up/down arrow
			display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
			display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
		}
		
		// In case we missed the IRQ due to debouncing, get data now
		if ((PS_INT_IN & PS_INT_PIN) == PS_INT_PIN) request.flag.altitude_measurement = 1;
	}	
#endif

#ifdef FEATURE_PROVIDE_ACCEL
	// Count down timeout
	if (is_acceleration_measurement()) 
	{
		// Countdown acceleration measurement timeout 
		sAccel.timeout--;

		// Stop measurement when timeout has elapsed
		if (sAccel.timeout == 0) as_stop();	
		
		// If DRDY is (still) high, request data again
		if ((AS_INT_IN & AS_INT_PIN) == AS_INT_PIN) request.flag.acceleration_measurement = 1; 
	}	
#endif

	//pfs
#ifndef ELIMINATE_BLUEROBIN
	// If BlueRobin transmitter is connected, get data from API
	if (is_bluerobin()) get_bluerobin_data();
#endif
	
	#ifdef CONFIG_BATTERY
	// If battery is low, decrement display counter
	if (sys.flag.low_battery)
	{
		if (sBatt.lobatt_display-- == 0) 
		{
			message.flag.prepare = 1;
			message.flag.type_lobatt = 1;
			sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE;
		}
	}
	#endif
	
	// If a message has to be displayed, set display flag
	if (message.all_flags)
	{
		if (message.flag.prepare)
		{
			message.flag.prepare = 0;
			message.flag.show    = 1;
		}
		else if (message.flag.erase) // message cycle is over, so erase it
		{
			message.flag.erase       = 0;
			message.flag.block_line1 = 0;
			message.flag.block_line2 = 0;
			display.flag.full_update = 1;
		}	
	}
	
	// -------------------------------------------------------------------
	// Check idle timeout, set timeout flag
	if (sys.flag.idle_timeout_enabled)
	{
		if (sTime.system_time - sTime.last_activity > INACTIVITY_TIME) sys.flag.idle_timeout = 1; //setFlag(sysFlag_g, SYS_TIMEOUT_IDLE);
	}
	
	// -------------------------------------------------------------------
	// Turn the Backlight off after timeout
	if (sButton.backlight_status == 1)
	{
		if (sButton.backlight_timeout > BACKLIGHT_TIME_ON)
		{
			//turn off Backlight
			P2OUT &= ~BUTTON_BACKLIGHT_PIN;
			P2DIR &= ~BUTTON_BACKLIGHT_PIN;
			sButton.backlight_timeout = 0;
			sButton.backlight_status = 0;
		}
		else
		{
			sButton.backlight_timeout++;
		}
	}
	// -------------------------------------------------------------------
	// Detect continuous button high states

	if (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED)
	{
		if (button_beep_counter++ > LEFT_BUTTON_LONG_TIME)
		{
			// Toggle no_beep buttons flag
			sys.flag.no_beep = ~sys.flag.no_beep;
	
			// Show "beep / nobeep" message synchronously with next second tick
			message.flag.prepare = 1;
			if (sys.flag.no_beep)	message.flag.type_no_beep_on   = 1;
			else					message.flag.type_no_beep_off  = 1;
			
			// Reset button beep counter
			button_beep_counter = 0;
		}
	} else if (BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED) // Trying to lock/unlock buttons?
	{
		if (button_lock_counter++ > LEFT_BUTTON_LONG_TIME)
		{
			// Toggle lock / unlock buttons flag
			sys.flag.lock_buttons = ~sys.flag.lock_buttons;
	
			// Show "buttons are locked/unlocked" message synchronously with next second tick
			message.flag.prepare = 1;
			if (sys.flag.lock_buttons)	message.flag.type_locked   = 1;
			else						message.flag.type_unlocked = 1;
			
			// Reset button lock counter
			button_lock_counter = 0;
		}
	}
	else // Trying to create a long button press?
	{
		// Reset button lock counter
		button_lock_counter = 0;
		
		if (BUTTON_STAR_IS_PRESSED) 	
		{
			sButton.star_timeout++;
			
			// Check if button was held low for some seconds
			if (sButton.star_timeout > LEFT_BUTTON_LONG_TIME) 
			{
				button.flag.star_long = 1;
				sButton.star_timeout = 0;
			}
		}
		else
		{
			sButton.star_timeout = 0;
		}
	
		if (BUTTON_NUM_IS_PRESSED) 	
		{
			sButton.num_timeout++;
		
			// Check if button was held low for some seconds
			if (sButton.num_timeout > LEFT_BUTTON_LONG_TIME) 
			{
				button.flag.num_long = 1;
				sButton.num_timeout = 0;
			}
		}
		else
		{
			sButton.num_timeout = 0;
		}
	}
	
	// Exit from LPM3 on RETI
	_BIC_SR_IRQ(LPM3_bits);               
}
Exemple #3
0
__interrupt void RTC_A_ISR(void)
#endif
{
	sTime.second++;
	if (sTime.second == 60) sTime.second = 0;
	
	static u8 button_lock_counter = 0; //gibbons TODO: need to put these just in the 1-sec interrupt section?
	static u8 button_beep_counter = 0;
	
#ifdef CONFIG_CW
	u8 CW_Message[] = "NOON\0";
#endif
	
	switch (RTCIV) {
		case RTC_RT0PSIFG: // Interval timer (16384Hz - 128Hz interrupts (binary powers) )
			// gibbons TODO: put stopwatch 1/100 sec interrupt here?
			break;
			
		case RTC_RT1PSIFG: // Interval timer (64Hz - 0.5Hz interrupts (binary powers) )
			break;
			
		case RTC_RTCRDYIFG: // RTC registers ready and safe to read (Use this for 1-sec update)
			
			// Add 1 second to stored (global) time, update sTime.drawFlag appropriately
			clock_tick();
			
			// Set clock update flag
			display.flag.update_time = 1;
			
			// While SimpliciTI stack operates or BlueRobin searches, freeze system state
			//pfs
#ifdef ELIMINATE_BLUEROBIN
			if (is_rf())
#else
			if (is_rf() || is_bluerobin_searching()) 
#endif
			{
				// SimpliciTI automatic timeout
				if (sRFsmpl.timeout == 0) 
				{
					simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
				}
				else
				{
					sRFsmpl.timeout--;
				}
				
				// Exit from LPM3 on RETI
				_BIC_SR_IRQ(LPM3_bits);     
				return;
			}
			
			// -------------------------------------------------------------------
			// Service modules that require 1/min processing
			if (sTime.drawFlag >= 2) 
			{
				// Measure battery voltage to keep track of remaining battery life
				request.flag.voltage_measurement = 1;
				
				// Check if alarm needs to be turned on
				//check_alarm(); //gibbons TODO: remove
			}

			// -------------------------------------------------------------------
			// Service active modules that require 1/s processing
			
#ifdef CONFIG_EGGTIMER
			if (sEggtimer.state == EGGTIMER_RUN) {
				eggtimer_tick(); // Subtract 1 second from eggtimer's count
			}
			
			if (sEggtimer.state == EGGTIMER_ALARM) { // no "else if" intentional
				// Decrement alarm duration counter
				if (sEggtimer.duration-- > 0)
				{
					request.flag.eggtimer_buzzer = 1;
				}
				else
				{
					stop_eggtimer_alarm(); // Set state to Stop and reset duration
				}
			}
#endif
			
			// Generate alarm signal
			if (sAlarm.state == ALARM_ON) 
			{
				// Decrement alarm duration counter
				if (sAlarm.duration-- > 0)
				{
					request.flag.alarm_buzzer = 1;
				}
				else
				{
					stop_alarm();
				}
			}

#ifdef CONFIG_PROUT
			if (is_prout()) prout_tick();
#endif

#ifdef CONFIG_VARIO
			if(is_vario()) vario_tick();
#endif

#ifdef CONFIG_STRENGTH
			// One more second gone by.
			if(is_strength())
			{
				strength_tick();
			}            
#endif

			// Do a temperature measurement each second while menu item is active
			if (is_temp_measurement()) request.flag.temperature_measurement = 1;
			
			// Do a pressure measurement each second while menu item is active
#ifdef CONFIG_ALTITUDE
			if (is_altitude_measurement()) 
			{
				// Countdown altitude measurement timeout while menu item is active
				sAlt.timeout--;

				// Stop measurement when timeout has elapsed
				if (sAlt.timeout == 0)	
				{
					stop_altitude_measurement();
					// Show ---- m/ft
					display_chars(LCD_SEG_L1_3_0, (u8*)"----", SEG_ON);
					// Clear up/down arrow
					display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
					display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
				}
				
				// In case we missed the IRQ due to debouncing, get data now
				if ((PS_INT_IN & PS_INT_PIN) == PS_INT_PIN) request.flag.altitude_measurement = 1;
			}	
#endif

#ifdef FEATURE_PROVIDE_ACCEL
			// Count down timeout
			if (is_acceleration_measurement()) 
			{
				// Countdown acceleration measurement timeout 
				sAccel.timeout--;

				// Stop measurement when timeout has elapsed
				if (sAccel.timeout == 0) as_stop();	
				
				// If DRDY is (still) high, request data again
				if ((AS_INT_IN & AS_INT_PIN) == AS_INT_PIN) request.flag.acceleration_measurement = 1; 
			}	
#endif

			//pfs
#ifndef ELIMINATE_BLUEROBIN
			// If BlueRobin transmitter is connected, get data from API
			if (is_bluerobin()) get_bluerobin_data();
#endif
			
			// If battery is low, decrement display counter
			if (sys.flag.low_battery)
			{
				if (sBatt.lobatt_display-- == 0) 
				{
					message.flag.prepare = 1;
					message.flag.type_lobatt = 1;
					sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE;
				}
			}
			
			// If a message has to be displayed, set display flag
			if (message.all_flags)
			{
				if (message.flag.prepare)
				{
					message.flag.prepare = 0;
					message.flag.show    = 1;
				}
				else if (message.flag.erase) // message cycle is over, so erase it
				{
					message.flag.erase       = 0;
					message.flag.block_line1 = 0;
					message.flag.block_line2 = 0;
					display.flag.full_update = 1;
				}	
			}
			
			// -------------------------------------------------------------------
			// Check idle timeout, set timeout flag
			if (sys.flag.idle_timeout_enabled)
			{
			    if (sTime.last_activity > 0) {
				if (--sTime.last_activity == 0) sys.flag.idle_timeout = 1; //setFlag(sysFlag_g, SYS_TIMEOUT_IDLE);
			    }
			}
			
			// -------------------------------------------------------------------
			// Detect continuous button high states

			if (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED)
			{
				if (button_beep_counter++ > LEFT_BUTTON_LONG_TIME)
				{
					// Toggle no_beep buttons flag
					sys.flag.no_beep = ~sys.flag.no_beep;
			
					// Show "beep / nobeep" message synchronously with next second tick
					message.flag.prepare = 1;
					if (sys.flag.no_beep)	message.flag.type_no_beep_on   = 1;
					else					message.flag.type_no_beep_off  = 1;
					
					// Reset button beep counter
					button_beep_counter = 0;
				}
			} else if (BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED) // Trying to lock/unlock buttons?
			{
				if (button_lock_counter++ > LEFT_BUTTON_LONG_TIME)
				{
					// Toggle lock / unlock buttons flag
					sys.flag.lock_buttons = ~sys.flag.lock_buttons;
			
					// Show "buttons are locked/unlocked" message synchronously with next second tick
					message.flag.prepare = 1;
					if (sys.flag.lock_buttons)	message.flag.type_locked   = 1;
					else						message.flag.type_unlocked = 1;
					
					// Reset button lock counter
					button_lock_counter = 0;
				}
			}
			else // Trying to create a long button press?
			{
				// Reset button lock counter
				button_lock_counter = 0;
				
				if (BUTTON_STAR_IS_PRESSED) 	
				{
					sButton.star_timeout++;
					
					// Check if button was held low for some seconds
					if (sButton.star_timeout > LEFT_BUTTON_LONG_TIME) 
					{
						button.flag.star_long = 1;
						sButton.star_timeout = 0;
					}
				}
				else
				{
					sButton.star_timeout = 0;
				}
			
				if (BUTTON_NUM_IS_PRESSED) 	
				{
					sButton.num_timeout++;
				
					// Check if button was held low for some seconds
					if (sButton.num_timeout > LEFT_BUTTON_LONG_TIME) 
					{
						button.flag.num_long = 1;
						sButton.num_timeout = 0;
					}
				}
				else
				{
					sButton.num_timeout = 0;
				}
			}
			
			
			// Exit from LPM3 on RETI
			_BIC_SR_IRQ(LPM3_bits); //gibbons TODO: move this to other interrupts from the RTC?
			
			break;
			
		case RTC_RTCTEVIFG: // Interval alarm event (min or hour changed, or rollover to midnight or noon) (choose one)
			// Minute, hour, noon, or midnight rollover beep (same beep as button press, at least for now)
#ifdef CONFIG_TIMECHIME
#ifdef CONFIG_CW
			CW_Send_String(CW_Message);
#else
			start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150));
#endif
			if (RTC_Toggle_12Hr) RTCCTL01 ^= 0x0100; // Toggle Time EVent between noon and midnight
#endif
			break;
			
		case RTC_RTCAIFG: // User-configurable alarm event
			// Indicate that alarm is on
			sAlarm.state = ALARM_ON;
			
			break;
	}

	//gibbons: TODO: Remove this old code? (Associated with Timer0_A0 1-sec ISR)
	// Disable IE 
	//TA0CCTL0 &= ~CCIE;
	// Reset IRQ flag  
	//TA0CCTL0 &= ~CCIFG;  
	// Add 1 sec to TACCR0 register (IRQ will be asserted at 0x7FFF and 0xFFFF = 1 sec intervals)
	//TA0CCR0 += 32768; //gibbons TODO: Should this perhaps be (32768 - 1) ?
	// Enable IE 
	//TA0CCTL0 |= CCIE;
}
__interrupt void TIMER0_A0_ISR(void)
{
	static u8 button_lock_counter = 0;
	
	// Disable IE 
	TA0CCTL0 &= ~CCIE;
	// Reset IRQ flag  
	TA0CCTL0 &= ~CCIFG;  
	// Add 1 sec to TACCR0 register (IRQ will be asserted at 0x7FFF and 0xFFFF = 1 sec intervals)
	TA0CCR0 += 32768;
	// Enable IE 
	TA0CCTL0 |= CCIE;
	
	// Add 1 second to global time
	clock_tick();

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// Count down and up
	if (sCountup.mode == COUNTUP_MODE_ON)
	{
		countup_tick();

		if (sCountdown.mode == COUNTDOWN_MODE_ON)
		{
			// Countdown acceleration measurement timeout
			sAccel.timeout--;

			// Stop measurement when timeout has elapsed
			if (sAccel.timeout == 0) as_stop();

			// If DRDY is (still) high, request data again
			if ((AS_INT_IN & AS_INT_PIN) == AS_INT_PIN) request.flag.acceleration_measurement = 1;

			// sAccel.xyz[0] = xaxis, sAccel.xyz[0] = yaxis, sAccel.xyz[0] = zaxis

			if ((sAccel.xyz[0] < sCountdown.thresholdlow[0] || sAccel.xyz[0] > sCountdown.thresholdhigh[0]) &&
				(sAccel.xyz[1] < sCountdown.thresholdlow[1] || sAccel.xyz[1] > sCountdown.thresholdhigh[1]))
			{
			// UNDER THRESHOLD VALUES
				if (sCountdown.speed == 1)
				{
					// Clear timer interrupt enable
					TA0CCTL2 &= ~CCIE;

					countdown_tick();
				}
				if (sCountdown.speed == 2)
				{
					// Recovery loop - set back to default as below threshold
					if (sCountdown.exceedcount[0] != sCountdown.exceeddefault[0])
					{
						sCountdown.exceedcount[0] = sCountdown.exceeddefault[0];
					}

					// Recovery loop - reduce recovery value if under threshold
					if (sCountdown.recoverycount != 0)
					{
						sCountdown.recoverycount--;
					}
					// Set speed to 1 if recovery is back to 0
					else
					{
						sCountdown.speed = 1;
						sCountdown.recoverycount = sCountdown.recoverydefault;
						countdown_tick();
					}
				}
				if (sCountdown.speed == 3)
				{
					// Recovery loop - set back to default as below threshold
					if (sCountdown.exceedcount[1] != sCountdown.exceeddefault[1])
					{
						sCountdown.exceedcount[1] = sCountdown.exceeddefault[1];
					}

					// Recovery loop - reduce recovery value if under threshold
					if (sCountdown.recoverycount != 0)
					{
						sCountdown.recoverycount--;
					}
					// Set speed to 1 if recovery is back to 0
					else
					{
						sCountdown.speed = 1;
						sCountdown.recoverycount = sCountdown.recoverydefault;
						countdown_tick();
					}
				}
			}
			// OVER THRESHOLD VALUES
			else
			{

				sCountdown.recoverycount = sCountdown.recoverydefault;

				if (sCountdown.speed == 1)
				{
					// Increase countdown speed
					sCountdown.speed = 2;

					// Init CCR register with current time
					TA0CCR2 = TA0R;

					// Load CCR register with next capture time
					TA0CCR2 += sCountdown.tickspeed[0];

					// Reset IRQ flag
					TA0CCTL2 &= ~CCIFG;

					// Enable timer interrupt
					TA0CCTL2 |= CCIE;

					countdown_tick();
				}
				if (sCountdown.speed == 2)
				{
					// Counting down from exceed2 limit
					if (sCountdown.exceedcount[0] != 0)
					{
						sCountdown.exceedcount[0]--;
					}
					// Speed up if equal to 0
					else
					{
						sCountdown.exceedcount[0] = sCountdown.exceeddefault[0];

						// Increase countdown speed
						sCountdown.speed = 3;
					}
				}
				if (sCountdown.speed == 3)
				{
					// Counting down from exceed3 limit
					if (sCountdown.exceedcount[1] != 0)
					{
						sCountdown.exceedcount[1]--;
					}
					// Speed up if equal to 0
					else
					{
						countdown_droptozero();
					}
				}
			}
		}
	}
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// Set clock update flag
	display.flag.update_time = 1;
	
	// While SimpliciTI stack operates or BlueRobin searches, freeze system state
	if (is_rf() || is_bluerobin_searching()) 
	{
		// SimpliciTI automatic timeout
		if (sRFsmpl.timeout == 0) 
		{
			simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
		}
		else
		{
			sRFsmpl.timeout--;
		}
		
		// Exit from LPM3 on RETI
		_BIC_SR_IRQ(LPM3_bits);     
		return;
	}
	
	// -------------------------------------------------------------------
	// Service modules that require 1/min processing
	if (sTime.drawFlag >= 2) 
	{
		// Measure battery voltage to keep track of remaining battery life
		request.flag.voltage_measurement = 1;
		
		// Check if alarm needs to be turned on
		check_alarm();
	}

	// -------------------------------------------------------------------
	// Service active modules that require 1/s processing
	
	// Generate alarm signal
	if (sAlarm.state == ALARM_ON) 
	{
		// Decrement alarm duration counter
		if (sAlarm.duration-- > 0)
		{
			request.flag.buzzer = 1;
		}
		else
		{
			sAlarm.duration = ALARM_ON_DURATION;
			stop_alarm();
		}
	}

	// Do a temperature measurement each second while menu item is active
	if (is_temp_measurement()) request.flag.temperature_measurement = 1;
	
	// Do a pressure measurement each second while menu item is active
	if (is_altitude_measurement()) 
	{
		// Countdown altitude measurement timeout while menu item is active
		sAlt.timeout--;

		// Stop measurement when timeout has elapsed
		if (sAlt.timeout == 0)	
		{
			stop_altitude_measurement();
			// Show ---- m/ft
			display_chars(LCD_SEG_L1_3_0, (u8*)"----", SEG_ON);
			// Clear up/down arrow
			display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
			display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
		}
		
		// In case we missed the IRQ due to debouncing, get data now
		if ((PS_INT_IN & PS_INT_PIN) == PS_INT_PIN) request.flag.altitude_measurement = 1;
	}	

	// Count down timeout
	if (is_acceleration_measurement()) 
	{
		// Countdown acceleration measurement timeout 
		sAccel.timeout--;

		// Stop measurement when timeout has elapsed
		if (sAccel.timeout == 0) as_stop();	
		
		// If DRDY is (still) high, request data again
		if ((AS_INT_IN & AS_INT_PIN) == AS_INT_PIN) request.flag.acceleration_measurement = 1; 
	}	

	// If BlueRobin transmitter is connected, get data from API
	if (is_bluerobin()) get_bluerobin_data();
	
	// If battery is low, decrement display counter
	if (sys.flag.low_battery)
	{
		if (sBatt.lobatt_display-- == 0) 
		{
			message.flag.prepare = 1;
			message.flag.type_lobatt = 1;
			sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE;
		}
	}
	
	// If a message has to be displayed, set display flag
	if (message.all_flags)
	{
		if (message.flag.prepare)
		{
			message.flag.prepare = 0;
			message.flag.show    = 1;
		}
		else if (message.flag.erase) // message cycle is over, so erase it
		{
			message.flag.erase       = 0;
			display.flag.full_update = 1;
		}	
	}
	
	// -------------------------------------------------------------------
	// Check idle timeout, set timeout flag
	if (sys.flag.idle_timeout_enabled)
	{
		if (sTime.system_time - sTime.last_activity > INACTIVITY_TIME) sys.flag.idle_timeout = 1; //setFlag(sysFlag_g, SYS_TIMEOUT_IDLE);
	}
	
	// -------------------------------------------------------------------
	// Detect continuous button high states
	
	// Trying to lock/unlock buttons?
	if (BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED)
	{
		if (button_lock_counter++ > LEFT_BUTTON_LONG_TIME)
		{
			// Toggle lock / unlock buttons flag
			sys.flag.lock_buttons = ~sys.flag.lock_buttons;
	
			// Show "buttons are locked/unlocked" message synchronously with next second tick
			message.flag.prepare = 1;
			if (sys.flag.lock_buttons)	message.flag.type_locked   = 1;
			else						message.flag.type_unlocked = 1;
			
			// Reset button lock counter
			button_lock_counter = 0;
		}
	}
	else // Trying to create a long button press?
	{
		// Reset button lock counter
		button_lock_counter = 0;
		
		if (BUTTON_UP_IS_PRESSED)
		{
			sButton.up_timeout++;
			
			// Check if button was held low for some seconds
			if (sButton.up_timeout > LEFT_BUTTON_LONG_TIME)
			{
				button.flag.up_long = 1;
				sButton.up_timeout = 0;
			}
		}
		else
		{
			sButton.up_timeout = 0;
		}
	
		if (BUTTON_DOWN_IS_PRESSED)
		{
			sButton.down_timeout++;
		
			// Check if button was held low for some seconds
			if (sButton.down_timeout > LEFT_BUTTON_LONG_TIME)
			{
				button.flag.down_long = 1;
				sButton.down_timeout = 0;
			}
		}
		else
		{
			sButton.down_timeout = 0;
		}

		if (BUTTON_NUM_IS_PRESSED)
		{
			sButton.num_timeout++;

			// Check if button was held low for some seconds
			if (sButton.num_timeout > LEFT_BUTTON_LONG_TIME)
			{
				button.flag.num_long = 1;
				sButton.num_timeout = 0;
			}
		}
		else
		{
			sButton.num_timeout = 0;
		}
	}
	
	// Exit from LPM3 on RETI
	_BIC_SR_IRQ(LPM3_bits);               
}