test

Dependencies:   mbed GR-PEACH_video mbed-rtos LCD_shield_config

Revision:
0:b2184c2d15dd
Child:
1:54a3e69f6f09
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Jun 30 11:05:41 2016 +0000
@@ -0,0 +1,549 @@
+#include "mbed.h"
+#include "DisplayBace.h"
+#include "rtos.h"
+
+#define VIDEO_CVBS             (0)                 /* Analog  Video Signal */
+#define VIDEO_CMOS_CAMERA      (1)                 /* Digital Video Signal */
+#define VIDEO_YCBCR422         (0)
+#define VIDEO_RGB888           (1)
+#define VIDEO_RGB565           (2)
+
+/**** User Selection *********/
+/** Camera **/
+#define VIDEO_INPUT_METHOD     (VIDEO_CMOS_CAMERA) /* Select  VIDEO_CVBS or VIDEO_CMOS_CAMERA                       */
+#define VIDEO_INPUT_FORMAT     (VIDEO_YCBCR422)    /* Select  VIDEO_YCBCR422 or VIDEO_RGB888 or VIDEO_RGB565        */
+#define USE_VIDEO_CH           (0)                 /* Select  0 or 1            If selecting VIDEO_CMOS_CAMERA, should be 0.)               */
+#define VIDEO_PAL              (0)                 /* Select  0(NTSC) or 1(PAL) If selecting VIDEO_CVBS, this parameter is not referenced.) */
+/** LCD **/
+#define LCD_TYPE               (0)                 /* Select  0(4.3inch) or 1(7.1inch) */
+/*****************************/
+
+/** LCD shield config **/
+#if (LCD_TYPE == 0)
+  #include "LCD_shield_config_4_3inch.h"
+#else
+  #include "LCD_shield_config_7_1inch.h"
+#endif
+
+/** Video and Grapics (GRAPHICS_LAYER_0) parameter **/
+/* video input */
+#if USE_VIDEO_CH == (0)
+  #define VIDEO_INPUT_CH       (DisplayBase::VIDEO_INPUT_CHANNEL_0)
+  #define VIDEO_INT_TYPE       (DisplayBase::INT_TYPE_S0_VFIELD)
+#else
+  #define VIDEO_INPUT_CH       (DisplayBase::VIDEO_INPUT_CHANNEL_1)
+  #define VIDEO_INT_TYPE       (DisplayBase::INT_TYPE_S1_VFIELD)
+#endif
+
+/* NTSC or PAL */
+#if VIDEO_PAL == 0
+  #define COL_SYS              (DisplayBase::COL_SYS_NTSC_358)
+#else
+  #define COL_SYS              (DisplayBase::COL_SYS_PAL_443)
+#endif
+
+/* Video input and LCD layer 0 output */
+#if VIDEO_INPUT_FORMAT == VIDEO_YCBCR422
+  #define VIDEO_FORMAT         (DisplayBase::VIDEO_FORMAT_YCBCR422)
+  #define GRAPHICS_FORMAT      (DisplayBase::GRAPHICS_FORMAT_YCBCR422)
+  #define WR_RD_WRSWA          (DisplayBase::WR_RD_WRSWA_NON)
+#elif VIDEO_INPUT_FORMAT == VIDEO_RGB565
+  #define VIDEO_FORMAT         (DisplayBase::VIDEO_FORMAT_RGB565)
+  #define GRAPHICS_FORMAT      (DisplayBase::GRAPHICS_FORMAT_RGB565)
+  #define WR_RD_WRSWA          (DisplayBase::WR_RD_WRSWA_32_16BIT)
+#else
+  #define VIDEO_FORMAT         (DisplayBase::VIDEO_FORMAT_RGB888)
+  #define GRAPHICS_FORMAT      (DisplayBase::GRAPHICS_FORMAT_RGB888)
+  #define WR_RD_WRSWA          (DisplayBase::WR_RD_WRSWA_32BIT)
+#endif
+
+/* The size of the video input is adjusted to the LCD size. */
+#define VIDEO_PIXEL_HW                LCD_PIXEL_WIDTH
+#define VIDEO_PIXEL_VW                LCD_PIXEL_HEIGHT
+
+/*! 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. */
+/* FRAME BUFFER Parameter GRAPHICS_LAYER_0 */
+#define FRAME_BUFFER_NUM              (3u)
+#if ( VIDEO_INPUT_FORMAT == VIDEO_YCBCR422 || VIDEO_INPUT_FORMAT == VIDEO_RGB565 )
+  #define FRAME_BUFFER_BYTE_PER_PIXEL (2u)
+#else
+  #define FRAME_BUFFER_BYTE_PER_PIXEL (4u)
+#endif
+#define FRAME_BUFFER_STRIDE           (((LCD_PIXEL_WIDTH * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
+
+/* TOUCH BUFFER Parameter GRAPHICS_LAYER_1 */
+#define TOUCH_BUFFER_BYTE_PER_PIXEL   (2u)
+#define TOUCH_BUFFER_STRIDE           (((LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
+
+/* Touch panel parameter */
+#define TOUCH_NUM                     (2u)
+#define DROW_POINT                    (5)
+
+static DisplayBase Display;
+static DigitalOut  lcd_pwon(P7_15);
+static DigitalOut  lcd_blon(P8_1);
+static PwmOut      lcd_cntrst(P8_15);
+static Serial      pc(USBTX, USBRX);
+static Semaphore   sem_touch_int(0);
+static TouckKey_LCD_shield touch(P4_0, P2_13, I2C_SDA, I2C_SCL);
+static Thread *    p_VideoLcdTask = NULL;
+static DigitalOut  led_blue(LED_BLUE);
+
+#if defined(__ICCARM__)
+/* 32 bytes aligned */
+#pragma data_alignment=32
+static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
+static uint8_t user_frame_buffer1[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
+static uint8_t user_frame_buffer2[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
+static uint8_t user_frame_buffer_touch[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
+#pragma data_alignment=4
+#else
+/* 32 bytes aligned */
+static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
+static uint8_t user_frame_buffer1[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
+static uint8_t user_frame_buffer2[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
+static uint8_t user_frame_buffer_touch[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
+#endif
+static volatile int32_t vfield_count = 0;
+static uint8_t * FrameBufferTbl[FRAME_BUFFER_NUM] = {user_frame_buffer0, user_frame_buffer1, user_frame_buffer2};
+static int write_buff_num = 0;
+static int read_buff_num = 0;
+static bool graphics_init_end = false;
+
+/****** cache control ******/
+static void dcache_clean(void * p_buf, uint32_t size) {
+    uint32_t start_addr = (uint32_t)p_buf & 0xFFFFFFE0;
+    uint32_t end_addr   = (uint32_t)p_buf + size;
+    uint32_t addr;
+
+    /* Data cache clean */
+    for (addr = start_addr; addr < end_addr; addr += 0x20) {
+        __v7_clean_dcache_mva((void *)addr);
+    }
+}
+
+/****** LCD ******/
+#if(0) /* When needing LCD Vsync interrupt, please make it effective. */
+static void IntCallbackFunc_LoVsync(DisplayBase::int_type_t int_type) {
+    /* Interrupt callback function for Vsync interruption */
+}
+#endif
+
+static void Init_LCD_Display(void) {
+    DisplayBase::graphics_error_t error;
+    DisplayBase::lcd_config_t lcd_config;
+    PinName lvds_pin[8] = {
+        /* data pin */
+        P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0
+    };
+
+    lcd_pwon = 0;
+    lcd_blon = 0;
+    Thread::wait(100);
+    lcd_pwon = 1;
+    lcd_blon = 1;
+
+    Display.Graphics_Lvds_Port_Init(lvds_pin, 8);
+
+    /* Graphics initialization process */
+    lcd_config = LcdCfgTbl_LCD_shield;
+    error = Display.Graphics_init(&lcd_config);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+    graphics_init_end = true;
+
+#if(0) /* When needing LCD Vsync interrupt, please make it effective. */
+    /* Interrupt callback function setting (Vsync signal output from scaler 0) */
+    error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_LO_VSYNC, 0, IntCallbackFunc_LoVsync);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+#endif
+}
+
+static void Start_LCD_Display(uint8_t * p_buf) {
+    DisplayBase::rect_t rect;
+
+    rect.vs = 0;
+    rect.vw = LCD_PIXEL_HEIGHT;
+    rect.hs = 0;
+    rect.hw = LCD_PIXEL_WIDTH;
+    Display.Graphics_Read_Setting(
+        DisplayBase::GRAPHICS_LAYER_0,
+        (void *)p_buf,
+        FRAME_BUFFER_STRIDE,
+        GRAPHICS_FORMAT,
+        WR_RD_WRSWA,
+        &rect
+    );
+    Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
+}
+
+/****** Video ******/
+#if(0) /* When needing video Vsync interrupt, please make it effective. */
+static void IntCallbackFunc_ViVsync(DisplayBase::int_type_t int_type) {
+    /* Interrupt callback function for Vsync interruption */
+}
+#endif
+
+static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) {
+    /* Interrupt callback function */
+    if (vfield_count == 0) {
+        vfield_count = 1;
+    } else {
+        vfield_count = 0;
+        if (p_VideoLcdTask != NULL) {
+            p_VideoLcdTask->signal_set(1);
+        }
+    }
+}
+
+static void Init_Video(void) {
+    DisplayBase::graphics_error_t error;
+
+    /* Graphics initialization process */
+    if (graphics_init_end == false) {
+        /* When not initializing LCD, this processing is needed. */
+        error = Display.Graphics_init(NULL);
+        if (error != DisplayBase::GRAPHICS_OK) {
+            printf("Line %d, error %d\n", __LINE__, error);
+            mbed_die();
+        }
+        graphics_init_end = true;
+    }
+
+#if VIDEO_INPUT_METHOD == VIDEO_CVBS
+    error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC, NULL);
+    if( error != DisplayBase::GRAPHICS_OK ) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+#elif VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA
+    DisplayBase::video_ext_in_config_t ext_in_config;
+    PinName cmos_camera_pin[11] = {
+        /* data pin */
+        P2_7, P2_6, P2_5, P2_4, P2_3, P2_2, P2_1, P2_0,
+        /* control pin */
+        P10_0,      /* DV0_CLK   */
+        P1_0,       /* DV0_Vsync */
+        P1_1        /* DV0_Hsync */
+    };
+
+    /* MT9V111 camera input config */
+    ext_in_config.inp_format     = DisplayBase::VIDEO_EXTIN_FORMAT_BT601; /* BT601 8bit YCbCr format */
+    ext_in_config.inp_pxd_edge   = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing data          */
+    ext_in_config.inp_vs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Vsync signals */
+    ext_in_config.inp_hs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Hsync signals */
+    ext_in_config.inp_endian_on  = DisplayBase::OFF;                      /* External input bit endian change on/off       */
+    ext_in_config.inp_swap_on    = DisplayBase::OFF;                      /* External input B/R signal swap on/off         */
+    ext_in_config.inp_vs_inv     = DisplayBase::SIG_POL_NOT_INVERTED;     /* External input DV_VSYNC inversion control     */
+    ext_in_config.inp_hs_inv     = DisplayBase::SIG_POL_INVERTED;         /* External input DV_HSYNC inversion control     */
+    ext_in_config.inp_f525_625   = DisplayBase::EXTIN_LINE_525;           /* Number of lines for BT.656 external input */
+    ext_in_config.inp_h_pos      = DisplayBase::EXTIN_H_POS_CRYCBY;       /* Y/Cb/Y/Cr data string start timing to Hsync reference */
+    ext_in_config.cap_vs_pos     = 6;                                     /* Capture start position from Vsync */
+    ext_in_config.cap_hs_pos     = 150;                                   /* Capture start position form Hsync */
+#if (LCD_TYPE == 0)
+    /* The same screen ratio as the screen ratio of the LCD. */
+    ext_in_config.cap_width      = 640;                                   /* Capture width */
+    ext_in_config.cap_height     = 363;                                   /* Capture height Max 468[line]
+                                                                             Due to CMOS(MT9V111) output signal timing and VDC5 specification */
+#else
+    ext_in_config.cap_width      = 640;                                   /* Capture width  */
+    ext_in_config.cap_height     = 468u;                                  /* Capture height Max 468[line]
+                                                                             Due to CMOS(MT9V111) output signal timing and VDC5 specification */
+#endif
+    error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_EXT, &ext_in_config);
+    if( error != DisplayBase::GRAPHICS_OK ) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+
+    /* MT9V111 camera input port setting */
+    error = Display.Graphics_Dvinput_Port_Init(cmos_camera_pin, 11);
+    if( error != DisplayBase::GRAPHICS_OK ) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+#endif
+
+#if(0) /* When needing video Vsync interrupt, please make it effective. */
+    /* Interrupt callback function setting (Vsync signal input to scaler 0) */
+    error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VI_VSYNC, 0, IntCallbackFunc_ViVsync);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+#endif
+
+    /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */
+    error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE, 0, IntCallbackFunc_Vfield);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+}
+
+static void Start_Video(uint8_t * p_buf) {
+    DisplayBase::graphics_error_t error;
+
+    /* Video capture setting (progressive form fixed) */
+    error = Display.Video_Write_Setting(
+                VIDEO_INPUT_CH,
+                COL_SYS,
+                p_buf,
+                FRAME_BUFFER_STRIDE,
+                VIDEO_FORMAT,
+                WR_RD_WRSWA,
+                VIDEO_PIXEL_VW,
+                VIDEO_PIXEL_HW
+            );
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+
+    /* Video write process start */
+    error = Display.Video_Start(VIDEO_INPUT_CH);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+
+    /* Video write process stop */
+    error = Display.Video_Stop(VIDEO_INPUT_CH);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+
+    /* Video write process start */
+    error = Display.Video_Start(VIDEO_INPUT_CH);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+}
+
+/****** Video input is output to LCD ******/
+static void video_lcd_task(void const *) {
+    DisplayBase::graphics_error_t error;
+    int wk_num;
+    int i;
+
+    /* Initialization memory */
+    for (i = 0; i < FRAME_BUFFER_NUM; i++) {
+        memset(FrameBufferTbl[i], 0, (FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT));
+        dcache_clean(FrameBufferTbl[i], (FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT));
+    }
+
+    /* Start of Video */
+    Start_Video(FrameBufferTbl[write_buff_num]);
+
+    /* Wait for first video drawing */
+    Thread::signal_wait(1);
+    write_buff_num++;
+    if (write_buff_num >= FRAME_BUFFER_NUM) {
+        write_buff_num = 0;
+    }
+    error = Display.Video_Write_Change(VIDEO_INPUT_CH, FrameBufferTbl[write_buff_num], FRAME_BUFFER_STRIDE);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+
+    /* Start of LCD */
+    Start_LCD_Display(FrameBufferTbl[read_buff_num]);
+
+    /* Backlight on */
+    Thread::wait(200);
+    lcd_cntrst.write(1.0);
+
+    while (1) {
+        Thread::signal_wait(1);
+        wk_num = write_buff_num + 1;
+        if (wk_num >= FRAME_BUFFER_NUM) {
+            wk_num = 0;
+        }
+        /* If the next buffer is empty, it's changed. */
+        if (wk_num != read_buff_num) {
+            read_buff_num  = write_buff_num;
+            write_buff_num = wk_num;
+            /* Change video buffer */
+            error = Display.Video_Write_Change(VIDEO_INPUT_CH, FrameBufferTbl[write_buff_num], FRAME_BUFFER_STRIDE);
+            if (error != DisplayBase::GRAPHICS_OK) {
+                printf("Line %d, error %d\n", __LINE__, error);
+                mbed_die();
+            }
+            /* Change LCD buffer */
+            Display.Graphics_Read_Change(DisplayBase::GRAPHICS_LAYER_0, (void *)FrameBufferTbl[read_buff_num]);
+        }
+    }
+}
+
+/****** Touch panel ******/
+static void drow_touch_pos(uint8_t * p_buf, int id, int x, int y) {
+    int idx_base;
+    int wk_idx;
+    int i;
+    int j;
+    uint8_t coller_pix[TOUCH_BUFFER_BYTE_PER_PIXEL];  /* ARGB4444 */
+
+    /* A coordinate in the upper left is calculated from a central coordinate. */
+    if ((x - (DROW_POINT / 2)) >= 0) {
+        x -= (DROW_POINT / 2);
+    }
+    if (x > (LCD_PIXEL_WIDTH - DROW_POINT)) {
+        x = (LCD_PIXEL_WIDTH - DROW_POINT);
+    }
+    if ((y - (DROW_POINT / 2)) >= 0) {
+        y -= (DROW_POINT / 2);
+    }
+    if (y > (LCD_PIXEL_HEIGHT - DROW_POINT)) {
+        y = (LCD_PIXEL_HEIGHT - DROW_POINT);
+    }
+    idx_base = (x + (LCD_PIXEL_WIDTH * y)) * TOUCH_BUFFER_BYTE_PER_PIXEL;
+
+    /* Select color */
+    if (id == 0) {
+        /* Blue */
+        coller_pix[0] = 0x0F;  /* 4:Green 4:Blue */
+        coller_pix[1] = 0xF0;  /* 4:Alpha 4:Red  */
+    } else {
+        /* Pink */
+        coller_pix[0] = 0x07;  /* 4:Green 4:Blue */
+        coller_pix[1] = 0xFF;  /* 4:Alpha 4:Red  */
+    }
+
+    /* Drawing */
+    for (i = 0; i < DROW_POINT; i++) {
+        wk_idx = idx_base + (LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL * i);
+        for (j = 0; j < DROW_POINT; j++) {
+            p_buf[wk_idx++] = coller_pix[0];
+            p_buf[wk_idx++] = coller_pix[1];
+        }
+    }
+}
+
+static void drow_touch_keyonoff(uint8_t * p_buf, int id, bool onoff) {
+    int idx_base;
+    int wk_idx;
+    int i;
+    int j;
+    uint8_t coller_pix[TOUCH_BUFFER_BYTE_PER_PIXEL];  /* ARGB4444 */
+
+    /* Display position */
+    if (id == 0) {
+        idx_base = 0;
+    } else {
+        idx_base = DROW_POINT * TOUCH_BUFFER_BYTE_PER_PIXEL;
+    }
+
+    /* Select color */
+    if (onoff == false) {
+        /* Transparency */
+        coller_pix[0] = 0x00;  /* 4:Green 4:Blue */
+        coller_pix[1] = 0x00;  /* 4:Alpha 4:Red  */
+    } else {
+        /* White */
+        coller_pix[0] = 0xff;  /* 4:Green 4:Blue */
+        coller_pix[1] = 0xff;  /* 4:Alpha 4:Red  */
+    }
+
+    /* Drawing */
+    for (i = 0; i < DROW_POINT; i++) {
+        wk_idx = idx_base + (LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL * i);
+        for (j = 0; j < DROW_POINT; j++) {
+            p_buf[wk_idx++] = coller_pix[0];
+            p_buf[wk_idx++] = coller_pix[1];
+        }
+    }
+}
+
+static void touch_int_callback(void) {
+    sem_touch_int.release();
+}
+
+static void touch_task(void const *) {
+    DisplayBase::rect_t rect;
+    TouchKey::touch_pos_t touch_pos[TOUCH_NUM];
+    int touch_num = 0;
+    int touch_num_last = 0;
+    int i;
+
+    /* The layer by which the touch panel location is drawn */
+    memset(user_frame_buffer_touch, 0, sizeof(user_frame_buffer_touch));
+    dcache_clean(user_frame_buffer_touch, sizeof(user_frame_buffer_touch));
+    rect.vs = 0;
+    rect.vw = LCD_PIXEL_HEIGHT;
+    rect.hs = 0;
+    rect.hw = LCD_PIXEL_WIDTH;
+    Display.Graphics_Read_Setting(
+        DisplayBase::GRAPHICS_LAYER_1,
+        (void *)user_frame_buffer_touch,
+        TOUCH_BUFFER_STRIDE,
+        DisplayBase::GRAPHICS_FORMAT_ARGB4444,
+        DisplayBase::WR_RD_WRSWA_32_16BIT,
+        &rect
+    );
+    Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_1);
+
+    /* Callback setting */
+    touch.SetCallback(&touch_int_callback);
+
+    /* Reset touch IC */
+    touch.Reset();
+
+    while (1) {
+        /* Wait touch event */
+        sem_touch_int.wait();
+
+        /* Get touch coordinates */
+        touch_num = touch.GetCoordinates(TOUCH_NUM, touch_pos);
+
+        /* When it's a new touch, touch frame buffer is initialized */
+        if ((touch_num != 0) && (touch_num_last == 0)) {
+            memset(user_frame_buffer_touch, 0, sizeof(user_frame_buffer_touch));
+        }
+        touch_num_last = touch_num;
+
+        /* Drawing of a touch coordinate */
+        for (i = 0; i < TOUCH_NUM; i ++) {
+            printf("{valid=%d,x=%d,y=%d} ", touch_pos[i].valid, touch_pos[i].x, touch_pos[i].y);
+            drow_touch_keyonoff(user_frame_buffer_touch, i, touch_pos[i].valid);
+            if (touch_pos[i].valid) {
+                drow_touch_pos(user_frame_buffer_touch, i, touch_pos[i].x, touch_pos[i].y);
+            }
+        }
+        printf("\n");
+
+        /* Data cache clean */
+        dcache_clean(user_frame_buffer_touch, sizeof(user_frame_buffer_touch));
+    }
+}
+
+/****** main ******/
+int main(void) {
+    /* Change the baud rate of the printf() */
+    pc.baud(921600);
+
+    /* Initialization of LCD */
+    Init_LCD_Display();    /* When using LCD, please call before than Init_Video(). */
+
+    /* Initialization of Video */
+    Init_Video();
+
+    /* Start Video and Lcd processing */
+    p_VideoLcdTask = new Thread(video_lcd_task, NULL, osPriorityAboveNormal, 1024 * 4);
+
+    /* Start touch panel processing */
+    Thread touchTask(touch_task, NULL, osPriorityNormal, 1024 * 4);
+
+    while (1) {
+        led_blue = !led_blue;
+        Thread::wait(1000);
+    }
+}