Video image display and touch panel sample for GR-PEACH LCD Shield.
Information
Japanese version is available in lower part of this page.
このページの後半に日本語版が用意されています.
Information
This sample has multiple frame buffers so that the clock source can display different cameras and LCDs cleanly. If you are using the NTSC signal, the following sample is simpler.
このサンプルはクロック元が異なるカメラとLCDを綺麗に表示するために、複数のフレームバッファを持っています。NTSC信号を使用するのであれば、以下のサンプルの方が単純です。
https://developer.mbed.org/users/dkato/code/GR-PEACH_NTSC_in_2ch/
What is this ?
The basic function of the GR-PEACH LCD Shield can be tried by this sample.
Display the information of the touch panel on the camera image.
A character font is shown to the screen lower right every 1 second.
Touch panel information
The touch location of the blue and the 2nd point becomes pink in the 1st touch location in case of a multi-touch.
While touching the screen, a white square in the upper left corner of the screen will be displayed.
Touch information is being output in printf. When doing terminal designation, please set 230400 as a baud rate.
Composition
GR-PEACH, GR-PEACH 4.3 inch LCD Shield or GR-PEACH 7.1 inch LCD Shield, GR-PEACH AUDIO CAMERA Shield and Camera.
When using analog input for video input, GR-PEACH AUDIO CAMERA Shield and the camera are unnecessary.
(Setting the VIDEO_CVBS to VIDEO_INPUT_METHOD)
Please input analog signal to NTSC1A pin. (Even if there are no input signals, a touch panel can be operated.).
Video input of default is a digital input (Cmos Camera). When changing the video input, please change the below.
mbed_app.json
{ "config": { "camera":{ "help": "0:disable 1:enable", "value": "1" }, "camera-type":{ "help": "Please see README.md", "value": "CAMERA_CVBS" }, "lcd":{ "help": "0:disable 1:enable", "value": "1" }, "lcd-type":{ "help": "Please see README.md", "value": "GR_PEACH_4_3INCH_SHIELD" } } }
camera-type "value" | Description |
---|---|
CAMERA_CVBS | GR-PEACH NTSC signal |
CAMERA_MT9V111 | GR-PEACH MT9V111 |
CAMERA_OV7725 | GR-LYHCEE included camera |
CAMERA_OV5642 | GR-PEACH OV5642 |
CAMERA_WIRELESS_CAMERA | GR-PEACH Wireless/Camera shield (MT9V111) |
lcd-type "value" | Description |
---|---|
GR_PEACH_4_3INCH_SHIELD | GR-PEACH 4.3 inch LCD shield |
GR_PEACH_7_1INCH_SHIELD | GR-PEACH 7.1 inch LCD shield |
GR_PEACH_RSK_TFT | GR-PEACH RSK board LCD |
GR_PEACH_DISPLAY_SHIELD | GR-PEACH Display Shield or DVi-Board |
GR_LYCHEE_LCD | GR-LYHCEE TF043HV001A0..etc(40pin) |
概要
このサンプルではGR-PEACH LCD Shieldの基本的な機能を試せます。
カメラ画像の上にタッチパネルの情報を重ねて表示します。
文字フォントが右下に1秒毎に表示されます。
タッチパネルの情報
マルチタッチの場合は1点目のタッチ位置は青、2点目のタッチ位置はピンクになります。
画面がタッチされている間、画面左上に白い四角が表示されます。
printfでもタッチ情報を出力しています。ターミナル表示を行う際は、ボーレートに230400を設定してください。
構成
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 とカメラは不要です。
(VIDEO_INPUT_METHOD にVIDEO_CVBS を設定)
NTSC1Aピンにアナログ信号を入力してください。(入力信号が無くてもタッチパネルは操作できます。)
デフォルトのビデオ入力はデジタル入力(Cmos Camera)です。ビデオ入力を変更する際は以下を変更してください。
mbed_app.json
{ "config": { "camera":{ "help": "0:disable 1:enable", "value": "1" }, "camera-type":{ "help": "Please see README.md", "value": "CAMERA_CVBS" }, "lcd":{ "help": "0:disable 1:enable", "value": "1" }, "lcd-type":{ "help": "Please see README.md", "value": "GR_PEACH_4_3INCH_SHIELD" } } }
camera-type "value" | Description |
---|---|
CAMERA_CVBS | GR-PEACH NTSC signal |
CAMERA_MT9V111 | GR-PEACH MT9V111 |
CAMERA_OV7725 | GR-LYHCEE included camera |
CAMERA_OV5642 | GR-PEACH OV5642 |
CAMERA_WIRELESS_CAMERA | GR-PEACH Wireless/Camera shield (MT9V111) |
lcd-type "value" | Description |
---|---|
GR_PEACH_4_3INCH_SHIELD | GR-PEACH 4.3 inch LCD shield |
GR_PEACH_7_1INCH_SHIELD | GR-PEACH 7.1 inch LCD shield |
GR_PEACH_RSK_TFT | GR-PEACH RSK board LCD |
GR_PEACH_DISPLAY_SHIELD | GR-PEACH Display Shield or DVi-Board |
GR_LYCHEE_LCD | GR-LYHCEE TF043HV001A0..etc(40pin) |
main.cpp
- Committer:
- dkato
- Date:
- 2018-10-25
- Revision:
- 10:cdef6df6eac9
- Parent:
- 9:61f53c094a1c
File content as of revision 10:cdef6df6eac9:
#include "mbed.h" #include "dcache-control.h" #include "EasyAttach_CameraAndLCD.h" #include "AsciiFont.h" #define STRING_DISP_TEST (1) #if (MBED_CONF_APP_LCD_TYPE == GR_PEACH_4_3INCH_SHIELD) #define ASPECT_RATIO_16_9 (1) #endif static DisplayBase Display; /************************** Camera **************************/ #if MBED_CONF_APP_CAMERA /*! 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. */ #define DATA_SIZE_PER_PIC (2u) #define FRAME_BUFFER_STRIDE (((LCD_PIXEL_WIDTH * DATA_SIZE_PER_PIC) + 31u) & ~31u) #define FRAME_BUFFER_HEIGHT (LCD_PIXEL_HEIGHT) #if defined(__ICCARM__) #pragma data_alignment=32 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram"; #else static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32))); #endif static void Start_Video_Camera(void) { DisplayBase::rect_t rect; // Initialize the background to black for (uint32_t i = 0; i < sizeof(user_frame_buffer0); i += 2) { user_frame_buffer0[i + 0] = 0x00; user_frame_buffer0[i + 1] = 0x80; } // Video capture setting (progressive form fixed) Display.Video_Write_Setting( DisplayBase::VIDEO_INPUT_CHANNEL_0, DisplayBase::COL_SYS_NTSC_358, (void *)user_frame_buffer0, FRAME_BUFFER_STRIDE, DisplayBase::VIDEO_FORMAT_YCBCR422, DisplayBase::WR_RD_WRSWA_32_16BIT, LCD_PIXEL_HEIGHT, LCD_PIXEL_WIDTH ); EasyAttach_CameraStart(Display, DisplayBase::VIDEO_INPUT_CHANNEL_0); // LCD setting 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 *)user_frame_buffer0, FRAME_BUFFER_STRIDE, DisplayBase::GRAPHICS_FORMAT_YCBCR422, DisplayBase::WR_RD_WRSWA_32_16BIT, &rect ); Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0); } #endif // MBED_CONF_APP_CAMERA /************************** Touch panel **************************/ #if defined(TouckKey_LCD_shield) /* 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 DRAW_POINT (8) static Semaphore sem_touch_int(0); #if defined(__ICCARM__) #pragma data_alignment=32 static uint8_t user_frame_buffer_touch[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]; #else static uint8_t user_frame_buffer_touch[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32))); #endif static void draw_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 - (DRAW_POINT / 2)) >= 0) { x -= (DRAW_POINT / 2); } if (x > ((int)LCD_PIXEL_WIDTH - DRAW_POINT)) { x = ((int)LCD_PIXEL_WIDTH - DRAW_POINT); } if ((y - (DRAW_POINT / 2)) >= 0) { y -= (DRAW_POINT / 2); } if (y > ((int)LCD_PIXEL_HEIGHT - DRAW_POINT)) { y = ((int)LCD_PIXEL_HEIGHT - DRAW_POINT); } idx_base = (x + ((int)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 < DRAW_POINT; i++) { wk_idx = idx_base + ((int)LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL * i); for (j = 0; j < DRAW_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) { DisplayBase::rect_t rect; TouchKey::touch_pos_t touch_pos[TOUCH_NUM]; int touch_num = 0; int touch_num_last = 0; uint32_t i; TouckKey_LCD_shield touch(P4_0, P2_13, I2C_SDA, I2C_SCL); /* 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=%lu,y=%lu} ", touch_pos[i].valid, touch_pos[i].x, touch_pos[i].y); if (touch_pos[i].valid) { draw_touch_pos(user_frame_buffer_touch, i, touch_pos[i].x, touch_pos[i].y); } } printf("\r\n"); /* Data cache clean */ dcache_clean(user_frame_buffer_touch, sizeof(user_frame_buffer_touch)); } } #endif // TouckKey_LCD_shield /************************** String Disp Test **************************/ #if STRING_DISP_TEST /* STRING BUFFER Parameter GRAPHICS_LAYER_2 */ #define STRING_PIXEL_HW (120) #define STRING_PIXEL_VM (24) #define STRING_BUFFER_BYTE_PER_PIXEL (2u) #define STRING_BUFFER_STRIDE (((LCD_PIXEL_WIDTH * STRING_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u) #if defined(__ICCARM__) #pragma data_alignment=32 static uint8_t user_frame_buffer_string[STRING_BUFFER_STRIDE * STRING_PIXEL_VM]; #else static uint8_t user_frame_buffer_string[STRING_BUFFER_STRIDE * STRING_PIXEL_VM]__attribute((aligned(32))); #endif static void string_task(void) { DisplayBase::rect_t rect; char test_cnt = 0x20; /* The layer by which the character string is drawn */ memset(user_frame_buffer_string, 0, sizeof(user_frame_buffer_string)); dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string)); rect.vs = LCD_PIXEL_HEIGHT - STRING_PIXEL_VM - 10; rect.vw = STRING_PIXEL_VM; rect.hs = LCD_PIXEL_WIDTH - STRING_PIXEL_HW - 10; rect.hw = STRING_PIXEL_HW; Display.Graphics_Read_Setting( DisplayBase::GRAPHICS_LAYER_2, (void *)user_frame_buffer_string, STRING_BUFFER_STRIDE, DisplayBase::GRAPHICS_FORMAT_ARGB4444, DisplayBase::WR_RD_WRSWA_32_16BIT, &rect ); Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_2); /* String */ AsciiFont ascii_font(user_frame_buffer_string, STRING_PIXEL_HW, STRING_PIXEL_VM, STRING_BUFFER_STRIDE, STRING_BUFFER_BYTE_PER_PIXEL); ascii_font.DrawStr("Font:", 0, 8, 0x0000ffff, 2); while (1) { //colour: rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red ascii_font.DrawChar(test_cnt, 84, 0, 0x0000aa9f, 3); if (test_cnt < 0x7e) { test_cnt++; } else { test_cnt = 0x20; } dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string)); ThisThread::sleep_for(1000); } } #endif // STRING_DISP_TEST /************************** main **************************/ int main(void) { /* Camera and LCD setting */ #if ASPECT_RATIO_16_9 EasyAttach_Init(Display, 640, 360); //aspect ratio 16:9 #else EasyAttach_Init(Display); //aspect ratio 4:3 #endif /* Start camera */ #if MBED_CONF_APP_CAMERA Start_Video_Camera(); #endif // MBED_CONF_APP_CAMERA /* LCD Backlight ON */ ThisThread::sleep_for(50); // After reset, wait a bit so that the power does not rise abruptly. EasyAttach_LcdBacklight(true); /* Start touch panel processing */ #if defined(TouckKey_LCD_shield) Thread touchTask; touchTask.start(callback(touch_task)); #endif // TouckKey_LCD_shield #if STRING_DISP_TEST /* Start string disp processing */ Thread stringTask; stringTask.start(callback(string_task)); #endif // STRING_DISP_TEST /* LED blink */ DigitalOut led_blue(LED_BLUE); while (1) { led_blue = !led_blue; ThisThread::sleep_for(500); } }