static void enter_sleep_mode(void) { bool_t wakeUp = bFalse; uint16_t i = 4; // Turn off GFX and backlight set_brightness(0); // Disable touch notification touch_set_event_handler(NULL); do { // Enable watchdog _SWDTEN = 1; // Enter idle Sleep(); // Watchdog should wakeup MCU after one second // See hal/mcu/mcu_config.c // Disable WDT _SWDTEN = 0; // AFTER ANY INTERRUPT REQUEST: // Wait delay_ms(100); // Touch panel pressed over 2 seconds? if(RV_OK == touch_process()) { wakeUp = bTrue; while(i--) { delay_ms(500); if(RV_OK != touch_process()) { wakeUp = bFalse; } } } // Clean up message queue knl_mailbox_init(&taskMailbox); } while(!wakeUp); // // Wake up // // Restore kernel handlers install_event_handlers(); // Re-enable GFX and backlight set_brightness(lightenBrightness); gui_invalidate_all(); // DONE! }
void run_touch_test( void ) { uint16_t ret = 0; hal_initialize(); gfx_init(); backlight_init(); backlight_set_brightness(90); tty_enable_view(bTrue); tty_output_delayed("TOUCH test! Initialization... \n", 1000); ret = touch_initialize(); guard(ret); touch_set_event_handler(touchEventFunc); #ifdef TEST_FOREVER for(;;) #endif { //tty_enable_view(False); //tty_reset(); ret = touch_process(); guard(ret); //tty_enable_view(True); delay_ms(100); } }
/** * \brief Set up calibration * * Allocates and initializes the application context; sets up the font, touch * event handler and calibration data; updates the display and then schedules * the calibration task. * * \param completed_task Task to schedule when calibration is complete */ void app_touch_calibrate_setup(struct workqueue_task *completed_task) { calibrate_context = membag_alloc(sizeof(struct touch_calibrate_context)); assert(calibrate_context != NULL); // Use twice as large font for this application. memcpy(&sysfont2x, &sysfont, sizeof(sysfont)); sysfont2x.scale = 2; // Temporarily replace touch event handler. calibrate_context->old_handler = touch_get_event_handler(); touch_set_event_handler(touch_calibrate_event_handler); // Clear the screen and draw the calibration guide text. gfx_set_clipping(0, 0, gfx_get_width(), gfx_get_height()); gfx_draw_filled_rect(0, 0, gfx_get_width(), gfx_get_height(), CAL_BG_COLOR); gfx_draw_progmem_string((const char __progmem_arg *) &calibrate_help_text, 10, 80, &sysfont2x, CAL_FG_COLOR, GFX_COLOR_TRANSPARENT); // Set panel coordinates for all calibration points. calibrate_context->cal_points[0].panel_x = (gfx_get_width() - CAL_OFFSET - 1); calibrate_context->cal_points[0].panel_y = (gfx_get_height() - CAL_OFFSET - 1); calibrate_context->cal_points[1].panel_x = (CAL_OFFSET); calibrate_context->cal_points[1].panel_y = (gfx_get_height() - CAL_OFFSET - 1); calibrate_context->cal_points[2].panel_x = (CAL_OFFSET); calibrate_context->cal_points[2].panel_y = (CAL_OFFSET); // Draw circle for first calibration point. gfx_draw_circle(calibrate_context->cal_points[0].panel_x, calibrate_context->cal_points[0].panel_y, CAL_RADIUS, CAL_FG_COLOR, GFX_WHOLE); // Initialize the calibration state and tasks before scheduling it. calibrate_context->state = 0; calibrate_context->completed_task = completed_task; workqueue_task_init(&calibrate_context->task, touch_calibrate_task_handler); workqueue_add_task(&main_workqueue, &calibrate_context->task); }
/** * \brief Application task worker * * Waits for the touch release events generated after the user has touched a * calibration circle drawn on screen, then stores the calibration data and * draws the circle for the next calibration point. * * Three such calibration points are stored before the calibration matrix for * the touch driver is computed and assigned to it. * * \sa touch_driver_group * * \note If the raw samples of a calibration point do not differ by at least * \ref CAL_TRESHOLD from the previous calibration point, it is interpreted as * an unintended touch and ignored. * * \param task Workqueue task for this worker function */ static void touch_calibrate_task_handler(struct workqueue_task *task) { int16_t dx; int16_t dy; struct touch_calibrate_context *cal_ctx; cal_ctx = container_of(task, struct touch_calibrate_context, task); switch (cal_ctx->state) { case 0: /* Fall through */ case 1: case 2: // Schedule task to run once more workqueue_add_task(&main_workqueue, &cal_ctx->task); // Run until touch is released if (cal_ctx->event.type != TOUCH_RELEASE) break; // Store calibration values cal_ctx->event.type = TOUCH_NO_EVENT; cal_ctx->cal_points[cal_ctx->state].raw_x = cal_ctx->event.point.raw_x; cal_ctx->cal_points[cal_ctx->state].raw_y = cal_ctx->event.point.raw_y; dx = cal_ctx->cal_points[cal_ctx->state - 1].raw_x - cal_ctx->cal_points[cal_ctx->state].raw_x; dy = cal_ctx->cal_points[cal_ctx->state - 1].raw_y - cal_ctx->cal_points[cal_ctx->state].raw_y; dx = abs(dx); dy = abs(dy); // If point is too close to the last one, wait for another touch if ((dx < CAL_TRESHOLD) && (dy < CAL_TRESHOLD)) break; // Clear old circle before moving on. gfx_draw_circle(cal_ctx->cal_points[cal_ctx->state].panel_x, cal_ctx->cal_points[cal_ctx->state].panel_y, CAL_RADIUS, CAL_BG_COLOR, GFX_WHOLE); // Move to next point cal_ctx->state++; /* Skip drawing last circles if we're done. */ if (cal_ctx->state >= 3) break; // Draw next circle. gfx_draw_circle(cal_ctx->cal_points[cal_ctx->state].panel_x, cal_ctx->cal_points[cal_ctx->state].panel_y, CAL_RADIUS, CAL_FG_COLOR, GFX_WHOLE); break; case 3: // Calibration completed // Clear circle before moving on. gfx_draw_circle(cal_ctx->cal_points[2].panel_x, cal_ctx->cal_points[2].panel_y, CAL_RADIUS, CAL_BG_COLOR, GFX_WHOLE); // Compute and assign the calibration matrix to the driver. touch_compute_calibration_matrix(cal_ctx->cal_points, &cal_ctx->cal_matrix); touch_set_calibration_matrix(&cal_ctx->cal_matrix); // Restore handler touch_set_event_handler(cal_ctx->old_handler); // Can now free memory membag_free(calibrate_context); // Schedule task if available if (calibrate_context->completed_task) { workqueue_add_task(&main_workqueue, calibrate_context->completed_task); } break; } }