__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(); } }
// ************************************************************************************************* // @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(); } }
__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 } } }
__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 } } }
__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(); } }
__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); }
__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 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 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); }
__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); }
__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); }