Exemplo n.º 1
0
/**
 * \brief Draw or delete indicator arrow in front of spinner
 *
 * \param *spinner initialized gfx_mono_spinctrl struct
 * \param draw     true on draw, false on delete
 */
static void gfx_mono_spinctrl_draw_indicator(struct gfx_mono_spinctrl *spinner,
        bool draw)
{
    if (draw) {
        gfx_mono_put_bitmap(&gfx_mono_spinctrl_bitmap_indicator, 0,
                            spinner->y);
    } else {
        gfx_mono_draw_filled_rect(0, spinner->y,
                                  GFX_MONO_SPINCTRL_INDICATOR_WIDTH,
                                  GFX_MONO_SPINCTRL_INDICATOR_HEIGHT,
                                  GFX_PIXEL_CLR);
    }
}
Exemplo n.º 2
0
/**
 * *\brief Initialize the menu handling. Clear screen and draw menu.
 *
 * \param menu  menu struct with menu options
 *
 */
void gfx_mono_menu_init(struct gfx_mono_menu *menu)
{
	/* Clear screen */
	gfx_mono_draw_filled_rect(0, 0,
			GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT, GFX_PIXEL_CLR);

	/* Draw the menu title on the top of the screen */
	gfx_mono_draw_progmem_string((char PROGMEM_PTR_T)menu->title,
			0, 0, &sysfont);

	/* Draw menu options below */
	menu_draw(menu, true);
}
Exemplo n.º 3
0
/**
 * \internal
 * \brief Test drawing a filled rectangle inside a page
 *
 * This test draws a filled rectangle inside a page and checks that this
 * is done.
 *
 * \param test Current test case.
 */
static void run_draw_filled_rectangle_test(const struct test_case *test)
{
	uint8_t actual[GFX_MONO_LCD_WIDTH];
	uint8_t expected_page[GFX_MONO_LCD_WIDTH];
	uint8_t expected_empty[GFX_MONO_LCD_WIDTH];
	uint8_t page;
	uint8_t i;

	// Clear entire display
	gfx_mono_draw_filled_rect(0, 0, GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT,
			GFX_PIXEL_CLR);

	// Fill page buffer holding rectangle
	set_buffer(expected_page, 0x00);
	for (i = 0; i < 10; i++) {
		expected_page[i + 50] = 0x7C;
	}
	
	// Fill empty page buffer
	set_buffer(expected_empty, 0x00);

	// Draw a 10x5 filled rectangle at position 50, 10
	gfx_mono_draw_filled_rect(50, 10, 10, 5, GFX_PIXEL_SET);

	// Get all pages from display and check that the rectangle is drawn
	for (page = 0; page < GFX_MONO_LCD_PAGES; page++) {
		gfx_mono_get_page(actual, page, 0, GFX_MONO_LCD_WIDTH);
		if (page == 1) {
			test_assert_true(test, is_page_correct(actual, expected_page),
					"Page with rectangle %d not matching expected page",
					page);
		} else {
			test_assert_true(test, is_page_correct(actual, expected_empty),
					"Empty page %d not matching expected page", page);
		}
	}
}
Exemplo n.º 4
0
/**
 * \internal
 * \brief Test filling the display
 *
 * This test fills the entire display and checks that this is done.
 *
 * \param test Current test case.
 */
static void run_set_display_test(const struct test_case *test)
{
	uint8_t actual[GFX_MONO_LCD_WIDTH];
	uint8_t expected_set[GFX_MONO_LCD_WIDTH];
	uint8_t page;

	// Clear entire display
	gfx_mono_draw_filled_rect(0, 0, GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT,
			GFX_PIXEL_CLR);

	// Filled expected page buffer
	set_buffer(expected_set, 0xFF);

	// Fill entire display
	gfx_mono_draw_filled_rect(0, 0, GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT,
			GFX_PIXEL_SET);

	// Get all pages from display and check that each matches the empty page
	for (page = 0; page < GFX_MONO_LCD_PAGES; page++) {
		gfx_mono_get_page(actual, page, 0, GFX_MONO_LCD_WIDTH);
		test_assert_true(test, is_page_correct(actual, expected_set),
				"Page %d not matching expected page", page);
	}
}
Exemplo n.º 5
0
/**
 * \internal
 * \brief Test drawing a line between to points
 *
 * This test draws a line between two points and checks that this is done.
 *
 * \param test Current test case.
 */
static void run_draw_diagonal_line_test(const struct test_case *test)
{
	uint8_t actual[GFX_MONO_LCD_WIDTH];
	uint8_t expected_page1[GFX_MONO_LCD_WIDTH];
	uint8_t expected_page2[GFX_MONO_LCD_WIDTH];
	uint8_t expected_empty[GFX_MONO_LCD_WIDTH];
	uint8_t page;

	// Clear entire display
	gfx_mono_draw_filled_rect(0, 0, GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT,
			GFX_PIXEL_CLR);

	// Fill first page buffer holding the line
	set_buffer(expected_page1, 0x00);
	expected_page1[0] = 0x03;
	expected_page1[1] = 0x0C;
	expected_page1[2] = 0x30;
	expected_page1[3] = 0xC0;

	// Fill second page buffer holding the line
	set_buffer(expected_page2, 0x00);
	expected_page2[4] = 0x01;
	
	// Fill empty page buffer
	set_buffer(expected_empty, 0x00);

	// Draw a line between 0,0 and 4, 8
	gfx_mono_draw_line(0, 0, 4, 8, GFX_PIXEL_SET);

	// Get all pages from display and check that the line is drawn
	for (page = 0; page < GFX_MONO_LCD_PAGES; page++) {
		gfx_mono_get_page(actual, page, 0, GFX_MONO_LCD_WIDTH);
		if (page == 0) {
			test_assert_true(test, is_page_correct(actual, expected_page1),
					"Page %d with line not matching expected page",
					page);
		} else if (page == 1) {
			test_assert_true(test, is_page_correct(actual, expected_page2),
					"Page %d with line not matching expected page",
					page);
		} else {
			test_assert_true(test, is_page_correct(actual, expected_empty),
					"Empty page %d not matching expected page", page);
		}
	}
}
Exemplo n.º 6
0
/**
 * \internal
 * \brief Test drawing a vertical line
 *
 * This test draws a vertical line and checks that this is done.
 *
 * \param test Current test case.
 */
static void run_draw_vertical_line_test(const struct test_case *test)
{
	uint8_t actual[GFX_MONO_LCD_WIDTH];
	uint8_t expected_page1[GFX_MONO_LCD_WIDTH];
	uint8_t expected_page2[GFX_MONO_LCD_WIDTH];
	uint8_t expected_empty[GFX_MONO_LCD_WIDTH];
	uint8_t page;

	// Clear entire display
	gfx_mono_draw_filled_rect(0, 0, GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT,
			GFX_PIXEL_CLR);

	// Fill page buffer holding the top of the line
	set_buffer(expected_page1, 0x00);
	expected_page1[4] = 0xFC;

	// Fill page buffer holding the bottom of the line
	set_buffer(expected_page2, 0x00);
	expected_page2[4] = 0x1F;

	// Fill empty page buffer
	set_buffer(expected_empty, 0x00);

	// Draw a vertical line at position 4, 2 with length 11
	gfx_mono_draw_vertical_line(4, 2, 11, GFX_PIXEL_SET);

	// Get all pages from display and check that the line is drawn
	for (page = 0; page < GFX_MONO_LCD_PAGES; page++) {
		gfx_mono_get_page(actual, page, 0, GFX_MONO_LCD_WIDTH);
		if (page == 0) {
			test_assert_true(test, is_page_correct(actual, expected_page1),
					"Page %d with line not matching expected page",
					page);
		} else if (page == 1) {
			test_assert_true(test, is_page_correct(actual, expected_page2),
					"Page %d with line not matching expected page",
					page);
		} else {
			test_assert_true(test, is_page_correct(actual, expected_empty),
					"Empty page %d not matching expected page", page);
		}
	}
}
Exemplo n.º 7
0
/**
 * \internal
 * \brief Test drawing the outline of a circle on a page
 *
 * This test draws the outline of a circle and checks that this is done.
 *
 * \param test Current test case.
 */
static void run_draw_circle_outline_test(const struct test_case *test)
{
	uint8_t actual[GFX_MONO_LCD_WIDTH];
	uint8_t expected_page[GFX_MONO_LCD_WIDTH];
	uint8_t expected_empty[GFX_MONO_LCD_WIDTH];
	uint8_t page;

	// Clear entire display
	gfx_mono_draw_filled_rect(0, 0, GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT,
			GFX_PIXEL_CLR);

	// Fill page buffer holding the outlined circle
	set_buffer(expected_page, 0x00);
	expected_page[47] = 0x1C;
	expected_page[48] = 0x22;
	expected_page[49] = 0x41;
	expected_page[50] = 0x41;
	expected_page[51] = 0x41;
	expected_page[52] = 0x22;
	expected_page[53] = 0x1C;

	// Fill empty page buffer
	set_buffer(expected_empty, 0x00);

	// Draw the outline of a circle with radius 3 and centre at position 50, 11
	gfx_mono_draw_circle(50, 11, 3, GFX_PIXEL_SET, GFX_WHOLE);

	// Get all pages from display and check that the circle is drawn
	for (page = 0; page < GFX_MONO_LCD_PAGES; page++) {
		gfx_mono_get_page(actual, page, 0, GFX_MONO_LCD_WIDTH);
		if (page == 1) {
			test_assert_true(test, is_page_correct(actual, expected_page),
					"Page %d with outlined circle not matching expected page",
					page);
		} else {
			test_assert_true(test, is_page_correct(actual, expected_empty),
					"Empty page %d not matching expected page", page);
		}
	}
}
/**
 * \brief Draws a character to the display
 *
 * \param c        Character to be drawn
 * \param x        X coordinate on screen.
 * \param y        Y coordinate on screen.
 * \param font     Font to draw character in
 */
void gfx_mono_draw_char(const char c, const gfx_coord_t x, const gfx_coord_t y,
		const struct font *font)
{
	gfx_mono_draw_filled_rect(x, y, font->width, font->height,
			GFX_PIXEL_CLR);

	switch (font->type) {
	case FONT_LOC_PROGMEM:
		gfx_mono_draw_char_progmem(c, x, y, font);
		break;

#ifdef CONFIG_HUGEMEM
	case FONT_LOC_HUGEMEM:
		gfx_mono_draw_char_hugemem(c, x, y, font);
		break;

#endif
	default:
		/* Unsupported mode, call assert */
		Assert(false);
		break;
	}
}
Exemplo n.º 9
0
/**
 * \internal
 * \brief Test drawing a horizontal line
 *
 * This test draws a horizontal line and checks that this is done.
 *
 * \param test Current test case.
 */
static void run_draw_horizontal_line_test(const struct test_case *test)
{
	uint8_t actual[GFX_MONO_LCD_WIDTH];
	uint8_t expected_page[GFX_MONO_LCD_WIDTH];
	uint8_t expected_empty[GFX_MONO_LCD_WIDTH];
	uint8_t page;
	uint8_t i;

	// Clear entire display
	gfx_mono_draw_filled_rect(0, 0, GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT,
			GFX_PIXEL_CLR);

	// Fill page buffer holding the line
	set_buffer(expected_page, 0x00);
	for (i = 0; i < 50; i++) {
		expected_page[i + 10] = 0x10;
	}

	// Fill empty page buffer
	set_buffer(expected_empty, 0x00);

	// Draw a horizontal line at postition 10, 20 with length 50
	gfx_mono_draw_horizontal_line(10, 20, 50, GFX_PIXEL_SET);

	// Get all pages from display and check that the line is drawn
	for (page = 0; page < GFX_MONO_LCD_PAGES; page++) {
		gfx_mono_get_page(actual, page, 0, GFX_MONO_LCD_WIDTH);
		if (page == 2) {
			test_assert_true(test, is_page_correct(actual, expected_page),
					"Page %d with line not matching expected page",
					page);
		} else {
			test_assert_true(test, is_page_correct(actual, expected_empty),
					"Empty page %d not matching expected page", page);
		}
	}
}
Exemplo n.º 10
0
void button_press(void){
	if(gpio_pin_is_low(GPIO_PUSH_BUTTON_1)){
		gfx_mono_draw_filled_rect(0,cursor_position,5,8,GFX_PIXEL_CLR);
		if(cursor_position==8) cursor_position = 24;
		else cursor_position-=8;
		gfx_mono_draw_char('>', 0, cursor_position, &sysfont);
	}
	if(gpio_pin_is_low(GPIO_PUSH_BUTTON_2)){
		gfx_mono_draw_filled_rect(0,cursor_position,5,8,GFX_PIXEL_CLR);
		if(cursor_position==24) cursor_position = 8;
		else cursor_position+=8;
		gfx_mono_draw_char('>', 0, cursor_position, &sysfont);
	}
	if(gpio_pin_is_low(GPIO_PUSH_BUTTON_0)){
		if(cursor_position==8){
			if(plant[0]==false){
				if(sun_value>=plant_cost){
					sun_value -= plant_cost;
					plant[0] = true;
					gfx_mono_draw_char('P',6,cursor_position,&sysfont);
				}
			}
			else{
				if(sun_value>=2){
					sun_value -= 2;
					tembak_atas[0]='*';
				}
				
			}
			
			}else if(cursor_position==16){
			if(plant[1]==false){
				if(sun_value>=plant_cost){
					sun_value -= plant_cost;
					plant[1] = true;
					gfx_mono_draw_char('P',6,cursor_position,&sysfont);
				}
			}
			else{
				if(sun_value>=2){
					sun_value -= 2;
					tembak_tengah[0]='*';
				}
				
			}
			
			}else{
			if(plant[2]==false){
				if(sun_value>=plant_cost){
					sun_value -= plant_cost;
					plant[2] = true;
					gfx_mono_draw_char('P',6,cursor_position,&sysfont);
				}
			}
			else{
				if(sun_value>=2){
					sun_value -= 2;
					tembak_bawah[0]='*';
				}
			}
		}
	}
}
Exemplo n.º 11
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);
	}
}
Exemplo n.º 12
0
void app_usb_task(void)
{
	static bool sw0_released = true;
	static bool usb_running = false;
	static bool cdc_running = false;
	static bool toggle = true;

	if (sw0_released && ioport_pin_is_low(GPIO_PUSH_BUTTON_0)) {
		/* A new press has been done */
		sw0_released = false;
		/* Switch USB state */
		if (usb_running) {
			udc_stop();
			gfx_mono_draw_filled_rect(DISPLAY_USB_STA_POS_X,
					DISPLAY_USB_STA_POS_Y,
					DISPLAY_USB_STA_SIZE_X,
					DISPLAY_USB_STA_SIZE_Y,
					GFX_PIXEL_CLR);
			app_microsd_start();
		} else {
			/* Stop FatFS on uSD card if enabled */
			app_microsd_stop();
			stdio_usb_init(); /* Start USB */
			gfx_mono_generic_put_bitmap(&bitmap_usb,
					DISPLAY_USB_STA_POS_X,
					DISPLAY_USB_STA_POS_Y);
		}

		usb_running = !usb_running;
		cdc_running = true;
	} else {
		/* Wait switch release */
		sw0_released = ioport_pin_is_high(GPIO_PUSH_BUTTON_0);
	}

	if (!usb_running) {
		return;
	}

	/* USB MSC task */
	while (udi_msc_process_trans()) {
	}

	if (app_usb_cdc_open && !cdc_running) {
		printf("\x0CSensor data logs:\r\n");
		cdc_running = true;
	}

	if (!app_usb_cdc_open && cdc_running) {
		cdc_running = false;
	}

	/* Toggle USB icon */
	if ((app_usb_cdc_open && app_usb_rec_toggle) ||
			(toggle && app_usb_rec_toggle)) {
		app_usb_rec_toggle = false;
		toggle = !toggle;
		gfx_mono_draw_rect(DISPLAY_USB_STACDC_POS_X,
				DISPLAY_USB_STACDC_POS_Y,
				DISPLAY_USB_STACDC_SIZE_X,
				DISPLAY_USB_STACDC_SIZE_Y,
				toggle ? GFX_PIXEL_SET : GFX_PIXEL_CLR);
	}
}
Exemplo n.º 13
0
/**
 * \internal
 * \brief Test drawing a bitmap stored in RAM
 *
 * This test draws a bitmap to position x = 50, y = 5 and checks that
 * it is aligned with display pages and that it is drawn correctly.
 *
 * \param test Current test case.
 */
static void run_draw_ram_bitmap_test(const struct test_case *test)
{
	uint8_t actual[GFX_MONO_LCD_WIDTH];
	uint8_t expected_page1[GFX_MONO_LCD_WIDTH];
	uint8_t expected_page2[GFX_MONO_LCD_WIDTH];
	uint8_t expected_empty[GFX_MONO_LCD_WIDTH];
	uint8_t page;
	struct gfx_mono_bitmap smiley;

	// Setup bitmap struct for bitmap stored in RAM
	smiley.type = GFX_MONO_BITMAP_RAM;
	smiley.width = 8;
	smiley.height = 16;
	smiley.data.pixmap = smiley_data;

	// Clear entire display
	gfx_mono_draw_filled_rect(0, 0, GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT,
			GFX_PIXEL_CLR);

	// Fill first page buffer holding smileys
	set_buffer(expected_page1, 0x00);
	expected_page1[50] = 0x3C;
	expected_page1[51] = 0x42;
	expected_page1[52] = 0x95;
	expected_page1[53] = 0xA1;
	expected_page1[54] = 0xA1;
	expected_page1[55] = 0x95;
	expected_page1[56] = 0x42;
	expected_page1[57] = 0x3C;

	// Fill second page buffer holding smileys
	set_buffer(expected_page2, 0x00);
	expected_page2[50] = 0x3C;
	expected_page2[51] = 0x42;
	expected_page2[52] = 0x95;
	expected_page2[53] = 0xA1;
	expected_page2[54] = 0xA1;
	expected_page2[55] = 0x95;
	expected_page2[56] = 0x42;
	expected_page2[57] = 0x3C;

	// Fill empty page buffer
	set_buffer(expected_empty, 0x00);

	// Output bitmap
	gfx_mono_put_bitmap(&smiley, 50, 5);

	// Get all pages from display and check that the bitmap is drawn
	for (page = 0; page < GFX_MONO_LCD_PAGES; page++) {
		gfx_mono_get_page(actual, page, 0, GFX_MONO_LCD_WIDTH);
		if (page == 0) {
			test_assert_true(test, is_page_correct(actual, expected_page1),
					"Page %d with smileys not matching expected page", page);
		} else if (page == 1) {
			test_assert_true(test, is_page_correct(actual, expected_page2),
					"Page %d with smileys not matching expected page", page);
		} else {
			test_assert_true(test, is_page_correct(actual, expected_empty),
					"Empty page %d not matching expected page", page);
		}
	}
}
Exemplo n.º 14
0
/**
 * \internal
 * \brief Test drawing a bitmap stored in FLASH
 *
 * This test draws a bitmap to position x = 60, y = 9 and checks that
 * it is aligned with display pages and that it is drawn correctly.
 *
 * \param test Current test case.
 */
static void run_draw_flash_bitmap_test(const struct test_case *test)
{
	uint8_t actual[GFX_MONO_LCD_WIDTH];
	uint8_t expected_page1[GFX_MONO_LCD_WIDTH];
	uint8_t expected_page2[GFX_MONO_LCD_WIDTH];
	uint8_t expected_empty[GFX_MONO_LCD_WIDTH];
	uint8_t page;
	struct gfx_mono_bitmap smiley_flash;

	// Setup bitmap for bitmap stored in FLASH
	smiley_flash.type = GFX_MONO_BITMAP_PROGMEM;
	smiley_flash.width = 8;
	smiley_flash.height = 16;
	smiley_flash.data.progmem = flash_bitmap;

	// Clear entire display
	gfx_mono_draw_filled_rect(0, 0, GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT,
			GFX_PIXEL_CLR);

	// Fill first page buffer holding smileys
	set_buffer(expected_page1, 0x00);
	expected_page1[60] = 0x3C;
	expected_page1[61] = 0x42;
	expected_page1[62] = 0x95;
	expected_page1[63] = 0xA1;
	expected_page1[64] = 0xA1;
	expected_page1[65] = 0x95;
	expected_page1[66] = 0x42;
	expected_page1[67] = 0x3C;

	// Fill second page buffer holding smileys
	set_buffer(expected_page2, 0x00);
	expected_page2[60] = 0x3C;
	expected_page2[61] = 0x42;
	expected_page2[62] = 0x95;
	expected_page2[63] = 0xA1;
	expected_page2[64] = 0xA1;
	expected_page2[65] = 0x95;
	expected_page2[66] = 0x42;
	expected_page2[67] = 0x3C;


	// Fill empty page buffer
	set_buffer(expected_empty, 0x00);

	// Output bitmap
	gfx_mono_put_bitmap(&smiley_flash, 60, 9);

	// Get all pages from display and check that the bitmap is drawn
	for (page = 0; page < GFX_MONO_LCD_PAGES; page++) {
		gfx_mono_get_page(actual, page, 0, GFX_MONO_LCD_WIDTH);
		if (page == 1) {
			test_assert_true(test, is_page_correct(actual, expected_page1),
					"Page %d with smileys not matching expected page",
					page);
		} else if (page == 2) {
			test_assert_true(test, is_page_correct(actual, expected_page2),
					"Page %d with smileys not matching expected page",
					page);
		} else {
			test_assert_true(test, is_page_correct(actual, expected_empty),
					"Empty page %d not matching expected page", page);
		}
	}
}
Exemplo n.º 15
0
/**
 * \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;
        }
    }
}
Exemplo n.º 16
0
/**
 * \brief Set the date using a spinner widget.
 *
 * This function will set show a spinner widget that lets the user select the
 * current date. This function will leave the clock unchanged, and only change
 * the date part of the RTC32 timestamp.
 */
static void set_date_application(void)
{
    struct calendar_date date;
    struct calendar_date new_date;
    struct keyboard_event input;
    uint32_t current_timestamp;
    uint32_t new_timestamp;
    uint8_t tz_hours;
    uint8_t tz_minutes;
    struct gfx_mono_spinctrl year_spinner;
    struct gfx_mono_spinctrl month_spinner;
    struct gfx_mono_spinctrl day_spinner;
    struct gfx_mono_spinctrl_spincollection date_spinners;
    int16_t spinner_results[3];
    uint8_t spinner_status;

    // Prepare the spinner widget for date selection
    gfx_mono_spinctrl_init(&year_spinner, SPINTYPE_INTEGER,
                           datetime_date_spinner_string_year, NULL, 2011, 2105, 0);
    gfx_mono_spinctrl_init(&month_spinner, SPINTYPE_INTEGER,
                           datetime_date_spinner_string_month, NULL, 1, 12, 0);
    gfx_mono_spinctrl_init(&day_spinner, SPINTYPE_INTEGER,
                           datetime_date_spinner_string_day, NULL, 1, 31, 0);

    // Create date spincollector
    gfx_mono_spinctrl_spincollection_init(&date_spinners);
    gfx_mono_spinctrl_spincollection_add_spinner(&year_spinner,
            &date_spinners);
    gfx_mono_spinctrl_spincollection_add_spinner(&month_spinner,
            &date_spinners);
    gfx_mono_spinctrl_spincollection_add_spinner(&day_spinner,
            &date_spinners);

    // Get timezone settings
    tz_hours = timezone_get_hours();
    tz_minutes = timezone_get_minutes();

    // Get current time
    current_timestamp = rtc_get_time();

    // Convert the current timestamp to a datestruct
    calendar_timestamp_to_date_tz(current_timestamp, tz_hours, tz_minutes,
                                  &date);

    // Set the spinner selection to the current date
    day_spinner.integer_data = date.date + 1;
    month_spinner.integer_data = date.month + 1;
    year_spinner.integer_data = date.year;

    // show the date selection spinner to get a new date
    gfx_mono_spinctrl_spincollection_show(&date_spinners);

    do {
        do {
            keyboard_get_key_state(&input);
            // Wait for key release
        } while (input.type != KEYBOARD_RELEASE);
        // Send key to spinnercollection
        spinner_status = gfx_mono_spinctrl_spincollection_process_key(
                             &date_spinners, input.keycode, spinner_results);
    } while (spinner_status != GFX_MONO_SPINCTRL_EVENT_FINISH);

    /* The result are stored in the same order that they were added
     * we subtract one from month and day, as they are indexed from 0 in the
     * date struct but we present them as starting from 1 in the spinner.
     */
    new_date.year = spinner_results[0];
    new_date.month = spinner_results[1] - 1;
    new_date.date = spinner_results[2] - 1;

    // Verify date set
    new_date.hour = 0;
    new_date.minute = 0;
    new_date.second = 0;
    if (calendar_date_to_timestamp_tz(&new_date, tz_hours, tz_minutes) == 0) {
        //Notify the user that the date was invalid and wait for key
        gfx_mono_draw_filled_rect(0, 0, GFX_MONO_LCD_WIDTH,
                                  GFX_MONO_LCD_HEIGHT, GFX_PIXEL_CLR);
        gfx_mono_draw_progmem_string(
            (char PROGMEM_PTR_T)datetime_invalid_date_string,
            10, 12, &sysfont);

        while (true) {
            keyboard_get_key_state(&input);
            if (input.type == KEYBOARD_RELEASE) {
                break;
            }
        }
        return;
    }

    // Date OK, change.

    // Get current time
    current_timestamp = rtc_get_time();
    // Convert the current timestamp to a datestruct
    calendar_timestamp_to_date_tz(current_timestamp, tz_hours, tz_minutes,
                                  &date);
    // Set new date in struct
    date.year = new_date.year;
    date.month = new_date.month;
    date.date = new_date.date;

    // Convert back to timestamp
    new_timestamp =
        calendar_date_to_timestamp_tz(&date, tz_hours, tz_minutes);
    // Set new timestamp
    rtc_set_time(new_timestamp);
}
Exemplo n.º 17
0
/**
 * \brief Terminal task
 *
 * This task prints the terminal text buffer to the display.
 *
 * \param params Parameters for the task. (Not used.)
 */
static void terminal_task(void *params)
{
	gfx_coord_t x, y;
	char current_char;
	uint8_t current_column;
	uint8_t current_line;
	uint8_t printed_lines;
	EventBits_t event_bits;
	const TickType_t ticks_to_wait = 10 / portTICK_PERIOD_MS;

	for (;;) {
		/* Wait a maximum of 10ms for either bit 2 to be set within
		    the event group.  Not clear the bits before exiting. */
		event_bits = xEventGroupWaitBits(
				event_group,   /* The event group being tested. */
				EVENT_DISPLAY_TERMINAL, /* The bits within the event group to wait for. */
				pdFALSE,        /* Bit should not be cleared before returning. */
				pdFALSE,       /* Don't wait for both bits, either bit will do. */
				ticks_to_wait);/* Wait a maximum of 10ms for either bit to be set. */

		if(event_bits & EVENT_DISPLAY_TERMINAL) {
			oled1_set_led_state(&oled1, OLED1_LED2_ID, true);

			// Grab both display and terminal mutexes before doing anything
			xSemaphoreTake(display_mutex, portMAX_DELAY);
			xSemaphoreTake(terminal_mutex, portMAX_DELAY);

			y = (TERMINAL_LINES - 1) * (SYSFONT_HEIGHT + 1);
			current_line = terminal_line_offset;

			for (printed_lines = 0; printed_lines < TERMINAL_LINES; printed_lines++)
					{
				x = 0;
				current_column = 0;

				// Print characters of string until zero terminator is encountered
				current_char = terminal_buffer[current_line][current_column];
				while (current_char != '\0') {
					gfx_mono_draw_char(current_char, x, y, &sysfont);

					// Move to next character on display and in buffer
					x += SYSFONT_WIDTH;
					current_column++;
					current_char = terminal_buffer[current_line][current_column];
				}

				// Erase remaining part of line on display
				if (current_column < TERMINAL_COLUMNS) {
					gfx_mono_draw_filled_rect(x, y,
							CANVAS_WIDTH - (current_column * SYSFONT_WIDTH),
							SYSFONT_HEIGHT, GFX_PIXEL_CLR);
				}

				// Move to previous line on display and in buffer
				y -= 1 + SYSFONT_HEIGHT;
				current_line += TERMINAL_BUFFER_LINES - 1;
				current_line %= TERMINAL_BUFFER_LINES;
			}

			xSemaphoreGive(terminal_mutex);
			xSemaphoreGive(display_mutex);

			oled1_set_led_state(&oled1, OLED1_LED2_ID, false);
		}

		vTaskDelay(TERMINAL_TASK_DELAY);
	}
}
Exemplo n.º 18
0
void app_sampling_init(void)
{
	/* QDec configuration */
	qdec_get_config_defaults(&qdec_config);
	qdec_config_phase_pins(&qdec_config, &PORTA, 6, false, 500);
	qdec_config_enable_rotary(&qdec_config);
	qdec_config_tc(&qdec_config, &TCC5);
	qdec_config_revolution(&qdec_config, 40);
	qdec_enabled(&qdec_config);

	/* ! ADC module configuration */
	struct adc_config adc_conf;

	/* Configure the ADC module:
	 * - signed, 12-bit results
	 * - VCC reference
	 * - 200 kHz maximum clock rate
	 * - manual conversion triggering
	 * - callback function
	 */
	adc_read_configuration(&LIGHT_SENSOR_ADC_MODULE, &adc_conf);
	adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12,
			ADC_REF_VCC);
	adc_set_clock_rate(&adc_conf, 200000);
	adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0);
	adc_write_configuration(&LIGHT_SENSOR_ADC_MODULE, &adc_conf);
	adc_set_callback(&LIGHT_SENSOR_ADC_MODULE, &app_sampling_handler);
	adc_enable(&LIGHT_SENSOR_ADC_MODULE);

	/* Configure ADC A channel 0 for light and NTC sensors.
	 * - differantial measurement (V- linked on internal GND)
	 * - gain x0.5
	 * - interrupt flag set on completed conversion
	 * - interrupts enabled
	 */
	adcch_read_configuration(&LIGHT_SENSOR_ADC_MODULE, ADC_CH0,
			&adcch_conf);
	adcch_set_input(&adcch_conf, LIGHT_SENSOR_ADC_INPUT,
			ADCCH_NEG_INTERNAL_GND, 0);
	adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE);
	adcch_enable_interrupt(&adcch_conf);
	adcch_write_configuration(&LIGHT_SENSOR_ADC_MODULE, ADC_CH0,
			&adcch_conf);

	fifo_init(&app_sampling_fifo_desc, app_sampling_fifo_buffer,
			APP_SAMPLING_FIFO_SIZE);
	rtc_set_callback(&app_sampling_start);

	/* Display background */
	gfx_mono_draw_line(DISPLAY_SAMPLING_TEXT_POS_X - 3,
			0,
			DISPLAY_SAMPLING_TEXT_POS_X - 3,
			32,
			GFX_PIXEL_SET);
	app_sampling_display_rate();
	gfx_mono_draw_string(DISPLAY_LIGHT_TEXT,
			DISPLAY_LIGHT_TEXT_POS_X,
			DISPLAY_LIGHT_TEXT_POS_Y,
			&sysfont);
	gfx_mono_draw_filled_rect(
			DISPLAY_LIGHT_PROBAR_START_POS_X,
			DISPLAY_LIGHT_PROBAR_START_POS_Y,
			DISPLAY_LIGHT_PROBAR_START_SIZE_X,
			DISPLAY_LIGHT_PROBAR_START_SIZE_Y,
			GFX_PIXEL_SET);
	gfx_mono_draw_filled_rect(
			DISPLAY_LIGHT_PROBAR_STOP_POS_X,
			DISPLAY_LIGHT_PROBAR_STOP_POS_Y,
			DISPLAY_LIGHT_PROBAR_STOP_SIZE_X,
			DISPLAY_LIGHT_PROBAR_STOP_SIZE_Y,
			GFX_PIXEL_SET);

	/* Start a RTC alarm immediatly */
	rtc_set_alarm_relative(0);
}
Exemplo n.º 19
0
void tampilkanTembak(void){
	for(i=0;i<19;++i){
		
		if(i==18){
			if(tembak_atas[i+1]=='*')
			gfx_mono_draw_filled_rect(i*6+12,8,10,7,GFX_PIXEL_CLR);
			if(tembak_tengah[i+1]=='*')
			gfx_mono_draw_filled_rect(i*6+12,16,10,7,GFX_PIXEL_CLR);
			if(tembak_bawah[i+1]=='*')
			gfx_mono_draw_filled_rect(i*6+12,24,10,7,GFX_PIXEL_CLR);
		}
		
		if(tembak_atas[i]=='*')
		{
			if(atas[i+j] =='@'){
				tembak_atas[i]=' ';
				atas[i+j] = ' ';
				zombie--;
				score++;
				gfx_mono_draw_filled_rect(i*6+6,8,12,7,GFX_PIXEL_CLR);
				}else{
				if(i>0){
					gfx_mono_draw_filled_rect(i*6+6,8,6,7,GFX_PIXEL_CLR);
				}
				
				gfx_mono_draw_char(tembak_atas[i],i*6+12,8,&sysfont);
			}
		}
		
		if(tembak_tengah[i]=='*')
		{
			if(tengah[i+j] =='@'){
				tembak_tengah[i]=' ';
				tengah[i+j] = ' ';
				zombie--;
				score++;
				gfx_mono_draw_filled_rect(i*6+6,16,12,7,GFX_PIXEL_CLR);
				}else {
				if(i>0){
					gfx_mono_draw_filled_rect(i*6+6,16,6,7,GFX_PIXEL_CLR);
				}
				gfx_mono_draw_char(tembak_tengah[i],i*6+12,16,&sysfont);
			}
		}
		
		if(tembak_bawah[i]=='*')
		{
			if(bawah[i+j] =='@'){
				tembak_bawah[i]=' ';
				bawah[i+j] = ' ';
				zombie--;
				score++;
				gfx_mono_draw_filled_rect(i*6+6,24,12,7,GFX_PIXEL_CLR);
				}else{
				if(i>0){
					gfx_mono_draw_filled_rect(i*6+6,24,6,7,GFX_PIXEL_CLR);
				}
				gfx_mono_draw_char(tembak_bawah[i],i*6+12,24,&sysfont);
			}
		}
	}
	for(i=19;i>0;i--){
		tembak_atas[i] =  tembak_atas[i-1];
		tembak_tengah[i] = tembak_tengah[i-1];
		tembak_bawah[i] = tembak_bawah[i-1];
	}
	tembak_atas[0] = ' ';
	tembak_tengah[0] = ' ';
	tembak_bawah[0] = ' ';
}
Exemplo n.º 20
0
/**
 * \brief Main function.
 *
 * Initializes the board, displays splash screens, then launches application.
 *
 * If the application exits (fails), the error is written to display and an
 * infinite loop with watchdog resets is entered.
 */
int main(void)
{
    /* Holds state of the QTouch button */
    enum pot_t potstate      = POT_OFF;
    /* Last state of the QTouch button for change detection */
    enum pot_t last_potstate = POT_OFF;
    /* Holds user-selected power-setting */
    uint8_t wattage      = 0;
    /* Last power-setting for change detection */
    uint8_t last_wattage = 0;
    /* Whether the plate element is/should be actuated */
    bool power      = false;
    /* Last power setting for change detection */
    bool last_power = false;
    /* Last time a simulation step was executed */
    uint32_t last_sim_step;
    /* Last time a control step was executed */
    uint32_t last_ctl_step;

    /* The WDT was just reset by the WDT functional test*/
    classb_last_wdt_reset = rtc_get_time();

    last_sim_step = classb_last_wdt_reset;
    last_ctl_step = classb_last_wdt_reset;

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

    cpu_irq_enable();

    /* Enable display backlight */
    ioport_set_pin_level(LCD_BACKLIGHT_ENABLE_PIN,
                         LCD_BACKLIGHT_ENABLE_LEVEL);

    /* If an error was detected, skip directly to displaying it */
    if (classb_error) {
        goto display_error;
    }


    /* Check if required jumpers are mounted, show explanation if not */
    if (!main_check_jumpers()) {
        show_explain_splash();
    }

    /* Display a splash screen showing button functions */
    show_button_splash();

    /* Initialize the ADC, DAC and Timer/Counter modules that are used to
     * emulate real world objects.
     */
    main_init_adc_dac();
    main_init_tc();

    /* Initialize subsystems used for Class B testing */
    oven_classb_init_tests();

    /* Reset the simulation states */
    oven_plant_init();

    /* Clear screen */
    gfx_mono_draw_filled_rect(0, 0, 128, 32, GFX_PIXEL_CLR);

    /* Draw the initial axis system */
    oven_ui_draw_axis();

    /* Draw the user interface */
    oven_ui_update_graphics(potstate, wattage, power);

    /* Run simulation as long as no error is detected in class B tests */
    while (!classb_error) {
        uint32_t current_time;

        oven_wdt_periodic_reset();
        current_time = rtc_get_time();

        /* Add power on SW1 press, wrap at 20 */
        if (oven_ui_power_button_is_pressed()) {
            wattage = (wattage + 5) % 20;
        }

        /* Check QTouch sensor and map this to `potstate`. This is
         * needed both for simulation and for the control routine.
         */
        potstate = (!touch_key_is_pressed()) ? POT_ON : POT_OFF;

        /* Execute control routine periodically */
        if (current_time > (last_ctl_step + OVEN_CTL_STEP_TIME)) {
            ovenctl_execute_control_step(current_time, &wattage,
                                         &power, potstate);
            last_ctl_step = current_time;
        }

        /* Execute simulation step periodically */
        if (current_time > (last_sim_step + OVEN_SIM_STEP_TIME)) {
            main_execute_simulation_step(current_time, potstate);
            last_sim_step = current_time;
        }

        /* Update graphics on wattage, power or pot on/off change */
        if ((potstate != last_potstate) || (power != last_power)
                || (wattage != last_wattage)) {
            oven_ui_update_graphics(potstate, wattage, power);
        }

        /* Update variable states for change detection on next loop
         * iteration.
         */
        last_power    = power;
        last_wattage  = wattage;
        last_potstate = potstate;

        /* If back/menu button is pressed, pause simulation and test
         * timers, and show menu.
         */
        if (oven_ui_back_button_is_pressed()) {
            /* Disable interrupt monitoring, if enabled */
            classb_intmon_set_state(TEMP_SANITY_TEST, M_DISABLE);
            classb_intmon_set_state(PER_CLASSB_TESTS, M_DISABLE);

            OVEN_PERIODIC_TEMPTEST_TC.CTRLA &= ~TC1_CLKSEL_gm;
            OVEN_PERIODIC_CLASSB_TC.CTRLA &= ~TC0_CLKSEL_gm;

            /* Show the error insertion menu */
            oven_classb_error_insertion();

            /* Re-enable timers upon return */
            OVEN_PERIODIC_CLASSB_TC.CTRLA |= TC_CLKSEL_DIV1024_gc;
            /* If user did not induce an error in the temperature
             * test timing, re-enable it correctly.
             */
            if ((OVEN_PERIODIC_TEMPTEST_TC.CTRLA & TC1_CLKSEL_gm)
                    == TC_CLKSEL_OFF_gc) {
                OVEN_PERIODIC_TEMPTEST_TC.CTRLA
                |= TC_CLKSEL_DIV1024_gc;
            }

            /* Re-enable interrupt monitoring if the oven is
             * supposed to be on, i.e., they were enabled before.
             */
            if (wattage > 0) {
                classb_intmon_set_state(TEMP_SANITY_TEST,
                                        M_ENABLE);
                classb_intmon_set_state(PER_CLASSB_TESTS,
                                        M_ENABLE);
            }

            /* Reset UI */
            gfx_mono_draw_filled_rect(0, 0, 128, 32, GFX_PIXEL_CLR);
            oven_ui_draw_axis();
            oven_ui_update_graphics(potstate, wattage, power);
        }
    }

display_error:
    /* Show red status LED and write the error on display */
    oven_ui_set_status_leds(S_RED);
    oven_classb_display_error();

    /* Enter infinite loop of watchdog resets so user can read display */
    while (true) {
        oven_wdt_periodic_reset();
    }
}
Exemplo n.º 21
0
/**
 * \brief Main demo task
 *
 * This task keeps track of which screen the user has selected, which tasks
 * to resume/suspend to draw the selected screen, and also draws the menu bar.
 *
 * The menu bar shows which screens the user can select by clicking the
 * corresponding buttons on the OLED1 Xplained Pro:
 * - \ref graph_task() "graph" (selected at start-up)
 * - \ref terminal_task() "term."
 * - \ref about_task() "about"
 *
 * \param params Parameters for the task. (Not used.)
 */
static void main_task(void *params)
{
	bool graph_buffer_initialized = false;
	bool selection_changed = true;
	bool select_graph_buffer;
	enum menu_items current_selection = MENU_ITEM_GRAPH;
	gfx_coord_t x, y, display_y_offset;
	xTaskHandle temp_task_handle = NULL;

	for(;;) {
		// Show that task is executing
		oled1_set_led_state(&oled1, OLED1_LED3_ID, true);

		// Check buttons to see if user changed the selection
		if (oled1_get_button_state(&oled1, OLED1_BUTTON1_ID)
					&& (current_selection != MENU_ITEM_GRAPH)) {
			current_selection = MENU_ITEM_GRAPH;
			selection_changed = true;
		} else if (oled1_get_button_state(&oled1, OLED1_BUTTON2_ID)
					&& (current_selection != MENU_ITEM_TERMINAL)) {
			current_selection = MENU_ITEM_TERMINAL;
			selection_changed = true;
		} else if (oled1_get_button_state(&oled1, OLED1_BUTTON3_ID)
					&& (current_selection != MENU_ITEM_ABOUT)) {
			current_selection = MENU_ITEM_ABOUT;
			selection_changed = true;
		}

		// If selection changed, handle the selection
		if (selection_changed) {
			// Wait for and take the display semaphore before doing any changes.
			xSemaphoreTake(display_mutex, portMAX_DELAY);

			// We can now safely suspend the previously resumed task
			if (temp_task_handle) {
				vTaskSuspend(temp_task_handle);
				temp_task_handle = NULL;
			}

			// Select the new drawing task and corresponding display buffer
			switch (current_selection) {
			case MENU_ITEM_GRAPH:
				// Graph task runs continuously, no need to set task handle
				select_graph_buffer = true;
				break;

			case MENU_ITEM_TERMINAL:
				temp_task_handle = terminal_task_handle;
				select_graph_buffer = false;
				break;

			default:
			case MENU_ITEM_ABOUT:
				temp_task_handle = about_task_handle;
				select_graph_buffer = false;
			}

			// Select and initialize display buffer to use.
			display_y_offset = select_graph_buffer ? CANVAS_GRAPH_Y_OFFSET : 0;

			// Draw the menu bar (only needs to be done once for graph)
			if (!select_graph_buffer || !graph_buffer_initialized) {
				// Clear the selected display buffer first
				gfx_mono_draw_filled_rect(0, display_y_offset,
						GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT / 2,
						GFX_PIXEL_CLR);

				// Draw menu lines, each item with height MENU_HEIGHT pixels
				y = display_y_offset + CANVAS_HEIGHT;
				gfx_mono_draw_horizontal_line(0, y, GFX_MONO_LCD_WIDTH,
						GFX_PIXEL_SET);

				x = MENU_ITEM_WIDTH;
				y++;

				for (uint8_t i = 0; i < (MENU_NUM_ITEMS - 1); i++) {
					gfx_mono_draw_vertical_line(x, y, MENU_HEIGHT,
							GFX_PIXEL_SET);
					x += 1 + MENU_ITEM_WIDTH;
				}

				// Highlight the current selection
				gfx_mono_draw_rect(current_selection * (1 + MENU_ITEM_WIDTH), y,
						MENU_ITEM_WIDTH, MENU_HEIGHT, GFX_PIXEL_SET);

				// Draw the menu item text
				x = (MENU_ITEM_WIDTH / 2) - ((5 * SYSFONT_WIDTH) / 2);
				y += (MENU_HEIGHT / 2) - (SYSFONT_HEIGHT / 2);

				for (uint8_t i = 0; i < MENU_NUM_ITEMS; i++) {
					gfx_mono_draw_string(menu_items_text[i], x, y, &sysfont);
					x += 1 + MENU_ITEM_WIDTH;
				}

				graph_buffer_initialized = true;
			}

			// Set display controller to output the new buffer
			ssd1306_set_display_start_line_address(display_y_offset);

			// We are done modifying the display, so give back the mutex
			xSemaphoreGive(display_mutex);

			selection_changed = false;

			// If a task handle was specified, resume it now
			if (temp_task_handle) {
				vTaskResume(temp_task_handle);
			}
		}

		// Show that task is done
		oled1_set_led_state(&oled1, OLED1_LED3_ID, false);

		vTaskDelay(MAIN_TASK_DELAY);
	}
}
Exemplo n.º 22
0
void adc_application(void)
{
	struct keyboard_event input_key;
	char string_buf[10];
	uint32_t adca0_val = 0;
	uint32_t adca1_val = 0;
	uint32_t adca2_val = 0;
	uint32_t adca3_val = 0;
	uint32_t adcb0_val = 0;
	uint32_t adcb1_val = 0;
	uint32_t adcb2_val = 0;
	uint32_t adcb3_val = 0;

	// Clear screen
	gfx_mono_draw_filled_rect(0, 0, 128, 32, GFX_PIXEL_CLR);

	// Draw static strings outside the loop
	gfx_mono_draw_string("ADC0", 100, 0, &sysfont);
	gfx_mono_draw_string("ADC1", 100, 8, &sysfont);
	gfx_mono_draw_string("ADC2", 100, 16, &sysfont);
	gfx_mono_draw_string("ADC3", 100, 24, &sysfont);
	gfx_mono_draw_string("ADC4", 0, 0, &sysfont);
	gfx_mono_draw_string("ADC5", 0, 8, &sysfont);
//	gfx_mono_draw_string("ADC6", 0, 16, &sysfont);
//	gfx_mono_draw_string("ADC7", 0, 24, &sysfont);
	gfx_mono_draw_string("Light", 0, 16, &sysfont);
	gfx_mono_draw_string("NTC", 0, 24, &sysfont);
	
	while (true) {
			// Start an ADC conversion
			/*adc_start_conversion(&ADCA, ADC_CH0);
			adc_start_conversion(&ADCA, ADC_CH1);
			adc_start_conversion(&ADCA, ADC_CH2);
			adc_start_conversion(&ADCA, ADC_CH3);*/
			lightsensor_measure();
			ntc_measure();
			adc_measure();
			adc2_measure();
			
			while (!adc_data_is_ready() && !adc2_data_is_ready() && !ntc_data_is_ready() && !lightsensor_data_is_ready()) {
				// Wait until the conversion is complete
			}
			
			//adc_wait_for_interrupt_flag(&ADCA, ADC_CH0);
			/*adc0_val = adc_get_result(&ADCA, ADC_CH0);
			adc1_val = adc_get_result(&ADCA, ADC_CH1);
			adc2_val = adc_get_result(&ADCA, ADC_CH2);
			adc3_val = adc_get_result(&ADCA, ADC_CH3);*/
			adca0_val = lightsensor_get_raw_value();
			adca1_val = ntc_get_raw_value();
			adca2_val = adc_get_raw_value();
			adca3_val = adc2_get_raw_value();
			snprintf(string_buf, sizeof(string_buf), "%4ld", adca0_val);
			gfx_mono_draw_string(string_buf, 30, 16, &sysfont);
			snprintf(string_buf, sizeof(string_buf), "%4ld", adca1_val);
			gfx_mono_draw_string(string_buf, 30, 24, &sysfont);
			snprintf(string_buf, sizeof(string_buf), "%4ld", adca2_val);
			gfx_mono_draw_string(string_buf, 30, 0, &sysfont);
			snprintf(string_buf, sizeof(string_buf), "%4ld", adca3_val);
			gfx_mono_draw_string(string_buf, 30, 8, &sysfont);
			
			// Start an ADCB conversion
			/*adc_start_conversion(&ADCB, ADC_CH0);
			adc_start_conversion(&ADCB, ADC_CH1);
			adc_start_conversion(&ADCB, ADC_CH2);
			adc_start_conversion(&ADCB, ADC_CH3);*/
			adcb0_measure();
			adcb1_measure();
			adcb2_measure();
			adcb3_measure();
			
			while (!adcb0_data_is_ready() && !adcb1_data_is_ready() && !adcb2_data_is_ready() && !adcb3_data_is_ready()) {
				// Wait until the conversion is complete
			}
			
			//adc_wait_for_interrupt_flag(&ADCB, ADC_CH0);
			/*adc0_val = adc_get_result(&ADCA, ADC_CH0);
			adc1_val = adc_get_result(&ADCA, ADC_CH1);
			adc2_val = adc_get_result(&ADCA, ADC_CH2);
			adc3_val = adc_get_result(&ADCA, ADC_CH3);*/
			adcb0_val = adcb0_get_raw_value();
			adcb1_val = adcb1_get_raw_value();
			adcb2_val = adcb2_get_raw_value();
			adcb3_val = adcb3_get_raw_value();
			snprintf(string_buf, sizeof(string_buf), "%4ld", adcb0_val);
			gfx_mono_draw_string(string_buf, 60, 0, &sysfont);
			snprintf(string_buf, sizeof(string_buf), "%4ld", adcb1_val);
			gfx_mono_draw_string(string_buf, 60, 8, &sysfont);
			snprintf(string_buf, sizeof(string_buf), "%4ld", adcb2_val);
			gfx_mono_draw_string(string_buf, 60, 16, &sysfont);
			snprintf(string_buf, sizeof(string_buf), "%4ld", adcb3_val);
			gfx_mono_draw_string(string_buf, 60, 24, &sysfont);
			
			keyboard_get_key_state(&input_key);
			if ((input_key.keycode == KEYBOARD_ENTER) &&
					(input_key.type == KEYBOARD_RELEASE)) {
				break;
			}
	}
}
Exemplo n.º 23
0
int main (void)
{
	sysclk_init();
	board_init();
	pmic_init();
	gfx_mono_init();
	adc_sensors_init();
	// Enable display backlight
	gpio_set_pin_high(NHD_C12832A1Z_BACKLIGHT);
	cpu_irq_enable();
	
	while(true){
		
		if(state==1){
			start_game();
			}else if(state==2){
			tc_enable(&TCC0);
			tc_set_overflow_interrupt_callback(&TCC0, sun_count);
			tc_set_wgm(&TCC0, TC_WG_NORMAL);
			tc_write_period(&TCC0, 13500);
			tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO);
			tc_write_clock_source(&TCC0, TC_CLKSEL_DIV256_gc);
			
			tc_enable(&TCC1);
			tc_set_overflow_interrupt_callback(&TCC1, button_press);
			tc_set_wgm(&TCC1, TC_WG_NORMAL);
			tc_write_period(&TCC1, 62500);
			tc_set_overflow_interrupt_level(&TCC1, TC_INT_LVL_LO);
			tc_write_clock_source(&TCC1, TC_CLKSEL_DIV8_gc);
			
			gfx_mono_draw_string("SUN:   0", 0, 0, &sysfont);
			gfx_mono_draw_string(">", 0, cursor_position, &sysfont);
			gfx_mono_draw_string("Score:  0", 63, 0, &sysfont);
			
			randomPeta();
			
			char* score_string = NULL;
			uint16_t old_score = 0;
			
			for(j = 0; j <= 70; j++){
				
				if(sun_value > 10){
					
					lightsensor_measure();
					while (!lightsensor_data_is_ready()) {
						// Wait until the conversion is complete
					}
					if(lightsensor_get_raw_value() > 250){
						sun_value -= 10;
						sunBurst();
						gfx_mono_draw_filled_rect(12,8,114,24,GFX_PIXEL_CLR);
					}
				}
				

				if(score > old_score){
					sprintf(score_string, "%3d", score);
					gfx_mono_draw_string(score_string, 100, 0, &sysfont);
					old_score = score;
				}
				
				if(lose){
					state=3;
					break;
					}else if(zombie==0){
					state=4;
					break;
				}
				
				
				tampilkanPeta();
				tampilkanTembak();
				delay_ms(1000);
			}
			}else if(state==3){
			cpu_irq_disable();
			gfx_mono_draw_filled_rect(0,0,128,32,GFX_PIXEL_CLR);
			while(true){
				gfx_mono_draw_string("GAME OVER",36,8,&sysfont)	;
				gfx_mono_draw_string("You Lose",39,20,&sysfont)	;
			}
			}else if(state==4){
			cpu_irq_disable();
			gfx_mono_draw_filled_rect(0,0,128,32,GFX_PIXEL_CLR);
			while(true){
				gfx_mono_draw_string("GAME OVER",36,2,&sysfont)	;
				gfx_mono_draw_string("You Win",42,12,&sysfont)	;
				gfx_mono_draw_string("Score = ",30,22,&sysfont)	;
				char* score_string = NULL;
				sprintf(score_string, "%3d", score);
				gfx_mono_draw_string(score_string, 79, 22, &sysfont);
			}
		}
	}
	
}
Exemplo n.º 24
0
/**
 * \internal
 * \brief Test drawing a filled circle spanning two pages
 *
 * This test draws a filled circle spanning two pages and checks that this is
 * done.
 *
 * \param test Current test case.
 */
static void run_draw_filled_circle_test(const struct test_case *test)
{
	uint8_t actual[GFX_MONO_LCD_WIDTH];
	uint8_t expected_page1[GFX_MONO_LCD_WIDTH];
	uint8_t expected_page2[GFX_MONO_LCD_WIDTH];
	uint8_t expected_empty[GFX_MONO_LCD_WIDTH];
	uint8_t page;

	// Clear entire display
	gfx_mono_draw_filled_rect(0, 0, GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT,
			GFX_PIXEL_CLR);

	// Fill first page buffer holding the top part of the circle
	set_buffer(expected_page1, 0x00);
	expected_page1[36] = 0x80;
	expected_page1[37] = 0xC0;
	expected_page1[38] = 0xE0;
	expected_page1[39] = 0xE0;
	expected_page1[40] = 0xE0;
	expected_page1[41] = 0xE0;
	expected_page1[42] = 0xE0;
	expected_page1[43] = 0xC0;
	expected_page1[44] = 0x80;

	// Fill second page buffer holding the lower part of the circle
	set_buffer(expected_page2, 0x00);
	expected_page2[35] = 0x1F;
	expected_page2[36] = 0x3F;
	expected_page2[37] = 0x7F;
	expected_page2[38] = 0xFF;
	expected_page2[39] = 0xFF;
	expected_page2[40] = 0xFF;
	expected_page2[41] = 0xFF;
	expected_page2[42] = 0xFF;
	expected_page2[43] = 0x7F;
	expected_page2[44] = 0x3F;
	expected_page2[45] = 0x1F;

	// Fill empty page buffer
	set_buffer(expected_empty, 0x00);

	// Draw a filled circle with radius 5 and centre at position 40, 18
	gfx_mono_draw_filled_circle(40, 18, 5, GFX_PIXEL_SET, GFX_WHOLE);

	// Get all pages from display and check that the circle is drawn
	for (page = 0; page < GFX_MONO_LCD_PAGES; page++) {
		gfx_mono_get_page(actual, page, 0, GFX_MONO_LCD_WIDTH);
		if (page == 1) {
			test_assert_true(test, is_page_correct(actual, expected_page1),
					"Page %d with filled circle not matching expected page",
					page);
		} else if (page == 2) {
			test_assert_true(test, is_page_correct(actual, expected_page2),
					"Page %d with filled circle not matching expected page",
					page); 
		} else {
			test_assert_true(test, is_page_correct(actual, expected_empty),
					"Empty page %d not matching expected page", page);
		}
	}
}
Exemplo n.º 25
0
void app_sampling_task(void)
{
	static uint16_t time_stamp;
	static uint8_t time_last;
	uint8_t time_pos;
	adc_result_t light;
	char string[30];
	uint8_t light_bar_pos;
	irqflags_t flags;
	static uint16_t qdec_position_last = 2;
	uint16_t qdec_position;

	/* Manage frequency sample through Quadrature encoder */
	qdec_position = qdec_get_position(&qdec_config) / 2;
	if (qdec_position != qdec_position_last) {
		/* Quadrature encoder have changed */
		qdec_position_last = qdec_position;
		app_sampling_rate = (qdec_position_last + 1) * 2;
		flags = cpu_irq_save();
		if (app_sampling_rtc_run) {
			time_stamp = rtc_get_time();
			rtc_set_alarm_relative(app_sampling_rate - 1);
		}

		cpu_irq_restore(flags);
		app_sampling_display_rate();
	}

	/* Update sampling progress bar */
	time_pos = ((rtc_get_time() - time_stamp) * 8) / app_sampling_rate;
	if (time_pos > 8) {
		time_pos = 8;
	}

	if (time_last > time_pos) {
		gfx_mono_draw_filled_circle(
				DISPLAY_SAMPLING_PROCIRCLE_POS_X,
				DISPLAY_SAMPLING_PROCIRCLE_POS_Y,
				DISPLAY_SAMPLING_PROCIRCLE_RADIUS,
				GFX_PIXEL_CLR,
				GFX_WHOLE);
	}

	if (time_last != time_pos) {
		gfx_mono_draw_filled_circle(
				DISPLAY_SAMPLING_PROCIRCLE_POS_X,
				DISPLAY_SAMPLING_PROCIRCLE_POS_Y,
				DISPLAY_SAMPLING_PROCIRCLE_RADIUS,
				GFX_PIXEL_SET,
				(1lu << time_pos) - 1);
	}

	time_last = time_pos;

	/* Manage FIFO about sensor data */
	if (2 > fifo_get_used_size(&app_sampling_fifo_desc)) {
		return; /* Not enought data */
	}

	/* Get values */
	time_stamp = fifo_pull_uint16_nocheck(&app_sampling_fifo_desc);
	light = (adc_result_t)fifo_pull_uint16_nocheck(&app_sampling_fifo_desc);

	/* Display values through USART */
	sprintf(string, "%4u,%02us - %3d light\r\n",
			time_stamp / 4, (time_stamp % 4) * 25,
			light);
	printf("%s", string);

	/* Update light progress bar */
	light_bar_pos = ((uint32_t)light * DISPLAY_LIGHT_PROBAR_MAX_SIZE_X)
			/ 2048lu;
	if (light_bar_pos > DISPLAY_LIGHT_PROBAR_MAX_SIZE_X) {
		light_bar_pos = DISPLAY_LIGHT_PROBAR_MAX_SIZE_X;
	}

	gfx_mono_draw_filled_rect(DISPLAY_LIGHT_PROBAR_POS_X,
			DISPLAY_LIGHT_PROBAR_POS_Y,
			light_bar_pos,
			DISPLAY_LIGHT_PROBAR_SIZE_Y,
			GFX_PIXEL_SET);
	gfx_mono_draw_filled_rect(DISPLAY_LIGHT_PROBAR_POS_X + light_bar_pos,
			DISPLAY_LIGHT_PROBAR_POS_Y,
			DISPLAY_LIGHT_PROBAR_MAX_SIZE_X - light_bar_pos,
			DISPLAY_LIGHT_PROBAR_SIZE_Y,
			GFX_PIXEL_CLR);
}
Exemplo n.º 26
0
void temp_disp_init()
{
    /* TODO: Replaced for testing
    // Initiate a temperature sensor reading
    ntc_measure();
    */
    // Initiate a ADCB reading
    adcb_ch0_measure();
    adcb_ch1_measure();
    adcb_ch2_measure();
    adcb_ch3_measure();

    // Struct for holding the temperature scale background
    tempscale.type = GFX_MONO_BITMAP_RAM;
    tempscale.width = 6;
    tempscale.height = 32;
    tempscale.data.pixmap = tempscale_img;

    // Screen border
    gfx_mono_draw_rect(0, 0, 128, 32, GFX_PIXEL_SET);
    // Clear screen
    gfx_mono_draw_filled_rect(1, 1, 126, 30, GFX_PIXEL_CLR);

    // Paint thermometer on screen
    // gfx_mono_put_bitmap(&tempscale, 10, 0);	// TODO: Can be removed.

    /* TODO: Simply replaced for testing
    // wait for NTC data to ready
    while (!ntc_data_is_ready());
    // Read the temperature once the ADC reading is done
    temperature = ntc_get_temperature();
    */
    // Wait for ADCB date to ready
    while (!adcb_data_is_ready());
    temperature0 = adcb_chX_get_temperature(0);//adcb_ch0_get_raw_value();
    temperature1 = adcb_chX_get_temperature(1);
    temperature2 = adcb_chX_get_temperature(2);
    temperature3 = adcb_chX_get_temperature(3);


    // Convert the temperature into the thermometer scale
    /* temp_scale = -0.36 * temperature + 20.25;
    if (temp_scale <= 0) {
    	temp_scale = 0;
    }
    */

    // Draw the scale element on top of the background temperature image
    /*gfx_mono_draw_filled_rect(12, 3, 2, temp_scale,
    GFX_PIXEL_CLR);
    */

    /*snprintf(temperature_string, sizeof(temperature_string), "%3i C",
    temperature);

    // Draw the Celsius string
    gfx_mono_draw_string(temperature_string, 22, 13, &sysfont);
    */
    // ********************** START UPDATE SCREEN ************************

    snprintf(temp1_string, sizeof(temp1_string), "TMP1:%3iC",
             temperature0);

    snprintf(temp2_string, sizeof(temp2_string), "TMP2:%3iC",
             temperature1);

    snprintf(temp3_string, sizeof(temp3_string), "TMP3:%3iC",
             temperature2);

    snprintf(pressure_string, sizeof(pressure_string), "BAR:%3i",
             temperature3);

    // TODO: Set up variables and call methods for reading all the values
    // Draw the Celsius string
    gfx_mono_draw_string(temp1_string, 1, 5, &sysfont);	// Temp1
    gfx_mono_draw_string(temp2_string, 64, 5, &sysfont);	// Temp2
    gfx_mono_draw_string(temp3_string, 1, 20, &sysfont);	// Temp3
    gfx_mono_draw_string(pressure_string, 64, 20, &sysfont);	// Pressure
}