/** * \brief Show button names on display */ void button_splash(void) { struct keyboard_event input; // Clear screen gfx_mono_draw_filled_rect(0, 0, 128, 32, GFX_PIXEL_CLR); gfx_mono_draw_filled_circle(10, 10, 4, GFX_PIXEL_SET, GFX_WHOLE); gfx_mono_draw_filled_circle(10, 22, 4, GFX_PIXEL_SET, GFX_WHOLE); gfx_mono_draw_filled_circle(117, 10, 4, GFX_PIXEL_SET, GFX_WHOLE); gfx_mono_draw_filled_circle(117, 22, 4, GFX_PIXEL_SET, GFX_WHOLE); gfx_mono_draw_string("Up", 90, 8, &sysfont); gfx_mono_draw_string("Down", 80, 20, &sysfont); gfx_mono_draw_string("Enter", 20, 8, &sysfont); gfx_mono_draw_string("Back", 20, 20, &sysfont); // Any key will exit the loop while (true) { keyboard_get_key_state(&input); if (input.type == KEYBOARD_RELEASE) { break; } } }
/** * \brief Show button names on display * * This function shows the user what the different on-board buttons do. When * the user presses a button, this function exits and the application can * continue. */ static void show_button_splash(void) { struct keyboard_event input; /* Clear screen */ gfx_mono_draw_filled_rect(0, 0, 128, 32, GFX_PIXEL_CLR); gfx_mono_draw_filled_circle(6, 6, 3, GFX_PIXEL_SET, GFX_WHOLE); gfx_mono_draw_filled_circle(6, 24, 3, GFX_PIXEL_SET, GFX_WHOLE); gfx_mono_draw_filled_circle(122, 6, 3, GFX_PIXEL_SET, GFX_WHOLE); gfx_mono_draw_filled_circle(122, 24, 3, GFX_PIXEL_SET, GFX_WHOLE); gfx_mono_draw_string("Oven power/", 50, 0, &sysfont); gfx_mono_draw_string("Up", 94, 8, &sysfont); gfx_mono_draw_string("Down", 90, 22, &sysfont); gfx_mono_draw_string("Menu/", 12, 0, &sysfont); gfx_mono_draw_string("Back", 12, 8, &sysfont); gfx_mono_draw_string("Pot/enter", 12, 22, &sysfont); /* Any key will exit the loop */ while (true) { oven_wdt_periodic_reset(); keyboard_get_key_state(&input); if (input.type == KEYBOARD_RELEASE) { break; } } }
int main(void){ struct gfx_mono_bitmap smiley; struct gfx_mono_bitmap smiley_flash; board_init(); sysclk_init(); /* Initialize GFX lib. Will configure the display controller and * create a framebuffer in RAM if the controller lack two-way communication */ gfx_mono_init(); // 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; // 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; // Output bitmaps to display gfx_mono_put_bitmap(&smiley, 50, 0); gfx_mono_put_bitmap(&smiley_flash, 0, 0); //Draw horizontal an vertical lines with length 128 and 32 pixels gfx_mono_draw_vertical_line(1, 0, 32, GFX_PIXEL_SET); gfx_mono_draw_horizontal_line(0, 2, 128, GFX_PIXEL_SET); // Draw a line from the top-left corner to the bottom right corner gfx_mono_draw_line(0, 0, 127, 31, GFX_PIXEL_SET); // Draw a rectangle with upper left corner at x=20,y=10 - width=height=10px gfx_mono_draw_rect(20, 10, 10, 10,GFX_PIXEL_SET); // Draw a 10x10 filled rectangle at x=10,y=10 gfx_mono_draw_filled_rect(10, 10, 10, 10, GFX_PIXEL_SET); // Draw a whole circle at x=50,y=16 with radios=8 and all octants drawn gfx_mono_draw_circle(50, 16, 8, GFX_PIXEL_SET,GFX_WHOLE); // Draw a filled circle with all quadrant drawn gfx_mono_draw_filled_circle(80, 16, 10, GFX_PIXEL_SET, GFX_WHOLE); while(true) { // This while left intentionally blank to halt execution. } }
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); }
/** * \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); } } }
/** * \brief Example application entry routine */ int main(void) { /* The sensor_platform_init() function will initialize the system * clock and sensor bus support in addition to configuring the * XMEGA-A3BU and Sensor Xplained boards. * * Use gfx_mono_init() to initialize the monochrome graphical system * API then write a splash screen after enabling the LCD display * backlight and setting the contrast. * * The MCU is going to be put in a sleep mode, so initialize the * sleep manager API with a call to the sleepmgr_init() routine. */ sensor_platform_init(); gfx_mono_init(); sleepmgr_init(); gpio_set_pin_high(NHD_C12832A1Z_BACKLIGHT); st7565r_set_contrast(ST7565R_DISPLAY_CONTRAST_MIN); /* Attach an accelerometer on a Sensors Xplained board. */ sensor_t accelerometer; sensor_attach(&accelerometer, SENSOR_TYPE_ACCELEROMETER, 0, 0); /* Enable the accelerometer low-g (free fall) event. */ sensor_enable_event(&accelerometer, SENSOR_EVENT_LOW_G); /* Set the free fall threshold (low-g event), bandwidth and range. */ sensor_set_threshold(&accelerometer, SENSOR_THRESHOLD_LOW_G, LOW_G_THRESHOLD); sensor_set_bandwidth(&accelerometer, BANDWIDTH); sensor_set_range(&accelerometer, RANGE); while (true) { /* Put the accelerometer into a low-power mode (if available). */ sensor_set_state(&accelerometer, SENSOR_STATE_LOW_POWER); LED_Off(ACCEL_LED); clear_screen(); /* Display the "armed" message and put the MCU in sleep mode. */ gfx_mono_draw_string("ATMEL Drop Demo\r\nXMEGA Powered Down\r\n" "g Sensor Armed", 1, 5, &sysfont); sleepmgr_lock_mode(SLEEP_MODE); sleepmgr_enter_sleep(); /* The following runs after the MCU has been woken by an * external low-g interrupt from the accelerometer. * * Turn on the red LED while falling and put the accelerometer * into a high-power mode (if available) to sample date points. */ LED_On(ACCEL_LED); sensor_set_state(&accelerometer, SENSOR_STATE_HIGHEST_POWER); static scalar_t acceleration_waveform[DATA_SAMPLE_COUNT]; scalar_t acceleration_max = 0; for (int data_count = 0; data_count < DATA_SAMPLE_COUNT; ++data_count) { acceleration_waveform[data_count] = 0; for (int i = 0; i < SAMPLE_AVG_COUNT; ++i) { /* Calculate the gravity vector magnitude. */ vector3_t gvec; sensor_get_vector(&accelerometer, &gvec); scalar_t const acceleration_magnitude = vector3_magnitude(&gvec); /* Store the maximum g magnitude for this * sub-group. */ if (acceleration_magnitude > acceleration_waveform[data_count]) { acceleration_waveform[data_count] = acceleration_magnitude; } /* Store the maximum g magnitude for the whole * data set. */ if (acceleration_magnitude > acceleration_max) { acceleration_max = acceleration_magnitude; } } } clear_screen(); /* Turn the max acceleration into a string and convert to g. */ static char max_g_string[20]; if (acceleration_max > LOW_G_SATURATION) { sprintf(max_g_string, "g Sensor Saturated"); } else { sprintf(max_g_string, "Peak = %02.2f g", acceleration_max / 1000); } /* Print the max g on the monochrome display. */ gfx_mono_draw_string("Drop Detected", 1, 5, &sysfont); gfx_mono_draw_string(max_g_string, 1, 13, &sysfont); gfx_mono_draw_string("Press SW1 for chart", 1, 21, &sysfont); do { LED_Toggle(ACCEL_LED); delay_ms(100); } while (!switch_pressed(SW1)); /* Plot the collected data points to create the waveform chart. */ clear_screen(); screen_border(); for (int data_count = 0; data_count < DATA_SAMPLE_COUNT; ++data_count) { gfx_mono_draw_filled_circle(data_count, 32 - (acceleration_waveform[data_count] / 500), 1, GFX_PIXEL_SET, GFX_WHOLE); } do { LED_Toggle(PROMPT_LED); delay_ms(100); } while (!switch_pressed(SW1)); LED_Off(PROMPT_LED); } }