Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: AsciiFont GR-PEACH_video LCD_shield_config
Fork of GR-PEACH_Video_Display by
main.cpp
- Committer:
- dkato
- Date:
- 2016-11-25
- Revision:
- 5:4e96673f4830
- Parent:
- 4:bafd63604b7c
- Child:
- 6:95b92f2035dc
File content as of revision 5:4e96673f4830:
#include "mbed.h"
#include "DisplayBace.h"
#include "rtos.h"
#include "AsciiFont.h"
#define VIDEO_CVBS (0) /* Analog Video Signal */
#define VIDEO_CMOS_CAMERA (1) /* Digital Video Signal */
#define VIDEO_YCBCR422 (0)
#define VIDEO_RGB888 (1)
#define VIDEO_RGB565 (2)
/**** User Selection *********/
/** Camera setting **/
#define VIDEO_INPUT_METHOD (VIDEO_CMOS_CAMERA) /* Select VIDEO_CVBS or VIDEO_CMOS_CAMERA */
#define VIDEO_INPUT_FORMAT (VIDEO_YCBCR422) /* Select VIDEO_YCBCR422 or VIDEO_RGB888 or VIDEO_RGB565 */
#define USE_VIDEO_CH (0) /* Select 0 or 1 If selecting VIDEO_CMOS_CAMERA, should be 0.) */
#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) */
/*****************************/
/** LCD shield config **/
#if (LCD_TYPE == 0)
#include "LCD_shield_config_4_3inch.h"
#else
#include "LCD_shield_config_7_1inch.h"
#endif
/** Video and Grapics (GRAPHICS_LAYER_0) parameter **/
/* video input */
#if USE_VIDEO_CH == (0)
#define VIDEO_INPUT_CH (DisplayBase::VIDEO_INPUT_CHANNEL_0)
#define VIDEO_INT_TYPE (DisplayBase::INT_TYPE_S0_VFIELD)
#else
#define VIDEO_INPUT_CH (DisplayBase::VIDEO_INPUT_CHANNEL_1)
#define VIDEO_INT_TYPE (DisplayBase::INT_TYPE_S1_VFIELD)
#endif
/* NTSC or PAL */
#if VIDEO_PAL == 0
#define COL_SYS (DisplayBase::COL_SYS_NTSC_358)
#else
#define COL_SYS (DisplayBase::COL_SYS_PAL_443)
#endif
/* Video input and LCD layer 0 output */
#if VIDEO_INPUT_FORMAT == VIDEO_YCBCR422
#define VIDEO_FORMAT (DisplayBase::VIDEO_FORMAT_YCBCR422)
#define GRAPHICS_FORMAT (DisplayBase::GRAPHICS_FORMAT_YCBCR422)
#define WR_RD_WRSWA (DisplayBase::WR_RD_WRSWA_NON)
#elif VIDEO_INPUT_FORMAT == VIDEO_RGB565
#define VIDEO_FORMAT (DisplayBase::VIDEO_FORMAT_RGB565)
#define GRAPHICS_FORMAT (DisplayBase::GRAPHICS_FORMAT_RGB565)
#define WR_RD_WRSWA (DisplayBase::WR_RD_WRSWA_32_16BIT)
#else
#define VIDEO_FORMAT (DisplayBase::VIDEO_FORMAT_RGB888)
#define GRAPHICS_FORMAT (DisplayBase::GRAPHICS_FORMAT_RGB888)
#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 */
#define FRAME_BUFFER_NUM (3u)
#if ( VIDEO_INPUT_FORMAT == VIDEO_YCBCR422 || VIDEO_INPUT_FORMAT == VIDEO_RGB565 )
#define FRAME_BUFFER_BYTE_PER_PIXEL (2u)
#else
#define FRAME_BUFFER_BYTE_PER_PIXEL (4u)
#endif
#define FRAME_BUFFER_STRIDE (((LCD_PIXEL_WIDTH * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
/* 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 DROW_POINT (5)
/* 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)
static DisplayBase Display;
static DigitalOut lcd_pwon(P7_15);
static DigitalOut lcd_blon(P8_1);
static PwmOut lcd_cntrst(P8_15);
static Serial pc(USBTX, USBRX);
static Semaphore sem_touch_int(0);
static TouckKey_LCD_shield touch(P4_0, P2_13, I2C_SDA, I2C_SCL);
static Thread * p_VideoLcdTask = NULL;
static DigitalOut led_blue(LED_BLUE);
#if defined(__ICCARM__)
/* 32 bytes aligned */
#pragma data_alignment=32
static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
#pragma data_alignment=32
static uint8_t user_frame_buffer1[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
#pragma data_alignment=32
static uint8_t user_frame_buffer2[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
#pragma data_alignment=32
static uint8_t user_frame_buffer_touch[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
#pragma data_alignment=32
static uint8_t user_frame_buffer_string[STRING_BUFFER_STRIDE * STRING_PIXEL_VM];
#else
/* 32 bytes aligned */
static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
static uint8_t user_frame_buffer1[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
static uint8_t user_frame_buffer2[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
static uint8_t user_frame_buffer_touch[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32)));
static uint8_t user_frame_buffer_string[STRING_BUFFER_STRIDE * STRING_PIXEL_VM]__attribute((aligned(32)));
#endif
static uint8_t * FrameBufferTbl[FRAME_BUFFER_NUM] = {user_frame_buffer0, user_frame_buffer1, user_frame_buffer2};
#if VIDEO_INPUT_METHOD == VIDEO_CVBS
static volatile int32_t vfield_count = 0;
#endif
static int write_buff_num = 0;
static int read_buff_num = 0;
static bool graphics_init_end = false;
/****** 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);
}
}
/****** LCD ******/
#if(0) /* When needing LCD Vsync interrupt, please make it effective. */
static void IntCallbackFunc_LoVsync(DisplayBase::int_type_t int_type) {
/* Interrupt callback function for Vsync interruption */
}
#endif
static void Init_LCD_Display(void) {
DisplayBase::graphics_error_t error;
DisplayBase::lcd_config_t lcd_config;
PinName lvds_pin[8] = {
/* data pin */
P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0
};
lcd_pwon = 0;
lcd_blon = 0;
Thread::wait(100);
lcd_pwon = 1;
lcd_blon = 1;
Display.Graphics_Lvds_Port_Init(lvds_pin, 8);
/* Graphics initialization process */
lcd_config = LcdCfgTbl_LCD_shield;
error = Display.Graphics_init(&lcd_config);
if (error != DisplayBase::GRAPHICS_OK) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
graphics_init_end = true;
#if(0) /* When needing LCD Vsync interrupt, please make it effective. */
/* Interrupt callback function setting (Vsync signal output from scaler 0) */
error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_LO_VSYNC, 0, IntCallbackFunc_LoVsync);
if (error != DisplayBase::GRAPHICS_OK) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
#endif
}
static void Start_LCD_Display(uint8_t * p_buf) {
DisplayBase::rect_t rect;
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 *)p_buf,
FRAME_BUFFER_STRIDE,
GRAPHICS_FORMAT,
WR_RD_WRSWA,
&rect
);
Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
}
/****** Video ******/
#if(0) /* When needing video Vsync interrupt, please make it effective. */
static void IntCallbackFunc_ViVsync(DisplayBase::int_type_t int_type) {
/* Interrupt callback function for Vsync interruption */
}
#endif
static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) {
/* Interrupt callback function */
#if VIDEO_INPUT_METHOD == VIDEO_CVBS
if (vfield_count == 0) {
vfield_count = 1;
} else {
vfield_count = 0;
#else
{
#endif
if (p_VideoLcdTask != NULL) {
p_VideoLcdTask->signal_set(1);
}
}
}
static void Init_Video(void) {
DisplayBase::graphics_error_t error;
/* Graphics initialization process */
if (graphics_init_end == false) {
/* When not initializing LCD, this processing is needed. */
error = Display.Graphics_init(NULL);
if (error != DisplayBase::GRAPHICS_OK) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
graphics_init_end = true;
}
#if VIDEO_INPUT_METHOD == VIDEO_CVBS
error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC, NULL);
if( error != DisplayBase::GRAPHICS_OK ) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
#elif VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA
DisplayBase::video_ext_in_config_t ext_in_config;
PinName cmos_camera_pin[11] = {
/* data pin */
P2_7, P2_6, P2_5, P2_4, P2_3, P2_2, P2_1, P2_0,
/* control pin */
P10_0, /* DV0_CLK */
P1_0, /* DV0_Vsync */
P1_1 /* DV0_Hsync */
};
/* MT9V111 camera input config */
ext_in_config.inp_format = DisplayBase::VIDEO_EXTIN_FORMAT_BT601; /* BT601 8bit YCbCr format */
ext_in_config.inp_pxd_edge = DisplayBase::EDGE_RISING; /* Clock edge select for capturing data */
ext_in_config.inp_vs_edge = DisplayBase::EDGE_RISING; /* Clock edge select for capturing Vsync signals */
ext_in_config.inp_hs_edge = DisplayBase::EDGE_RISING; /* Clock edge select for capturing Hsync signals */
ext_in_config.inp_endian_on = DisplayBase::OFF; /* External input bit endian change on/off */
ext_in_config.inp_swap_on = DisplayBase::OFF; /* External input B/R signal swap on/off */
ext_in_config.inp_vs_inv = DisplayBase::SIG_POL_NOT_INVERTED; /* External input DV_VSYNC inversion control */
ext_in_config.inp_hs_inv = DisplayBase::SIG_POL_INVERTED; /* External input DV_HSYNC inversion control */
ext_in_config.inp_f525_625 = DisplayBase::EXTIN_LINE_525; /* Number of lines for BT.656 external input */
ext_in_config.inp_h_pos = DisplayBase::EXTIN_H_POS_CRYCBY; /* Y/Cb/Y/Cr data string start timing to Hsync reference */
ext_in_config.cap_vs_pos = 6; /* Capture start position from Vsync */
ext_in_config.cap_hs_pos = 150; /* Capture start position form Hsync */
#if (LCD_TYPE == 0)
/* The same screen ratio as the screen ratio of the LCD. */
ext_in_config.cap_width = 640; /* Capture width */
ext_in_config.cap_height = 363; /* Capture height Max 468[line]
Due to CMOS(MT9V111) output signal timing and VDC5 specification */
#else
ext_in_config.cap_width = 640; /* Capture width */
ext_in_config.cap_height = 468; /* Capture height Max 468[line]
Due to CMOS(MT9V111) output signal timing and VDC5 specification */
#endif
error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_EXT, &ext_in_config);
if( error != DisplayBase::GRAPHICS_OK ) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
/* Camera input port setting */
error = Display.Graphics_Dvinput_Port_Init(cmos_camera_pin, 11);
if( error != DisplayBase::GRAPHICS_OK ) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
#endif
#if(0) /* When needing video Vsync interrupt, please make it effective. */
/* Interrupt callback function setting (Vsync signal input to scaler 0) */
error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VI_VSYNC, 0, IntCallbackFunc_ViVsync);
if (error != DisplayBase::GRAPHICS_OK) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
#endif
/* Interrupt callback function setting (Field end signal for recording function in scaler 0) */
error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE, 0, IntCallbackFunc_Vfield);
if (error != DisplayBase::GRAPHICS_OK) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
}
static void Start_Video(uint8_t * p_buf) {
DisplayBase::graphics_error_t error;
/* Video capture setting (progressive form fixed) */
error = Display.Video_Write_Setting(
VIDEO_INPUT_CH,
COL_SYS,
p_buf,
FRAME_BUFFER_STRIDE,
VIDEO_FORMAT,
WR_RD_WRSWA,
VIDEO_PIXEL_VW,
VIDEO_PIXEL_HW
);
if (error != DisplayBase::GRAPHICS_OK) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
/* Video write process start */
error = Display.Video_Start(VIDEO_INPUT_CH);
if (error != DisplayBase::GRAPHICS_OK) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
/* Video write process stop */
error = Display.Video_Stop(VIDEO_INPUT_CH);
if (error != DisplayBase::GRAPHICS_OK) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
/* Video write process start */
error = Display.Video_Start(VIDEO_INPUT_CH);
if (error != DisplayBase::GRAPHICS_OK) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
}
/****** Video input is output to LCD ******/
static void video_lcd_task(void) {
DisplayBase::graphics_error_t error;
int wk_num;
int i;
/* Initialization memory */
for (i = 0; i < FRAME_BUFFER_NUM; i++) {
memset(FrameBufferTbl[i], 0, (FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT));
dcache_clean(FrameBufferTbl[i], (FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT));
}
/* Start of Video */
Start_Video(FrameBufferTbl[write_buff_num]);
/* Wait for first video drawing */
Thread::signal_wait(1);
write_buff_num++;
if (write_buff_num >= FRAME_BUFFER_NUM) {
write_buff_num = 0;
}
error = Display.Video_Write_Change(VIDEO_INPUT_CH, FrameBufferTbl[write_buff_num], FRAME_BUFFER_STRIDE);
if (error != DisplayBase::GRAPHICS_OK) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
/* Start of LCD */
Start_LCD_Display(FrameBufferTbl[read_buff_num]);
/* Backlight on */
Thread::wait(200);
lcd_cntrst.write(1.0);
while (1) {
Thread::signal_wait(1);
wk_num = write_buff_num + 1;
if (wk_num >= FRAME_BUFFER_NUM) {
wk_num = 0;
}
/* If the next buffer is empty, it's changed. */
if (wk_num != read_buff_num) {
read_buff_num = write_buff_num;
write_buff_num = wk_num;
/* Change video buffer */
error = Display.Video_Write_Change(VIDEO_INPUT_CH, FrameBufferTbl[write_buff_num], FRAME_BUFFER_STRIDE);
if (error != DisplayBase::GRAPHICS_OK) {
printf("Line %d, error %d\n", __LINE__, error);
mbed_die();
}
/* Change LCD buffer */
Display.Graphics_Read_Change(DisplayBase::GRAPHICS_LAYER_0, (void *)FrameBufferTbl[read_buff_num]);
}
}
}
/****** Touch panel ******/
static void drow_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 - (DROW_POINT / 2)) >= 0) {
x -= (DROW_POINT / 2);
}
if (x > (LCD_PIXEL_WIDTH - DROW_POINT)) {
x = (LCD_PIXEL_WIDTH - DROW_POINT);
}
if ((y - (DROW_POINT / 2)) >= 0) {
y -= (DROW_POINT / 2);
}
if (y > (LCD_PIXEL_HEIGHT - DROW_POINT)) {
y = (LCD_PIXEL_HEIGHT - DROW_POINT);
}
idx_base = (x + (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 < DROW_POINT; i++) {
wk_idx = idx_base + (LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL * i);
for (j = 0; j < DROW_POINT; j++) {
p_buf[wk_idx++] = coller_pix[0];
p_buf[wk_idx++] = coller_pix[1];
}
}
}
static void drow_touch_keyonoff(uint8_t * p_buf, int id, bool onoff) {
int idx_base;
int wk_idx;
int i;
int j;
uint8_t coller_pix[TOUCH_BUFFER_BYTE_PER_PIXEL]; /* ARGB4444 */
/* Display position */
if (id == 0) {
idx_base = 0;
} else {
idx_base = DROW_POINT * TOUCH_BUFFER_BYTE_PER_PIXEL;
}
/* Select color */
if (onoff == false) {
/* Transparency */
coller_pix[0] = 0x00; /* 4:Green 4:Blue */
coller_pix[1] = 0x00; /* 4:Alpha 4:Red */
} else {
/* White */
coller_pix[0] = 0xff; /* 4:Green 4:Blue */
coller_pix[1] = 0xff; /* 4:Alpha 4:Red */
}
/* Drawing */
for (i = 0; i < DROW_POINT; i++) {
wk_idx = idx_base + (LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL * i);
for (j = 0; j < DROW_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;
int i;
/* 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=%d,y=%d} ", touch_pos[i].valid, touch_pos[i].x, touch_pos[i].y);
drow_touch_keyonoff(user_frame_buffer_touch, i, touch_pos[i].valid);
if (touch_pos[i].valid) {
drow_touch_pos(user_frame_buffer_touch, i, touch_pos[i].x, touch_pos[i].y);
}
}
printf("\n");
/* Data cache clean */
dcache_clean(user_frame_buffer_touch, sizeof(user_frame_buffer_touch));
}
}
/****** main ******/
int main(void) {
DisplayBase::rect_t rect;
char test_cnt = 0x20;
/* Change the baud rate of the printf() */
pc.baud(921600);
/* Initialization of LCD */
Init_LCD_Display(); /* When using LCD, please call before than Init_Video(). */
/* Initialization of Video */
Init_Video();
/* Start Video and Lcd processing */
p_VideoLcdTask = new Thread;
p_VideoLcdTask->start(video_lcd_task);
/* Start touch panel processing */
Thread touchTask;
touchTask.start(touch_task);
/* 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) {
led_blue = !led_blue;
//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));
Thread::wait(1000);
}
}
