Exemplo n.º 1
0
// *************************************************************************************************
// @fn          Timer0_A4_Delay
// @brief       Wait for some microseconds
// @param       ticks (1 tick = 1/32768 sec)
// @return      none
// *************************************************************************************************
void Timer0_A4_Delay(u16 ticks)
{
    u16 value = 0;

    // Exit immediately if Timer0 not running - otherwise we'll get stuck here
    if ((TA0CTL & (BIT4 | BIT5)) == 0)
        return;

    // Disable timer interrupt
    TA0CCTL4 &= ~CCIE;

    // Clear delay_over flag
    sys.flag.delay_over = 0;

    // Add delay to current timer value
    // To make sure this value is correctly read
    while (value != TA0R)
        value = TA0R;
    value += ticks;

    // Update CCR
    TA0CCR4 = value;

    // Reset IRQ flag
    TA0CCTL4 &= ~CCIFG;

    // Enable timer interrupt
    TA0CCTL4 |= CCIE;

    // Wait for timer IRQ
    while (1)
    {
        // Delay in LPM
        to_lpm();               // will also set GIE again

#ifdef USE_WATCHDOG
        // Service watchdog
        WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
#endif
        // Redraw stopwatch display
        if (is_stopwatch())
            display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_PARTIAL);

        // Check stop condition
        // disable interrupt to prevent flag's change caused by interrupt methods
        __disable_interrupt();
        if (sys.flag.delay_over)
            break;
    }
    __enable_interrupt();
}
Exemplo n.º 2
0
// *************************************************************************************************
// @fn          Timer0_A4_Delay
// @brief       Wait for some microseconds
// @param       ticks (1 tick = 1/32768 sec)
// @return      none
// *************************************************************************************************
void Timer0_A4_Delay(u16 ticks)
{
	u16 value;
	
	// Exit immediately if Timer0 not running - otherwise we'll get stuck here
	if ((TA0CTL & (BIT4 | BIT5)) == 0) return;    

	// Disable timer interrupt    
	TA0CCTL4 &= ~CCIE; 	

	// Clear delay_over flag
	sys.flag.delay_over = 0;
	
	// Add delay to current timer value
	value = TA0R + ticks;
	
	// Update CCR
	TA0CCR4 = value;   

	// Reset IRQ flag    
	TA0CCTL4 &= ~CCIFG; 
	          
	// Enable timer interrupt    
	TA0CCTL4 |= CCIE; 
	
	// Wait for timer IRQ
	while (1)
	{
		// Delay in LPM
		to_lpm();

#ifdef USE_WATCHDOG		
		// Service watchdog
		WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
#endif
		// Redraw stopwatch display
		if (is_stopwatch()) display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_PARTIAL);

		// Redraw countdown display
		if (is_countdown_active()) display_countdown(LINE1, DISPLAY_LINE_UPDATE_PARTIAL);

		// Redraw countup display
		if (is_countup_active()) display_countup(LINE2, DISPLAY_LINE_UPDATE_PARTIAL);

		// Check stop condition
		if (sys.flag.delay_over) break;
	}
}
Exemplo n.º 3
0
__interrupt void PORT2_ISR(void)
{
    // Clear flags
    u8 int_flag, int_enable;
    u8 buzzer = 0;
    u8 simpliciti_button_event = 0;
    static u8 simpliciti_button_repeat = 0;

    // Remember interrupt enable bits
    int_enable = BUTTONS_IE;

    if ((!button.flag.star_long) && (!button.flag.num_long))
    {
        // Clear button flags
        button.all_flags = 0;

        // Store valid button interrupt flag
        int_flag = BUTTONS_IFG & int_enable;

        // ---------------------------------------------------
        // While SimpliciTI stack is active, buttons behave differently:
        //  - Store button events in SimpliciTI packet data
        //  - Exit SimpliciTI when button DOWN was pressed
        if (is_rf())
        {
            // Erase previous button press after a number of resends (increase number if link
            // quality is low)
            // This will create a series of packets containing the same button press
            // Necessary because we have no acknowledge
            // Filtering (edge detection) will be done by receiver software
            if (simpliciti_button_repeat++ > 6)
            {
                simpliciti_data[0] &= ~0xF0;
                simpliciti_button_repeat = 0;
            }

            if ((int_flag & BUTTON_STAR_PIN) == BUTTON_STAR_PIN)
            {
                simpliciti_data[0] |= SIMPLICITI_BUTTON_STAR;
                simpliciti_button_event = 1;
            }
            else if ((int_flag & BUTTON_NUM_PIN) == BUTTON_NUM_PIN)
            {
                simpliciti_data[0] |= SIMPLICITI_BUTTON_NUM;
                simpliciti_button_event = 1;
            }
            else if ((int_flag & BUTTON_UP_PIN) == BUTTON_UP_PIN)
            {
                simpliciti_data[0] |= SIMPLICITI_BUTTON_UP;
                simpliciti_button_event = 1;
            }
            else if ((int_flag & BUTTON_DOWN_PIN) == BUTTON_DOWN_PIN)
            {
                simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
            }

            // Trigger packet sending inside SimpliciTI stack
            if (simpliciti_button_event)
                simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA;
        }
        else                    // Normal operation
        {
            // Debounce buttons
            if ((int_flag & ALL_BUTTONS) != 0)
            {
                // Disable PORT2 IRQ
                __disable_interrupt();
                BUTTONS_IE = 0x00;
                __enable_interrupt();

                // Debounce delay 1
                Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN));

                // Reset inactivity detection
                sTime.last_activity = sTime.system_time;
            }

            // ---------------------------------------------------
            // STAR button IRQ
            if (IRQ_TRIGGERED(int_flag, BUTTON_STAR_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_STAR_IS_PRESSED)
                {
                    button.flag.star = 1;
                    button.flag.star_not_long = 0;
                    // Generate button click
                    buzzer = 1;
                }
                else if ((BUTTONS_IES & BUTTON_STAR_PIN) == BUTTON_STAR_PIN)
                {
                    button.flag.star = 1;
                    button.flag.star_not_long = 0;
                    BUTTONS_IES &= ~BUTTON_STAR_PIN;
                }
            }
            // ---------------------------------------------------
            // NUM button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_NUM_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_NUM_IS_PRESSED)
                {
                    button.flag.num = 1;
                    button.flag.num_not_long = 0;
                    // Generate button click
                    buzzer = 1;
                }
                else if ((BUTTONS_IES & BUTTON_NUM_PIN) == BUTTON_NUM_PIN)
                {
                    button.flag.num = 1;
                    button.flag.num_not_long = 0;
                    BUTTONS_IES &= ~BUTTON_NUM_PIN;
                }
            }
            // ---------------------------------------------------
            // UP button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_UP_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_UP_IS_PRESSED)
                {
                    button.flag.up = 1;

                    // Generate button click
                    buzzer = 1;
                }
            }
            // ---------------------------------------------------
            // DOWN button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_DOWN_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_DOWN_IS_PRESSED)
                {
                    button.flag.down = 1;

                    // Generate button click
                    buzzer = 1;

                    // Faster reaction for stopwatch stop button press
                    if (is_stopwatch() && !sys.flag.lock_buttons)
                    {
                        stop_stopwatch();
                        button.flag.down = 0;
                    }
                }
            }
            // ---------------------------------------------------
            // B/L button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_BACKLIGHT_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_BACKLIGHT_IS_PRESSED)
                {
                    sButton.backlight_status = 1;
                    sButton.backlight_timeout = 0;
                    P2OUT |= BUTTON_BACKLIGHT_PIN;
                    P2DIR |= BUTTON_BACKLIGHT_PIN;
                }
            }
        }

        // Trying to lock/unlock buttons?
        if (button.flag.num && button.flag.down)
        {
            // No buzzer output
            buzzer = 0;
            button.all_flags = 0;
        }

        // Generate button click when button was activated
        if (buzzer)
        {
            // Any button event stops active alarm
            if (sAlarm.state == ALARM_ON)
            {
                stop_alarm();
                button.all_flags = 0;
            }
            else if (!sys.flag.up_down_repeat_enabled)
            {
                start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150));
            }

            // Debounce delay 2
            Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT));
        }

        // ---------------------------------------------------
        // Acceleration sensor IRQ
        if (IRQ_TRIGGERED(int_flag, AS_INT_PIN))
        {
            // Get data from sensor
            request.flag.acceleration_measurement = 1;
        }

        // ---------------------------------------------------
        // Pressure sensor IRQ
        if (IRQ_TRIGGERED(int_flag, PS_INT_PIN))
        {
            // Get data from sensor
            request.flag.altitude_measurement = 1;
        }

        // ---------------------------------------------------
        // Safe long button event detection
        if (button.flag.star || button.flag.num)
        {
            // Additional debounce delay to enable safe high detection - 50ms
            Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_LEFT));

            // Check if this button event is short enough
            if (BUTTON_STAR_IS_PRESSED)
            {
                // Change interrupt edge to detect button release
                BUTTONS_IES |= BUTTON_STAR_PIN;
                button.flag.star = 0;
                // This flag is used to detect if the user released the button before the
                // time for a long button press (3s)
                button.flag.star_not_long = 1;
            }
            if (BUTTON_NUM_IS_PRESSED)
            {
                // Change interrupt edge to detect button release
                BUTTONS_IES |= BUTTON_NUM_PIN;
                button.flag.num = 0;
                // This flag is used to detect if the user released the button before the
                // time for a long button press (3s)
                button.flag.num_not_long = 1;
            }
        }

    }
    // Reenable PORT2 IRQ
    __disable_interrupt();
    BUTTONS_IFG = 0x00;
    BUTTONS_IE = int_enable;
    __enable_interrupt();

    // Exit from LPM3/LPM4 on RETI
    __bic_SR_register_on_exit(LPM4_bits);
}
Exemplo n.º 4
0
Arquivo: ports.c Projeto: epall/cage
__interrupt void PORT2_ISR(void)
{
	u8 int_flag, int_enable;
	u8 buzzer = 0;
	u8 simpliciti_button_event = 0;
	static u8 simpliciti_button_repeat = 0;

	// Clear button flags
	button.all_flags = 0;

	// Remember interrupt enable bits
	int_enable = BUTTONS_IE;

	// Store valid button interrupt flag
	int_flag = BUTTONS_IFG & int_enable;

	// ---------------------------------------------------
	// While SimpliciTI stack is active, buttons behave differently:
	//  - Store M1/M2/S1 button events in SimpliciTI packet data
	//  - Exit SimpliciTI when S2 was pressed 
  	if (is_rf())
  	{
  		// Erase previous button press after a number of resends (increase number if link quality is low)
  		// This will create a series of packets containing the same button press
  		// Necessary because we have no acknowledge
  		// Filtering (edge detection) will be done by receiver software
  		if (simpliciti_button_repeat++ > 6) 
  		{
  			simpliciti_data[0] &= ~0xF0;
  			simpliciti_button_repeat = 0;
  		}
  		
  		if ((int_flag & BUTTON_M1_PIN) == BUTTON_M1_PIN)			
  		{
  			simpliciti_data[0] |= SIMPLICITI_BUTTON_M1;
  			simpliciti_button_event = 1;
  		}
  		else if ((int_flag & BUTTON_M2_PIN) == BUTTON_M2_PIN)	
  		{
  			simpliciti_data[0] |= SIMPLICITI_BUTTON_M2;
  			simpliciti_button_event = 1;
  		}
		else if ((int_flag & BUTTON_S1_PIN) == BUTTON_S1_PIN)	
		{
			simpliciti_data[0] |= SIMPLICITI_BUTTON_S1;
			simpliciti_button_event = 1;
		}
		else if ((int_flag & BUTTON_S2_PIN) == BUTTON_S2_PIN)	
		{
			simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
		}
		
		// Trigger packet sending inside SimpliciTI stack
		if (simpliciti_button_event) simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA;
  	}
  	else // Normal operation
  	{
		// Debounce buttons
		if ((int_flag & ALL_BUTTONS) != 0)
		{ 
			// Disable PORT2 IRQ
			__disable_interrupt();
			BUTTONS_IE = 0x00; 
			__enable_interrupt();
	
			// Debounce delay 1
			Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN));
	
			// Reset inactivity detection
			sTime.last_activity = sTime.system_time;
			
			// Reset M button high detection
			sTime.previous_m_button_event = sTime.system_time;
		}

		// ---------------------------------------------------
		// M1 button IRQ
		if (IRQ_TRIGGERED(int_flag, BUTTON_M1_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_M1_IS_PRESSED)
			{
				button.flag.m1 = 1;
				
				sys.flag.mask_m1_button = 0;
		
				// Generate button click
				buzzer = 1;
			}
		}
		// ---------------------------------------------------
		// M2 button IRQ
		else if (IRQ_TRIGGERED(int_flag, BUTTON_M2_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_M2_IS_PRESSED)
			{
				button.flag.m2 = 1;
				
				sys.flag.mask_m2_button = 0;
	
				// Generate button click
				buzzer = 1;
			}
		}
		// ---------------------------------------------------
		// S1 button IRQ
		else if (IRQ_TRIGGERED(int_flag, BUTTON_S1_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_S1_IS_PRESSED)
			{
				button.flag.s1 = 1;
		
				// Generate button click
				buzzer = 1;
			}
		}
		// ---------------------------------------------------
		// S2 button IRQ
		else if (IRQ_TRIGGERED(int_flag, BUTTON_S2_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_S2_IS_PRESSED)
			{
				button.flag.s2 = 1;
	
				// Generate button click
				buzzer = 1;
				
				// Faster reaction for stopwatch stop button press
				if (is_stopwatch()) 
				{
					stop_stopwatch();
					button.flag.s2 = 0;
				}
					
			}
		}
		// ---------------------------------------------------
		// B/L button IRQ
		else if (IRQ_TRIGGERED(int_flag, BUTTON_BL_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_BL_IS_PRESSED)
			{
				button.flag.bl = 1;
			}
		}	
	}

	// Generate button click when button was activated
	if (buzzer)
	{
		// Any button event stops active alarm
		if (sAlarm.state == ALARM_ON) 
		{
			stop_alarm();
			button.all_flags = 0;
		}
		else if (!sys.flag.s_button_repeat_enabled)
		{
			start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150));
		}
		
		// Debounce delay 2
		Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT));
	}
	
	// ---------------------------------------------------
	// Acceleration sensor IRQ
	if (IRQ_TRIGGERED(int_flag, AS_INT_PIN))
	{
		// Get data from sensor
		request.flag.acceleration_measurement = 1;
  	}
  	
  	// ---------------------------------------------------
	// Pressure sensor IRQ
	if (IRQ_TRIGGERED(int_flag, PS_INT_PIN)) 
	{
		// Get data from sensor
		request.flag.altitude_measurement = 1;
  	}
  	
  	// ---------------------------------------------------
  	// Enable safe long button event detection
  	if(button.flag.m1 || button.flag.m2) 
	{
		// Additional debounce delay to enable safe high detection
		Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_M));
	
		// Check if this button event is short enough
		if (BUTTON_M1_IS_PRESSED) button.flag.m1 = 0;
		if (BUTTON_M2_IS_PRESSED) button.flag.m2 = 0;	
	}
	
	// Reenable PORT2 IRQ
	__disable_interrupt();
	BUTTONS_IFG = 0x00; 	
	BUTTONS_IE  = int_enable; 	
	__enable_interrupt();

	// Exit from LPM3/LPM4 on RETI
	__bic_SR_register_on_exit(LPM4_bits); 
}
__interrupt void PORT2_ISR(void)
{
    // Clear flags
    unsigned char int_flag, int_enable;
    unsigned char buzzer = 0;

    // Remember interrupt enable bits
    int_enable = BUTTONS_IE;

    if ((!button.flag.star_long) && (!button.flag.num_long))
    {
        // Clear button flags
        button.all_flags = 0;

        // Store valid button interrupt flag
        int_flag = BUTTONS_IFG & int_enable;

        {
            // Debounce buttons
            if ((int_flag & ALL_BUTTONS) != 0)
            {
                // Disable PORT2 IRQ
                __disable_interrupt();
                BUTTONS_IE = 0x00;
                __enable_interrupt();

                // Debounce delay 1
                Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN));
            }

            // ---------------------------------------------------
            // STAR button IRQ
            if (IRQ_TRIGGERED(int_flag, BUTTON_STAR_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_STAR_IS_PRESSED)
                {
                    button.flag.star = 1;
                    button.flag.star_not_long = 0;
                    // Generate button click
                    buzzer = 1;
                }
                else if ((BUTTONS_IES & BUTTON_STAR_PIN) == BUTTON_STAR_PIN)
                {
                    button.flag.star = 1;
                    button.flag.star_not_long = 0;
                    BUTTONS_IES &= ~BUTTON_STAR_PIN;
                }
            }
            // ---------------------------------------------------
            // NUM button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_NUM_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_NUM_IS_PRESSED)
                {
                    button.flag.num = 1;
                    button.flag.num_not_long = 0;
                    // Generate button click
                    buzzer = 1;
                }
                else if ((BUTTONS_IES & BUTTON_NUM_PIN) == BUTTON_NUM_PIN)
                {
                    button.flag.num = 1;
                    button.flag.num_not_long = 0;
                    BUTTONS_IES &= ~BUTTON_NUM_PIN;
                }
            }
            // ---------------------------------------------------
            // UP button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_UP_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_UP_IS_PRESSED)
                {
                    button.flag.up = 1;

                    // Generate button click
                    buzzer = 1;
                }
            }
            // ---------------------------------------------------
            // DOWN button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_DOWN_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_DOWN_IS_PRESSED)
                {
                    button.flag.down = 1;

                    // Generate button click
                    buzzer = 1;

                    // Faster reaction for stopwatch stop button press
                    if (is_stopwatch() && !sys.flag.lock_buttons)
                    {
                        stop_stopwatch();
                        button.flag.down = 0;
                    }
                }
            }
            // ---------------------------------------------------
            // B/L button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_BACKLIGHT_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_BACKLIGHT_IS_PRESSED)
                {
                    sButton.backlight_status = 1;
                    sButton.backlight_timeout = 0;
                    P2OUT |= BUTTON_BACKLIGHT_PIN;
                    P2DIR |= BUTTON_BACKLIGHT_PIN;
                }
            }
        }

        // Trying to lock/unlock buttons?
        if (button.flag.num && button.flag.down)
        {
            // No buzzer output
            buzzer = 0;
            button.all_flags = 0;
        }

        // ---------------------------------------------------
        // Acceleration sensor IRQ
        if (IRQ_TRIGGERED(int_flag, AS_INT_PIN))
        {
            // Get data from sensor
            request.flag.acceleration_measurement = 1;
        }

        // ---------------------------------------------------
        // Safe long button event detection
        if (button.flag.star || button.flag.num)
        {
            // Additional debounce delay to enable safe high detection - 50ms
            Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_LEFT));

            // Check if this button event is short enough
            if (BUTTON_STAR_IS_PRESSED)
            {
                // Change interrupt edge to detect button release
                BUTTONS_IES |= BUTTON_STAR_PIN;
                button.flag.star = 0;
                // This flag is used to detect if the user released the button before the
                // time for a long button press (3s)
                button.flag.star_not_long = 1;
            }
            if (BUTTON_NUM_IS_PRESSED)
            {
                // Change interrupt edge to detect button release
                BUTTONS_IES |= BUTTON_NUM_PIN;
                button.flag.num = 0;
                // This flag is used to detect if the user released the button before the
                // time for a long button press (3s)
                button.flag.num_not_long = 1;
            }
        }

    }
    // Reenable PORT2 IRQ
    __disable_interrupt();
    BUTTONS_IFG = 0x00;
    BUTTONS_IE = int_enable;
    __enable_interrupt();

    // Exit from LPM3/LPM4 on RETI
    __bic_SR_register_on_exit(LPM4_bits);
}