Sample of NTSC 2ch input.

Dependencies:   GR-PEACH_video LCD_shield_config

概要

2系統のNTSC入力をLCDの左右に分けて表示するサンプルです。
ハードウエア機能を用いることで起動時にビデオ入力とLCD出力の設定した後は自動で動作し続けます。そのため、起動後のCPU負荷が少ないのが特徴です。

機能設定

下記のマクロを変更することで、一部機能を変更できます。

main.cpp

/**** User Selection *********/
/** Camera setting **/
#define VIDEO_INPUT_FORMAT     (VIDEO_YCBCR422)    /* Select  VIDEO_YCBCR422 or VIDEO_RGB888 or VIDEO_RGB565        */
#define VIDEO_PAL              (0)                 /* Select  0(NTSC) or 1(PAL) If selecting VIDEO_CVBS, this parameter is not referenced.) */
/** LCD setting **/
#define LCD_TYPE               (0)                 /* Select  0(4.3inch) or 1(7.1inch) */
/*****************************/


VIDEO_INPUT_FORMATVIDEO_YCBCR422、VIDEO_RGB888、VIDEO_RGB565から選択できます。
VIDEO_PAL0を設定するとNTSC、1を設定するとPALの設定となります。
LCD_TYPE0を設定するとGR-PEACH 4.3 inch LCD Shield、1を設定するとGR-PEACH 7.1 inch LCD Shieldの設定となります。


また、下記関数の引数を変更することで、入力画像の表示位置や大きさを変更できます。
(Output bufferの範囲を超えるような値は設定しないでください。幅は16の倍数、高さは8の倍数を設定してください。)

main.cpp main()

    /* Start of Video ch0 */
    Start_Video(
        DisplayBase::VIDEO_INPUT_CHANNEL_0,   /* Video input channe */
        user_frame_buffer0,                   /* Output buffer */
        0,                                    /* The x coordinate of the upper-left corner */
        0,                                    /* The y coordinate of the upper-left corner */
        (LCD_PIXEL_WIDTH / 2),                /* width  (A multiple of 16) */
        LCD_PIXEL_HEIGHT                      /* height (A multiple of 8) */
    );

(上記の例はNTSC1Aの入力をLCDの画面左側に表示するための設定です。入力画像の高さはLCD画面サイズと同じ、幅は画面サイズの1/2に設定しています。)

構成

GR-PEACHGR-PEACH 4.3 inch LCD Shield または GR-PEACH 7.1 inch LCD ShieldGR-PEACH AUDIO CAMERA Shield

GR-PEACH AUDIO CAMERA Shieldを使用しない場合は、NTSC1Aピン、および、NTSC1Bピンにアナログ信号を入力してください。 /media/uploads/dkato/video_display_analog.jpg
(写真はNTSC1Aピン(黄色)とGNDピン(黒)を引き出した例です。)

Revision:
1:e59e938472ac
Parent:
0:f8cb87301ad8
--- a/main.cpp	Mon Aug 08 12:59:36 2016 +0000
+++ b/main.cpp	Thu Aug 25 04:57:15 2016 +0000
@@ -44,10 +44,6 @@
   #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 */
@@ -142,8 +138,12 @@
     }
 }
 
-static void Start_Video(DisplayBase::video_input_channel_t ch, uint8_t * p_buf) {
+static void Start_Video(DisplayBase::video_input_channel_t ch, uint8_t * p_frame_buffer,
+ uint16_t pos_x, uint16_t pos_y, uint16_t width, uint16_t height) {
     DisplayBase::graphics_error_t error;
+    uint8_t * p_buf;
+
+    p_buf = p_frame_buffer + (FRAME_BUFFER_BYTE_PER_PIXEL * pos_x) + (FRAME_BUFFER_STRIDE * pos_y);
 
     /* Video capture setting (progressive form fixed) */
     error = Display.Video_Write_Setting(
@@ -153,8 +153,8 @@
                 FRAME_BUFFER_STRIDE,
                 VIDEO_FORMAT,
                 WR_RD_WRSWA,
-                VIDEO_PIXEL_VW,
-                VIDEO_PIXEL_HW / 2
+                (height & ~7u),      /* A multiple of 8 */
+                (width  & ~15u)      /* A multiple of 16 */
             );
     if (error != DisplayBase::GRAPHICS_OK) {
         printf("Line %d, error %d\n", __LINE__, error);
@@ -183,6 +183,18 @@
     }
 }
 
+/****** 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);
+    }
+}
+
 /****** main ******/
 int main(void) {
     /* Initialization of LCD */
@@ -192,11 +204,35 @@
     Init_Video();
 
     /* Initialization memory */
-    memset(user_frame_buffer0, 0, (FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT));
+#if VIDEO_INPUT_FORMAT == VIDEO_YCBCR422
+    for (int i = 0; i < sizeof(user_frame_buffer0); i += 2) {
+        user_frame_buffer0[i + 0] = 0x10;
+        user_frame_buffer0[i + 1] = 0x80;
+    }
+#else
+    memset(user_frame_buffer0, 0, sizeof(user_frame_buffer0));
+#endif
+    dcache_clean(user_frame_buffer0, sizeof(user_frame_buffer0));
 
-    /* Start of Video */
-    Start_Video(DisplayBase::VIDEO_INPUT_CHANNEL_0, &user_frame_buffer0[0]);
-    Start_Video(DisplayBase::VIDEO_INPUT_CHANNEL_1, &user_frame_buffer0[FRAME_BUFFER_STRIDE / 2]);
+    /* Start of Video ch0 */
+    Start_Video(
+        DisplayBase::VIDEO_INPUT_CHANNEL_0,   /* Video input channe */
+        user_frame_buffer0,                   /* Output buffer */
+        0,                                    /* The x coordinate of the upper-left corner */
+        0,                                    /* The y coordinate of the upper-left corner */
+        (LCD_PIXEL_WIDTH / 2),                /* width  (A multiple of 16) */
+        LCD_PIXEL_HEIGHT                      /* height (A multiple of 8) */
+    );
+
+    /* Start of Video ch1 */
+    Start_Video(
+        DisplayBase::VIDEO_INPUT_CHANNEL_1,   /* Video input channe */
+        user_frame_buffer0,                   /* Output buffer */
+        (LCD_PIXEL_WIDTH / 2),                /* The x coordinate of the upper-left corner */
+        0,                                    /* The y coordinate of the upper-left corner */
+        (LCD_PIXEL_WIDTH / 2),                /* width  (A multiple of 16) */
+        LCD_PIXEL_HEIGHT                      /* height (A multiple of 8) */
+    );
 
     /* Start of LCD */
     Start_LCD_Display(&user_frame_buffer0[0]);