static void icon_paint(paint_event_t* event) { icon_t* i = widget_get_instance_data(event->widget); rect_t rect = widget_get_rect(event->widget); point_t center = rect_center(rect); if (!widget_is_enabled(event->widget)) { gfx_set_bg_color(DARK_GRAY); gfx_clear_rect(rect); } /* draw icon */ if (i->image != NULL) { gfx_set_fg_color(i->icon_color); gfx_draw_bitmap( center.x - (i->image->width / 2), center.y - (i->image->height / 2), i->image); } }
/** * \brief Application worker function. * * This task worker updates the parameters of the simulated process and the * display unless the application context has been cleared, in which case the * function returns immediately. * * Refer to the detailed description of \ref apps_tank_group for information on * the simulated process. * * If the tank level reaches 0, the indicator for demand will change color to * indicate that the supply is insufficient. If, on the other hand, it reaches * \ref VALUE_LEVEL_MAXIMUM, the alarm light changes color to indicate that the * supply is too great. * * \note The task for this worker function is enqueued by the timer callback * function. * * \param task Workqueue task for this worker function. */ static void tank_worker(struct workqueue_task *task) { struct gfx_bitmap *alarm_bitmap = NULL; bool alarm_update = false; int32_t rand; uint8_t supply; uint16_t demand; int16_t flow; int16_t level; // Quit immediately if application context has been cleared. if (!tank_ctx) { return; } // Get current values of the process parameters. level = wtk_progress_bar_get_value(tank_ctx->level); supply = wtk_slider_get_value(tank_ctx->supply); demand = wtk_progress_bar_get_value(tank_ctx->demand); rand = tank_ctx->rand; // Update the random variable if enough ticks have passed. if (--(tank_ctx->rand_ticks) == 0) { tank_ctx->rand_ticks = TICKS_PER_RANDOM_UPDATE; // Flip some LSBs to help avoid a stuck process. rand ^= demand & 0x03; // Compute new random value and store it for next iteration. rand = tank_logistic_map(rand); tank_ctx->rand = rand; } // Now, compute the new demand from a weighted scheme. demand = rand + (2 * demand) + level; demand /= 4; demand = min_u(demand, VALUE_DEMAND_MAXIMUM); /* Compute the total flow and scale it down for a smoother * simulation. */ flow = supply; flow -= demand; flow /= 4; // Compute new level for the tank. level += flow; /* Update the demand indicator. Change its color if the demand * exceeds the supply and available water in the tank. */ if (level <= 0) { if (!tank_ctx->flow_alarm) { tank_ctx->flow_alarm = true; wtk_progress_bar_set_colors(tank_ctx->demand, COLOR_DEMAND_CRITICAL, COLOR_DEMAND_BACKGROUND); } level = 0; } else { if (tank_ctx->flow_alarm) { tank_ctx->flow_alarm = false; wtk_progress_bar_set_colors(tank_ctx->demand, COLOR_DEMAND_NORMAL, COLOR_DEMAND_BACKGROUND); } } wtk_progress_bar_set_value(tank_ctx->demand, demand); /* Update the tank level indicator. * The level of the tank cannot exceed the defined maximum, * and its alarm light must be updated whenever this level * is crossed. */ if (level >= VALUE_LEVEL_MAXIMUM) { if (!tank_ctx->level_alarm) { tank_ctx->level_alarm = true; alarm_update = true; alarm_bitmap = &tank_ctx->bitmaps[BITMAP_RED_LIGHT]; } level = VALUE_LEVEL_MAXIMUM; } else { if (tank_ctx->level_alarm) { tank_ctx->level_alarm = false; alarm_update = true; alarm_bitmap = &tank_ctx->bitmaps[BITMAP_GREEN_LIGHT]; } } wtk_progress_bar_set_value(tank_ctx->level, level); /* If a level alarm update occurred, set up clipping area and draw * the new alarm light bitmap. */ if (alarm_update) { #ifdef CONFIG_GFX_USE_CLIPPING gfx_set_clipping(BITMAP_LIGHT_POSITION_X, BITMAP_LIGHT_POSITION_Y, BITMAP_LIGHT_POSITION_X + BITMAP_LIGHT_SIZE_X - 1, BITMAP_LIGHT_POSITION_Y + BITMAP_LIGHT_SIZE_Y - 1 ); #endif /* CONFIG_GFX_USE_CLIPPING */ gfx_draw_bitmap(alarm_bitmap, BITMAP_LIGHT_POSITION_X, BITMAP_LIGHT_POSITION_Y); } }
/** \brief Main function. Execution starts here. */ int main(void) { uint8_t uc_result; /* Initialize the sleep manager */ sleepmgr_init(); membag_init(); sysclk_init(); init_specific_board(); /* Initialize the console uart */ configure_console(); /* Output demo infomation. */ printf("-- SAM Toolkit Demo Example --\n\r"); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); /* Configure systick for 1 ms. */ puts("Configure system tick to get 1ms tick period.\r"); if (SysTick_Config(sysclk_get_cpu_hz() / 1000)) { puts("Systick configuration error\r"); while (1) { } } /* Initialize gfx module */ gfx_init(); win_init(); /* Initialize FatFS and bitmap draw interface */ demo_draw_bmpfile_init(); /* Initialize touchscreen without calibration */ rtouch_init(LCD_WIDTH, LCD_HEIGHT); rtouch_enable(); rtouch_set_event_handler(event_handler); /* Initialize demo parameters */ demo_parameters_initialize(); while (g_demo_parameters.calib_points[0].raw.x == 0) { uc_result = rtouch_calibrate(); if (uc_result == 0) { demo_set_special_mode_status(DEMO_LCD_CALIBRATE_MODE, 0); puts("Calibration successful !\r"); break; } else { puts("Calibration failed; error delta is too big ! Please retry calibration procedure...\r"); } } /* Re-caculate the calibration data */ rtouch_compute_calibration( (rtouch_calibration_point_t *)&g_demo_parameters.calib_points[0]); /* Setup root window */ setup_gui_root_window(); gfx_draw_bitmap(&win_startup_bmp, 0, 40); /* Set backlight by the data read from demo parameters */ aat31xx_set_backlight(g_demo_parameters.backlight); /* Default RTC configuration, 24-hour mode */ rtc_set_hour_mode(RTC, 0); rtc_set_time(RTC, g_demo_parameters.hour, g_demo_parameters.minute, g_demo_parameters.second); rtc_set_date( RTC, g_demo_parameters.year, g_demo_parameters.month, g_demo_parameters.day, 1 ); /* Create a semaphore to manage the memories data transfer */ vSemaphoreCreateBinary(main_trans_semphr); /* Turn on main widget */ app_widget_main_on(true); /* Initialize QTouch */ demo_qt_init(); /* Start USB stack to authorize VBus monitoring */ udc_start(); if (!udc_include_vbus_monitoring()) { /* VBUS monitoring is not available on this product * thereby VBUS has to be considered as present */ main_vbus_action(true); } /* Create task to window task */ if (xTaskCreate(task_win, "WIN", TASK_WIN_STACK_SIZE, NULL, TASK_WIN_STACK_PRIORITY, NULL) != pdPASS) { printf("Failed to create test led task\r\n"); } /* Create task to usb mass storage task */ if (xTaskCreate(task_usb, "USB", TASK_USB_STACK_SIZE, NULL, TASK_USB_STACK_PRIORITY, NULL) != pdPASS) { printf("Failed to create test led task\r\n"); } /* Start the scheduler. */ vTaskStartScheduler(); /* Will only get here if there was insufficient memory to create the * idle task. */ return 0; }
/** * \brief This task, when activated, send every ten seconds on debug UART the * whole report of free heap and total tasks status */ static void task_win(void *pvParameters) { uint32_t hour, minute, second; uint32_t year, month, date,week; uint8_t uc_result; UNUSED(pvParameters); for (;;) { while (demo_get_special_mode_status(DEMO_LCD_CALIBRATE_MODE)) { app_widget_settings_on(false); uc_result = rtouch_calibrate(); if (uc_result == 0) { demo_set_special_mode_status( DEMO_LCD_CALIBRATE_MODE, 0); app_widget_settings_on(true); puts("Calibration successful !\r"); break; } else { puts("Calibration failed; error delta is too big ! Please retry calibration procedure...\r"); } } if (demo_get_special_mode_status(DEMO_WAIT_MODE) || demo_get_special_mode_status(DEMO_SLEEP_MODE)) { app_widget_lpm_on(true); demo_set_special_mode_status(DEMO_WAIT_MODE, 0); demo_set_special_mode_status(DEMO_SLEEP_MODE, 0); } /* Play PPT */ if (demo_get_special_mode_status(DEMO_PPT_MODE)) { demo_start_adc(true); if (pontentiometer_value == ppt_delay_clapse_counter) { snprintf( ppt_slide_path, sizeof(ppt_slide_path), "%s%s%s%u%s", SCR_PPT_SLIDE_PATH, SCR_PPT_SLIDE_FOLDER, SCR_PPT_SLIDE_BASENAME, ppt_silder_index, SCR_PPT_SLIDE_EXT ); demo_ppt.data.custom = ppt_slide_path; gfx_draw_bitmap(&demo_ppt, 0, 0); ppt_delay_clapse_counter = 0; ppt_silder_index++; if (ppt_silder_index >= SCR_PPT_SLIDE_MAX) { ppt_silder_index = 0; } } ppt_delay_clapse_counter++; continue; } if (touch_event_on_ppt == 1) { app_widget_main_on(true); touch_event_on_ppt = 0; } demo_qtouch_event_handler(); /* Process queued events in the windowing system */ win_process_events(); if (demo_get_special_mode_status(DEMO_MAIN_MODE)) { /* Retrieve date and time */ rtc_get_time( RTC, &hour, &minute, &second ); snprintf( demo_cur_time, sizeof(demo_cur_time), "%02u:%02u:%02u", hour, minute, second ); /* Draw the time text */ gfx_draw_string(demo_cur_time, 15, 300, &sysfont, COLOR_WHITE, COLOR_WHITE); gfx_draw_string(demo_cur_time, 15, 300, &sysfont, GFX_COLOR_TRANSPARENT, COLOR_BLUE); /* Retrieve date and time */ rtc_get_date( RTC, &year, &month, &date, &week ); snprintf( demo_cur_date, sizeof(demo_cur_date), "%04u/%02u/%02u", year, month, date ); /* Draw the help text */ gfx_draw_string(demo_cur_date, 135, 300, &sysfont, COLOR_WHITE, COLOR_WHITE); gfx_draw_string(demo_cur_date, 135, 300, &sysfont, GFX_COLOR_TRANSPARENT, COLOR_BLUE); } vTaskDelay(100); } }