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_FORMAT | VIDEO_YCBCR422、VIDEO_RGB888、VIDEO_RGB565から選択できます。 |
---|---|
VIDEO_PAL | 0を設定するとNTSC、1を設定するとPALの設定となります。 |
LCD_TYPE | 0を設定すると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-PEACH、GR-PEACH 4.3 inch LCD Shield または GR-PEACH 7.1 inch LCD Shield、GR-PEACH AUDIO CAMERA Shield。
GR-PEACH AUDIO CAMERA Shieldを使用しない場合は、NTSC1Aピン、および、NTSC1Bピンにアナログ信号を入力してください。
(写真はNTSC1Aピン(黄色)とGNDピン(黒)を引き出した例です。)
Diff: main.cpp
- 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]);