michael kosinski / Mbed OS GR-PEACH_Video_Display

Dependencies:   AsciiFont GR-PEACH_video LCD_shield_config

Fork of GR-PEACH_Video_Display by Daiki Kato

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "DisplayBace.h"
00003 #include "rtos.h"
00004 #include "AsciiFont.h"
00005 
00006 #define VIDEO_CVBS             (0)                 /* Analog  Video Signal */
00007 #define VIDEO_CMOS_CAMERA      (1)                 /* Digital Video Signal */
00008 #define VIDEO_YCBCR422         (0)
00009 #define VIDEO_RGB888           (1)
00010 #define VIDEO_RGB565           (2)
00011 
00012 /**** User Selection *********/
00013 /** Camera setting **/
00014 #define VIDEO_INPUT_METHOD     (VIDEO_CVBS) /* Select  VIDEO_CVBS or VIDEO_CMOS_CAMERA                       */
00015 #define VIDEO_INPUT_FORMAT     (VIDEO_YCBCR422)    /* Select  VIDEO_YCBCR422 or VIDEO_RGB888 or VIDEO_RGB565        */
00016 #define USE_VIDEO_CH           (0)                 /* Select  0 or 1            If selecting VIDEO_CMOS_CAMERA, should be 0.)               */
00017 #define VIDEO_PAL              (0)                 /* Select  0(NTSC) or 1(PAL) If selecting VIDEO_CVBS, this parameter is not referenced.) */
00018 /** LCD setting **/
00019 #define LCD_TYPE               (0)                 /* Select  0(4.3inch) or 1(7.1inch) */
00020 /*****************************/
00021 
00022 /** LCD shield config **/
00023 #if (LCD_TYPE == 0)
00024   #include "LCD_shield_config_4_3inch.h"
00025 #else
00026   #include "LCD_shield_config_7_1inch.h"
00027 #endif
00028 
00029 /** Video and Grapics (GRAPHICS_LAYER_0) parameter **/
00030 /* video input */
00031 #if USE_VIDEO_CH == (0)
00032   #define VIDEO_INPUT_CH       (DisplayBase::VIDEO_INPUT_CHANNEL_0)
00033   #define VIDEO_INT_TYPE       (DisplayBase::INT_TYPE_S0_VFIELD)
00034 #else
00035   #define VIDEO_INPUT_CH       (DisplayBase::VIDEO_INPUT_CHANNEL_1)
00036   #define VIDEO_INT_TYPE       (DisplayBase::INT_TYPE_S1_VFIELD)
00037 #endif
00038 
00039 /* NTSC or PAL */
00040 #if VIDEO_PAL == 0
00041   #define COL_SYS              (DisplayBase::COL_SYS_NTSC_358)
00042 #else
00043   #define COL_SYS              (DisplayBase::COL_SYS_PAL_443)
00044 #endif
00045 
00046 /* Video input and LCD layer 0 output */
00047 #if VIDEO_INPUT_FORMAT == VIDEO_YCBCR422
00048   #define VIDEO_FORMAT         (DisplayBase::VIDEO_FORMAT_YCBCR422)
00049   #define GRAPHICS_FORMAT      (DisplayBase::GRAPHICS_FORMAT_YCBCR422)
00050   #define WR_RD_WRSWA          (DisplayBase::WR_RD_WRSWA_NON)
00051 #elif VIDEO_INPUT_FORMAT == VIDEO_RGB565
00052   #define VIDEO_FORMAT         (DisplayBase::VIDEO_FORMAT_RGB565)
00053   #define GRAPHICS_FORMAT      (DisplayBase::GRAPHICS_FORMAT_RGB565)
00054   #define WR_RD_WRSWA          (DisplayBase::WR_RD_WRSWA_32_16BIT)
00055 #else
00056   #define VIDEO_FORMAT         (DisplayBase::VIDEO_FORMAT_RGB888)
00057   #define GRAPHICS_FORMAT      (DisplayBase::GRAPHICS_FORMAT_RGB888)
00058   #define WR_RD_WRSWA          (DisplayBase::WR_RD_WRSWA_32BIT)
00059 #endif
00060 
00061 /* The size of the video input is adjusted to the LCD size. */
00062 #define VIDEO_PIXEL_HW                LCD_PIXEL_WIDTH
00063 #define VIDEO_PIXEL_VW                LCD_PIXEL_HEIGHT
00064 
00065 /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128
00066     in accordance with the frame buffer burst transfer mode. */
00067 /* FRAME BUFFER Parameter GRAPHICS_LAYER_0 */
00068 #define FRAME_BUFFER_NUM              (3u)
00069 #if ( VIDEO_INPUT_FORMAT == VIDEO_YCBCR422 || VIDEO_INPUT_FORMAT == VIDEO_RGB565 )
00070   #define FRAME_BUFFER_BYTE_PER_PIXEL (2u)
00071 #else
00072   #define FRAME_BUFFER_BYTE_PER_PIXEL (4u)
00073 #endif
00074 #define FRAME_BUFFER_STRIDE           (((LCD_PIXEL_WIDTH * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
00075 
00076 /* TOUCH BUFFER Parameter GRAPHICS_LAYER_1 */
00077 #define TOUCH_BUFFER_BYTE_PER_PIXEL   (2u)
00078 #define TOUCH_BUFFER_STRIDE           (((LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
00079 
00080 /* Touch panel parameter */
00081 #define TOUCH_NUM                     (2u)
00082 #define DRAW_POINT                    (5)
00083 
00084 /* STRING BUFFER Parameter GRAPHICS_LAYER_2 */
00085 #define STRING_PIXEL_HW               (120)
00086 #define STRING_PIXEL_VM               (24)
00087 #define STRING_BUFFER_BYTE_PER_PIXEL  (2u)
00088 #define STRING_BUFFER_STRIDE          (((LCD_PIXEL_WIDTH * STRING_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
00089 
00090 static DisplayBase Display;
00091 static DigitalOut  lcd_pwon(P7_15);
00092 static DigitalOut  lcd_blon(P8_1);
00093 static PwmOut      lcd_cntrst(P8_15);
00094 static Serial      pc(USBTX, USBRX);
00095 static Semaphore   sem_touch_int(0);
00096 static TouckKey_LCD_shield touch(P4_0, P2_13, I2C_SDA, I2C_SCL);
00097 static Thread *    p_VideoLcdTask = NULL;
00098 static DigitalOut  led_blue(LED_BLUE);
00099 
00100 #if defined(__ICCARM__)
00101 /* 32 bytes aligned */
00102 #pragma data_alignment=32
00103 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
00104 #pragma data_alignment=32
00105 static uint8_t user_frame_buffer1[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
00106 #pragma data_alignment=32
00107 static uint8_t user_frame_buffer2[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
00108 #pragma data_alignment=32
00109 static uint8_t user_frame_buffer_touch[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
00110 #pragma data_alignment=32
00111 static uint8_t user_frame_buffer_string[STRING_BUFFER_STRIDE * STRING_PIXEL_VM];
00112 #else
00113 /* 32 bytes aligned */
00114 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
00115 static uint8_t user_frame_buffer1[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
00116 static uint8_t user_frame_buffer2[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
00117 static uint8_t user_frame_buffer_touch[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
00118 static uint8_t user_frame_buffer_string[STRING_BUFFER_STRIDE * STRING_PIXEL_VM]__attribute((aligned(32)));
00119 #endif
00120 static uint8_t * FrameBufferTbl[FRAME_BUFFER_NUM] = {user_frame_buffer0, user_frame_buffer1, user_frame_buffer2};
00121 #if VIDEO_INPUT_METHOD == VIDEO_CVBS
00122 static volatile int32_t vfield_count = 0;
00123 #endif
00124 static int write_buff_num = 0;
00125 static int read_buff_num = 0;
00126 static bool graphics_init_end = false;
00127 
00128 /****** cache control ******/
00129 static void dcache_clean(void * p_buf, uint32_t size) {
00130     uint32_t start_addr = (uint32_t)p_buf & 0xFFFFFFE0;
00131     uint32_t end_addr   = (uint32_t)p_buf + size;
00132     uint32_t addr;
00133 
00134     /* Data cache clean */
00135     for (addr = start_addr; addr < end_addr; addr += 0x20) {
00136         __v7_clean_dcache_mva((void *)addr);
00137     }
00138 }
00139 
00140 /****** LCD ******/
00141 #if(0) /* When needing LCD Vsync interrupt, please make it effective. */
00142 static void IntCallbackFunc_LoVsync(DisplayBase::int_type_t int_type) {
00143     /* Interrupt callback function for Vsync interruption */
00144 }
00145 #endif
00146 
00147 static void Init_LCD_Display(void) {
00148     DisplayBase::graphics_error_t error;
00149     DisplayBase::lcd_config_t lcd_config;
00150     PinName lvds_pin[8] = {
00151         /* data pin */
00152         P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0
00153     };
00154 
00155     lcd_pwon = 0;
00156     lcd_blon = 0;
00157     Thread::wait(100);
00158     lcd_pwon = 1;
00159     lcd_blon = 1;
00160 
00161     Display.Graphics_Lvds_Port_Init(lvds_pin, 8);
00162 
00163     /* Graphics initialization process */
00164     lcd_config = LcdCfgTbl_LCD_shield;
00165     error = Display.Graphics_init(&lcd_config);
00166     if (error != DisplayBase::GRAPHICS_OK) {
00167         printf("Line %d, error %d\n", __LINE__, error);
00168         mbed_die();
00169     }
00170     graphics_init_end = true;
00171 
00172 #if(0) /* When needing LCD Vsync interrupt, please make it effective. */
00173     /* Interrupt callback function setting (Vsync signal output from scaler 0) */
00174     error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_LO_VSYNC, 0, IntCallbackFunc_LoVsync);
00175     if (error != DisplayBase::GRAPHICS_OK) {
00176         printf("Line %d, error %d\n", __LINE__, error);
00177         mbed_die();
00178     }
00179 #endif
00180 }
00181 
00182 static void Start_LCD_Display(uint8_t * p_buf) {
00183     DisplayBase::rect_t rect;
00184 
00185     rect.vs = 0;
00186     rect.vw = LCD_PIXEL_HEIGHT;
00187     rect.hs = 0;
00188     rect.hw = LCD_PIXEL_WIDTH;
00189     Display.Graphics_Read_Setting(
00190         DisplayBase::GRAPHICS_LAYER_0,
00191         (void *)p_buf,
00192         FRAME_BUFFER_STRIDE,
00193         GRAPHICS_FORMAT,
00194         WR_RD_WRSWA,
00195         &rect
00196     );
00197     Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
00198 }
00199 
00200 /****** Video ******/
00201 #if(0) /* When needing video Vsync interrupt, please make it effective. */
00202 static void IntCallbackFunc_ViVsync(DisplayBase::int_type_t int_type) {
00203     /* Interrupt callback function for Vsync interruption */
00204 }
00205 #endif
00206 
00207 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) {
00208     /* Interrupt callback function */
00209 #if VIDEO_INPUT_METHOD == VIDEO_CVBS
00210     if (vfield_count == 0) {
00211         vfield_count = 1;
00212     } else {
00213         vfield_count = 0;
00214 #else
00215     {
00216 #endif
00217         if (p_VideoLcdTask != NULL) {
00218             p_VideoLcdTask->signal_set(1);
00219         }
00220     }
00221 }
00222 
00223 static void Init_Video(void) {
00224     DisplayBase::graphics_error_t error;
00225 
00226     /* Graphics initialization process */
00227     if (graphics_init_end == false) {
00228         /* When not initializing LCD, this processing is needed. */
00229         error = Display.Graphics_init(NULL);
00230         if (error != DisplayBase::GRAPHICS_OK) {
00231             printf("Line %d, error %d\n", __LINE__, error);
00232             mbed_die();
00233         }
00234         graphics_init_end = true;
00235     }
00236 
00237 #if VIDEO_INPUT_METHOD == VIDEO_CVBS
00238     error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC, NULL);
00239     if( error != DisplayBase::GRAPHICS_OK ) {
00240         printf("Line %d, error %d\n", __LINE__, error);
00241         mbed_die();
00242     }
00243 #elif VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA
00244     DisplayBase::video_ext_in_config_t ext_in_config;
00245     PinName cmos_camera_pin[11] = {
00246         /* data pin */
00247         P2_7, P2_6, P2_5, P2_4, P2_3, P2_2, P2_1, P2_0,
00248         /* control pin */
00249         P10_0,      /* DV0_CLK   */
00250         P1_0,       /* DV0_Vsync */
00251         P1_1        /* DV0_Hsync */
00252     };
00253 
00254     /* MT9V111 camera input config */
00255     ext_in_config.inp_format     = DisplayBase::VIDEO_EXTIN_FORMAT_BT601; /* BT601 8bit YCbCr format */
00256     ext_in_config.inp_pxd_edge   = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing data          */
00257     ext_in_config.inp_vs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Vsync signals */
00258     ext_in_config.inp_hs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Hsync signals */
00259     ext_in_config.inp_endian_on  = DisplayBase::OFF;                      /* External input bit endian change on/off       */
00260     ext_in_config.inp_swap_on    = DisplayBase::OFF;                      /* External input B/R signal swap on/off         */
00261     ext_in_config.inp_vs_inv     = DisplayBase::SIG_POL_NOT_INVERTED;     /* External input DV_VSYNC inversion control     */
00262     ext_in_config.inp_hs_inv     = DisplayBase::SIG_POL_INVERTED;         /* External input DV_HSYNC inversion control     */
00263     ext_in_config.inp_f525_625   = DisplayBase::EXTIN_LINE_525;           /* Number of lines for BT.656 external input */
00264     ext_in_config.inp_h_pos      = DisplayBase::EXTIN_H_POS_CRYCBY;       /* Y/Cb/Y/Cr data string start timing to Hsync reference */
00265     ext_in_config.cap_vs_pos     = 6;                                     /* Capture start position from Vsync */
00266     ext_in_config.cap_hs_pos     = 150;                                   /* Capture start position form Hsync */
00267 #if (LCD_TYPE == 0)
00268     /* The same screen ratio as the screen ratio of the LCD. */
00269     ext_in_config.cap_width      = 640;                                   /* Capture width */
00270     ext_in_config.cap_height     = 363;                                   /* Capture height Max 468[line]
00271                                                                              Due to CMOS(MT9V111) output signal timing and VDC5 specification */
00272 #else
00273     ext_in_config.cap_width      = 640;                                   /* Capture width  */
00274     ext_in_config.cap_height     = 468;                                   /* Capture height Max 468[line]
00275                                                                              Due to CMOS(MT9V111) output signal timing and VDC5 specification */
00276 #endif
00277     error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_EXT, &ext_in_config);
00278     if( error != DisplayBase::GRAPHICS_OK ) {
00279         printf("Line %d, error %d\n", __LINE__, error);
00280         mbed_die();
00281     }
00282 
00283     /* Camera input port setting */
00284     error = Display.Graphics_Dvinput_Port_Init(cmos_camera_pin, 11);
00285     if( error != DisplayBase::GRAPHICS_OK ) {
00286         printf("Line %d, error %d\n", __LINE__, error);
00287         mbed_die();
00288     }
00289 #endif
00290 
00291 #if(0) /* When needing video Vsync interrupt, please make it effective. */
00292     /* Interrupt callback function setting (Vsync signal input to scaler 0) */
00293     error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VI_VSYNC, 0, IntCallbackFunc_ViVsync);
00294     if (error != DisplayBase::GRAPHICS_OK) {
00295         printf("Line %d, error %d\n", __LINE__, error);
00296         mbed_die();
00297     }
00298 #endif
00299 
00300     /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */
00301     error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE, 0, IntCallbackFunc_Vfield);
00302     if (error != DisplayBase::GRAPHICS_OK) {
00303         printf("Line %d, error %d\n", __LINE__, error);
00304         mbed_die();
00305     }
00306 }
00307 
00308 static void Start_Video(uint8_t * p_buf) {
00309     DisplayBase::graphics_error_t error;
00310 
00311     /* Video capture setting (progressive form fixed) */
00312     error = Display.Video_Write_Setting(
00313                 VIDEO_INPUT_CH,
00314                 COL_SYS,
00315                 p_buf,
00316                 FRAME_BUFFER_STRIDE,
00317                 VIDEO_FORMAT,
00318                 WR_RD_WRSWA,
00319                 VIDEO_PIXEL_VW,
00320                 VIDEO_PIXEL_HW
00321             );
00322     if (error != DisplayBase::GRAPHICS_OK) {
00323         printf("Line %d, error %d\n", __LINE__, error);
00324         mbed_die();
00325     }
00326 
00327     /* Video write process start */
00328     error = Display.Video_Start(VIDEO_INPUT_CH);
00329     if (error != DisplayBase::GRAPHICS_OK) {
00330         printf("Line %d, error %d\n", __LINE__, error);
00331         mbed_die();
00332     }
00333 
00334     /* Video write process stop */
00335     error = Display.Video_Stop(VIDEO_INPUT_CH);
00336     if (error != DisplayBase::GRAPHICS_OK) {
00337         printf("Line %d, error %d\n", __LINE__, error);
00338         mbed_die();
00339     }
00340 
00341     /* Video write process start */
00342     error = Display.Video_Start(VIDEO_INPUT_CH);
00343     if (error != DisplayBase::GRAPHICS_OK) {
00344         printf("Line %d, error %d\n", __LINE__, error);
00345         mbed_die();
00346     }
00347 }
00348 
00349 /****** Video input is output to LCD ******/
00350 static void video_lcd_task(void) {
00351     DisplayBase::graphics_error_t error;
00352     int wk_num;
00353     int i;
00354 
00355     /* Initialization memory */
00356     for (i = 0; i < FRAME_BUFFER_NUM; i++) {
00357         memset(FrameBufferTbl[i], 0, (FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT));
00358         dcache_clean(FrameBufferTbl[i], (FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT));
00359     }
00360 
00361     /* Start of Video */
00362     Start_Video(FrameBufferTbl[write_buff_num]);
00363 
00364     /* Wait for first video drawing */
00365     Thread::signal_wait(1);
00366     write_buff_num++;
00367     if (write_buff_num >= FRAME_BUFFER_NUM) {
00368         write_buff_num = 0;
00369     }
00370     error = Display.Video_Write_Change(VIDEO_INPUT_CH, FrameBufferTbl[write_buff_num], FRAME_BUFFER_STRIDE);
00371     if (error != DisplayBase::GRAPHICS_OK) {
00372         printf("Line %d, error %d\n", __LINE__, error);
00373         mbed_die();
00374     }
00375 
00376     /* Start of LCD */
00377     Start_LCD_Display(FrameBufferTbl[read_buff_num]);
00378 
00379     /* Backlight on */
00380     Thread::wait(200);
00381     lcd_cntrst.write(1.0);
00382 
00383     while (1) {
00384         Thread::signal_wait(1);
00385         wk_num = write_buff_num + 1;
00386         if (wk_num >= FRAME_BUFFER_NUM) {
00387             wk_num = 0;
00388         }
00389         /* If the next buffer is empty, it's changed. */
00390         if (wk_num != read_buff_num) {
00391             read_buff_num  = write_buff_num;
00392             write_buff_num = wk_num;
00393             /* Change video buffer */
00394             error = Display.Video_Write_Change(VIDEO_INPUT_CH, FrameBufferTbl[write_buff_num], FRAME_BUFFER_STRIDE);
00395             if (error != DisplayBase::GRAPHICS_OK) {
00396                 printf("Line %d, error %d\n", __LINE__, error);
00397                 mbed_die();
00398             }
00399             /* Change LCD buffer */
00400             Display.Graphics_Read_Change(DisplayBase::GRAPHICS_LAYER_0, (void *)FrameBufferTbl[read_buff_num]);
00401         }
00402     }
00403 }
00404 
00405 /****** Touch panel ******/
00406 static void draw_touch_pos(uint8_t * p_buf, int id, int x, int y) {
00407     int idx_base;
00408     int wk_idx;
00409     int i;
00410     int j;
00411     uint8_t coller_pix[TOUCH_BUFFER_BYTE_PER_PIXEL];  /* ARGB4444 */
00412 
00413     /* A coordinate in the upper left is calculated from a central coordinate. */
00414     if ((x - (DRAW_POINT / 2)) >= 0) {
00415         x -= (DRAW_POINT / 2);
00416     }
00417     if (x > (LCD_PIXEL_WIDTH - DRAW_POINT)) {
00418         x = (LCD_PIXEL_WIDTH - DRAW_POINT);
00419     }
00420     if ((y - (DRAW_POINT / 2)) >= 0) {
00421         y -= (DRAW_POINT / 2);
00422     }
00423     if (y > (LCD_PIXEL_HEIGHT - DRAW_POINT)) {
00424         y = (LCD_PIXEL_HEIGHT - DRAW_POINT);
00425     }
00426     idx_base = (x + (LCD_PIXEL_WIDTH * y)) * TOUCH_BUFFER_BYTE_PER_PIXEL;
00427 
00428     /* Select color */
00429     if (id == 0) {
00430         /* Blue */
00431         coller_pix[0] = 0x0F;  /* 4:Green 4:Blue */
00432         coller_pix[1] = 0xF0;  /* 4:Alpha 4:Red  */
00433     } else {
00434         /* Pink */
00435         coller_pix[0] = 0x07;  /* 4:Green 4:Blue */
00436         coller_pix[1] = 0xFF;  /* 4:Alpha 4:Red  */
00437     }
00438 
00439     /* Drawing */
00440     for (i = 0; i < DRAW_POINT; i++) {
00441         wk_idx = idx_base + (LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL * i);
00442         for (j = 0; j < DRAW_POINT; j++) {
00443             p_buf[wk_idx++] = coller_pix[0];
00444             p_buf[wk_idx++] = coller_pix[1];
00445         }
00446     }
00447 }
00448 
00449 static void draw_touch_keyonoff(uint8_t * p_buf, int id, bool onoff) {
00450     int idx_base;
00451     int wk_idx;
00452     int i;
00453     int j;
00454     uint8_t coller_pix[TOUCH_BUFFER_BYTE_PER_PIXEL];  /* ARGB4444 */
00455 
00456     /* Display position */
00457     if (id == 0) {
00458         idx_base = 0;
00459     } else {
00460         idx_base = DRAW_POINT * TOUCH_BUFFER_BYTE_PER_PIXEL;
00461     }
00462 
00463     /* Select color */
00464     if (onoff == false) {
00465         /* Transparency */
00466         coller_pix[0] = 0x00;  /* 4:Green 4:Blue */
00467         coller_pix[1] = 0x00;  /* 4:Alpha 4:Red  */
00468     } else {
00469         /* White */
00470         coller_pix[0] = 0xff;  /* 4:Green 4:Blue */
00471         coller_pix[1] = 0xff;  /* 4:Alpha 4:Red  */
00472     }
00473 
00474     /* Drawing */
00475     for (i = 0; i < DRAW_POINT; i++) {
00476         wk_idx = idx_base + (LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL * i);
00477         for (j = 0; j < DRAW_POINT; j++) {
00478             p_buf[wk_idx++] = coller_pix[0];
00479             p_buf[wk_idx++] = coller_pix[1];
00480         }
00481     }
00482 }
00483 
00484 static void touch_int_callback(void) {
00485     sem_touch_int.release();
00486 }
00487 
00488 static void touch_task(void) {
00489     DisplayBase::rect_t rect;
00490     TouchKey::touch_pos_t touch_pos[TOUCH_NUM];
00491     int touch_num = 0;
00492     int touch_num_last = 0;
00493     int i;
00494 
00495     /* The layer by which the touch panel location is drawn */
00496     memset(user_frame_buffer_touch, 0, sizeof(user_frame_buffer_touch));
00497     dcache_clean(user_frame_buffer_touch, sizeof(user_frame_buffer_touch));
00498     rect.vs = 0;
00499     rect.vw = LCD_PIXEL_HEIGHT;
00500     rect.hs = 0;
00501     rect.hw = LCD_PIXEL_WIDTH;
00502     Display.Graphics_Read_Setting(
00503         DisplayBase::GRAPHICS_LAYER_1,
00504         (void *)user_frame_buffer_touch,
00505         TOUCH_BUFFER_STRIDE,
00506         DisplayBase::GRAPHICS_FORMAT_ARGB4444,
00507         DisplayBase::WR_RD_WRSWA_32_16BIT,
00508         &rect
00509     );
00510     Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_1);
00511 
00512     /* Callback setting */
00513     touch.SetCallback(&touch_int_callback);
00514 
00515     /* Reset touch IC */
00516     touch.Reset();
00517 
00518     while (1) {
00519         /* Wait touch event */
00520         sem_touch_int.wait();
00521 
00522         /* Get touch coordinates */
00523         touch_num = touch.GetCoordinates(TOUCH_NUM, touch_pos);
00524 
00525         /* When it's a new touch, touch frame buffer is initialized */
00526         if ((touch_num != 0) && (touch_num_last == 0)) {
00527             memset(user_frame_buffer_touch, 0, sizeof(user_frame_buffer_touch));
00528         }
00529         touch_num_last = touch_num;
00530 
00531         /* Drawing of a touch coordinate */
00532         for (i = 0; i < TOUCH_NUM; i ++) {
00533             printf("{valid=%d,x=%d,y=%d} ", touch_pos[i].valid, touch_pos[i].x, touch_pos[i].y);
00534             draw_touch_keyonoff(user_frame_buffer_touch, i, touch_pos[i].valid);
00535             if (touch_pos[i].valid) {
00536                 draw_touch_pos(user_frame_buffer_touch, i, touch_pos[i].x, touch_pos[i].y);
00537             }
00538         }
00539         printf("\n");
00540 
00541         /* Data cache clean */
00542         dcache_clean(user_frame_buffer_touch, sizeof(user_frame_buffer_touch));
00543     }
00544 }
00545 
00546 /****** main ******/
00547 int main(void) {
00548     DisplayBase::rect_t rect;
00549     char test_cnt = 0x20;
00550 
00551     /* Change the baud rate of the printf() */
00552     pc.baud(921600);
00553 
00554     /* Initialization of LCD */
00555     Init_LCD_Display();    /* When using LCD, please call before than Init_Video(). */
00556 
00557     /* Initialization of Video */
00558     Init_Video();
00559 
00560     /* Start Video and Lcd processing */
00561     p_VideoLcdTask = new Thread;
00562     p_VideoLcdTask->start(video_lcd_task);
00563 
00564     /* Start touch panel processing */
00565     Thread touchTask;
00566     touchTask.start(touch_task);
00567 
00568     /* The layer by which the character string is drawn */
00569     memset(user_frame_buffer_string, 0, sizeof(user_frame_buffer_string));
00570     dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string));
00571     rect.vs = LCD_PIXEL_HEIGHT - STRING_PIXEL_VM - 10;
00572     rect.vw = STRING_PIXEL_VM;
00573     rect.hs = LCD_PIXEL_WIDTH - STRING_PIXEL_HW - 10;
00574     rect.hw = STRING_PIXEL_HW;
00575     Display.Graphics_Read_Setting(
00576         DisplayBase::GRAPHICS_LAYER_2,
00577         (void *)user_frame_buffer_string,
00578         STRING_BUFFER_STRIDE,
00579         DisplayBase::GRAPHICS_FORMAT_ARGB4444,
00580         DisplayBase::WR_RD_WRSWA_32_16BIT,
00581         &rect
00582     );
00583     Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_2);
00584 
00585     /* String */
00586     AsciiFont ascii_font(user_frame_buffer_string, STRING_PIXEL_HW, STRING_PIXEL_VM,
00587                          STRING_BUFFER_STRIDE, STRING_BUFFER_BYTE_PER_PIXEL);
00588     ascii_font.DrawStr("Font:", 0, 8, 0x0000ffff, 2);
00589     while (1) {
00590         led_blue = !led_blue;
00591         //colour: rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red
00592         ascii_font.DrawChar(test_cnt, 84, 0, 0x0000aa9f, 3);
00593         if (test_cnt < 0x7e) {
00594             test_cnt++;
00595         } else {
00596             test_cnt = 0x20;
00597         }
00598         dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string));
00599         Thread::wait(1000);
00600     }
00601 }