__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); }
__interrupt void RTC_A_ISR(void) #endif { sTime.second++; if (sTime.second == 60) sTime.second = 0; static u8 button_lock_counter = 0; //gibbons TODO: need to put these just in the 1-sec interrupt section? static u8 button_beep_counter = 0; #ifdef CONFIG_CW u8 CW_Message[] = "NOON\0"; #endif switch (RTCIV) { case RTC_RT0PSIFG: // Interval timer (16384Hz - 128Hz interrupts (binary powers) ) // gibbons TODO: put stopwatch 1/100 sec interrupt here? break; case RTC_RT1PSIFG: // Interval timer (64Hz - 0.5Hz interrupts (binary powers) ) break; case RTC_RTCRDYIFG: // RTC registers ready and safe to read (Use this for 1-sec update) // Add 1 second to stored (global) time, update sTime.drawFlag appropriately clock_tick(); // Set clock update flag display.flag.update_time = 1; // While SimpliciTI stack operates or BlueRobin searches, freeze system state //pfs #ifdef ELIMINATE_BLUEROBIN if (is_rf()) #else if (is_rf() || is_bluerobin_searching()) #endif { // SimpliciTI automatic timeout if (sRFsmpl.timeout == 0) { simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; } else { sRFsmpl.timeout--; } // Exit from LPM3 on RETI _BIC_SR_IRQ(LPM3_bits); return; } // ------------------------------------------------------------------- // Service modules that require 1/min processing if (sTime.drawFlag >= 2) { // Measure battery voltage to keep track of remaining battery life request.flag.voltage_measurement = 1; // Check if alarm needs to be turned on //check_alarm(); //gibbons TODO: remove } // ------------------------------------------------------------------- // Service active modules that require 1/s processing #ifdef CONFIG_EGGTIMER if (sEggtimer.state == EGGTIMER_RUN) { eggtimer_tick(); // Subtract 1 second from eggtimer's count } if (sEggtimer.state == EGGTIMER_ALARM) { // no "else if" intentional // Decrement alarm duration counter if (sEggtimer.duration-- > 0) { request.flag.eggtimer_buzzer = 1; } else { stop_eggtimer_alarm(); // Set state to Stop and reset duration } } #endif // Generate alarm signal if (sAlarm.state == ALARM_ON) { // Decrement alarm duration counter if (sAlarm.duration-- > 0) { request.flag.alarm_buzzer = 1; } else { stop_alarm(); } } #ifdef CONFIG_PROUT if (is_prout()) prout_tick(); #endif #ifdef CONFIG_VARIO if(is_vario()) vario_tick(); #endif #ifdef CONFIG_STRENGTH // One more second gone by. if(is_strength()) { strength_tick(); } #endif // Do a temperature measurement each second while menu item is active if (is_temp_measurement()) request.flag.temperature_measurement = 1; // Do a pressure measurement each second while menu item is active #ifdef CONFIG_ALTITUDE if (is_altitude_measurement()) { // Countdown altitude measurement timeout while menu item is active sAlt.timeout--; // Stop measurement when timeout has elapsed if (sAlt.timeout == 0) { stop_altitude_measurement(); // Show ---- m/ft display_chars(LCD_SEG_L1_3_0, (u8*)"----", SEG_ON); // Clear up/down arrow display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); } // In case we missed the IRQ due to debouncing, get data now if ((PS_INT_IN & PS_INT_PIN) == PS_INT_PIN) request.flag.altitude_measurement = 1; } #endif #ifdef FEATURE_PROVIDE_ACCEL // Count down timeout if (is_acceleration_measurement()) { // Countdown acceleration measurement timeout sAccel.timeout--; // Stop measurement when timeout has elapsed if (sAccel.timeout == 0) as_stop(); // If DRDY is (still) high, request data again if ((AS_INT_IN & AS_INT_PIN) == AS_INT_PIN) request.flag.acceleration_measurement = 1; } #endif //pfs #ifndef ELIMINATE_BLUEROBIN // If BlueRobin transmitter is connected, get data from API if (is_bluerobin()) get_bluerobin_data(); #endif // If battery is low, decrement display counter if (sys.flag.low_battery) { if (sBatt.lobatt_display-- == 0) { message.flag.prepare = 1; message.flag.type_lobatt = 1; sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE; } } // If a message has to be displayed, set display flag if (message.all_flags) { if (message.flag.prepare) { message.flag.prepare = 0; message.flag.show = 1; } else if (message.flag.erase) // message cycle is over, so erase it { message.flag.erase = 0; message.flag.block_line1 = 0; message.flag.block_line2 = 0; display.flag.full_update = 1; } } // ------------------------------------------------------------------- // Check idle timeout, set timeout flag if (sys.flag.idle_timeout_enabled) { if (sTime.last_activity > 0) { if (--sTime.last_activity == 0) sys.flag.idle_timeout = 1; //setFlag(sysFlag_g, SYS_TIMEOUT_IDLE); } } // ------------------------------------------------------------------- // Detect continuous button high states if (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED) { if (button_beep_counter++ > LEFT_BUTTON_LONG_TIME) { // Toggle no_beep buttons flag sys.flag.no_beep = ~sys.flag.no_beep; // Show "beep / nobeep" message synchronously with next second tick message.flag.prepare = 1; if (sys.flag.no_beep) message.flag.type_no_beep_on = 1; else message.flag.type_no_beep_off = 1; // Reset button beep counter button_beep_counter = 0; } } else if (BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED) // Trying to lock/unlock buttons? { if (button_lock_counter++ > LEFT_BUTTON_LONG_TIME) { // Toggle lock / unlock buttons flag sys.flag.lock_buttons = ~sys.flag.lock_buttons; // Show "buttons are locked/unlocked" message synchronously with next second tick message.flag.prepare = 1; if (sys.flag.lock_buttons) message.flag.type_locked = 1; else message.flag.type_unlocked = 1; // Reset button lock counter button_lock_counter = 0; } } else // Trying to create a long button press? { // Reset button lock counter button_lock_counter = 0; if (BUTTON_STAR_IS_PRESSED) { sButton.star_timeout++; // Check if button was held low for some seconds if (sButton.star_timeout > LEFT_BUTTON_LONG_TIME) { button.flag.star_long = 1; sButton.star_timeout = 0; } } else { sButton.star_timeout = 0; } if (BUTTON_NUM_IS_PRESSED) { sButton.num_timeout++; // Check if button was held low for some seconds if (sButton.num_timeout > LEFT_BUTTON_LONG_TIME) { button.flag.num_long = 1; sButton.num_timeout = 0; } } else { sButton.num_timeout = 0; } } // Exit from LPM3 on RETI _BIC_SR_IRQ(LPM3_bits); //gibbons TODO: move this to other interrupts from the RTC? break; case RTC_RTCTEVIFG: // Interval alarm event (min or hour changed, or rollover to midnight or noon) (choose one) // Minute, hour, noon, or midnight rollover beep (same beep as button press, at least for now) #ifdef CONFIG_TIMECHIME #ifdef CONFIG_CW CW_Send_String(CW_Message); #else start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150)); #endif if (RTC_Toggle_12Hr) RTCCTL01 ^= 0x0100; // Toggle Time EVent between noon and midnight #endif break; case RTC_RTCAIFG: // User-configurable alarm event // Indicate that alarm is on sAlarm.state = ALARM_ON; break; } //gibbons: TODO: Remove this old code? (Associated with Timer0_A0 1-sec ISR) // Disable IE //TA0CCTL0 &= ~CCIE; // Reset IRQ flag //TA0CCTL0 &= ~CCIFG; // Add 1 sec to TACCR0 register (IRQ will be asserted at 0x7FFF and 0xFFFF = 1 sec intervals) //TA0CCR0 += 32768; //gibbons TODO: Should this perhaps be (32768 - 1) ? // Enable IE //TA0CCTL0 |= CCIE; }
__interrupt void TIMER0_A0_ISR(void) { static u8 button_lock_counter = 0; // Disable IE TA0CCTL0 &= ~CCIE; // Reset IRQ flag TA0CCTL0 &= ~CCIFG; // Add 1 sec to TACCR0 register (IRQ will be asserted at 0x7FFF and 0xFFFF = 1 sec intervals) TA0CCR0 += 32768; // Enable IE TA0CCTL0 |= CCIE; // Add 1 second to global time clock_tick(); // 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); }
extern void display_vario( u8 line, u8 update ) { static u8 _idone; // initialisation helper static u8 _vbeat; // heartbeat u32 pressure; switch( update ) { case DISPLAY_LINE_CLEAR: stop_buzzer(); display_symbol( LCD_ICON_BEEPER1, SEG_OFF ); display_symbol( LCD_ICON_BEEPER2, SEG_OFF ); display_symbol( LCD_ICON_RECORD, SEG_OFF ); _display_l2_clean(); return; case DISPLAY_LINE_UPDATE_FULL: display_symbol( LCD_ICON_BEEPER1, ( G_vario.beep_mode ) ? SEG_ON : SEG_OFF ); display_symbol( LCD_ICON_BEEPER2, ( ( G_vario.beep_mode == VARIO_BEEPMODE_ASCENT_0 ) || ( G_vario.beep_mode == VARIO_BEEPMODE_BOTH )) ? SEG_ON : SEG_OFF ); // // fall through to partial update // case DISPLAY_LINE_UPDATE_PARTIAL: break; } #if VARIO_F_TIME // Update flight time regardless of whether we do have an altitude. // // Be careful to only update the time when a time update is active, // ie, not because this refresh is due to a DOWN button press. // if ( display.flag.update_time ) { G_vario.stats.f_time.ss++; if ( G_vario.stats.f_time.ss > 59 ) { G_vario.stats.f_time.ss = 0; G_vario.stats.f_time.mm++; if ( G_vario.stats.f_time.mm > 59 ) { G_vario.stats.f_time.mm = 0; G_vario.stats.f_time.hh++; } // Reset flight time after 19 hours, more will not fit on lcd ! if ( G_vario.stats.f_time.hh > 19 ) G_vario.stats.f_time.hh = 0; } } #endif // // Partial or full update. Make sure pressure sensor is being sampled, ie, // that line 1 is in altimeter mode. // if ( is_altitude_measurement() ) { s16 diff; if ( vario_p_read( &pressure ) ) { // Happens during key presses, never mind. return; // no data, wait for update } // // If this is the very first time we are here, we have no previous // pressure, handle that situation. // if ( !_idone ) { diff = 0; ++_idone; } else { // // Calculate difference in Pascal - we will need it anyway for the // buzzer. Pressure decreases with altitude, ensure going lower is // negative. // diff = G_vario.prev_pa - pressure; #if VARIO_VZ // update stats as we may want to see these after the flight. if ( diff > G_vario.stats.vzmax ) G_vario.stats.vzmax = diff; if ( diff < G_vario.stats.vzmin ) G_vario.stats.vzmin = diff; #endif #if VARIO_ALTMAX // Peek at current altitude in altimeter data. if ( G_vario.stats.altmax < sAlt.altitude ) G_vario.stats.altmax = sAlt.altitude; #endif } _display_l2_clean(); // Pulse the vario heartbeat indicator. ++_vbeat; display_symbol( LCD_ICON_RECORD, ( _vbeat & 1 ) ? SEG_ON : SEG_OFF ); // Now see what value to display. switch( G_vario.view_mode ) { case VARIO_VIEWMODE_ALT_M: // // convert the difference in Pa to a vertical velocity. // _display_signed( _pascal_to_vz( diff ), 1 ); break; #if VARIO_ALT_PA case VARIO_VIEWMODE_ALT_PA: // // display raw difference in Pascal. // _display_signed( diff, 0 ); break; #endif #if VARIO_PA case VARIO_VIEWMODE_PA: // // display pressure as hhhh.pp (hPa and Pa) // _display_signed( pressure, 1 ); break; #endif #if VARIO_VZ case VARIO_VIEWMODE_VZMAX: display_symbol( LCD_SYMB_MAX, SEG_ON); _display_signed( _pascal_to_vz( G_vario.stats.vzmax ), 1 ); break; case VARIO_VIEWMODE_VZMIN: display_symbol( LCD_SYMB_MAX, SEG_ON); _display_signed( _pascal_to_vz( G_vario.stats.vzmin ), 1 ); break; #endif #if VARIO_ALTMAX case VARIO_VIEWMODE_ALT_MAX: display_symbol( LCD_SYMB_MAX, SEG_ON); _display_signed( G_vario.stats.altmax, 0 ); break; #endif #if VARIO_F_TIME case VARIO_VIEWMODE_F_TIME: display_chars(LCD_SEG_L2_5_0, int_to_array(G_vario.stats.f_time.hh,2,0), SEG_ON); display_chars(LCD_SEG_L2_3_0, int_to_array(G_vario.stats.f_time.mm,2,0), SEG_ON); display_chars(LCD_SEG_L2_1_0, int_to_array(G_vario.stats.f_time.ss,2,0), SEG_ON); display_symbol(LCD_SEG_L2_COL1, SEG_ON); display_symbol(LCD_SEG_L2_COL0, SEG_ON); break; #endif case VARIO_VIEWMODE_MAX: break; } // switch view mode // If beeper is enabled, beep. switch ( G_vario.beep_mode ) { case VARIO_BEEPMODE_ASCENT_0: if ( diff >= 0 ) chirp( diff ); break; case VARIO_BEEPMODE_ASCENT_1: if ( diff > 0 ) chirp( diff ); break; case VARIO_BEEPMODE_BOTH: if ( diff ) chirp( diff ); break; case VARIO_BEEPMODE_OFF: case VARIO_BEEPMODE_MAX: break; } // update previous pressure measurement. G_vario.prev_pa = pressure; } // L1 is in altimeter mode else { _display_l2_clean(); display_chars(LCD_SEG_L2_5_0, (u8*) " NOALT", SEG_ON); _idone = 0; // avoid false peaks when re-enabling the altimeter } }