/** * \brief Draw OK button at bottom of screen * * This function draws an OK button at the bottom of the screen. It will * also draw an indicator arrow in front of the button if the indicator bool * is true. If the draw bool is false, the OK button will be deleted, and if * the indicator bool is false, the indicator will be deleted. * * \param draw true on draw, false on delete * \param indicator true on draw indicator, false on delete */ static void gfx_mono_spinctrl_draw_button(bool draw, bool indicator) { uint8_t width; uint8_t height; uint8_t offset; char string_buf[22]; /* Clear bottom line */ gfx_mono_draw_filled_rect(0, (SYSFONT_HEIGHT + 1) * GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION, GFX_MONO_LCD_WIDTH, SYSFONT_HEIGHT, GFX_PIXEL_CLR); snprintf(string_buf, sizeof(string_buf), "OK"); gfx_mono_get_string_bounding_box(string_buf, &sysfont, &width, &height); offset = (GFX_MONO_LCD_WIDTH - width) / 2; if (draw) { /* Draw OK button in the middle of the last line */ gfx_mono_draw_string(string_buf, offset, (SYSFONT_HEIGHT + 1) * GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION, &sysfont); if (indicator) { /* Draw indicator arrow in front of button */ gfx_mono_put_bitmap(&gfx_mono_spinctrl_bitmap_indicator, offset - GFX_MONO_SPINCTRL_INDICATOR_WIDTH, (SYSFONT_HEIGHT + 1) * GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION); } else { /* Delete indicator */ gfx_mono_draw_filled_rect(offset - GFX_MONO_SPINCTRL_INDICATOR_WIDTH, (SYSFONT_HEIGHT + 1) * GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION, GFX_MONO_SPINCTRL_INDICATOR_WIDTH, GFX_MONO_SPINCTRL_INDICATOR_HEIGHT, GFX_PIXEL_CLR); } } else { /* Delete OK button */ gfx_mono_draw_filled_rect( offset - GFX_MONO_SPINCTRL_INDICATOR_WIDTH, (SYSFONT_HEIGHT + 1) * GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION, 20, SYSFONT_HEIGHT, GFX_PIXEL_CLR); } }
/** * \brief Production date application * * This application will display the time since the XMEGA-A3BU Xplained board * has been produced. During production the production time is stored in EEPROM * and the RTC is initialized to the same time. The RTC is then left running * from the battery backup. This application reads out the production date from * EEPROM and shows the difference between the current time and the production * date; in other words the time the RTC timer has been running on battery * since production. * * \note If the EEPROM is erased and no production date can be set, it will * default to time 01.01.1970, the start of the UNIX time epoch. */ void production_date_application(void) { struct keyboard_event input_key; uint32_t past_timestamp = 0xFFFFFFFF; uint32_t rtc_timestamp; struct calendar_date rtc_date; struct calendar_date date_diff; struct calendar_date production_date; uint32_t production_date_timestamp; uint16_t months; uint8_t width; uint8_t height; uint8_t offset; char string_buf[22]; // Clear screen gfx_mono_draw_filled_rect(0, 0, 128, 32, GFX_PIXEL_CLR); // Draw application title gfx_mono_draw_string("Time since production", 0, 0, &sysfont); // Get production timestamp production_date_timestamp = production_date_get_timestamp(); // Convert timestamp to date struct calendar_timestamp_to_date(production_date_timestamp, &production_date); // Exit the application if "back" key is pressed while (true) { keyboard_get_key_state(&input_key); if ((input_key.keycode == KEYBOARD_BACK) && (input_key.type == KEYBOARD_RELEASE)) { break; } // Get current time from RTC32 rtc_timestamp = rtc_get_time(); if (rtc_timestamp == past_timestamp) { // Same time as last time, no need for update continue; } past_timestamp = rtc_timestamp; // Convert timestamp to date struct calendar_timestamp_to_date(rtc_timestamp, &rtc_date); // Find the difference between the current date and production date calendar_time_between_dates(&rtc_date, &production_date, &date_diff); // Use months + year*12 as we are a line short to have both year and month months = (date_diff.year * 12) + date_diff.month; // Center month string on screen. Align day string with month string snprintf(string_buf, sizeof(string_buf), "%2d Months", months); gfx_mono_get_string_bounding_box(string_buf, &sysfont, &width, &height); offset = (GFX_MONO_LCD_WIDTH - width) / 2; gfx_mono_draw_string(string_buf, offset, 8, &sysfont); snprintf(string_buf, sizeof(string_buf), "%2d Days", date_diff.date); gfx_mono_draw_string(string_buf, offset, 16, &sysfont); // Display hour, minute, second snprintf(string_buf, sizeof(string_buf),"%.2d:%.2d:%.2d", date_diff.hour, date_diff.minute, date_diff.second); gfx_mono_get_string_bounding_box(string_buf, &sysfont, &width, &height); offset = (GFX_MONO_LCD_WIDTH - width) / 2; gfx_mono_draw_string(string_buf, offset, 24, &sysfont); } }
/** * \brief Display current date and time in the selected timezone */ static void display_date_time_application(void) { struct calendar_date date; struct keyboard_event input_key; uint8_t width; uint8_t height; uint8_t offset; int8_t tz_hours_temp; int8_t tz_minutes_temp; uint32_t past_timestamp = 0xFFFFFFFF; uint32_t rtc_timestamp = 0; char string_buf[32] = "Date & Time"; //clear screen gfx_mono_draw_filled_rect(0, 0, 128, 32, GFX_PIXEL_CLR); // Get current timestamp from the RTC32 rtc_timestamp = rtc_get_time(); // Get timezone settings tz_hours_temp = timezone_get_hours(); tz_minutes_temp = timezone_get_minutes(); // Print "Date & Time" at first line of the display gfx_mono_get_string_bounding_box(string_buf, &sysfont, &width, &height); offset = (GFX_MONO_LCD_WIDTH - width) / 2; gfx_mono_draw_string(string_buf, offset, 0, &sysfont); // Convert RTC time to a date struct containing the current date and time calendar_timestamp_to_date_tz(rtc_timestamp, tz_hours_temp, tz_minutes_temp, &date); while (true) { // Return from application if "back" key is pressed and released keyboard_get_key_state(&input_key); if ((input_key.keycode == KEYBOARD_BACK) && (input_key.type == KEYBOARD_RELEASE)) { break; } rtc_timestamp = rtc_get_time(); // Update printed time if the time has changed if(rtc_timestamp != past_timestamp) { calendar_add_second_to_date(&date); // Print current date centered on line 3 snprintf(string_buf, sizeof(string_buf),"%s %.2d.%.2d.%d", day[date.dayofweek], date.date + 1, date.month + 1, date.year); gfx_mono_get_string_bounding_box(string_buf, &sysfont, &width, &height); offset = (GFX_MONO_LCD_WIDTH - width) / 2; gfx_mono_draw_string(string_buf, offset, 12, &sysfont); snprintf(string_buf, sizeof(string_buf), "%.2d:%.2d:%.2d", date.hour, date.minute, date.second); // Center text gfx_mono_get_string_bounding_box(string_buf, &sysfont,&width, &height); offset = (GFX_MONO_LCD_WIDTH - width) / 2; gfx_mono_draw_string(string_buf, offset, 20, &sysfont); past_timestamp = rtc_timestamp; } } }