Mar. 14. 2018

Dependencies:   GraphicsFramework GR-PEACH_video LCD_shield_config AsciiFont R_BSP USBHost_custom

Revision:
0:f5de229c9a00
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touch_proc/touch_proc.cpp	Mon Jan 23 06:22:08 2017 +0000
@@ -0,0 +1,699 @@
+#include "mbed.h"
+#include "DisplayBace.h"
+#include "rtos.h"
+#include "LCD_shield_config_4_3inch.h"
+#include "RGA.h"
+#include "BinaryImage_RZ_A1H.h"
+#include "recognition_proc.h"
+
+/*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128
+    in accordance with the frame buffer burst transfer mode. */
+/* TOUCH BUFFER Parameter GRAPHICS_LAYER_2 */
+#define TOUCH_BUFFER_BYTE_PER_PIXEL     (4u)
+#define TOUCH_BUFFER_STRIDE             (((LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
+
+/* Disp mode */
+#define DISP_MODE_NORMAL                (0)
+#define DISP_MODE_SETTING_1             (1)
+#define DISP_MODE_SETTING_2             (2)
+#define DISP_MODE_SETTING_3             (3)
+
+/* Setting range  */
+#define THRESHOLD_MIN                   (1)
+#define THRESHOLD_MAX                   (1000)
+#define SIZE_RANGE_MIN                  (20)
+#define SIZE_RANGE_MAX                  (1000)
+#define POSE_MIN                        (0)
+#define POSE_MAX                        (2)
+#define ANGLE_MIN                       (0)
+#define ANGLE_MAX                       (1)
+
+/* slide bar */
+#define POS_SLIDE_BAR_X                 (185)
+#define SLIDE_BAR_LENGTH                (200)
+#define POS_PROGRESS_0_X                (POS_SLIDE_BAR_X + 15)
+
+/* func_code */
+#define TOUCH_KEY_CLOSE                 (1)
+#define TOUCH_KEY_SETTING_1             (2)
+#define TOUCH_KEY_SETTING_2             (3)
+#define TOUCH_KEY_SETTING_3             (4)
+#define TOUCH_KEY_REGISTRATION          (5)
+#define TOUCH_KEY_THRESHOLD_BODY        (6)
+#define TOUCH_KEY_THRESHOLD_FACE        (7)
+#define TOUCH_KEY_THRESHOLD_RECO        (8)
+#define TOUCH_KEY_RANGE_BODY_MIN        (9)
+#define TOUCH_KEY_RANGE_BODY_MAX        (10)
+#define TOUCH_KEY_RANGE_FACE_MIN        (11)
+#define TOUCH_KEY_RANGE_FACE_MAX        (12)
+#define TOUCH_KEY_FACE_POSE             (13)
+#define TOUCH_KEY_FACE_ANGLE            (14)
+#define TOUCH_KEY_BODY_DETECTION        (15)
+#define TOUCH_KEY_FACE_DETECTION        (16)
+#define TOUCH_KEY_AGE_ESTIMATION        (17)
+#define TOUCH_KEY_GENDER_ESTIMATION     (18)
+#define TOUCH_KEY_EXPRESSION_ESTIMATION (19)
+#define TOUCH_KEY_SETTING_LAST          (20)
+#define TOUCH_KEY_RESET_SETTING         (21)
+
+typedef struct {
+    uint32_t pic_pos_x;             /* X position of the key picture. */
+    uint32_t pic_pos_y;             /* Y position of the key picture. */
+    uint32_t pic_width;             /* Width of the key picture. */
+    uint32_t pic_height;            /* Height of the key picture. */
+    uint32_t func_code;             /* func code of the key picture. */
+} key_pic_info_t;
+
+static const key_pic_info_t touch_key_tbl_normal[] = {
+    /*                X      Y    Width  Height   Func code                      */
+    {                330,    10,   140,    36,    TOUCH_KEY_BODY_DETECTION        },
+    {                330,    56,   140,    36,    TOUCH_KEY_FACE_DETECTION        },
+    {                330,   102,   140,    36,    TOUCH_KEY_AGE_ESTIMATION        },
+    {                330,   148,   140,    36,    TOUCH_KEY_GENDER_ESTIMATION     },
+    {                330,   194,   140,    36,    TOUCH_KEY_EXPRESSION_ESTIMATION },
+    {                448,   240,    32,    32,    TOUCH_KEY_SETTING_LAST          },
+    {                  0,     0,   320,   240,    TOUCH_KEY_REGISTRATION          },
+    {                  0,     0,     0,     0,    0                               } /* table end */
+};
+
+static const key_pic_info_t touch_key_tbl_setting_1[] = {
+    /*                X      Y    Width  Height   Func code                      */
+    {                127,   220,    80,    34,    TOUCH_KEY_RESET_SETTING         },
+    {                273,   220,    80,    34,    TOUCH_KEY_CLOSE                 },
+    {                 21,    20,   146,    34,    TOUCH_KEY_SETTING_1             },
+    {                167,    20,   146,    34,    TOUCH_KEY_SETTING_2             },
+    {                313,    20,   146,    34,    TOUCH_KEY_SETTING_3             },
+    { POS_SLIDE_BAR_X-20,  80-8,   281,    30,    TOUCH_KEY_THRESHOLD_BODY        },
+    { POS_SLIDE_BAR_X-20, 120-8,   281,    30,    TOUCH_KEY_THRESHOLD_FACE        },
+    { POS_SLIDE_BAR_X-20, 160-8,   281,    30,    TOUCH_KEY_THRESHOLD_RECO        },
+    {                  0,     0,     0,     0,    0                               } /* table end */
+};
+
+static const key_pic_info_t touch_key_tbl_setting_2[] = {
+    /*                X      Y    Width  Height   Func code                      */
+    {                127,   220,    80,    34,    TOUCH_KEY_RESET_SETTING         },
+    {                273,   220,    80,    34,    TOUCH_KEY_CLOSE                 },
+    {                 21,    20,   146,    34,    TOUCH_KEY_SETTING_1             },
+    {                167,    20,   146,    34,    TOUCH_KEY_SETTING_2             },
+    {                313,    20,   146,    34,    TOUCH_KEY_SETTING_3             },
+    { POS_SLIDE_BAR_X-20,  80-8,   281,    30,    TOUCH_KEY_RANGE_BODY_MIN        },
+    { POS_SLIDE_BAR_X-20, 110-8,   281,    30,    TOUCH_KEY_RANGE_BODY_MAX        },
+    { POS_SLIDE_BAR_X-20, 150-8,   281,    30,    TOUCH_KEY_RANGE_FACE_MIN        },
+    { POS_SLIDE_BAR_X-20, 180-8,   281,    30,    TOUCH_KEY_RANGE_FACE_MAX        },
+    {                  0,     0,     0,     0,    0                               } /* table end */
+};
+
+static const key_pic_info_t touch_key_tbl_setting_3[] = {
+    /*                X      Y    Width  Height   Func code                      */
+    {                127,   220,    80,    34,    TOUCH_KEY_RESET_SETTING         },
+    {                273,   220,    80,    34,    TOUCH_KEY_CLOSE                 },
+    {                 21,    20,   146,    34,    TOUCH_KEY_SETTING_1             },
+    {                167,    20,   146,    34,    TOUCH_KEY_SETTING_2             },
+    {                313,    20,   146,    34,    TOUCH_KEY_SETTING_3             },
+    { POS_SLIDE_BAR_X-20,  80-8,   281,    30,    TOUCH_KEY_FACE_POSE             },
+    { POS_SLIDE_BAR_X-20, 120-8,   281,    30,    TOUCH_KEY_FACE_ANGLE            },
+    {                  0,     0,     0,     0,    0                               } /* table end */
+};
+
+static const key_pic_info_t * p_touch_key_tbl[] = {
+    touch_key_tbl_normal,           /* DISP_MODE_NORMAL    */
+    touch_key_tbl_setting_1,        /* DISP_MODE_SETTING_1 */
+    touch_key_tbl_setting_2,        /* DISP_MODE_SETTING_2 */
+    touch_key_tbl_setting_3,        /* DISP_MODE_SETTING_3 */
+    NULL
+};
+
+static TouckKey_LCD_shield touch(P4_0, P2_13, I2C_SDA, I2C_SCL);
+static Semaphore   sem_touch_int(0);
+
+#if defined(__ICCARM__)
+/* 32 bytes aligned */
+#pragma data_alignment=32
+static uint8_t user_frame_buffer_touch0[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
+#pragma data_alignment=32
+static uint8_t user_frame_buffer_touch1[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
+#else
+/* 32 bytes aligned */
+static uint8_t user_frame_buffer_touch0[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
+static uint8_t user_frame_buffer_touch1[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
+#endif
+
+static volatile int32_t vsync_count = 0;
+static recognition_setting_t * p_setting;
+static int disp_mode;
+
+/****** Touch panel ******/
+static uint32_t Scan_Key(const key_pic_info_t * key_tbl, const uint32_t pos_x, const uint32_t pos_y) {
+    uint32_t ret = 0;
+
+    while (ret == 0) {
+        if (key_tbl->func_code == 0) {
+            break;
+        }
+        /* Check the range of the X position */
+        if ((pos_x >= key_tbl->pic_pos_x) && (pos_x <= (key_tbl->pic_pos_x + key_tbl->pic_width))) {
+            /* Check the range of the Y position */
+            if ((pos_y >= key_tbl->pic_pos_y) && (pos_y <= (key_tbl->pic_pos_y + key_tbl->pic_height))) {
+                /* Decide the func code. */
+                ret = key_tbl->func_code;
+            }
+        }
+        key_tbl++;
+    }
+
+    return ret;
+}
+
+static void draw_button(Canvas2D_ContextClass * p_canvas2d) {
+    const graphics_image_t* p_wk;
+
+    /* Draw background */
+    p_canvas2d->drawImage(background, 320, 0);
+
+    /* Draw "HUMAN BODY" button */
+    if ((p_setting->execFlag & HVC_ACTIV_BODY_DETECTION) == 0) {
+        p_wk = button_off;
+    } else {
+        p_wk = button_on;
+    }
+    p_canvas2d->drawImage(p_wk, 330, 10);
+    p_canvas2d->drawImage(str_human_body, 330 + 19, 10 + 11);
+
+    /* Draw "FACE" or "RECOGNITION" button */
+    if ((p_setting->execFlag & HVC_ACTIV_FACE_RECOGNITION) == 0) {
+        if ((p_setting->execFlag & HVC_ACTIV_FACE_DETECTION) == 0) {
+            p_wk = button_off;
+        } else {
+            p_wk = button_on;
+        }
+        p_canvas2d->drawImage(p_wk, 330, 56);
+        p_canvas2d->drawImage(str_face, 330 + 51, 56 + 11);
+    } else {
+        p_canvas2d->drawImage(button_on2, 330, 56);
+        p_canvas2d->drawImage(str_recognition, 330 + 19, 56 + 11);
+    }
+
+    /* Draw "AGE" button */
+    if ((p_setting->execFlag & HVC_ACTIV_FACE_DETECTION) == 0) {
+        p_wk = button_inv;
+    } else if ((p_setting->execFlag & HVC_ACTIV_AGE_ESTIMATION) == 0) {
+        p_wk = button_off;
+    } else {
+        p_wk = button_on;
+    }
+    p_canvas2d->drawImage(p_wk, 330, 102);
+    p_canvas2d->drawImage(str_age, 330 + 54, 102 + 11);
+
+    /* Draw "GENDER" button */
+    if ((p_setting->execFlag & HVC_ACTIV_FACE_DETECTION) == 0) {
+        p_wk = button_inv;
+    } else if ((p_setting->execFlag & HVC_ACTIV_GENDER_ESTIMATION) == 0) {
+        p_wk = button_off;
+    } else {
+        p_wk = button_on;
+    }
+    p_canvas2d->drawImage(p_wk, 330, 148);
+    p_canvas2d->drawImage(str_gender, 330 + 39, 148 + 11);
+
+    /* Draw "EXPRESSION" button */
+    if ((p_setting->execFlag & HVC_ACTIV_FACE_DETECTION) == 0) {
+        p_wk = button_inv;
+    } else if ((p_setting->execFlag & HVC_ACTIV_EXPRESSION_ESTIMATION) == 0) {
+        p_wk = button_off;
+    } else {
+        p_wk = button_on;
+    }
+    p_canvas2d->drawImage(p_wk, 330, 194);
+    p_canvas2d->drawImage(str_expression, 330 + 23, 194 + 11);
+
+    /* Draw setting icon */
+    p_canvas2d->drawImage(icon_setting, LCD_PIXEL_WIDTH - 32, LCD_PIXEL_HEIGHT - 32);
+}
+
+static void draw_number(Canvas2D_ContextClass * p_canvas2d, int x, int y, int number) {
+    int wk_num;
+    bool disp_flg = false;
+    const graphics_image_t * p_num_tbl[] = {
+        char_0, char_1, char_2, char_3, char_4, char_5, char_6, char_7, char_8, char_9
+    };
+
+    wk_num = (number / 1000) % 10;
+    if ((wk_num != 0) || (disp_flg != false)) {
+        p_canvas2d->drawImage(p_num_tbl[wk_num], x + 9 * 0, y);
+        R_OSPL_CLEAR_ERROR();
+        disp_flg = true;
+    }
+    wk_num = (number / 100) % 10;
+    if ((wk_num != 0) || (disp_flg != false)) {
+        p_canvas2d->drawImage(p_num_tbl[wk_num], x + 9 * 1, y);
+        R_OSPL_CLEAR_ERROR();
+        disp_flg = true;
+    }
+    wk_num = (number / 10) % 10;
+    if ((wk_num != 0) || (disp_flg != false)) {
+        p_canvas2d->drawImage(p_num_tbl[wk_num], x + 9 * 2, y);
+        R_OSPL_CLEAR_ERROR();
+    }
+    wk_num = number % 10;
+    p_canvas2d->drawImage(p_num_tbl[wk_num], x + 9 * 3, y);
+    R_OSPL_CLEAR_ERROR();
+}
+
+static void draw_slide_bar(Canvas2D_ContextClass * p_canvas2d, int y, INT32 data, int min, int max) {
+    p_canvas2d->globalAlpha = 0.7f;
+    p_canvas2d->fillStyle = "#D9C3E6";
+    p_canvas2d->fillRect(POS_PROGRESS_0_X, y + 6, SLIDE_BAR_LENGTH + 10, 2);
+    p_canvas2d->globalAlpha = 1.0f;
+    p_canvas2d->drawImage(char_left, POS_SLIDE_BAR_X, y);
+    p_canvas2d->drawImage(char_rigth, POS_PROGRESS_0_X + SLIDE_BAR_LENGTH + 10 + 1, y);
+    p_canvas2d->fillStyle = "#5B9BD5";
+    p_canvas2d->fillRect(POS_PROGRESS_0_X + (int)(SLIDE_BAR_LENGTH * ((float)(data - min) / (max - min))), y, 10, 14);
+}
+
+static void draw_setting_menu(Canvas2D_ContextClass * p_canvas2d) {
+    if (disp_mode == DISP_MODE_NORMAL) {
+        return;
+    }
+
+    p_canvas2d->globalAlpha = 0.95f;
+    p_canvas2d->drawImage(background_setting, 0, 0);
+
+    /* Tab */
+    if (disp_mode == DISP_MODE_SETTING_1) {
+        p_canvas2d->globalAlpha = 0.9f;
+        p_canvas2d->fillStyle = "#5B9BD5";
+        p_canvas2d->fillRect(21, 20, 146, 34);
+        p_canvas2d->globalAlpha = 1.0f;
+    } else {
+        p_canvas2d->globalAlpha = 0.3f;
+    }
+    p_canvas2d->drawImage(str_threshold_value, 23, 30);
+
+    if (disp_mode == DISP_MODE_SETTING_2) {
+        p_canvas2d->globalAlpha = 0.9f;
+        p_canvas2d->fillStyle = "#5B9BD5";
+        p_canvas2d->fillRect(167, 20, 146, 34);
+        p_canvas2d->globalAlpha = 1.0f;
+    } else {
+        p_canvas2d->globalAlpha = 0.3f;
+    }
+    p_canvas2d->drawImage(str_detection_size, 181, 30);
+
+    if (disp_mode == DISP_MODE_SETTING_3) {
+        p_canvas2d->globalAlpha = 0.9f;
+        p_canvas2d->fillStyle = "#5B9BD5";
+        p_canvas2d->fillRect(313, 20, 146, 34);
+        p_canvas2d->globalAlpha = 1.0f;
+    } else {
+        p_canvas2d->globalAlpha = 0.3f;
+    }
+    p_canvas2d->drawImage(str_face, 342, 30);
+    p_canvas2d->drawImage(str_angle, 383, 30);
+
+    /* Setting */
+    p_canvas2d->globalAlpha = 1.0f;
+    if (disp_mode == DISP_MODE_SETTING_1) {
+        p_canvas2d->drawImage(str_human_body, 30, 80);
+        p_canvas2d->drawImage(str_face, 30, 120);
+        p_canvas2d->drawImage(str_recognition, 30, 160);
+
+        draw_slide_bar(p_canvas2d,  80, p_setting->threshold.bdThreshold, THRESHOLD_MIN, THRESHOLD_MAX);
+        draw_slide_bar(p_canvas2d, 120, p_setting->threshold.dtThreshold, THRESHOLD_MIN, THRESHOLD_MAX);
+        draw_slide_bar(p_canvas2d, 160, p_setting->threshold.rsThreshold, THRESHOLD_MIN, THRESHOLD_MAX);
+
+        draw_number(p_canvas2d, 430,  80, p_setting->threshold.bdThreshold);
+        draw_number(p_canvas2d, 430, 120, p_setting->threshold.dtThreshold);
+        draw_number(p_canvas2d, 430, 160, p_setting->threshold.rsThreshold);
+    } else if (disp_mode == DISP_MODE_SETTING_2) {
+        p_canvas2d->drawImage(str_human_body, 30, 80);
+        p_canvas2d->drawImage(str_min, 140, 80);
+        p_canvas2d->drawImage(str_max, 140, 110);
+        p_canvas2d->drawImage(str_face, 30, 150);
+        p_canvas2d->drawImage(str_min, 140, 150);
+        p_canvas2d->drawImage(str_max, 140, 180);
+
+        draw_slide_bar(p_canvas2d,  80, p_setting->sizeRange.bdMinSize, SIZE_RANGE_MIN, SIZE_RANGE_MAX);
+        draw_slide_bar(p_canvas2d, 110, p_setting->sizeRange.bdMaxSize, SIZE_RANGE_MIN, SIZE_RANGE_MAX);
+        draw_slide_bar(p_canvas2d, 150, p_setting->sizeRange.dtMinSize, SIZE_RANGE_MIN, SIZE_RANGE_MAX);
+        draw_slide_bar(p_canvas2d, 180, p_setting->sizeRange.dtMaxSize, SIZE_RANGE_MIN, SIZE_RANGE_MAX);
+
+        draw_number(p_canvas2d, 430,  80, p_setting->sizeRange.bdMinSize);
+        draw_number(p_canvas2d, 430, 110, p_setting->sizeRange.bdMaxSize);
+        draw_number(p_canvas2d, 430, 150, p_setting->sizeRange.dtMinSize);
+        draw_number(p_canvas2d, 430, 180, p_setting->sizeRange.dtMaxSize);
+    } else {
+        int wk_data;
+
+        p_canvas2d->drawImage(str_yaw, 30, 80);
+        p_canvas2d->drawImage(str_angle, 30 + 41, 80);
+        p_canvas2d->drawImage(str_roll, 30, 120);
+        p_canvas2d->drawImage(str_angle, 30 + 42, 120);
+
+        if (p_setting->pose == 0) {
+            wk_data = 30;
+        } else if (p_setting->pose == 1) {
+            wk_data = 60;
+        } else {
+            wk_data = 90;
+        }
+        draw_slide_bar(p_canvas2d,  80, p_setting->pose, POSE_MIN , POSE_MAX);
+        p_canvas2d->drawImage(char_plus_minus, 426, 80);
+        draw_number(p_canvas2d, 420,  80, wk_data); /* 30 60 90 */
+        p_canvas2d->drawImage(char_angle, 457, 80);
+
+        if (p_setting->angle == 0) {
+            wk_data = 15;
+        } else {
+            wk_data = 45;
+        }
+        draw_slide_bar(p_canvas2d, 120, p_setting->angle, ANGLE_MIN, ANGLE_MAX);
+        p_canvas2d->drawImage(char_plus_minus, 426, 120);
+        draw_number(p_canvas2d, 420, 120, wk_data); /* 15 45 */
+        p_canvas2d->drawImage(char_angle, 457, 120);
+    }
+    p_canvas2d->drawImage(str_reset, 144, 230);
+    p_canvas2d->drawImage(str_close, 290, 230);
+}
+
+static void draw_touch_layer(DisplayBase * p_display, frame_buffer_t * frmbuf_info, Canvas2D_ContextClass * p_canvas2d) {
+    while (vsync_count > 0) {
+        Thread::wait(1);
+    }
+
+    /* Swap the frame buffer */
+    if (frmbuf_info->draw_buffer_index == 1) {
+        frmbuf_info->draw_buffer_index = 0;
+    } else {
+        frmbuf_info->draw_buffer_index = 1;
+    }
+
+    /* Clear */
+    p_canvas2d->clearRect(0, 0, frmbuf_info->width, frmbuf_info->height);
+
+    /* Draw button */
+    draw_button(p_canvas2d);
+
+    /* Draw setting menu */
+    draw_setting_menu(p_canvas2d);
+
+    /* Complete drawing */
+    R_GRAPHICS_Finish(p_canvas2d->c_LanguageContext);
+    p_display->Graphics_Read_Change(DisplayBase::GRAPHICS_LAYER_2,
+     (void *)frmbuf_info->buffer_address[frmbuf_info->draw_buffer_index]);
+    vsync_count = 1;
+}
+
+static void set_progress(int x, INT32 * p_data, int min, int max, bool * p_slide, int last_key) {
+    int now_pos = POS_PROGRESS_0_X + (int)(SLIDE_BAR_LENGTH * (float)(*p_data - min) / (max - min));
+
+    x -= 5;
+    if ((last_key == 0) && (x > (now_pos - 10)) && (x < (now_pos + 20))) {
+        *p_slide = true;
+    }
+    if (x < POS_PROGRESS_0_X) {
+        x = POS_PROGRESS_0_X;
+    }
+    if (x > (POS_PROGRESS_0_X + SLIDE_BAR_LENGTH)) {
+        x = (POS_PROGRESS_0_X + SLIDE_BAR_LENGTH);
+    }
+    if (*p_slide) {
+        *p_data = ((float)(x - POS_PROGRESS_0_X) / (float)SLIDE_BAR_LENGTH * (float)(max - min)) + min;
+    } else if ((x > now_pos) && (*p_data < max)) {
+        *p_data += 1;
+    } else if ((x < now_pos) && (*p_data > min)) {
+        *p_data -= 1;
+    } else {
+        /* do nothing */
+    }
+}
+
+static void init_touch_layer(DisplayBase * p_display, frame_buffer_t * frmbuf_info, Canvas2D_ContextClass * p_canvas2d) {
+    errnum_t err;
+    Canvas2D_ContextConfigClass config;
+    DisplayBase::rect_t rect;
+
+    /* The layer by which the buttons is drawn */
+    memset(user_frame_buffer_touch0, 0, sizeof(user_frame_buffer_touch0));
+    memset(user_frame_buffer_touch1, 0, sizeof(user_frame_buffer_touch1));
+    frmbuf_info->buffer_address[0] = user_frame_buffer_touch0;
+    frmbuf_info->buffer_address[1] = user_frame_buffer_touch1;
+    frmbuf_info->buffer_count      = 2;
+    frmbuf_info->show_buffer_index = 0;
+    frmbuf_info->draw_buffer_index = 0;
+    frmbuf_info->width             = LCD_PIXEL_WIDTH;
+    frmbuf_info->byte_per_pixel    = TOUCH_BUFFER_BYTE_PER_PIXEL;
+    frmbuf_info->stride            = TOUCH_BUFFER_STRIDE;
+    frmbuf_info->height            = LCD_PIXEL_HEIGHT;
+    frmbuf_info->pixel_format      = PIXEL_FORMAT_ARGB8888;
+
+    rect.vs = 0;
+    rect.vw = LCD_PIXEL_HEIGHT;
+    rect.hs = 0;
+    rect.hw = LCD_PIXEL_WIDTH;
+    p_display->Graphics_Read_Setting(
+        DisplayBase::GRAPHICS_LAYER_2,
+        (void *)frmbuf_info->buffer_address[frmbuf_info->draw_buffer_index],
+        TOUCH_BUFFER_STRIDE,
+        DisplayBase::GRAPHICS_FORMAT_ARGB8888,
+        DisplayBase::WR_RD_WRSWA_32BIT,
+        &rect
+    );
+    p_display->Graphics_Start(DisplayBase::GRAPHICS_LAYER_2);
+
+    /* Drawing buttons */
+    config.frame_buffer = frmbuf_info;
+    *p_canvas2d = R_RGA_New_Canvas2D_ContextClass(config);
+    err = R_OSPL_GetErrNum();
+    if (err != 0) {
+        printf("Line %d, err %d\n", __LINE__, err);
+        mbed_die();
+    }
+}
+
+static void touch_int_callback(void) {
+    sem_touch_int.release();
+}
+
+void touch_lcd_int(DisplayBase::int_type_t int_type) {
+    /* Interrupt callback function for Vsync interruption */
+    if (int_type == DisplayBase::INT_TYPE_S0_LO_VSYNC) {
+        if (vsync_count > 0) {
+            vsync_count--;
+        }
+    }
+}
+
+void touch_task(DisplayBase * p_display) {
+    frame_buffer_t frame_buffer_info;
+    Canvas2D_ContextClass canvas2d;
+    TouchKey::touch_pos_t touch_pos[1];
+    int touch_num = 0;
+    int touch_num_last = 0;
+    bool key_rep = false;
+    int func_code;
+    int func_code_last = 0;
+    bool slide = false;
+    Timer key_time;
+    int wait_time;
+    int last_setting_mode = DISP_MODE_SETTING_1;
+
+    p_setting = GetRecognitionSettingPointer();
+    disp_mode = DISP_MODE_NORMAL;
+
+    /* Initializing Touch layer */
+    init_touch_layer(p_display, &frame_buffer_info, &canvas2d);
+    draw_touch_layer(p_display, &frame_buffer_info, &canvas2d);
+
+    /* Callback setting */
+    touch.SetCallback(&touch_int_callback);
+
+    /* Reset touch IC */
+    touch.Reset();
+
+    key_time.reset();
+    key_time.start();
+
+    while (1) {
+        /* Wait touch event */
+        sem_touch_int.wait();
+
+        /* Get touch coordinates */
+        touch_num = touch.GetCoordinates(1, touch_pos);
+
+        if (slide) {
+            wait_time = 80;
+        } else {
+            wait_time = 250;
+        }
+        if ((key_time.read_ms() > wait_time) || (touch_num != touch_num_last)) {
+            key_time.reset();
+            key_time.start();
+            if ((touch_num != 0) && ((touch_num_last == 0) || (key_rep == true))) {
+                key_rep = false;
+                func_code = Scan_Key(p_touch_key_tbl[disp_mode], touch_pos[0].x, touch_pos[0].y);
+                if (slide) {
+                    func_code = func_code_last;
+                }
+                if (func_code != 0) {
+                    switch (func_code) {
+                        case TOUCH_KEY_SETTING_LAST:
+                            disp_mode = last_setting_mode;
+                            break;
+                        case TOUCH_KEY_CLOSE:
+                            disp_mode = DISP_MODE_NORMAL;
+                            SetSettingReq();
+                            break;
+                        case TOUCH_KEY_SETTING_1:
+                            disp_mode = DISP_MODE_SETTING_1;
+                            last_setting_mode = DISP_MODE_SETTING_1;
+                            break;
+                        case TOUCH_KEY_SETTING_2:
+                            disp_mode = DISP_MODE_SETTING_2;
+                            last_setting_mode = DISP_MODE_SETTING_2;
+                            break;
+                        case TOUCH_KEY_SETTING_3:
+                            disp_mode = DISP_MODE_SETTING_3;
+                            last_setting_mode = DISP_MODE_SETTING_3;
+                            break;
+                        case TOUCH_KEY_REGISTRATION:
+                            if ((p_setting->execFlag & HVC_ACTIV_FACE_RECOGNITION) != 0) {
+                                SetRegistrationrReq();
+                            }
+                            break;
+                        case TOUCH_KEY_THRESHOLD_BODY:
+                            set_progress(touch_pos[0].x, &p_setting->threshold.bdThreshold,
+                                         THRESHOLD_MIN, THRESHOLD_MAX, &slide, touch_num_last);
+                            key_rep = true;
+                            break;
+                        case TOUCH_KEY_THRESHOLD_FACE:
+                            set_progress(touch_pos[0].x, &p_setting->threshold.dtThreshold,
+                                         THRESHOLD_MIN, THRESHOLD_MAX, &slide, touch_num_last);
+                            key_rep = true;
+                            break;
+                        case TOUCH_KEY_THRESHOLD_RECO:
+                            set_progress(touch_pos[0].x, &p_setting->threshold.rsThreshold,
+                                         THRESHOLD_MIN, THRESHOLD_MAX, &slide, touch_num_last);
+                            key_rep = true;
+                            break;
+                        case TOUCH_KEY_RANGE_BODY_MIN:
+                            set_progress(touch_pos[0].x, &p_setting->sizeRange.bdMinSize,
+                                         SIZE_RANGE_MIN, SIZE_RANGE_MAX, &slide, touch_num_last);
+                            if (p_setting->sizeRange.bdMinSize > p_setting->sizeRange.bdMaxSize) {
+                                p_setting->sizeRange.bdMaxSize = p_setting->sizeRange.bdMinSize;
+                            }
+                            key_rep = true;
+                            break;
+                        case TOUCH_KEY_RANGE_BODY_MAX:
+                            set_progress(touch_pos[0].x, &p_setting->sizeRange.bdMaxSize,
+                                         SIZE_RANGE_MIN, SIZE_RANGE_MAX, &slide, touch_num_last);
+                            if (p_setting->sizeRange.bdMaxSize < p_setting->sizeRange.bdMinSize) {
+                                p_setting->sizeRange.bdMinSize = p_setting->sizeRange.bdMaxSize;
+                            }
+                            key_rep = true;
+                            break;
+                        case TOUCH_KEY_RANGE_FACE_MIN:
+                            set_progress(touch_pos[0].x, &p_setting->sizeRange.dtMinSize,
+                                         SIZE_RANGE_MIN, SIZE_RANGE_MAX, &slide, touch_num_last);
+                            if (p_setting->sizeRange.dtMinSize > p_setting->sizeRange.dtMaxSize) {
+                                p_setting->sizeRange.dtMaxSize = p_setting->sizeRange.dtMinSize;
+                            }
+                            key_rep = true;
+                            break;
+                        case TOUCH_KEY_RANGE_FACE_MAX:
+                            set_progress(touch_pos[0].x, &p_setting->sizeRange.dtMaxSize,
+                                         SIZE_RANGE_MIN, SIZE_RANGE_MAX, &slide, touch_num_last);
+                            if (p_setting->sizeRange.dtMaxSize < p_setting->sizeRange.dtMinSize) {
+                                p_setting->sizeRange.dtMinSize = p_setting->sizeRange.dtMaxSize;
+                            }
+                            key_rep = true;
+                            break;
+                        case TOUCH_KEY_FACE_POSE:
+                            set_progress(touch_pos[0].x, &p_setting->pose,
+                                         POSE_MIN, POSE_MAX, &slide, touch_num_last);
+                            if (slide) {
+                                key_rep = true;
+                            }
+                            break;
+                        case TOUCH_KEY_FACE_ANGLE:
+                            set_progress(touch_pos[0].x, &p_setting->angle,
+                                         ANGLE_MIN, ANGLE_MAX, &slide, touch_num_last);
+                            if (slide) {
+                                key_rep = true;
+                            }
+                            break;
+                        case TOUCH_KEY_BODY_DETECTION:
+                            if ((p_setting->execFlag & HVC_ACTIV_BODY_DETECTION) != 0) {
+                                p_setting->execFlag &= ~HVC_ACTIV_BODY_DETECTION;
+                            } else {
+                                p_setting->execFlag |= HVC_ACTIV_BODY_DETECTION;
+                            }
+                            break;
+                        case TOUCH_KEY_FACE_DETECTION:
+                            if ((p_setting->execFlag & HVC_ACTIV_FACE_DETECTION) == 0) {
+                                p_setting->execFlag |= HVC_ACTIV_FACE_DETECTION;
+                            } else if ((p_setting->execFlag & HVC_ACTIV_FACE_RECOGNITION) == 0) {
+                                p_setting->execFlag |= HVC_ACTIV_FACE_RECOGNITION;
+                            } else {
+                                p_setting->execFlag &= ~(HVC_ACTIV_FACE_DETECTION | HVC_ACTIV_FACE_RECOGNITION);
+                            }
+                            break;
+                        case TOUCH_KEY_AGE_ESTIMATION:
+                            if ((p_setting->execFlag & HVC_ACTIV_FACE_DETECTION) == 0) {
+                                /* do nothing */
+                            } else if ((p_setting->execFlag & HVC_ACTIV_AGE_ESTIMATION) != 0) {
+                                p_setting->execFlag &= ~HVC_ACTIV_AGE_ESTIMATION;
+                            } else {
+                                p_setting->execFlag |= HVC_ACTIV_AGE_ESTIMATION;
+                            }
+                            break;
+                        case TOUCH_KEY_GENDER_ESTIMATION:
+                            if ((p_setting->execFlag & HVC_ACTIV_FACE_DETECTION) == 0) {
+                                /* do nothing */
+                            } else if ((p_setting->execFlag & HVC_ACTIV_GENDER_ESTIMATION) != 0) {
+                                p_setting->execFlag &= ~HVC_ACTIV_GENDER_ESTIMATION;
+                            } else {
+                                p_setting->execFlag |= HVC_ACTIV_GENDER_ESTIMATION;
+                            }
+                            break;
+                        case TOUCH_KEY_EXPRESSION_ESTIMATION:
+                            if ((p_setting->execFlag & HVC_ACTIV_FACE_DETECTION) == 0) {
+                                /* do nothing */
+                            } else if ((p_setting->execFlag & HVC_ACTIV_EXPRESSION_ESTIMATION) != 0) {
+                                p_setting->execFlag &= ~HVC_ACTIV_EXPRESSION_ESTIMATION;
+                            } else {
+                                p_setting->execFlag |= HVC_ACTIV_EXPRESSION_ESTIMATION;
+                            }
+                            break;
+                        case TOUCH_KEY_RESET_SETTING:
+                            if (disp_mode == DISP_MODE_SETTING_1) {
+                                p_setting->threshold.bdThreshold = BODY_THRESHOLD_DEFAULT;
+                                p_setting->threshold.hdThreshold = HAND_THRESHOLD_DEFAULT;
+                                p_setting->threshold.dtThreshold = FACE_THRESHOLD_DEFAULT;
+                                p_setting->threshold.rsThreshold = REC_THRESHOLD_DEFAULT;
+                            } else if (disp_mode == DISP_MODE_SETTING_2) {
+                                p_setting->sizeRange.bdMinSize = BODY_SIZE_RANGE_MIN_DEFAULT;
+                                p_setting->sizeRange.bdMaxSize = BODY_SIZE_RANGE_MAX_DEFAULT;
+                                p_setting->sizeRange.hdMinSize = HAND_SIZE_RANGE_MIN_DEFAULT;
+                                p_setting->sizeRange.hdMaxSize = HAND_SIZE_RANGE_MAX_DEFAULT;
+                                p_setting->sizeRange.dtMinSize = FACE_SIZE_RANGE_MIN_DEFAULT;
+                                p_setting->sizeRange.dtMaxSize = FACE_SIZE_RANGE_MAX_DEFAULT;
+                            } else if (disp_mode == DISP_MODE_SETTING_3) {
+                                p_setting->pose  = FACE_POSE_DEFAULT;
+                                p_setting->angle = FACE_ANGLE_DEFAULT;
+                            } else {
+                                /* do nothing */
+                            }
+                            break;
+                        default:
+                            break;
+                    }
+                    draw_touch_layer(p_display, &frame_buffer_info, &canvas2d);
+                }
+                func_code_last = func_code;
+            } else {
+                slide = false;
+            }
+        }
+        touch_num_last = touch_num;
+    }
+}