Example #1
0
// Disp a specific screen
void DisplayManager::display() {
  lcd.clear(); lcd.setCursor(0, 0);

  if (display_mode == -2) {
    display_menu();
    return;
  }

  switch (display_mode) {
  case DATETIME:
    display_datetime();
    break;

  case POSITION:
    display_position();
    break;

  case ALTITUDE:
    display_altitude();
    break;

  case BATTERYM:
    display_battery();
    break;

  default:
    lcd.print(satellites);
    lcd.setCursor(0, 1);
    lcd.print(iterations);
    return;
  }
}
Example #2
0
void update(enum sys_message msg)
{
	read_altitude();
    
	display_altitude(sAlt.altitude, 0);
    
    display_climb(sAlt.climb, ALT_SCREEN_CLIMB);

    display_altitude(sAlt.minAltitude, ALT_SCREEN_MIN);
	display_altitude(sAlt.maxAltitude, ALT_SCREEN_MAX);
    
    display_altitude(sAlt.accuClimbDown, ALT_SCREEN_ACC_N);
    display_altitude(sAlt.accuClimbUp, ALT_SCREEN_ACC_P);
    
    if((accelerometer == 1) &&(submenuState == 0)){
        display_clear(0 ,2);
        display_chars(0, LCD_SEG_L2_4_0, "ACCEL", SEG_SET);
    }
    
    time_callback(SYS_MSG_RTC_HOUR  | SYS_MSG_RTC_MINUTE);
}
Example #3
0
void display_altitude(u8 line, u8 update)
{
    u8 * str;
#ifndef CONFIG_METRIC_ONLY
    s16 ft;
#endif

    // redraw whole screen
    if (update == DISPLAY_LINE_UPDATE_FULL)
    {
        // Enable pressure measurement
        sAlt.state = MENU_ITEM_VISIBLE;

        // Start measurement
        start_altitude_measurement();
#ifdef CONFIG_ALTI_ACCUMULATOR
        display_chars(LCD_SEG_L1_3_0, (u8*)"ALT ", SEG_ON);
#endif
#ifdef CONFIG_METRIC_ONLY
        display_symbol(LCD_UNIT_L1_M, SEG_ON);
#else
        if (sys.flag.use_metric_units)
        {
            // Display "m" symbol
            display_symbol(LCD_UNIT_L1_M, SEG_ON);
        }
        else
        {
            // Display "ft" symbol
            display_symbol(LCD_UNIT_L1_FT, SEG_ON);
        }
#endif
        // Display altitude
        display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL);
    }
    else if (update == DISPLAY_LINE_UPDATE_PARTIAL)
    {
        // Update display only while measurement is active
        if (sAlt.timeout > 0)
        {
#ifndef CONFIG_METRIC_ONLY
            if (sys.flag.use_metric_units)
            {
#endif
                // Display altitude in xxxx m format, allow 3 leading blank digits
                if (sAlt.altitude >= 0)
                {
#ifdef CONFIG_ALTI_ACCUMULATOR
                    str = _itoa(sAlt.altitude, 5, 4);
#else
                    str = _itoa(sAlt.altitude, 4, 3);
#endif
                    display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
                    display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
                }
                else
                {
#ifdef CONFIG_ALTI_ACCUMULATOR
                    str = _itoa(sAlt.altitude*(-1), 4, 3);
#else
                    str = _itoa(sAlt.altitude*(-1), 5, 4);
#endif
                    display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
                    display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
                }
#ifndef CONFIG_METRIC_ONLY
            }
            else
            {
                // Convert from meters to feet
                ft = convert_m_to_ft(sAlt.altitude);
#ifndef CONFIG_ALTI_ACCUMULATOR
                // Limit to 9999ft (3047m)
                if (ft > 9999) ft = 9999;
#endif
                // Display altitude in xxxx ft format, allow 3 leading blank digits
                if (ft >= 0)
                {
#ifdef CONFIG_ALTI_ACCUMULATOR
                    str = _itoa(ft, 4, 3);
#else
                    str = _itoa(ft, 5, 4);
#endif
                    display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
                    display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
                }
                else
                {
#ifdef CONFIG_ALTI_ACCUMULATOR
                    str = _itoa(ft*(-1), 4, 3);
#else
                    str = _itoa(ft*(-1), 5, 4);
#endif
                    display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
                    display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
                }
            }
#endif
#ifdef CONFIG_ALTI_ACCUMULATOR
            // display altitude on bottom line (5 digits)
            clear_line(LINE2);
            display_chars(LCD_SEG_L2_4_0, str, SEG_ON);
#else
            display_chars(LCD_SEG_L1_3_0, str, SEG_ON);
#endif
        }
    }
    else if (update == DISPLAY_LINE_CLEAR)
    {
        // Disable pressure measurement
        sAlt.state = MENU_ITEM_NOT_VISIBLE;

        // Stop measurement
        stop_altitude_measurement();

        // Clean up function-specific segments before leaving function
#ifdef CONFIG_ALTI_ACCUMULATOR
        // clear off the altitude display from the second line
        clear_line(LINE2);
        // should really try to get the date displayed here again too
#endif
        display_symbol(LCD_UNIT_L1_M, SEG_OFF);
        display_symbol(LCD_UNIT_L1_FT, SEG_OFF);
        display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
        display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
    }
}
Example #4
0
// *************************************************************************************************
// @fn          display_altitude
// @brief       Display routine. Supports display in meters and feet. 
// @param       u8 line                 LINE1
//                              u8 update               DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_CLEAR
// @return      none
// *************************************************************************************************
void display_altitude(u8 line, u8 update)
{
   u8 *str;
   s16 ft;

   // Start measurement
   start_altitude_measurement();

   // redraw whole screen
   if (update == DISPLAY_LINE_UPDATE_FULL)
   {
      if (sys.flag.use_metric_units)
      {
         // Display "m" symbol
         display_symbol(LCD_UNIT_L1_M, SEG_ON);
      }
      else
      {
         // Display "ft" symbol
         display_symbol(LCD_UNIT_L1_FT, SEG_ON);
      }

      // Display altitude
      display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL);
   }
   else if (update == DISPLAY_LINE_UPDATE_PARTIAL)
   {
      if (sys.flag.use_metric_units)
      {
         // Display altitude in xxxx m format, allow 3 leading blank digits
         if (sAlt.altitude >= 0)
         {
            str = int_to_array(sAlt.altitude, 4, 3);
            display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
            display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
         }
         else
         {
            str = int_to_array(sAlt.altitude * (-1), 4, 3);
            display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
            display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
         }
      }
      else
      {
         // Convert from meters to feet
         ft = convert_m_to_ft(sAlt.altitude);

         // Limit to 9999ft (3047m)
         if (ft > 9999)
            ft = 9999;

         // Display altitude in xxxx ft format, allow 3 leading blank digits
         if (ft >= 0)
         {
            str = int_to_array(ft, 4, 3);
            display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
            display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
         }
         else
         {
            str = int_to_array(ft * (-1), 4, 3);
            display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
            display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
         }
      }
      display_chars(LCD_SEG_L1_3_0, str, SEG_ON);
   }
   else if (update == DISPLAY_LINE_CLEAR)
   {
      // Stop measurement
      stop_altitude_measurement();

      // Clean up function-specific segments before leaving function
      display_symbol(LCD_UNIT_L1_M, SEG_OFF);
      display_symbol(LCD_UNIT_L1_FT, SEG_OFF);
      display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
      display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
   }
}
Example #5
0
// *************************************************************************************************
// @fn          test_mode
// @brief       Manual test mode. Activated by holding buttons STAR and UP simultaneously. 
//				Cancelled by any other button press.
// @param      	none
// @return      none
// *************************************************************************************************
void test_mode(void)
{
	u8 test_step, start_next_test;
	u8 * str;
	u8 i;
	
	// Disable timer - no need for a clock tick
	Timer0_Stop();
	
	// Disable LCD charge pump while in standby mode 
	// This reduces current consumption by ca. 5?A to ca. 10?A
	LCDBVCTL = 0;
	
	// Show welcome screen 
	display_chars(LCD_SEG_L1_3_0, (u8*)"0430", SEG_ON);
	display_chars(LCD_SEG_L2_4_0, (u8*)"CC430", SEG_ON);
	display_symbol(LCD_SEG_L1_COL, SEG_ON);
	display_symbol(LCD_ICON_HEART, SEG_ON);
	display_symbol(LCD_ICON_STOPWATCH, SEG_ON);
	display_symbol(LCD_ICON_RECORD, SEG_ON);
	display_symbol(LCD_ICON_ALARM, SEG_ON);
	display_symbol(LCD_ICON_BEEPER1, SEG_ON);
	display_symbol(LCD_ICON_BEEPER2, SEG_ON);
	display_symbol(LCD_ICON_BEEPER3, SEG_ON);
	display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
	display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
	display_symbol(LCD_SYMB_AM, SEG_ON);

	// Hold watchdog
	WDTCTL = WDTPW + WDTHOLD;

	// Wait for button press 
	_BIS_SR(LPM3_bits + GIE); 
	__no_operation();

	// Clear display
	display_all_off();
	
#ifdef USE_LCD_CHARGE_PUMP
	// Charge pump voltage generated internally, internal bias (V2-V4) generation
	// This ensures that the contrast and LCD control is constant for the whole battery lifetime
	LCDBVCTL = LCDCPEN | VLCD_2_72;
#endif
	
	// Renenable timer
	Timer0_Start();
	
	// Debounce button press
	Timer0_A4_Delay(CONV_MS_TO_TICKS(100));
		
	while(1)
	{
		// Check button event
		if (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED)
		{
			// Start with test #0
			test_step = 0;
			start_next_test = 1;
			while(1)
			{
				if (start_next_test)
				{
					// Clean up previous test display
					display_all_off();
					
					start_next_test = 0;

					switch (test_step)
					{
						case 0: // All LCD segments on
								display_all_on(); 
								// Wait until buttons are off
								while (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED);
								break;
						case 1:	// Altitude measurement
#ifdef CONFIG_ALTITUDE
								display_altitude(LINE1, DISPLAY_LINE_UPDATE_FULL);
								for (i=0; i<2; i++)
								{
									while((PS_INT_IN & PS_INT_PIN) == 0); 
									do_altitude_measurement(FILTER_OFF);
									display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL);
								}
								stop_altitude_measurement();	
#endif
								break;
						case 2: // Temperature measurement
								display_temperature(LINE1, DISPLAY_LINE_UPDATE_FULL);
								for (i=0; i<4; i++)
								{
									Timer0_A4_Delay(CONV_MS_TO_TICKS(250));
									temperature_measurement(FILTER_OFF);
									display_temperature(LINE1, DISPLAY_LINE_UPDATE_PARTIAL);
								}
								break;
						case 3: // Acceleration measurement
								as_start();
								for (i=0; i<4; i++)
								{
									Timer0_A4_Delay(CONV_MS_TO_TICKS(250));
									as_get_data(sAccel.xyz);
									str = itoa( sAccel.xyz[0], 3, 0);
									display_chars(LCD_SEG_L1_2_0, str, SEG_ON);
									str = itoa( sAccel.xyz[2], 3, 0);
									display_chars(LCD_SEG_L2_2_0, str, SEG_ON);
								}
								as_stop();
								break;
						//pfs
						#ifndef ELIMINATE_BLUEROBIN
						case 4:	// BlueRobin test
								button.flag.up = 1;
								sx_bluerobin(LINE1);
								Timer0_A4_Delay(CONV_MS_TO_TICKS(100));
								get_bluerobin_data();
								display_heartrate(LINE1, DISPLAY_LINE_UPDATE_FULL);
								stop_bluerobin();
								break;
						#endif
					}
					
					// Debounce button
					Timer0_A4_Delay(CONV_MS_TO_TICKS(200));
				}
				
				// Check button event
				if (BUTTON_STAR_IS_PRESSED) 
				{
					test_step = 1;
					start_next_test = 1;
				}
				else if (BUTTON_NUM_IS_PRESSED) 
				{
					test_step = 2;
					start_next_test = 1;
				}
				else if (BUTTON_UP_IS_PRESSED) 
				{
					test_step = 3;
					start_next_test = 1;
				}
				else if (BUTTON_DOWN_IS_PRESSED) 
				{
					test_step = 4;
					start_next_test = 1;
				}
				else if (BUTTON_BACKLIGHT_IS_PRESSED) 
				{
					// Wait until button has been released (avoid restart)
					while (BUTTON_BACKLIGHT_IS_PRESSED);

					// Disable LCD and LCD charge pump
					LCDBCTL0 &= ~BIT0;
					LCDBVCTL  = 0;
					
					// Debounce button press
					Timer0_A4_Delay(CONV_MS_TO_TICKS(500));

					// Disable timer - no need for a clock tick
					Timer0_Stop();
					
					// Hold watchdog
					WDTCTL = WDTPW + WDTHOLD;
					
					// Sleep until button is pressed (ca. 4?A current consumption)
					_BIS_SR(LPM4_bits + GIE);
					__no_operation();
				
					// Force watchdog reset for a clean restart 
					WDTCTL = 1; 
				}
				
#ifdef USE_WATCHDOG		
				// Service watchdog
				WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
#endif
				// To LPM3
				_BIS_SR(LPM3_bits + GIE);  
				__no_operation();
			}
		}
		else
		{
			// Debounce button
			Timer0_A4_Delay(CONV_MS_TO_TICKS(100));
			button.all_flags = 0;
			break;
		}
	}
}
Example #6
0
void edit_base_set(uint8_t pos, int8_t step)
{	
	helpers_loop_s16(&baseCalib[pos], limit_low, limit_high, step);
	
	display_altitude(baseCalib[pos], 0);
}
Example #7
0
void edit_base_sel(uint8_t pos)
{	
	display_altitude(baseCalib[pos], 0);
	display_chars(0, LCD_SEG_L1_3_0, NULL, BLINK_ON);
	display_chars(0, LCD_SEG_L2_5_0, pre_str[pos], SEG_SET);
}
// *************************************************************************************************
// @fn          display_altitude
// @brief       Display routine. Supports display in meters and feet.
// @param       u8 line                 LINE1
//                              u8 update               DISPLAY_LINE_UPDATE_FULL,
// DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_CLEAR
// @return      none
// *************************************************************************************************
void display_altitude(u8 line, u8 update)
{
    u8 *str;
    s16 ft;

    // redraw whole screen
    if (update == DISPLAY_LINE_UPDATE_FULL)
    {
        // Enable pressure measurement
        sAlt.state = MENU_ITEM_VISIBLE;

        // Start measurement
        start_altitude_measurement();


        // Display altitude
        display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL);
    }
    else if (update == DISPLAY_LINE_UPDATE_PARTIAL)
    {
        // Update display only while measurement is active
        if (sAlt.timeout > 0)
        {
          if (sAlt.display == DISPLAY_DEFAULT_VIEW)
          {
            display_symbol(LCD_UNIT_L1_PER_H, SEG_OFF);
            display_symbol(LCD_SYMB_AM, SEG_OFF);            
            if (sys.flag.use_metric_units)
            {
               // Display "m" symbol
               display_symbol(LCD_UNIT_L1_M, SEG_ON);
             }
            else
             {
              // Display "ft" symbol
              display_symbol(LCD_UNIT_L1_FT, SEG_ON);
              }        
            if (sys.flag.use_metric_units)
            {
                // Display altitude in xxxx m format, allow 3 leading blank digits
                if (sAlt.altitude >= 0)
                {
                    str = int_to_array(sAlt.altitude, 4, 3);
                    display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
                    display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
                }
                else
                {
                    str = int_to_array((-1)*sAlt.altitude, 4, 3);
                    //const u8 neg_txt[3] ="NEG";
                    //str = (u8 *)neg_txt;
                    display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
                    display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
                }
            }
            else
            {
                // Convert from meters to feet
                ft = convert_m_to_ft(sAlt.altitude);

                // Limit to 9999ft (3047m)
                if (ft > 9999)
                    ft = 9999;

                // Display altitude in xxxx ft format, allow 3 leading blank digits
                if (ft >= 0)
                {
                    str = int_to_array(ft, 4, 3);
                    display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
                    display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
                }
                else
                {
                    str = int_to_array(ft * (-1), 4, 3);
                    display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
                    display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
                }
            }
  
            display_symbol(LCD_ICON_RECORD, SEG_OFF_BLINK_OFF);
            display_chars(LCD_SEG_L1_3_0, str, SEG_ON);
          }
          else if (sAlt.display == DISPLAY_ALTERNATIVE_VIEW)
          {
            // Display Pressure in hPa
            
            u16 PressureToDisp = (u16) (((float)sAlt.pressure + 100.00 * (float) sAlt.pressure_offset) / 100.00 + 0.5);
            str = int_to_array(PressureToDisp, 4, 3);
            
            display_symbol(LCD_SYMB_AM, SEG_OFF);            
                    
            display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
            display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
        
            display_symbol(LCD_UNIT_L1_M, SEG_OFF);
            display_symbol(LCD_UNIT_L1_FT, SEG_OFF);
            display_symbol(LCD_UNIT_L1_PER_H, SEG_ON_BLINK_OFF);
            
            display_chars(LCD_SEG_L1_3_0, str, SEG_ON);
          }
          else if (sAlt.display == DISPLAY_ALTERNATIVE_VIEW1)
          {
            // Display Pressure in mmHg
            u16 PressureToDisp = (u16) (3.0 * ((float)sAlt.pressure + 100.00 * (float)sAlt.pressure_offset) / 400.00  + 0.5);            
            str = int_to_array(PressureToDisp, 4, 3);
            
//            str = int_to_array(sAlt.pressure_delta, 4, 3);            
            
            display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
            display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
        
            display_symbol(LCD_UNIT_L1_M, SEG_OFF);
            display_symbol(LCD_UNIT_L1_FT, SEG_OFF);
            display_symbol(LCD_UNIT_L1_PER_H, SEG_OFF);
            display_symbol(LCD_ICON_RECORD, SEG_OFF_BLINK_OFF);
            
            display_symbol(LCD_SYMB_AM, SEG_ON);            
              
            display_chars(LCD_SEG_L1_3_0, str, SEG_ON);
            
          }
          else if (sAlt.display == DISPLAY_ALTERNATIVE_VIEW2)
          {   
            display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
            display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);              
            display_symbol(LCD_SYMB_AM, SEG_OFF);            
            display_symbol(LCD_UNIT_L1_M, SEG_OFF);
            display_symbol(LCD_UNIT_L1_FT, SEG_OFF);            
            display_symbol(LCD_UNIT_L1_PER_H, SEG_OFF);
            display_symbol(LCD_ICON_RECORD, SEG_ON_BLINK_ON);
            
            s16 dp = sAlt.pressure_delta;            
            if (dp > 250)
            {
              // unstable high pressure
              display_chars(LCD_SEG_L1_3_0, (u8 *) "UN H", SEG_ON);
            }
            else if ((dp >= 50) && (dp <= 250))
            {
              // stable good weather
              display_chars(LCD_SEG_L1_3_0, (u8 *) " SUN", SEG_ON);
            }
            else if ((dp >= -50) && (dp < 50))
            {
              // stable              
              display_chars(LCD_SEG_L1_3_0, (u8 *) "STAB", SEG_ON);
            }
            else if ((dp > -250) && (dp < -50))
            {
              // stable rainy
              display_chars(LCD_SEG_L1_3_0, (u8 *) "RAIN", SEG_ON);
            }
            else 
            {
              // unstable low
              display_chars(LCD_SEG_L1_3_0, (u8 *) "UN L", SEG_ON);
            }
 
            
            /*
            u32 Temp = (u32)((float) sAlt.pressure_sum / ((float) sAlt.pressure_counter * 100.0) + 0.5);
            str = int_to_array(Temp, 4, 3);
            display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
            display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);              
            display_symbol(LCD_SYMB_AM, SEG_OFF);            
            display_symbol(LCD_UNIT_L1_M, SEG_OFF);
            display_symbol(LCD_UNIT_L1_FT, SEG_OFF);
            display_symbol(LCD_UNIT_L1_PER_H, SEG_ON_BLINK_ON); 
            display_chars(LCD_SEG_L1_3_0, str, SEG_ON);            
            */
          }
          else
          {                
            if (sAlt.pressure_delta >= 0)
            {
              str = int_to_array(sAlt.pressure_delta, 4, 3);           
              display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
              display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
            }
            else
            {
              str = int_to_array(sAlt.pressure_delta * (-1), 4, 3);                        
              display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
              display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);              
            }
            display_symbol(LCD_ICON_RECORD, SEG_OFF_BLINK_OFF);
            display_symbol(LCD_SYMB_AM, SEG_OFF);            
            display_symbol(LCD_UNIT_L1_M, SEG_OFF);
            display_symbol(LCD_UNIT_L1_FT, SEG_OFF);
            display_symbol(LCD_UNIT_L1_PER_H, SEG_ON); 
            display_chars(LCD_SEG_L1_3_0, str, SEG_ON);
          }          
            
        }
    }
    else if (update == DISPLAY_LINE_CLEAR)
    {
        // Disable pressure measurement
        sAlt.state = MENU_ITEM_NOT_VISIBLE;

        // Stop measurement
        stop_altitude_measurement();

        // Clean up function-specific segments before leaving function
        display_symbol(LCD_UNIT_L1_M, SEG_OFF);
        display_symbol(LCD_UNIT_L1_FT, SEG_OFF);
        display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
        display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
        display_symbol(LCD_UNIT_L1_PER_H, SEG_OFF_BLINK_OFF);    
        display_symbol(LCD_SYMB_AM, SEG_OFF);         
        display_symbol(LCD_ICON_RECORD, SEG_OFF_BLINK_OFF);
            
        sAlt.display = DISPLAY_DEFAULT_VIEW;
    }
}
// *************************************************************************************************
// @fn          display_altitude
// @brief       Display routine. Supports display in meters and feet. 
// @param       u8 line         LINE1
//              u8 update       DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_CLEAR
// @return      none
// *************************************************************************************************
void display_altitude(u8 line, u8 update)
{
    u8 * str;
    s16 ft;
    
    // redraw whole screen
    if (update == DISPLAY_LINE_UPDATE_FULL) 
    {
        // Enable pressure measurement
        sAlt.state = MENU_ITEM_VISIBLE;

        // Start measurement
        start_altitude_measurement();
        
        // Display altitude
        display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL);
    }
    else if (update == DISPLAY_LINE_UPDATE_PARTIAL)
    {
        // Update display only while measurement is active
        if (sAlt.timeout > 0)
        {
            // Altitude view
            if (PressDisplay == DISPLAY_DEFAULT_VIEW)
            {
                display_symbol(LCD_SEG_L1_DP1, SEG_OFF);
                if (sys.flag.use_metric_units)
                {
                    // Display "m" symbol
                    display_symbol(LCD_UNIT_L1_M, SEG_ON);
                    // Display altitude in xxxx m format, allow 3 leading blank digits
                    if (sAlt.altitude >= 0)
                    {
                        str = itoa(sAlt.altitude, 4, 3);
                        display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
                        display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
                    }
                    else
                    {
                        str = itoa(sAlt.altitude*(-1), 4, 3);
                        display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
                        display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
                    }
                }
                else
                {
                    // Display "ft" symbol
                    display_symbol(LCD_UNIT_L1_FT, SEG_ON);                 
                    
                    // Convert from meters to feet
                    ft = convert_m_to_ft(sAlt.altitude);
                    
                    // Limit to 9999ft (3047m)
                    if (ft > 9999) ft = 9999;
                    
                    // Display altitude in xxxx ft format, allow 3 leading blank digits
                    if (ft >= 0)
                    {
                        str = itoa(ft, 4, 3);
                        display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
                        display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
                    }
                    else
                    {
                        str = itoa(ft*(-1), 4, 3);
                        display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
                        display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
                    }               
                }
            }
            // Pressure view, unit: milliBar = hectoPascal
            else if (PressDisplay == DISPLAY_ALTERNATIVE_VIEW)
            {
                display_symbol(LCD_SEG_L1_DP1, SEG_OFF);
                display_symbol(LCD_UNIT_L1_M, SEG_OFF);
                display_symbol(LCD_UNIT_L1_FT, SEG_OFF);
                display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
                display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
                str = itoa(AmbientPressure, 4, 3);
            }
            // Pressure view, unit: PSI (Pound-force per square inch absolute) 1mbar = 0.01450377 PSI
            else  // DISPLAY_ALTERNATIVE_VIEW_2
            {
                str = itoa((u32)AmbientPressure * 10000L / 6895L, 4, 3);
                display_symbol(LCD_SEG_L1_DP1, SEG_ON);
            }
            display_chars(LCD_SEG_L1_3_0, str, SEG_ON);
        }
    }
    else if (update == DISPLAY_LINE_CLEAR)
    {
        // Disable pressure measurement
        sAlt.state = MENU_ITEM_NOT_VISIBLE;

        // Stop measurement
        stop_altitude_measurement();
        
        // Clean up function-specific segments before leaving function
        display_symbol(LCD_SEG_L1_DP1, SEG_OFF);
        display_symbol(LCD_UNIT_L1_M, SEG_OFF);
        display_symbol(LCD_UNIT_L1_FT, SEG_OFF);
        display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
        display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
    }
}