// ************************************************************************************************* // @fn display_date // @brief Display date in DD.MM format (metric units) or MM.DD (English units). // @param u8 line LINE1, LINE2 // u8 update DISPLAY_LINE_UPDATE_FULL, // DISPLAY_LINE_UPDATE_PARTIAL // @return none // ************************************************************************************************* void display_date(u8 line, u8 update) { u8 *str; if (update == DISPLAY_LINE_UPDATE_FULL) { if (sDate.display == DISPLAY_DEFAULT_VIEW) { // Convert day to string str = int_to_array(sDate.day, 2, 0); if (sys.flag.use_metric_units) { display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); } else { display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); } // Convert month to string str = int_to_array(sDate.month, 2, 0); if (sys.flag.use_metric_units) { display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); } else { display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); } // Display "." to separate day and month display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON); } else { // Convert year to string str = int_to_array(sDate.year, 4, 0); display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_3_0), str, SEG_ON); // Clear "." display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_OFF); } } else if (update == DISPLAY_LINE_CLEAR) { // Show day and month on display when coming around next time sDate.display = DISPLAY_DEFAULT_VIEW; } }
// ************************************************************************************************* // @fn display_heartrate // @brief Heart rate display routine. // @param u8 line LINE1 // u8 update DISPLAY_LINE_UPDATE_FULL, // DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_CLEAR // @return none // ************************************************************************************************* void display_heartrate(u8 line, u8 update) { u8 *str; if (update != DISPLAY_LINE_CLEAR) { if (is_bluerobin()) { str = int_to_array(sBlueRobin.heartrate, 3, 2); display_chars(LCD_SEG_L1_2_0, str, SEG_ON); } else { display_chars(LCD_SEG_L1_2_0, (u8 *) "---", SEG_ON); } } // Redraw whole screen if (!is_bluerobin()) { if (update == DISPLAY_LINE_UPDATE_FULL) { display_symbol(LCD_ICON_HEART, SEG_ON); } else if (update == DISPLAY_LINE_CLEAR) { // Clear heart when not connected display_symbol(LCD_ICON_HEART, SEG_OFF); } } }
// // _display_signed() - display a signed value on the second line. // // If is_fraction is false, display value on the second line, nnnnnn // Otherwise display value as fraction on the second line, nnnn.nn // // Used to display pressure (in Pascal) as hPa and cm/s as m/s. // static void _display_signed( s32 value, u8 is_fraction ) { u8 *str; int i; int is_neg; is_neg = ( value < 0 ); if ( is_neg ) { is_neg = 1; value *= -1; } str = int_to_array( value, 6, (is_fraction) ? 3 : 5 ); for ( i = 0; (is_neg && (str[i] == ' ')); i++ ) { if (str[i+1] != ' ') str[i] = '-'; } display_chars( LCD_SEG_L2_5_0, str, SEG_ON ); if ( is_fraction ) display_symbol( LCD_SEG_L2_DP, SEG_ON ); }
// ************************************************************************************************* // @fn display_alarm // @brief Display alarm time. 24H / 12H time format. // @param u8 line LINE1, LINE2 // u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR // @return none // ************************************************************************************************* void display_alarm(u8 line, u8 update) { u8 hour12; if (update == DISPLAY_LINE_UPDATE_FULL) { if (sys.flag.use_metric_units) { // Display 24H alarm time "HH:MM" display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), int_to_array(sAlarm.hour, 2, 0), SEG_ON); } else { // Display 12H alarm time "HH:MM" + AM/PM hour12 = convert_hour_to_12H_format(sAlarm.hour); display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), int_to_array(hour12, 2, 0), SEG_ON); // Display AM/PM symbol display_am_pm_symbol(sAlarm.hour); } display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), int_to_array(sAlarm.minute, 2, 0), SEG_ON); display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_ON); // Show blinking alarm icon display_symbol(LCD_ICON_ALARM, SEG_ON_BLINK_ON); } else if (update == DISPLAY_LINE_CLEAR) { // Clean up function-specific segments before leaving function display_symbol(LCD_SYMB_AM, SEG_OFF); // Clear / set alarm icon if (sAlarm.state == ALARM_DISABLED) { display_symbol(LCD_ICON_ALARM, SEG_OFF_BLINK_OFF); } else { display_symbol(LCD_ICON_ALARM, SEG_ON_BLINK_OFF); } } }
void int_to_array__one_byte(){ int symbol = 40; unsigned char buffer[sizeof(int)]; unsigned int size; int_to_array(buffer, &size, symbol); t_assert(size == 1); t_assert(buffer[0] == 40); }
void int_to_array__negative(){ int symbol = -1; unsigned char buffer[sizeof(int)]; unsigned int size; int_to_array(buffer, &size, symbol); t_assert(size == sizeof(int)); t_assert(buffer[0] == 0xFF); }
void int_to_array__two_bytes(){ int symbol = 258; unsigned char buffer[sizeof(int)]; unsigned int size; int_to_array(buffer, &size, symbol); t_assert(size == 2); t_assert(buffer[0] == 2); t_assert(buffer[1] == 1); }
// ************************************************************************************************* // @fn display_alarm // @brief Display alarm time. 24H / 12H time format. // @param u8 line LINE1, LINE2 // u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR // @return none // ************************************************************************************************* void display_alarm(u8 line, u8 update) { if (update == DISPLAY_LINE_UPDATE_FULL) { // Display 24H alarm time "HH:MM" display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), int_to_array(sAlarm.hour, 2, 0), SEG_ON); display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), int_to_array(sAlarm.minute, 2, 0), SEG_ON); display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_ON); // Show blinking alarm icon display_symbol(LCD_ICON_ALARM, SEG_ON_BLINK_ON); // // If alarm is enabled, show icon // if (sAlarm.state == ALARM_ENABLED) // { // display_symbol(LCD_ICON_ALARM, SEG_ON_BLINK_OFF); // } // // When alarm is disabled, blink icon to indicate that this is not current time! // else if (sAlarm.state == ALARM_DISABLED) // { // } } else if (update == DISPLAY_LINE_CLEAR) { // Clean up function-specific segments before leaving function display_symbol(LCD_SYMB_AM, SEG_OFF); // Clear / set alarm icon if (sAlarm.state == ALARM_DISABLED) { display_symbol(LCD_ICON_ALARM, SEG_OFF_BLINK_OFF); } else { display_symbol(LCD_ICON_ALARM, SEG_ON_BLINK_OFF); } } }
// ************************************************************************************************* // @fn display_battery_V // @brief Display routine for battery voltage. // @param u8 line LINE2 // u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR // @return none // ************************************************************************************************* void display_battery_V(u8 line, u8 update) { u8 *str; // Redraw line if (update == DISPLAY_LINE_UPDATE_FULL) { // Set battery and V icon display_symbol(LCD_SYMB_BATTERY, SEG_ON); // Menu item is visible sBatt.state = MENU_ITEM_VISIBLE; // Display result in xx.x format str = int_to_array(sBatt.voltage, 3, 0); display_chars(LCD_SEG_L2_2_0, str, SEG_ON); display_symbol(LCD_SEG_L2_DP, SEG_ON); } else if (update == DISPLAY_LINE_UPDATE_PARTIAL) { // Display result in xx.x format str = int_to_array(sBatt.voltage, 3, 0); display_chars(LCD_SEG_L2_2_0, str, SEG_ON); display.flag.update_battery_voltage = 0; } else if (update == DISPLAY_LINE_CLEAR) { // Menu item is not visible sBatt.state = MENU_ITEM_NOT_VISIBLE; // Clear function-specific symbols display_symbol(LCD_SYMB_BATTERY, SEG_OFF); } }
void display_counter(u8 line, u8 update) { u8 * str; // Redraw line switch( update ) { case DISPLAY_LINE_UPDATE_FULL: sCounter.data[0] = sCounter.data[1] = sCounter.data[2] = 0; sCounter.sum = 0; sCounter.rise_state = 0; // Start sensor bmp_as_start(); // Set icon // Menu item is visible sCounter.state = MENU_ITEM_VISIBLE; // Display result in xx.x format case DISPLAY_LINE_UPDATE_PARTIAL: // Display result in xx.x format str = int_to_array(sCounter.count, 4, 0); display_chars(LCD_SEG_L1_3_0, str, SEG_ON); display.flag.update_counter = 0; if ( sCounter.style ) { display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); } else { display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); } break; case DISPLAY_LINE_CLEAR: bmp_as_stop(); // Menu item is not visible sCounter.state = MENU_ITEM_NOT_VISIBLE; // Clear function-specific symbols display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); break; } }
// ************************************************************************************************* // @fn display_time // @brief Clock display routine. Supports 24H and 12H time format. // @param u8 line LINE1 // u8 update DISPLAY_LINE_UPDATE_FULL, // DISPLAY_LINE_UPDATE_PARTIAL // @return none // ************************************************************************************************* void display_time(u8 update) { u8 hour12; float sidereal; s32 sideint; // Partial update display_symbol(LCD_ICON_RECORD, SEG_OFF); if (update == DISPLAY_LINE_UPDATE_PARTIAL) { if (sTime.drawFlag != 0) { if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) { switch (sTime.drawFlag) { case 3: if (sys.flag.use_metric_units) { // Display 24H time "HH" display_chars(LCD_SEG_L1_3_2, int_to_array(sTime.hour, 2, 0), SEG_ON); } else { // Display 12H time "HH" + AM/PM hour12 = convert_hour_to_12H_format(sTime.hour); display_chars(LCD_SEG_L1_3_2, int_to_array(hour12, 2, 0), SEG_ON); display_am_pm_symbol(sTime.hour); } case 2: display_chars(LCD_SEG_L1_1_0, int_to_array(sTime.minute, 2, 0), SEG_ON); } } else { display_time(DISPLAY_LINE_UPDATE_FULL); } } } else if (update == DISPLAY_LINE_UPDATE_FULL) { // Full update if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) { // Display 24H/12H time hour12 = sTime.hour; if (!sys.flag.use_metric_units) { // Display 12H time "HH" + AM/PM information hour12 = convert_hour_to_12H_format(hour12); display_am_pm_symbol(sTime.hour); } display_chars(LCD_SEG_L1_3_2, int_to_array(hour12, 2, 0), SEG_ON); // Display minute display_chars(LCD_SEG_L1_1_0, int_to_array(sTime.minute, 2, 0), SEG_ON); } else { // Display sidereal display_symbol(LCD_ICON_RECORD, SEG_ON); sidereal = (sTime.second + 60.0F * ((sTime.minute - sminute) + 60.0F * ((sTime.hour - shour) + 24.0F * sday))) * 1.0027378956F; sideint = (s32)sidereal / 60;//sidereal minutes display_chars(LCD_SEG_L1_1_0, int_to_array(sideint % 60, 2, 0), SEG_ON); sideint /= 60;//sidereal hours display_chars(LCD_SEG_L1_3_2, int_to_array(sideint % 24, 2, 0), SEG_ON); if(sday > 180) display_chars(LCD_SEG_L1_3_0, (u8 *) "SYNC", SEG_ON);//out of range } display_symbol(LCD_SEG_L1_COL, SEG_ON_BLINK_ON); } else if (update == DISPLAY_LINE_CLEAR) { display_symbol(LCD_SEG_L1_COL, SEG_OFF_BLINK_OFF); // Change display style to default (HH:MM) sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; // Clean up AM/PM icon display_symbol(LCD_SYMB_AM, SEG_OFF); } }
// ************************************************************************************************* // @fn mx_time // @brief Clock set routine. // @param u8 line LINE1, LINE2 // @return none // ************************************************************************************************* void mx_time() { u8 select; s32 timeformat; s16 timeformat1; s32 hours; s32 minutes; // Clear display clear_display_all(); // Convert global time to local variables // Global time keeps on ticking in background until it is overwritten if (sys.flag.use_metric_units) { timeformat = TIMEFORMAT_24H; } else { timeformat = TIMEFORMAT_12H; } timeformat1 = timeformat; hours = sTime.hour; minutes = sTime.minute; // Init value index select = 0; // Loop values until all are set or user breaks set while (1) { // Idle timeout: exit without saving if (sys.flag.idle_timeout) { // Roll back time format if (timeformat1 == TIMEFORMAT_24H) sys.flag.use_metric_units = 1; else sys.flag.use_metric_units = 0; display_symbol(LCD_SYMB_AM, SEG_OFF); break; } // Button STAR (short): save, then exit if (button.flag.star) { // Stop clock timer Timer0_Stop(); // Store local variables in global clock time shour = sTime.hour = hours; sminute = sTime.minute = minutes; sday = sTime.second = 0; //sidereal basis^^^ // Start clock timer Timer0_Start(); // Full display update is done when returning from function display_symbol(LCD_SYMB_AM, SEG_OFF); break; } switch (select) { case 0: // Clear LINE1 and LINE2 and AM icon - required when coming back from // set_value(seconds) clear_display(); display_symbol(LCD_SYMB_AM, SEG_OFF); // Set 24H / 12H time format set_value( &timeformat, 1, 0, 0, 1, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_SELECTION + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_1, display_selection_Timeformat1); // Modify global time format variable immediately to update AM/PM icon correctly if (timeformat == TIMEFORMAT_24H) sys.flag.use_metric_units = 1; else sys.flag.use_metric_units = 0; select = 1; break; case 1: // Display HH:MM (LINE1) and .SS (LINE2) display_chars(LCD_SEG_L1_3_2, int_to_array(hours, 2, 0), SEG_ON); display_symbol(LCD_SEG_L1_COL, SEG_ON); display_chars(LCD_SEG_L1_1_0, int_to_array(minutes, 2, 0), SEG_ON); // Set hours set_value(&hours, 2, 0, 0, 23, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, display_hours); select = 2; break; case 2: // Set minutes set_value(&minutes, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value); select = 0; break; } } // Clear button flags button.all_flags = 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; // 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 mx_alarm // @brief Set alarm time. // @param u8 line LINE1 // @return none // ************************************************************************************************* void mx_alarm(u8 line) { u8 select; s32 hours; s32 minutes; u8 *str; // Clear display clear_display_all(); // Keep global values in case new values are discarded hours = sAlarm.hour; minutes = sAlarm.minute; // Display HH:MM (LINE1) str = int_to_array(hours, 2, 0); display_chars(LCD_SEG_L1_3_2, str, SEG_ON); display_symbol(LCD_SEG_L1_COL, SEG_ON); str = int_to_array(minutes, 2, 0); display_chars(LCD_SEG_L1_1_0, str, SEG_ON); // Init value index select = 0; // Loop values until all are set or user breaks set while (1) { // Idle timeout: exit without saving if (sys.flag.idle_timeout) break; // STAR (short): save, then exit if (button.flag.star) { // Store local variables in global alarm time sAlarm.hour = hours; sAlarm.minute = minutes; // Set display update flag display.flag.line1_full_update = 1; break; } switch (select) { case 0: // Set hour set_value(&hours, 2, 0, 0, 23, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, display_hours); select = 1; break; case 1: // Set minutes set_value(&minutes, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value); select = 0; break; } } // Clear button flag button.all_flags = 0; // Indicate to display function that new value is available display.flag.update_alarm = 1; }
// ************************************************************************************************* // @fn display_time // @brief Clock display routine. Supports 24H and 12H time format. // @param u8 line LINE1 // u8 update DISPLAY_LINE_UPDATE_FULL, // DISPLAY_LINE_UPDATE_PARTIAL // @return none // ************************************************************************************************* void display_time(u8 line, u8 update) { u8 hour12; // Partial update if (update == DISPLAY_LINE_UPDATE_PARTIAL) { if (sTime.drawFlag != 0) { if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) { switch (sTime.drawFlag) { case 3: if (sys.flag.use_metric_units) { // Display 24H time "HH" display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), int_to_array(sTime.hour, 2, 0), SEG_ON); } else { // Display 12H time "HH" + AM/PM hour12 = convert_hour_to_12H_format(sTime.hour); display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), int_to_array(hour12, 2, 0), SEG_ON); display_am_pm_symbol(sTime.hour); } case 2: display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), int_to_array(sTime.minute, 2, 0), SEG_ON); } } else { // Seconds are always updated display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), int_to_array(sTime.second, 2, 0), SEG_ON); } } } else if (update == DISPLAY_LINE_UPDATE_FULL) { // Full update if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) { // Display 24H/12H time if (sys.flag.use_metric_units) { // Display 24H time "HH" display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), int_to_array(sTime.hour, 2, 0), SEG_ON); } else { // Display 12H time "HH" + AM/PM information hour12 = convert_hour_to_12H_format(sTime.hour); display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), int_to_array(hour12, 2, 0), SEG_ON); // Display AM/PM information if (line == LINE1) { display_am_pm_symbol(sTime.hour); } } // Display minute display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), int_to_array(sTime.minute, 2, 0), SEG_ON); display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_ON_BLINK_ON); } else { // Display seconds display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), int_to_array(sTime.second, 2, 0), SEG_ON); display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON); } } else if (update == DISPLAY_LINE_CLEAR) { display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_OFF_BLINK_OFF); // Change display style to default (HH:MM) sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; // Clean up AM/PM icon display_symbol(LCD_SYMB_AM, SEG_OFF); } }
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 } }
void display_pin2(u8 update) { display_battery_V(DISPLAY_LINE_CLEAR); display_chars(LCD_SEG_L2_3_0, int_to_array(pin_gen, 4, 0), SEG_ON); }
// ************************************************************************************************* // @fn mx_date // @brief Date set routine. // @param line LINE1, LINE2 // @return none // ************************************************************************************************* void mx_date(u8 line) { u8 select; s32 day; s32 month; s32 year; s16 max_days; u8 *str; u8 *str1; // Clear display clear_display_all(); // Convert global to local variables day = sDate.day; month = sDate.month; year = sDate.year; // Init value index select = 0; // Init display // LINE1: DD.MM (metric units) or MM.DD (English units) // LINE2: YYYY (will be drawn by set_value) if (sys.flag.use_metric_units) { str = int_to_array(day, 2, 0); display_chars(LCD_SEG_L1_3_2, str, SEG_ON); str1 = int_to_array(month, 2, 0); display_chars(LCD_SEG_L1_1_0, str1, SEG_ON); } else // English units { str = int_to_array(day, 2, 0); display_chars(LCD_SEG_L1_1_0, str, SEG_ON); str1 = int_to_array(month, 2, 0); display_chars(LCD_SEG_L1_3_2, str1, SEG_ON); } display_symbol(LCD_SEG_L1_DP1, SEG_ON); // Loop values until all are set or user breaks set while (1) { // Idle timeout: exit without saving if (sys.flag.idle_timeout) break; // Button STAR (short): save, then exit if (button.flag.star) { // Copy local variables to global variables sDate.day = day; sDate.month = month; sDate.year = year; // Full display update is done when returning from function break; } switch (select) { case 0: // Set year set_value(&year, 4, 0, 2008, 2100, SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_3_0, display_value); select = 1; break; case 1: // Set month if (sys.flag.use_metric_units) { set_value( &month, 2, 0, 1, 12, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value); } else // English units { set_value( &month, 2, 0, 1, 12, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, display_value); } select = 2; break; case 2: // Set day if (sys.flag.use_metric_units) { set_value( &day, 2, 0, 1, max_days, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, display_value); } else // English units { set_value( &day, 2, 0, 1, max_days, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value); } select = 0; break; } // Check if day is still valid, if not clamp to last day of current month max_days = get_numberOfDays(month, year); if (day > max_days) day = max_days; } // Clear button flag button.all_flags = 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 *) "TONY", SEG_ON); display_chars(LCD_SEG_L2_4_0, (u8 *) "MAGLA", 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 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(); 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 if (bmp_used) { bmp_as_start(); } else { cma_as_start(); } for (i = 0; i < 4; i++) { Timer0_A4_Delay(CONV_MS_TO_TICKS(250)); if (bmp_used) { bmp_as_get_data(sAccel.xyz); } else { cma_as_get_data(sAccel.xyz); } str = int_to_array(sAccel.xyz[0], 3, 0); display_chars(LCD_SEG_L1_2_0, str, SEG_ON); str = int_to_array(sAccel.xyz[2], 3, 0); display_chars(LCD_SEG_L2_2_0, str, SEG_ON); } if (bmp_used) { bmp_as_stop(); } else { cma_as_stop(); } break; 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; } // 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; // Turn off backlight P2OUT &= ~BUTTON_BACKLIGHT_PIN; P2DIR &= ~BUTTON_BACKLIGHT_PIN; break; } } }
// ************************************************************************************************* // @fn display_acceleration // @brief Display routine. // @param u8 line LINE1 // u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR // @return none // ************************************************************************************************* void display_acceleration(u8 line, u8 update) { u8 *str; u8 raw_data; u16 accel_data; // Show warning if acceleration sensor was not initialised properly if (!as_ok) { display_chars(LCD_SEG_L1_2_0, (u8 *) "ERR", SEG_ON); } else { // Redraw whole screen if (update == DISPLAY_LINE_UPDATE_FULL) { { // Start acceleration sensor if (!is_acceleration_measurement()) { // Clear previous acceleration value sAccel.data = 0; // Start sensor cma_as_start(); // Set timeout counter sAccel.timeout = ACCEL_MEASUREMENT_TIMEOUT; // Set mode sAccel.mode = ACCEL_MODE_ON; // Start with Y-axis values sAccel.view_style = DISPLAY_ACCEL_Y; } // Display decimal point display_symbol(LCD_SEG_L1_DP1, SEG_ON); } } else if (update == DISPLAY_LINE_UPDATE_PARTIAL) { // Convert X/Y/Z values to mg switch (sAccel.view_style) { case DISPLAY_ACCEL_X: raw_data = sAccel.xyz[0]; display_char(LCD_SEG_L1_3, 'X', SEG_ON); break; case DISPLAY_ACCEL_Y: raw_data = sAccel.xyz[1]; display_char(LCD_SEG_L1_3, 'Y', SEG_ON); break; default: raw_data = sAccel.xyz[2]; display_char(LCD_SEG_L1_3, 'Z', SEG_ON); break; } accel_data = convert_acceleration_value_to_mgrav(raw_data) / 10; // Filter acceleration accel_data = (u16) ((accel_data * 0.2) + (sAccel.data * 0.8)); // Store average acceleration sAccel.data = accel_data; // Display acceleration in x.xx format str = int_to_array(accel_data, 3, 0); display_chars(LCD_SEG_L1_2_0, str, SEG_ON); // Display sign if (acceleration_value_is_positive(raw_data)) { display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); } else { display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); } } else if (update == DISPLAY_LINE_CLEAR) { // Stop acceleration sensor cma_as_stop(); // Clear mode sAccel.mode = ACCEL_MODE_OFF; // Clean up display display_symbol(LCD_SEG_L1_DP1, SEG_OFF); display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); } } }
// ************************************************************************************************* // @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); } }
// ************************************************************************************************* // @fn display_temperature // @brief Common display routine for metric and English units. // @param u8 line LINE1 // u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR // @return none // ************************************************************************************************* void display_temperature(u8 line, u8 update) { u8 *str; s16 temperature; // Redraw whole screen if (update == DISPLAY_LINE_UPDATE_FULL) { // Menu item is visible sTemp.state = MENU_ITEM_VISIBLE; // Perform one temperature measurement with disabled filter temperature_measurement(FILTER_OFF); // Display temperature display_temperature(LINE2, DISPLAY_LINE_UPDATE_PARTIAL); } else if (update == DISPLAY_LINE_UPDATE_PARTIAL) { // When using English units, convert °C to °F (temp*1.8+32) if (!sys.flag.use_metric_units) { temperature = convert_C_to_F(sTemp.degrees); } else { temperature = sTemp.degrees; } // Indicate temperature sign through arrow up/down icon if (temperature < 0) { // Convert negative to positive number temperature = ~temperature; temperature += 1; display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); } else // Temperature is >= 0 { display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); } // Limit min/max temperature to +/- 99.9 °C / °F if (temperature > 999) temperature = 999; // Display result in xx.x format str = int_to_array(temperature, 3, 1); display_chars(LCD_SEG_L2_3_0, str, SEG_ON); // Display °C / °F display_symbol(LCD_SEG_L2_DP, SEG_ON); // display_symbol(LCD_UNIT_L1_DEGREE, SEG_ON); if (sys.flag.use_metric_units) display_char(LCD_SEG_L2_0, 'C', SEG_ON); else display_char(LCD_SEG_L2_0, 'F', SEG_ON); } else if (update == DISPLAY_LINE_CLEAR) { // Menu item is not visible sTemp.state = MENU_ITEM_NOT_VISIBLE; // Clean up function-specific segments before leaving function display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); // display_symbol(LCD_UNIT_L1_DEGREE, SEG_OFF); display_symbol(LCD_SEG_L2_DP, SEG_OFF); } }
// ************************************************************************************************* // @fn display_date // @brief Display date in DD.MM format (metric units) or MM.DD (English units). // @param u8 line LINE1, LINE2 // u8 update DISPLAY_LINE_UPDATE_FULL, // DISPLAY_LINE_UPDATE_PARTIAL // @return none // ************************************************************************************************* void display_date(u8 line, u8 update) { #ifdef CONFIG_DAY_OF_WEEK const u8 weekDayStr[7][3] = {"SUN","MON","TUE","WED","THU","FRI","SAT"}; #endif u8 *str; if (update == DISPLAY_LINE_UPDATE_FULL) { switch (sDate.display) { case DISPLAY_DEFAULT_VIEW: //WWW.DD // Convert day to string #ifdef CONFIG_DAY_OF_WEEK str = int_to_array(sDate.day, 2, 1); display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); //pfs BEGIN replace year display with day of week //pfs algorith from http://klausler.com/new-dayofweek.html #define BASE_YEAR 2001 // not a leap year, so no need to add 1 u8 skew; skew = (sDate.year - BASE_YEAR)+(sDate.year - BASE_YEAR)/4; // compute number of leap years since BASE_YEAR if ((29 == get_numberOfDays(2, sDate.year)) && (sDate.month < 3)) skew--; // if this is a leap year but before February 29 skew = (skew + sDate.day); // add day of current month //add this month's skew value switch(sDate.month) { case 5: skew += 1; break; case 8: skew += 2; break; case 2: case 3: case 11: skew += 3; break; case 6: skew += 4; break; case 9: case 12: skew += 5; break; case 4: case 7: skew += 6; break; default: //January and October break; } skew = skew%7; str = (u8 *)weekDayStr[skew]; display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_4_2), str, SEG_ON); display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON); break; #else // Convert day to string str = int_to_array(sDate.day, 2, 0); #ifndef CONFIG_METRIC_ONLY if (sys.flag.use_metric_units) { #endif display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); #ifndef CONFIG_METRIC_ONLY } else { display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); } #endif // Convert month to string str = int_to_array(sDate.month, 2, 0); #ifndef CONFIG_METRIC_ONLY if (sys.flag.use_metric_units) { display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); } else { display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); } #else display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); #endif //CONFIG_METRIC_ONLY // Display "." to separate day and month display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON); break; #endif //CONFIG_DAY_OF_WEEK case DISPLAY_ALTERNATIVE_VIEW: //MM DD #ifdef CONFIG_DAY_OF_WEEK // Convert day to string display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON); // display date #ifndef CONFIG_METRIC_ONLY if (!sys.flag.use_metric_units) { str = int_to_array(sDate.day, 2, 0); display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); // Convert month to string str = int_to_array(sDate.month, 2, 1); display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); } else #else if (1) #endif //CONFIG_METRIC_ONLY { str = int_to_array(sDate.day, 2, 0); display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); str = int_to_array(sDate.month, 2, 0); display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); } break; case DISPLAY_ALTERNATIVE2_VIEW: //YYYY #endif //CONFIG_DAY_OF_WEEK // Convert year to string str = int_to_array(sDate.year, 4, 0); display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_3_0), str, SEG_ON); // Clear "." display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_OFF); break; default: display_time(line, update); break; } } else if (update == DISPLAY_LINE_CLEAR) { // Show day and month on display when coming around next time sDate.display = DISPLAY_DEFAULT_VIEW; } }