Daiki Kato / Mbed OS GR-PEACH_Video_Display
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "dcache-control.h"
00003 #include "EasyAttach_CameraAndLCD.h"
00004 #include "AsciiFont.h"
00005 
00006 #define STRING_DISP_TEST       (1)
00007 
00008 #if (MBED_CONF_APP_LCD_TYPE == GR_PEACH_4_3INCH_SHIELD)
00009 #define ASPECT_RATIO_16_9      (1)
00010 #endif
00011 
00012 static DisplayBase Display;
00013 
00014 /************************** Camera **************************/
00015 #if MBED_CONF_APP_CAMERA
00016 /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128
00017     in accordance with the frame buffer burst transfer mode. */
00018 #define DATA_SIZE_PER_PIC      (2u)
00019 #define FRAME_BUFFER_STRIDE    (((LCD_PIXEL_WIDTH * DATA_SIZE_PER_PIC) + 31u) & ~31u)
00020 #define FRAME_BUFFER_HEIGHT    (LCD_PIXEL_HEIGHT)
00021 
00022 #if defined(__ICCARM__)
00023 #pragma data_alignment=32
00024 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram";
00025 #else
00026 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32)));
00027 #endif
00028 
00029 static void Start_Video_Camera(void) {
00030     DisplayBase::rect_t rect;
00031 
00032     // Initialize the background to black
00033     for (uint32_t i = 0; i < sizeof(user_frame_buffer0); i += 2) {
00034         user_frame_buffer0[i + 0] = 0x00;
00035         user_frame_buffer0[i + 1] = 0x80;
00036     }
00037 
00038     // Video capture setting (progressive form fixed)
00039     Display.Video_Write_Setting(
00040         DisplayBase::VIDEO_INPUT_CHANNEL_0,
00041         DisplayBase::COL_SYS_NTSC_358,
00042         (void *)user_frame_buffer0,
00043         FRAME_BUFFER_STRIDE,
00044         DisplayBase::VIDEO_FORMAT_YCBCR422,
00045         DisplayBase::WR_RD_WRSWA_32_16BIT,
00046         LCD_PIXEL_HEIGHT,
00047         LCD_PIXEL_WIDTH
00048     );
00049     EasyAttach_CameraStart(Display, DisplayBase::VIDEO_INPUT_CHANNEL_0);
00050 
00051     // LCD setting
00052     rect.vs = 0;
00053     rect.vw = LCD_PIXEL_HEIGHT;
00054     rect.hs = 0;
00055     rect.hw = LCD_PIXEL_WIDTH;
00056     Display.Graphics_Read_Setting(
00057         DisplayBase::GRAPHICS_LAYER_0,
00058         (void *)user_frame_buffer0,
00059         FRAME_BUFFER_STRIDE,
00060         DisplayBase::GRAPHICS_FORMAT_YCBCR422,
00061         DisplayBase::WR_RD_WRSWA_32_16BIT,
00062         &rect
00063     );
00064     Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
00065 }
00066 #endif // MBED_CONF_APP_CAMERA
00067 
00068 
00069 /************************** Touch panel **************************/
00070 #if defined(TouckKey_LCD_shield)
00071 /* TOUCH BUFFER Parameter GRAPHICS_LAYER_1 */
00072 #define TOUCH_BUFFER_BYTE_PER_PIXEL   (2u)
00073 #define TOUCH_BUFFER_STRIDE           (((LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
00074 /* Touch panel parameter */
00075 #define TOUCH_NUM                     (2u)
00076 #define DRAW_POINT                    (8)
00077 
00078 static Semaphore   sem_touch_int(0);
00079 #if defined(__ICCARM__)
00080 #pragma data_alignment=32
00081 static uint8_t user_frame_buffer_touch[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
00082 #else
00083 static uint8_t user_frame_buffer_touch[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
00084 #endif
00085 
00086 static void draw_touch_pos(uint8_t * p_buf, int id, int x, int y) {
00087     int idx_base;
00088     int wk_idx;
00089     int i;
00090     int j;
00091     uint8_t coller_pix[TOUCH_BUFFER_BYTE_PER_PIXEL];  /* ARGB4444 */
00092 
00093     /* A coordinate in the upper left is calculated from a central coordinate. */
00094     if ((x - (DRAW_POINT / 2)) >= 0) {
00095         x -= (DRAW_POINT / 2);
00096     }
00097     if (x > ((int)LCD_PIXEL_WIDTH - DRAW_POINT)) {
00098         x = ((int)LCD_PIXEL_WIDTH - DRAW_POINT);
00099     }
00100     if ((y - (DRAW_POINT / 2)) >= 0) {
00101         y -= (DRAW_POINT / 2);
00102     }
00103     if (y > ((int)LCD_PIXEL_HEIGHT - DRAW_POINT)) {
00104         y = ((int)LCD_PIXEL_HEIGHT - DRAW_POINT);
00105     }
00106     idx_base = (x + ((int)LCD_PIXEL_WIDTH * y)) * TOUCH_BUFFER_BYTE_PER_PIXEL;
00107 
00108     /* Select color */
00109     if (id == 0) {
00110         /* Blue */
00111         coller_pix[0] = 0x0F;  /* 4:Green 4:Blue */
00112         coller_pix[1] = 0xF0;  /* 4:Alpha 4:Red  */
00113     } else {
00114         /* Pink */
00115         coller_pix[0] = 0x07;  /* 4:Green 4:Blue */
00116         coller_pix[1] = 0xFF;  /* 4:Alpha 4:Red  */
00117     }
00118 
00119     /* Drawing */
00120     for (i = 0; i < DRAW_POINT; i++) {
00121         wk_idx = idx_base + ((int)LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL * i);
00122         for (j = 0; j < DRAW_POINT; j++) {
00123             p_buf[wk_idx++] = coller_pix[0];
00124             p_buf[wk_idx++] = coller_pix[1];
00125         }
00126     }
00127 }
00128 
00129 static void touch_int_callback(void) {
00130     sem_touch_int.release();
00131 }
00132 
00133 static void touch_task(void) {
00134     DisplayBase::rect_t rect;
00135     TouchKey::touch_pos_t touch_pos[TOUCH_NUM];
00136     int touch_num = 0;
00137     int touch_num_last = 0;
00138     uint32_t i;
00139     TouckKey_LCD_shield touch(P4_0, P2_13, I2C_SDA, I2C_SCL);
00140 
00141     /* The layer by which the touch panel location is drawn */
00142     memset(user_frame_buffer_touch, 0, sizeof(user_frame_buffer_touch));
00143     dcache_clean(user_frame_buffer_touch, sizeof(user_frame_buffer_touch));
00144     rect.vs = 0;
00145     rect.vw = LCD_PIXEL_HEIGHT;
00146     rect.hs = 0;
00147     rect.hw = LCD_PIXEL_WIDTH;
00148     Display.Graphics_Read_Setting(
00149         DisplayBase::GRAPHICS_LAYER_1,
00150         (void *)user_frame_buffer_touch,
00151         TOUCH_BUFFER_STRIDE,
00152         DisplayBase::GRAPHICS_FORMAT_ARGB4444,
00153         DisplayBase::WR_RD_WRSWA_32_16BIT,
00154         &rect
00155     );
00156     Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_1);
00157 
00158     /* Callback setting */
00159     touch.SetCallback(&touch_int_callback);
00160 
00161     /* Reset touch IC */
00162     touch.Reset();
00163 
00164     while (1) {
00165         /* Wait touch event */
00166         sem_touch_int.wait();
00167 
00168         /* Get touch coordinates */
00169         touch_num = touch.GetCoordinates(TOUCH_NUM, touch_pos);
00170 
00171         /* When it's a new touch, touch frame buffer is initialized */
00172         if ((touch_num != 0) && (touch_num_last == 0)) {
00173             memset(user_frame_buffer_touch, 0, sizeof(user_frame_buffer_touch));
00174         }
00175         touch_num_last = touch_num;
00176 
00177         /* Drawing of a touch coordinate */
00178         for (i = 0; i < TOUCH_NUM; i ++) {
00179             printf("{valid=%d,x=%lu,y=%lu} ", touch_pos[i].valid, touch_pos[i].x, touch_pos[i].y);
00180             if (touch_pos[i].valid) {
00181                 draw_touch_pos(user_frame_buffer_touch, i, touch_pos[i].x, touch_pos[i].y);
00182             }
00183         }
00184         printf("\r\n");
00185 
00186         /* Data cache clean */
00187         dcache_clean(user_frame_buffer_touch, sizeof(user_frame_buffer_touch));
00188     }
00189 }
00190 #endif // TouckKey_LCD_shield
00191 
00192 
00193 /************************** String Disp Test **************************/
00194 #if STRING_DISP_TEST
00195 /* STRING BUFFER Parameter GRAPHICS_LAYER_2 */
00196 #define STRING_PIXEL_HW               (120)
00197 #define STRING_PIXEL_VM               (24)
00198 #define STRING_BUFFER_BYTE_PER_PIXEL  (2u)
00199 #define STRING_BUFFER_STRIDE          (((LCD_PIXEL_WIDTH * STRING_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
00200 
00201 #if defined(__ICCARM__)
00202 #pragma data_alignment=32
00203 static uint8_t user_frame_buffer_string[STRING_BUFFER_STRIDE * STRING_PIXEL_VM];
00204 #else
00205 static uint8_t user_frame_buffer_string[STRING_BUFFER_STRIDE * STRING_PIXEL_VM]__attribute((aligned(32)));
00206 #endif
00207 
00208 static void string_task(void) {
00209     DisplayBase::rect_t rect;
00210     char test_cnt = 0x20;
00211 
00212     /* The layer by which the character string is drawn */
00213     memset(user_frame_buffer_string, 0, sizeof(user_frame_buffer_string));
00214     dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string));
00215 
00216     rect.vs = LCD_PIXEL_HEIGHT - STRING_PIXEL_VM - 10;
00217     rect.vw = STRING_PIXEL_VM;
00218     rect.hs = LCD_PIXEL_WIDTH - STRING_PIXEL_HW - 10;
00219     rect.hw = STRING_PIXEL_HW;
00220     Display.Graphics_Read_Setting(
00221         DisplayBase::GRAPHICS_LAYER_2,
00222         (void *)user_frame_buffer_string,
00223         STRING_BUFFER_STRIDE,
00224         DisplayBase::GRAPHICS_FORMAT_ARGB4444,
00225         DisplayBase::WR_RD_WRSWA_32_16BIT,
00226         &rect
00227     );
00228     Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_2);
00229 
00230     /* String */
00231     AsciiFont ascii_font(user_frame_buffer_string, STRING_PIXEL_HW, STRING_PIXEL_VM,
00232                          STRING_BUFFER_STRIDE, STRING_BUFFER_BYTE_PER_PIXEL);
00233     ascii_font.DrawStr("Font:", 0, 8, 0x0000ffff, 2);
00234 
00235     while (1) {
00236         //colour: rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red
00237         ascii_font.DrawChar(test_cnt, 84, 0, 0x0000aa9f, 3);
00238         if (test_cnt < 0x7e) {
00239             test_cnt++;
00240         } else {
00241             test_cnt = 0x20;
00242         }
00243         dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string));
00244         ThisThread::sleep_for(1000);
00245     }
00246 }
00247 #endif // STRING_DISP_TEST
00248 
00249 
00250 /************************** main **************************/
00251 int main(void) {
00252     /* Camera and LCD setting */
00253 #if ASPECT_RATIO_16_9
00254     EasyAttach_Init(Display, 640, 360);  //aspect ratio 16:9
00255 #else
00256     EasyAttach_Init(Display);            //aspect ratio 4:3
00257 #endif
00258 
00259     /* Start camera */
00260 #if MBED_CONF_APP_CAMERA
00261     Start_Video_Camera();
00262 #endif // MBED_CONF_APP_CAMERA
00263 
00264     /* LCD Backlight ON */
00265     ThisThread::sleep_for(50);  // After reset, wait a bit so that the power does not rise abruptly.
00266     EasyAttach_LcdBacklight(true);
00267 
00268     /* Start touch panel processing */
00269 #if defined(TouckKey_LCD_shield)
00270     Thread touchTask;
00271     touchTask.start(callback(touch_task));
00272 #endif // TouckKey_LCD_shield
00273 
00274 #if STRING_DISP_TEST
00275     /* Start string disp processing */
00276     Thread stringTask;
00277     stringTask.start(callback(string_task));
00278 #endif // STRING_DISP_TEST
00279 
00280     /* LED blink */
00281     DigitalOut  led_blue(LED_BLUE);
00282     while (1) {
00283         led_blue = !led_blue;
00284         ThisThread::sleep_for(500);
00285     }
00286 }