// ************************************************************************************************* // @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 #ifdef CONFIG_STOP_WATCH // Redraw stopwatch display if (is_stopwatch_run()) display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_PARTIAL); #endif // Check stop condition if (sys.flag.delay_over) break; } }
__interrupt void PORT2_ISR(void) #endif { u8 int_flag, int_enable; u8 buzzer = 0; #ifndef CONFIG_SWAP u8 simpliciti_button_event = 0; static u8 simpliciti_button_repeat = 0; #endif // 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; #ifndef CONFIG_SWAP // --------------------------------------------------- // 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 { #endif // 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; // Generate button click buzzer = 1; } } // --------------------------------------------------- // NUM button IRQ else if (IRQ_TRIGGERED(int_flag, BUTTON_NUM_PIN)) { // Filter bouncing noise if (BUTTON_NUM_IS_PRESSED) { button.flag.num = 1; // Generate button click buzzer = 1; if( !sys.flag.lock_buttons) { #ifdef CONFIG_STOP_WATCH // Faster reaction for stopwatch split button press if (is_stopwatch_run()) { split_stopwatch(); button.flag.num = 0; } #endif } } } // --------------------------------------------------- // 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; if( !sys.flag.lock_buttons) { #ifdef CONFIG_STOP_WATCH // Faster reaction for stopwatch stop button press if (is_stopwatch_run()) { stop_stopwatch(); button.flag.down = 0; } // Faster reaction for stopwatch start button press else if (is_stopwatch_stop()) { start_stopwatch(); button.flag.down = 0; } #endif } } } // --------------------------------------------------- // 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; button.flag.backlight = 1; } } #ifndef CONFIG_SWAP } #else // Notify button event to the SWAP browser if (isSwapMode()) swButtonEvent(); #endif // Trying to lock/unlock buttons? if ((button.flag.num && button.flag.down) || (button.flag.star && button.flag.up)) { // No buzzer output buzzer = 0; button.all_flags = 0; } // Generate button click when button was activated if (buzzer) { // Any button event stops active alarm #ifdef CONFIG_ALARM if (sAlarm.state == ALARM_ON) { stop_alarm(); button.all_flags = 0; } else #endif #ifdef CONFIG_EGGTIMER if (sEggtimer.state == EGGTIMER_ALARM) { stop_eggtimer_alarm(); button.all_flags = 0; } else #endif if (!sys.flag.up_down_repeat_enabled && !sys.flag.no_beep) { 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)); } #ifdef FEATURE_PROVIDE_ACCEL // --------------------------------------------------- // Acceleration sensor IRQ if (IRQ_TRIGGERED(int_flag, AS_INT_PIN)) { // Get data from sensor request.flag.acceleration_measurement = 1; } #endif // --------------------------------------------------- // 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 Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_LEFT)); // Check if this button event is short enough if (BUTTON_STAR_IS_PRESSED) button.flag.star = 0; if (BUTTON_NUM_IS_PRESSED) button.flag.num = 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); }