// ************************************************************************************************* // @fn mx_time // @brief Clock set routine. // @param unsigned char line LINE1, LINE2 // @return none // ************************************************************************************************* void mx_time(unsigned char line) { unsigned char select; int timeformat; short timeformat1; int hours; int minutes; int seconds; unsigned char *str; // 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; seconds = sTime.second; // 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 sTime.hour = hours; sTime.minute = minutes; sTime.second = seconds; // 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) 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); str = int_to_array(seconds, 2, 0); display_chars(LCD_SEG_L2_1_0, str, SEG_ON); display_symbol(LCD_SEG_L2_DP, 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 = 3; break; case 3: // Set seconds set_value(&seconds, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_1_0, display_value); select = 0; break; } } // Clear button flags button.all_flags = 0; }
// ************************************************************************************************* // @fn mx_altitude // @brief Mx button handler to set the altitude offset. // @param u8 line LINE1 // @return none // ************************************************************************************************* void mx_altitude(u8 line) { s32 altitude; s32 limit_high, limit_low; // Clear display clear_display_all(); // Set lower and upper limits for offset correction if (sys.flag.use_metric_units) { // Display "m" symbol display_symbol(LCD_UNIT_L1_M, SEG_ON); // Convert global variable to local variable altitude = sAlt.altitude; // Limits for set_value function limit_low = -100; limit_high = 4000; } else // English units { // Display "ft" symbol display_symbol(LCD_UNIT_L1_FT, SEG_ON); // Convert altitude in meters to feet altitude = sAlt.altitude; // Convert from meters to feet altitude = convert_m_to_ft(altitude); // Limits for set_value function limit_low = -500; limit_high = 9999; } // 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) { // When using English units, convert ft back to m before updating pressure table if (!sys.flag.use_metric_units) altitude = convert_ft_to_m((s16) altitude); // Update pressure table update_pressure_table((s16) altitude, sAlt.pressure, sAlt.temperature); // Set display update flag display.flag.line1_full_update = 1; break; } // Set current altitude - offset is set when leaving function set_value(&altitude, 4, 3, limit_low, limit_high, SETVALUE_DISPLAY_VALUE + SETVALUE_FAST_MODE + SETVALUE_DISPLAY_ARROWS, LCD_SEG_L1_3_0, display_value); } // Clear button flags button.all_flags = 0; }
// ************************************************************************************************* // @fn mx_sidereal // @brief Sidereal Clock set routine. // has three layers of different configuration sets // @param uint8_t line LINE1, LINE2 // @return none // ************************************************************************************************* void mx_sidereal(uint8_t line) { uint8_t select; int32_t hours; int32_t minutes; int32_t seconds; int32_t lon_degrees[SIDEREAL_NUM_LON]; int32_t lon_minutes[SIDEREAL_NUM_LON]; int32_t lon_seconds[SIDEREAL_NUM_LON]; int32_t sync; int32_t heart; uint8_t level; int32_t direction[SIDEREAL_NUM_LON]; int32_t UTCoffset; uint8_t *str; int i; // Clear display clear_display_all(); // Convert global time to local variables hours = sSidereal_time.hour; minutes = sSidereal_time.minute; seconds = sSidereal_time.second; sync = sSidereal_time.sync; for (i = 0; i < SIDEREAL_NUM_LON; i++) { if (sSidereal_time.lon[i].deg < 0 || sSidereal_time.lon[i].min < 0 || sSidereal_time.lon[i].sec < 0) { direction[i] = 0; lon_degrees[i] = -sSidereal_time.lon[i].deg; lon_minutes[i] = -sSidereal_time.lon[i].min; lon_seconds[i] = -sSidereal_time.lon[i].sec; } else { direction[i] = 1; lon_degrees[i] = sSidereal_time.lon[i].deg; lon_minutes[i] = sSidereal_time.lon[i].min; lon_seconds[i] = sSidereal_time.lon[i].sec; } } UTCoffset = sTime.UTCoffset; // Init value index (start with Auto Sync selection) select = 0; heart = 0; level = sSidereal_time.lon_selection; // Loop values until all are set or user breaks set while (1) { // Idle timeout: exit without saving if (sys.flag.idle_timeout) { display_symbol(LCD_SYMB_AM, SEG_OFF); display_symbol(LCD_UNIT_L1_DEGREE, SEG_OFF); display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); break; } if (heart != 0) { if (select <= 4) { //go to longitude settings if (heart > 0) { select = 5; level = 0; } //go to time zone settings else { select = 10; } clear_display_all(); display_symbol(LCD_SYMB_AM, SEG_OFF); } else if (select <= 9) { if (heart < 0) { //go to previous level if (level > 0) { level -= 1; select = 5; } //go to time/sync settings else { select = 0; } } else { //go to next level if (level < SIDEREAL_NUM_LON - 1) { level += 1; select = 5; } //go to time zone settings else { select = 10; } } clear_display_all(); display_symbol(LCD_UNIT_L1_DEGREE, SEG_OFF); display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); } else { //go to time/sync settings if (heart > 0) { select = 0; } //go to longitude settings else { select = 5; level = SIDEREAL_NUM_LON - 1; } clear_display_all(); display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); } heart = 0; } // Button STAR (short): save, then exit if (button.flag.star) { //store sync settings sSidereal_time.sync = sync; sTime.UTCoffset = UTCoffset; for (i = 0; i < SIDEREAL_NUM_LON; i++) { //store direction as sign of longitude if (direction[i] & 0x1) { sSidereal_time.lon[i].deg = lon_degrees[i]; sSidereal_time.lon[i].min = lon_minutes[i]; sSidereal_time.lon[i].sec = lon_seconds[i]; } else { sSidereal_time.lon[i].deg = -lon_degrees[i]; sSidereal_time.lon[i].min = -lon_minutes[i]; sSidereal_time.lon[i].sec = -lon_seconds[i]; } } //only save new lon_selection when it is clear which level is selected if (select <= 9 && select > 4) { sSidereal_time.lon_selection = level; } #ifdef CONFIG_INFOMEM //store new longitude and time zone in information memory uint16_t buf[SIDEREAL_NUM_LON * sizeof(struct longitude) / 2 + 1]; ((uint8_t *)buf)[0] = sTime.UTCoffset; ((uint8_t *)buf)[1] = sSidereal_time.lon_selection; memcpy(buf + 1, &(sSidereal_time.lon), SIDEREAL_NUM_LON * sizeof(struct longitude)); infomem_app_replace(SIDEREAL_INFOMEM_ID, buf, SIDEREAL_NUM_LON * sizeof(struct longitude) / 2 + 1); #endif //sync time if desired if (sync >= 1) { sync_sidereal(); } else { // Disable interrupts to prevent race conditions Timer0_A1_Stop(); // Store local variables in global sidereal clock time sSidereal_time.hour = hours; sSidereal_time.minute = minutes; sSidereal_time.second = seconds; // Set clock timer for one sidereal second in the future Timer0_A1_Start(); } // Full display update is done when returning from function 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_DEGREE, SEG_OFF); break; } switch (select) { case 0: // Heart Symbol to switch to longitude settings // Display HH:MM (LINE1) and As .SS (LINE2) str = _itoa(hours, 2, 0); display_chars(LCD_SEG_L1_3_2, str, SEG_ON); display_symbol(LCD_SEG_L1_COL, SEG_ON); str = _itoa(minutes, 2, 0); display_chars(LCD_SEG_L1_1_0, str, SEG_ON); str = _itoa(seconds, 2, 0); display_chars(LCD_SEG_L2_1_0, str, SEG_ON); display_symbol(LCD_SEG_L2_DP, SEG_ON); str = _itoa(sync, 1, 0); display_char(LCD_SEG_L2_3, *str, SEG_ON); display_char(LCD_SEG_L2_4, 'A', SEG_ON); set_value(&heart, 0, 0, -1, 1, SETVALUE_DISPLAY_SYMBOL + SETVALUE_NEXT_VALUE, LCD_ICON_HEART, display_value1); select = 1; break; case 1: // Set Automatic Sync setings set_value(&sync, 1, 0, 0, 2, SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_3, display_value1); select = 2; break; case 2: // 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_12_or_24); select = 3; break; case 3: // Set minutes set_value(&minutes, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value1); select = 4; break; case 4: // Set seconds set_value(&seconds, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_1_0, display_value1); select = 0; break; /*=============================================*/ case 5: // Heart Symbol to switch to time settings or UTC offset //display current level at free digit next to the degrees str = _itoa(level + 1, 1, 0); display_chars(LCD_SEG_L1_0, str, SEG_ON); str = _itoa(lon_degrees[level], 3, 0); display_chars(LCD_SEG_L1_3_1, str, SEG_ON); display_symbol(LCD_UNIT_L1_DEGREE, SEG_ON); str = _itoa(lon_minutes[level], 2, 0); display_chars(LCD_SEG_L2_4_3, str, SEG_ON); str = _itoa(lon_seconds[level], 2, 0); display_chars(LCD_SEG_L2_1_0, str, SEG_ON); display_symbol(LCD_SEG_L2_COL0, SEG_ON); if (direction[level] & 0x1) { display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); } else { display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); } set_value(&heart, 0, 0, -1, 1, SETVALUE_DISPLAY_SYMBOL + SETVALUE_NEXT_VALUE, LCD_ICON_HEART, display_value1); select = 6; break; case 6: // Set orientation set_value(direction + level, 0, 0, 0, 1, SETVALUE_ROLLOVER_VALUE + SETVALUE_NEXT_VALUE + SETVALUE_SWITCH_ARROWS, 0, display_value1); select = 7; break; case 7: // Set degrees set_value(lon_degrees + level, 3, 0, 0, 180, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_1, display_value1); select = 8; break; case 8: // Set minutes set_value(lon_minutes + level, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_4_3, display_value1); select = 9; break; case 9: // Set seconds set_value(lon_seconds + level, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_1_0, display_value1); select = 5; break; /*=============================================*/ case 10: // Heart Symbol to switch to longitude settings if (UTCoffset >= 0) { str = _itoa(UTCoffset, 3, 0); if (UTCoffset > 0) { display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); } } else { str = _itoa(- UTCoffset, 3, 0); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); } display_chars(LCD_SEG_L1_3_1, str, SEG_ON); display_symbol(LCD_SEG_L1_DP1, SEG_ON); memcpy(str, "UTC", 3); display_chars(LCD_SEG_L2_4_2, str, SEG_ON); set_value(&heart, 0, 0, -1, 1, SETVALUE_DISPLAY_SYMBOL + SETVALUE_NEXT_VALUE, LCD_ICON_HEART, display_value1); select = 11; break; case 11: // Set UTC OFFSET set_value(&UTCoffset, 3, 0, -120, 120, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE + SETVALUE_DISPLAY_ARROWS + SETVALUE_STEP_FIFE, LCD_SEG_L1_3_1, display_value1); select = 10; break; } } // Clear button flags button.all_flags = 0; }
// ************************************************************************************************* // @fn mx_date // @brief Date set routine. // @param line LINE1, LINE2 // @return none // ************************************************************************************************* void mx_date(line_t line) { #ifdef CONFIG_USE_SYNC_TOSET_TIME return; #else u8 select; s32 day; s32 month; s32 year; s16 max_days; u8 * str; // 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: YYYY (will be drawn by set_value) // LINE2: MM DD str = itoa(day, 2, 1); display_chars(LCD_SEG_L2_1_0, str, SEG_ON); str = itoa(month, 2, 1); display_chars(LCD_SEG_L2_5_4, str, 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; #ifdef CONFIG_SIDEREAL if(sSidereal_time.sync>0) sync_sidereal(); #endif #if (CONFIG_DST > 0) dst_calculate_dates(); #endif // 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_L1_3_0, display_value1); select = 1; break; case 1: // Set month set_value(&month, 2, 1, 1, 12, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_5_4, display_value1); select = 2; break; case 2: // Set day set_value(&day, 2, 1, 1, max_days, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_1_0, display_value1); 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; #endif }
// ************************************************************************************************* // @fn mx_temperature // @brief Mx button handler to set the temperature offset. // @param u8 line LINE1 // @return none // ************************************************************************************************* void mx_temperature(u8 line) { s32 temperature; s16 temperature0; volatile s16 temperature1; volatile s16 offset; // Clear display clear_display_all(); // When using English units, convert internal °C to °F before handing over value to set_value function if (!sys.flag.use_metric_units) { // Convert global variable to local variable temperature = convert_C_to_F(sTemp.degrees); temperature0 = sTemp.degrees; } else { // Convert global variable to local variable temperature = sTemp.degrees; temperature0 = temperature; } // 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) { // For English units, convert set °F to °C if (!sys.flag.use_metric_units) { temperature1 = convert_F_to_C(temperature); } else { temperature1 = temperature; } // New offset is difference between old and new value offset = temperature1 - temperature0; sTemp.offset += offset; // Force filter to new value sTemp.degrees = temperature1; // Set display update flag display.flag.line1_full_update = 1; break; } // Display °C or °F depending on unit system if (sys.flag.use_metric_units) display_char(LCD_SEG_L1_0, 'C', SEG_ON); else display_char(LCD_SEG_L1_0, 'F', SEG_ON); display_symbol(LCD_SEG_L1_DP1, SEG_ON); display_symbol(LCD_UNIT_L1_DEGREE, SEG_ON); // Set current temperature - offset is set when leaving function set_value(&temperature, 3, 1, -999, 999, SETVALUE_DISPLAY_VALUE + SETVALUE_DISPLAY_ARROWS, LCD_SEG_L1_3_1, display_value1); } // Clear button flags button.all_flags = 0; }