Пример #1
0
__interrupt void radio_ISR(void)
#endif
{
#ifdef CONFIG_SWAP
  MRFI_RadioIsr();
#else
  u8 rf1aivec = RF1AIV;

        // Forward to SimpliciTI interrupt service routine
        if (is_rf())
        {
                MRFI_RadioIsr();
        }
        else // BlueRobin packet end interrupt service routine
        {
                if (rf1aivec == RF1AIV_RFIFG9)
                {
                //pfs
                ;
                #ifndef ELIMINATE_BLUEROBIN
                        if ((sBlueRobin.state == BLUEROBIN_SEARCHING) || (sBlueRobin.state == BLUEROBIN_CONNECTED))
                        {
                                BlueRobin_RadioISR_v();
                        }
                #endif
                }
                else if (rf1aivec == RF1AIV_NONE) // RF1A interface interrupt (error etc.)
                {
                        asm("   nop"); // break here
                }
        }
#endif
}
// *************************************************************************************************
// @fn          sx_bluerobin
// @brief       BlueRobin direct function. Button UP connects/disconnects with transmitter unit.
// @param       u8 line         LINE1
// @return      none
// *************************************************************************************************
void sx_bluerobin(u8 line)
{
    u8 stop = 0;

    // Exit if battery voltage is too low for radio operation
    if (sys.flag.low_battery)
        return;

    // Exit if SimpliciTI stack is active
    if (is_rf())
        return;

    // UP: connect / disconnect transmitter
    if (button.flag.up)
    {
        if (sBlueRobin.state == BLUEROBIN_OFF)
        {
            // If no transmitter can be found, stop BlueRobin stack
            if (!start_bluerobin())
                stop = 1;
        }
        else if (sBlueRobin.state == BLUEROBIN_CONNECTED)
        {
            // Shutdown connection
            stop = 1;
        }
    }

    // Shutdown connection
    if (stop)
    {
        stop_bluerobin();
    }
}
Пример #3
0
// *************************************************************************************************
// @fn          sx_rfbsl
// @brief       This functions starts the RFBSL
// @param       line            LINE1, LINE2
// @return      none
// *************************************************************************************************
void sx_rfbsl(u8 line)
{
    // Exit if battery voltage is too low for radio operation
    if (sys.flag.low_battery)
        return;

    // Exit if BlueRobin stack is active
    if (is_bluerobin())
        return;

    // Exit if SimpliciTI stack is active
    if (is_rf())
        return;

    rfBSL_button_confirmation++;

    if (rfBSL_button_confirmation == 2)
    {
        // Before entering RFBSL clear the LINE1 Symbols
        display_symbol(LCD_SYMB_AM, SEG_OFF);

        clear_line(LINE1);

        // Write RAM to indicate we will be downloading the RAM Updater first
        display_chars(LCD_SEG_L2_5_0, (u8 *) " RFBSL", SEG_ON);
        display_chars(LCD_SEG_L1_3_0, (u8 *) " RAM", SEG_ON);

        // Call RFBSL
        CALL_RFSBL();
    }
}
Пример #4
0
__interrupt void radio_ISR(void)
{
    u8 rf1aivec = RF1AIV;

    // Forward to SimpliciTI interrupt service routine
    if (is_rf())
    {
        MRFI_RadioIsr();
    }
    else                                  // BlueRobin packet end interrupt service routine
    {
        if (rf1aivec == RF1AIV_RFIFG9)
        {

        }
        else if (rf1aivec == RF1AIV_NONE) // RF1A interface interrupt (error etc.)
        {
            asm ("	nop"); // break here
        }
    }
}
Пример #5
0
Файл: radio.c Проект: epall/cage
__interrupt void radio_ISR(void)
{
	u8 rf1aivec = RF1AIV;
	
	// Forward to SimpliciTI interrupt service routine
	if (is_rf())
	{
		MRFI_RadioIsr();
	}
	else // BlueRobin packet end interrupt service routine
	{		
		if (rf1aivec == RF1AIV_RFIFG9)
		{    
			if ((sBlueRobin.state == BLUEROBIN_SEARCHING) || (sBlueRobin.state == BLUEROBIN_CONNECTED))
			{
				BlueRobin_RadioISR_v();
			}
		}
		else if (rf1aivec == RF1AIV_NONE) // RF1A interface interrupt (error etc.)
		{
			asm("	nop"); // break here
		}
	}
}
Пример #6
0
__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);
}
// *************************************************************************************************
// @fn          sx_bluerobin
// @brief       BlueRobin direct function. Button UP connects/disconnects with sender unit.
// @param       u8 line		LINE1
// @return      none
// *************************************************************************************************
void sx_bluerobin(u8 line)
{
	u8 stop = 0;
	
	// Exit if battery voltage is too low for radio operation
	if (sys.flag.low_battery) return;
	
	// Exit if SimpliciTI stack is active
	if (is_rf()) return;
		
	// UP: connect / disconnect transmitter
	if(button.flag.up)
	{
		if (sBlueRobin.state == BLUEROBIN_OFF)
		{
			// Init BlueRobin timer and radio
			open_radio();

			// Initialize BR library
			BRRX_Init_v();
			  
			// Set BR data transmission properties
			BRRX_SetPowerdownDelay_v(10);       // Power down channel after 10 consecutive lost data packets (~9 seconds)
			BRRX_SetSearchTimeout_v(8);         // Stop searching after 8 seconds
			
			// Sensitivity in learn mode reduced --> connect only to close transmitters
			// Skip this part if chest strap id was set in a previous learn mode run
#if REMEMBER_TX_ID == TRUE
			if (sBlueRobin.cs_id == 0) BRRX_SetSignalLevelReduction_v(5);

#else
			// Forget previously learned transmitter ID and connect to next close transmitter
			sBlueRobin.cs_id = 0;
			BRRX_SetSignalLevelReduction_v(5);  	
#endif

			// Apply frequency offset compensation to radio register FSCTRL0
			// If calibration memory was erased, rf_frequoffset defaults to 0x00 and has no effect
			WriteSingleReg(FSCTRL0, rf_frequoffset);

			// New state is SEARCH			
			sBlueRobin.state = BLUEROBIN_SEARCHING;	

			// Blink RF icon to show searching
			display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON);
			display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON);
			display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON);

			// Turn on radio and establish connection if channel not already started
			if (BRRX_GetState_t(HR_CHANNEL) == TX_OFF)
			{
				// Start in learn mode (connect to closest heart rate transmitter)
				BRRX_SetID_v(HR_CHANNEL, sBlueRobin.cs_id);
				BRRX_Start_v(HR_CHANNEL);

				// Wait until learning phase is over
			 	while (BRRX_GetState_t(HR_CHANNEL)==TX_SEARCH) 
			 	{
					Timer0_A4_Delay(CONV_MS_TO_TICKS(200));
    			}
			}
			
		 	// Check if connection attempt was successful
			if (BRRX_GetState_t(HR_CHANNEL)==TX_ACTIVE)	
			{
				// Successfully connected to transmitter
				sBlueRobin.state = BLUEROBIN_CONNECTED;		
				
				// When in learn mode, copy chest strap ID
				if (sBlueRobin.cs_id == 0) 
				{
					sBlueRobin.cs_id = BRRX_GetID_u32(HR_CHANNEL);
				}

				// Show steady RF icon to indicate established connection
				display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF);
				display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF);
				display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF);
				// Show blinking icon
				display_symbol(LCD_ICON_HEART, SEG_ON_BLINK_ON);
			}
			else // Error -> Shutdown connection
			{
			  	stop = 1;
			}			
		}
		else if (sBlueRobin.state == BLUEROBIN_CONNECTED)
		{
			// Shutdown connection
			stop = 1;
		}
	}	
	
	// Shutdown connection
	if (stop)
	{
		stop_bluerobin();		
	}
}
Пример #8
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);
}
Пример #9
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;
}
Пример #10
0
Файл: ports.c Проект: 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); 
}
Пример #11
0
__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 BlueRobin searches freeze system state
    if (is_bluerobin_searching())
    {
        // Exit from LPM3 on RETI
        _BIC_SR_IRQ(LPM3_bits);
        return;
    }

    if ((is_rf()) && (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--;
        }
    }

    // -------------------------------------------------------------------
    // Service modules that require 1/min processing
    if (sTime.drawFlag >= 2)
    {
        // Measure battery voltage
        request.flag.voltage_measurement = 1;
    }

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

    // Request data logging
    if (is_datalog())
        request.flag.datalog = 1;

    // Request temperature and pressure measurement
    if (is_altitude_measurement())
        request.flag.altitude_measurement = 1;

    // Get BlueRobin data from API
    if (is_bluerobin())
        get_bluerobin_data();

    // If battery is low, count down 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);
}
Пример #12
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);               
}
Пример #13
0
__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);               
}