Exemple #1
0
/**
 * \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);
	}
}
Exemple #2
0
/**
 * \brief Main function.
 *
 * Initializes the board and reads out the production date stored in EEPROM and
 * set timezone from EEPROM if it is set. If it is not set it will open the
 * timezone selector to select the local timezone. It then runs the menu system
 * in an infinite while loop.
 */
int main(void)
{
	uint8_t menu_status;
	struct keyboard_event input;
	uint32_t rtc_timestamp;

	sysclk_init();
	board_init();
	pmic_init();
	gfx_mono_init();
	touch_init();
	adc_sensors_init();

	// Enable display backlight
	gpio_set_pin_high(NHD_C12832A1Z_BACKLIGHT);

	// Workaround for known issue: Enable RTC32 sysclk
	sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC);
	while (RTC32.SYNCCTRL & RTC32_SYNCBUSY_bm) {
		// Wait for RTC32 sysclk to become stable
	}

	// If we have battery power and RTC is running, don't initialize RTC32
	if (rtc_vbat_system_check(false) != VBAT_STATUS_OK) {
		rtc_init();

		// Set current time to after production date
		rtc_timestamp = production_date_get_timestamp() + 1;
		rtc_set_time(rtc_timestamp);
	}

	// Get current time
	rtc_timestamp = rtc_get_time();
	// Make sure RTC has not been set to a too early date .
	if (rtc_timestamp < FIRST_POSSIBLE_TIMESTAMP) {
		// Set time to 01.01.2011 00:00:00
		rtc_set_time(FIRST_POSSIBLE_TIMESTAMP);
	}

	// Initialize USB CDC class
	cdc_start();

	cpu_irq_enable();

	// Display a splash screen showing button functions
	button_splash();

	// Set timezone from EEPROM or to a default value
	timezone_init();

	/* Main loop. Read keyboard status and pass input to menu system.
	 * When an element has been selected in the menu, it will return the
	 * index of the element that should be run. This can be an application
	 * or another menu.
	 */
	while (true) {

		// (re)initialize menu system
		gfx_mono_menu_init(&main_menu);

		do {
			do {
				keyboard_get_key_state(&input);
			// Wait for key release
			} while (input.type != KEYBOARD_RELEASE);

			// Send key to menu system
			menu_status = gfx_mono_menu_process_key(&main_menu, input.keycode);
		// Wait for something useful to happen in the menu system
		} while (menu_status == GFX_MONO_MENU_EVENT_IDLE);

		switch (menu_status) {
		case 0:
			ntc_sensor_application();
			break;
		case 1:
			lightsensor_application();
			break;
		case 2:
			production_date_application();
			break;
		case 3:
			date_time_application();
			break;
		case 4:
			// Toggle LCD Backlight
			gpio_toggle_pin(NHD_C12832A1Z_BACKLIGHT);
			break;
		case GFX_MONO_MENU_EVENT_EXIT:
			// Fall trough to default and show button splash
		default:
			button_splash();
			break;
		};
	}
}